Resolve inheritance between identified records
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user