fix(template-engine): collision detection sees all slots of a repeatedly-composed template
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
This commit is contained in:
@@ -123,24 +123,37 @@ public static class CollisionDetector
|
||||
List<ResolvedMember> members,
|
||||
HashSet<int> visited)
|
||||
{
|
||||
// `visited` is the current RECURSION PATH, not a global visited-set: an id is
|
||||
// added on entry and REMOVED on exit (finally), so a template legitimately
|
||||
// composed into more than one slot is re-descended for each slot. The early
|
||||
// return fires only on a genuine cycle — an id already on the ACTIVE path.
|
||||
// (A global visited-set would blind the detector to every collision reachable
|
||||
// only through the second-and-later slot of a repeatedly-composed template.)
|
||||
if (!visited.Add(template.Id))
|
||||
return;
|
||||
|
||||
// Add direct members of this composed template with the prefix. Inherited
|
||||
// placeholder rows are KEPT here: the composed-module walk does not climb the
|
||||
// composed template's parent chain, so the placeholders are the only
|
||||
// representation of a derived module's inherited members.
|
||||
CollectDirectMembers(template, prefix, $"module '{prefix}'", members, skipInherited: false);
|
||||
|
||||
// Recurse into nested compositions
|
||||
foreach (var composition in template.Compositions)
|
||||
try
|
||||
{
|
||||
if (lookup.TryGetValue(composition.ComposedTemplateId, out var nested))
|
||||
// Add direct members of this composed template with the prefix. Inherited
|
||||
// placeholder rows are KEPT here: the composed-module walk does not climb the
|
||||
// composed template's parent chain, so the placeholders are the only
|
||||
// representation of a derived module's inherited members.
|
||||
CollectDirectMembers(template, prefix, $"module '{prefix}'", members, skipInherited: false);
|
||||
|
||||
// Recurse into nested compositions
|
||||
foreach (var composition in template.Compositions)
|
||||
{
|
||||
var nestedPrefix = $"{prefix}.{composition.InstanceName}";
|
||||
CollectComposedMembers(nested, nestedPrefix, lookup, members, visited);
|
||||
if (lookup.TryGetValue(composition.ComposedTemplateId, out var nested))
|
||||
{
|
||||
var nestedPrefix = $"{prefix}.{composition.InstanceName}";
|
||||
CollectComposedMembers(nested, nestedPrefix, lookup, members, visited);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
visited.Remove(template.Id);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CollectInheritedMembers(
|
||||
|
||||
Reference in New Issue
Block a user