diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index b730398..902e25f 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -111,6 +111,8 @@ Test selected and unused fallbacks. Defer the no-base path to Stages 3–4. ## Stage 3 — Share import declaration preparation +**Status:** Complete. Focused import and placement checks passed. + In `import_acquisition.go`, extract the context-independent first pass of `walkDeclarations` so both normal traversal and the contextless path can use it. Prepare from the already parsed declaration specs, apply diff --git a/internal/engine/import_acquisition.go b/internal/engine/import_acquisition.go index e71580f..73d4a9b 100644 --- a/internal/engine/import_acquisition.go +++ b/internal/engine/import_acquisition.go @@ -242,19 +242,27 @@ func (s *importTraversal) checkInitialLimits() *Diagnostic { return nil } -func (s *importTraversal) walkDeclarations(basePath string, declarations []importDeclarationSpec, depth int, parentDestination Path, sourceIndex int) []Diagnostic { +func prepareImportDeclarations(declarations []importDeclarationSpec, defaults ImportDefaults, parentDestination Path) ([]resolvedImportPolicy, []Diagnostic) { policies := make([]resolvedImportPolicy, len(declarations)) for index, spec := range declarations { - policy, diagnostics := resolveImportPolicy(spec, s.policy.importDefaults) + policy, diagnostics := resolveImportPolicy(spec, defaults) if len(diagnostics) != 0 { - return diagnostics + return nil, diagnostics } if policy.placement == PlacementModeSequenceItem && len(appendDestination(parentDestination, policy.destination).segments) == 0 { site := spec.fieldSites["placement"] - return []Diagnostic{{Code: CodeImportInvalid, Severity: SeverityError, Path: site.path.clone(), Message: "sequence-item placement requires a nonempty destination", Primary: cloneLocation(&site.location)}} + return nil, []Diagnostic{{Code: CodeImportInvalid, Severity: SeverityError, Path: site.path.clone(), Message: "sequence-item placement requires a nonempty destination", Primary: cloneLocation(&site.location)}} } policies[index] = policy } + return policies, nil +} + +func (s *importTraversal) walkDeclarations(basePath string, declarations []importDeclarationSpec, depth int, parentDestination Path, sourceIndex int) []Diagnostic { + policies, diagnostics := prepareImportDeclarations(declarations, s.policy.importDefaults, parentDestination) + if len(diagnostics) != 0 { + return diagnostics + } for index, spec := range declarations { policy := policies[index] var selection importSelection