Resolve inheritance between identified records

This commit is contained in:
2026-10-23 20:48:46 +00:00
parent 268fd03579
commit 33a51606da
10 changed files with 447 additions and 31 deletions

View File

@@ -158,6 +158,11 @@ func (w *inheritanceWalker) visit(node **document.Node, path Path, unscoped bool
}
}
case document.Sequence:
if sequenceHasIdentifiedInheritanceReferences(*node) {
if problem := w.expandIdentifiedSequence(node, path); problem != nil {
return problem
}
}
working := **node
working.Sequence = slices.Clone(working.Sequence)
*node = &working
@@ -171,6 +176,60 @@ func (w *inheritanceWalker) visit(node **document.Node, path Path, unscoped bool
return nil
}
func (w *inheritanceWalker) expandIdentifiedSequence(node **document.Node, path Path) *Diagnostic {
policy, hasPolicy := w.collectionPolicies.at(path)
applicationFields, _ := w.applicationPolicy.identityFieldsAt(path)
var lower *collectionPolicy
if hasPolicy {
lower = &policy
}
resolution, policyDiagnostics := resolveCollectionPolicy(path, nil, applicationFields, lower)
if len(policyDiagnostics) != 0 {
return &policyDiagnostics[0]
}
// Without an identity rule, retain the existing diagnostic for a reference
// that has no enclosing sibling scope. A null cancellation needs no lookup.
if len(resolution.effectiveIdentityFields) == 0 {
return nil
}
original := *node
graph, diagnostics := analyzeIdentifiedInheritanceGraph(*node, path, resolution.effectiveIdentityFields)
if len(diagnostics) != 0 {
return &diagnostics[0]
}
before, _ := inheritanceLowerBoundCount(*node, -1)
limits := w.limits
if limits.nodes >= 0 {
limits.nodes -= w.nodes - before
}
resolved, diagnostics := applyIdentifiedInheritanceTemplates(
graph, limits, w.origins, w.collectionPolicies, w.applicationPolicy, w.retained,
)
if len(diagnostics) != 0 {
return &diagnostics[0]
}
*node = resolved.root
for pointer, entry := range w.collectionPolicies.collections {
if pathHasPrefix(entry.destination, path) {
delete(w.collectionPolicies.collections, pointer)
}
}
for _, entry := range resolved.collectionPolicies.collections {
w.collectionPolicies.set(entry.destination, entry.policy)
}
deleteOriginSubtree(w.origins, path, original)
for pointer, origin := range resolved.origins {
w.origins[pointer] = origin
}
w.transfers = append(w.transfers, resolved.transfers...)
w.controls = append(w.controls, resolved.controls...)
w.replacements = append(w.replacements, resolved.replacements...)
w.operations = append(w.operations, resolved.operations...)
after, _ := inheritanceLowerBoundCount(*node, -1)
w.nodes += after - before
return nil
}
func scopeHasInheritanceDefinitions(scope *document.Node) bool {
for _, entry := range scope.Mapping {
if entry.Value.Kind != document.Mapping {