Integrate policy-aware item scopes
This commit is contained in:
@@ -201,10 +201,12 @@ func loadImportedWithAccessTrackedAndProcessingPolicyDeferred(access *filesystem
|
||||
state.stack = append(state.stack, mainRoute)
|
||||
var body *document.Node
|
||||
var declarations []importDeclarationSpec
|
||||
var sequenceDeclarations []sequenceDeclarationSpec
|
||||
var diagnostics []Diagnostic
|
||||
if processing != nil {
|
||||
body = processing.payload
|
||||
declarations = processing.imports
|
||||
sequenceDeclarations = cloneSequenceDeclarations(processing.sequences)
|
||||
} else {
|
||||
body, declarations, diagnostics = splitImportDirectives(main.document)
|
||||
}
|
||||
@@ -213,6 +215,7 @@ func loadImportedWithAccessTrackedAndProcessingPolicyDeferred(access *filesystem
|
||||
state.scope.contributions = append(state.scope.contributions, acquiredContribution{
|
||||
source: cloneSourceInfo(mainInfo), identity: mainNodeKey, role: importRoleMain,
|
||||
scopeOwner: mainNodeKey, payload: body, document: body, processing: processing,
|
||||
sequenceDeclarations: cloneSequenceDeclarations(sequenceDeclarations),
|
||||
})
|
||||
diagnostics = state.walkDeclarations(basePath, declarations, 0, Path{})
|
||||
} else {
|
||||
@@ -255,7 +258,7 @@ func loadImportedWithAccessTrackedAndProcessingPolicyDeferred(access *filesystem
|
||||
contributions: []acquiredContribution{{
|
||||
source: cloneSourceInfo(mainInfo), payload: body, identity: mainNodeKey,
|
||||
role: importRoleMain, scopeOwner: mainNodeKey, destination: destination.clone(),
|
||||
processing: processing, pendingItem: &localScope,
|
||||
processing: processing, sequenceDeclarations: cloneSequenceDeclarations(sequenceDeclarations), pendingItem: &localScope,
|
||||
}},
|
||||
}
|
||||
}
|
||||
@@ -313,14 +316,17 @@ func composeAcquiredInputWithPolicies(input assembledInput, lower collectionPoli
|
||||
if len(scope.contributions) == 1 && scope.contributions[0].role == importRoleMain && scope.contributions[0].pendingItem != nil {
|
||||
main := scope.contributions[0]
|
||||
localScope := cloneAcquisitionScope(*main.pendingItem)
|
||||
if diagnostics := traversal.composePendingItems(&localScope); len(diagnostics) != 0 {
|
||||
if diagnostics := traversal.composePendingItems(&localScope, policy); len(diagnostics) != 0 {
|
||||
return nil, prependCompositionDiagnosticPaths(diagnostics, main.destination.Index(0))
|
||||
}
|
||||
documents := make([]*document.Node, 0, len(localScope.contributions))
|
||||
for _, contribution := range localScope.contributions {
|
||||
documents = append(documents, contribution.document)
|
||||
}
|
||||
completed, diagnostics := composeDocuments(documents...)
|
||||
completed, diagnostics := composeDocumentsWithCollectionPolicy(
|
||||
policy, localScope.collectionPolicies,
|
||||
acquiredSequenceDeclarations(localScope), documents...,
|
||||
)
|
||||
if len(diagnostics) != 0 {
|
||||
return nil, prependCompositionDiagnosticPaths(diagnostics, main.destination.Index(0))
|
||||
}
|
||||
@@ -392,19 +398,20 @@ func composeAcquiredScopeWithPolicy(
|
||||
versionState *sourceVersionState,
|
||||
accounting *importAccounting,
|
||||
) (*composedDocument, []Diagnostic) {
|
||||
_ = lower
|
||||
traversal := importTraversal{
|
||||
accounting: accounting, limits: defaultImportLimits(), rule: rule,
|
||||
versionState: versionState, importGraph: graph.clone(),
|
||||
}
|
||||
if diagnostics := traversal.composePendingItems(scope); len(diagnostics) != 0 {
|
||||
if diagnostics := traversal.composePendingItems(scope, policy); len(diagnostics) != 0 {
|
||||
return nil, diagnostics
|
||||
}
|
||||
documents := make([]*document.Node, 0, len(scope.contributions))
|
||||
for _, contribution := range scope.contributions {
|
||||
documents = append(documents, contribution.document)
|
||||
}
|
||||
composition, diagnostics := composeDocumentsWithPolicy(policy, documents...)
|
||||
composition, diagnostics := composeDocumentsWithCollectionPolicy(
|
||||
policy, lower, acquiredSequenceDeclarations(*scope), documents...,
|
||||
)
|
||||
if len(diagnostics) != 0 {
|
||||
return nil, diagnostics
|
||||
}
|
||||
@@ -617,6 +624,7 @@ func (s *importTraversal) visitPath(candidate selectedImportCandidate, spec impo
|
||||
|
||||
var body *document.Node
|
||||
var declarations []importDeclarationSpec
|
||||
var sequenceDeclarations []sequenceDeclarationSpec
|
||||
var diagnostics []Diagnostic
|
||||
var processing *sourceVersionProcessingResult
|
||||
if s.versionState != nil && s.versionState.mode != sourceVersionModeDefault {
|
||||
@@ -652,7 +660,7 @@ func (s *importTraversal) visitPath(candidate selectedImportCandidate, spec impo
|
||||
s.active[identity] = len(s.stack)
|
||||
s.visited[identity] = route
|
||||
s.stack = append(s.stack, route)
|
||||
diagnostics := s.visitItemSource(canonical, nodeKey, destination, relativeDestination, depth, info, body, declarations, processing)
|
||||
diagnostics := s.visitItemSource(canonical, nodeKey, destination, relativeDestination, depth, info, body, declarations, sequenceDeclarations, processing)
|
||||
delete(s.active, identity)
|
||||
s.stack = s.stack[:len(s.stack)-1]
|
||||
return diagnostics
|
||||
@@ -671,6 +679,7 @@ func (s *importTraversal) visitPath(candidate selectedImportCandidate, spec impo
|
||||
source: cloneSourceInfo(info), payload: body, document: placed,
|
||||
identity: nodeKey, role: role, scopeOwner: s.scope.owner,
|
||||
destination: placementDestination.clone(), relativeDestination: relativeDestination.clone(), processing: processing,
|
||||
sequenceDeclarations: cloneSequenceDeclarations(sequenceDeclarations),
|
||||
})
|
||||
s.active[identity] = len(s.stack)
|
||||
s.visited[identity] = route
|
||||
@@ -701,7 +710,7 @@ func (s *importTraversal) sourceDestination(destination Path) Path {
|
||||
return s.itemFallback.clone()
|
||||
}
|
||||
|
||||
func (s *importTraversal) visitItemSource(canonical string, identity importNodeKey, destination, relativeDestination Path, depth int, info SourceInfo, body *document.Node, declarations []importDeclarationSpec, processing *sourceVersionProcessingResult) []Diagnostic {
|
||||
func (s *importTraversal) visitItemSource(canonical string, identity importNodeKey, destination, relativeDestination Path, depth int, info SourceInfo, body *document.Node, declarations []importDeclarationSpec, sequenceDeclarations []sequenceDeclarationSpec, processing *sourceVersionProcessingResult) []Diagnostic {
|
||||
parentScope := s.scope
|
||||
parentItemScope, parentPrefix, parentFallback := s.itemScope, s.itemPrefix, s.itemFallback
|
||||
s.scope = acquisitionScope{owner: identity}
|
||||
@@ -715,7 +724,7 @@ func (s *importTraversal) visitItemSource(canonical string, identity importNodeK
|
||||
s.scope.contributions = append(s.scope.contributions, acquiredContribution{
|
||||
source: cloneSourceInfo(info), payload: body, document: body,
|
||||
identity: identity, role: importRoleItem, scopeOwner: identity,
|
||||
processing: processing,
|
||||
processing: processing, sequenceDeclarations: cloneSequenceDeclarations(sequenceDeclarations),
|
||||
})
|
||||
diagnostics := s.walkDeclarations(s.access.dir(canonical), declarations, depth, Path{})
|
||||
itemScope := s.scope
|
||||
@@ -742,21 +751,24 @@ func (s *importTraversal) scheduleAcquisitionScopes(scope *acquisitionScope) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *importTraversal) composePendingItems(scope *acquisitionScope) []Diagnostic {
|
||||
func (s *importTraversal) composePendingItems(scope *acquisitionScope, policy sequencePolicy) []Diagnostic {
|
||||
for index := range scope.contributions {
|
||||
contribution := &scope.contributions[index]
|
||||
if contribution.pendingItem == nil {
|
||||
continue
|
||||
}
|
||||
itemScope := contribution.pendingItem
|
||||
if diagnostics := s.composePendingItems(itemScope); len(diagnostics) != 0 {
|
||||
if diagnostics := s.composePendingItems(itemScope, policy); len(diagnostics) != 0 {
|
||||
return projectItemDiagnosticPaths(diagnostics, *scope, contribution.destination, index)
|
||||
}
|
||||
documents := make([]*document.Node, 0, len(itemScope.contributions))
|
||||
for _, nested := range itemScope.contributions {
|
||||
documents = append(documents, nested.document)
|
||||
}
|
||||
completed, diagnostics := composeDocuments(documents...)
|
||||
completed, diagnostics := composeDocumentsWithCollectionPolicy(
|
||||
policy, itemScope.collectionPolicies,
|
||||
acquiredSequenceDeclarations(*itemScope), documents...,
|
||||
)
|
||||
if len(diagnostics) != 0 {
|
||||
return projectItemDiagnosticPaths(diagnostics, *scope, contribution.destination, index)
|
||||
}
|
||||
@@ -783,6 +795,18 @@ func (s *importTraversal) composePendingItems(scope *acquisitionScope) []Diagnos
|
||||
return nil
|
||||
}
|
||||
|
||||
func acquiredSequenceDeclarations(scope acquisitionScope) []sequenceDeclarationSpec {
|
||||
var declarations []sequenceDeclarationSpec
|
||||
for _, contribution := range scope.contributions {
|
||||
for _, declaration := range contribution.sequenceDeclarations {
|
||||
projected := cloneSequenceDeclarations([]sequenceDeclarationSpec{declaration})[0]
|
||||
projected.destination = appendDestination(contribution.relativeDestination, declaration.destination)
|
||||
declarations = append(declarations, projected)
|
||||
}
|
||||
}
|
||||
return declarations
|
||||
}
|
||||
|
||||
func importedVersionClaim(documents []*document.Node, scope acquisitionScope, composed *composedDocument, rule *VersionRule) *Diagnostic {
|
||||
if composed == nil || rule == nil {
|
||||
return nil
|
||||
@@ -915,6 +939,37 @@ func projectNestedEvidence(composed *composedDocument, scope acquisitionScope) {
|
||||
projectNestedOrigins(composed.origins, contribution.nested.root, contribution.nested.origins, prefix)
|
||||
}
|
||||
composed.applications = projectedApplications
|
||||
projectNestedCollectionPolicies(composed, scope, ranges)
|
||||
}
|
||||
|
||||
func projectNestedCollectionPolicies(composed *composedDocument, scope acquisitionScope, ranges map[sequenceRangeKey]sequenceRange) {
|
||||
if composed == nil {
|
||||
return
|
||||
}
|
||||
baseOffsets := make(map[string]int)
|
||||
for sourceIndex, contribution := range scope.contributions {
|
||||
if contribution.nested == nil || len(contribution.nested.collectionPolicies.collections) == 0 {
|
||||
continue
|
||||
}
|
||||
itemIndex := priorSequenceLength([]acquisitionScope{{contributions: scope.contributions[:sourceIndex]}}, contribution.destination)
|
||||
if assigned, found := ranges[sequenceRangeKey{sourceIndex: sourceIndex, path: contribution.destination.String()}]; found {
|
||||
if projected, ok := assigned.outputForInput(0); ok {
|
||||
itemIndex = projected
|
||||
}
|
||||
}
|
||||
key := contribution.destination.String()
|
||||
base, initialized := baseOffsets[key]
|
||||
policy, _ := composed.collectionPolicies.at(contribution.destination)
|
||||
if !initialized {
|
||||
base = len(policy.recordOrder)
|
||||
baseOffsets[key] = base
|
||||
}
|
||||
policy.setRecordPolicyAt(base+itemIndex, collectionRecordPolicy{
|
||||
owner: newCollectionRecordPolicy().owner,
|
||||
scope: contribution.nested.collectionPolicies,
|
||||
})
|
||||
composed.collectionPolicies.set(contribution.destination, policy)
|
||||
}
|
||||
}
|
||||
|
||||
func projectNestedOrigins(target map[string]Origin, root *document.Node, origins map[string]Origin, prefix Path) {
|
||||
|
||||
Reference in New Issue
Block a user