Share requirement branch traversal

This commit is contained in:
2026-11-05 14:04:58 +00:00
parent 5dcfc2e953
commit a4901cbb0e
2 changed files with 34 additions and 48 deletions

View File

@@ -468,6 +468,10 @@ creation (previously 9, 135, and 8,255). Prompt requirements tests pass on Go
comparisons retain known/skipped/unknown outcomes, inactive computed names,
optional index behavior, root access, and meaningful incompleteness.
Completion: `if` and `with` share branch traversal while retaining distinct body
and else dot scopes. Focused internal and public requirements tests pass on Go
1.27.3, including existing independent rendering and skipped-path cases.
## Stage 18: Add Bounded Diagnostic Prefix Encoding
**Catalog:** 17, encoding primitive. **Files:** repair formatter private helpers/tests.

View File

@@ -451,6 +451,34 @@ func (walker *requirementWalker) walkTemplate(compiled *template.Template) error
return err
}
func (walker *requirementWalker) visitBranch(branch *parse.BranchNode, reach requirementReachability, dot dotIdentity, changesDot bool) error {
condition := conditionEvaluation{}
if reach == requirementInactive {
if err := walker.visit(branch.Pipe, requirementInactive, dot); err != nil {
return err
}
} else {
condition = walker.evaluateCondition(branch.Pipe, reach, dot)
}
before := walker.dependencies
bodyDot := dot
if changesDot {
bodyDot = walker.withDotIdentity(branch.Pipe, dot, condition)
}
thenReach := branchReach(reach, condition.known, condition.truth(), true)
elseReach := branchReach(reach, condition.known, condition.truth(), false)
if err := walker.visit(branch.List, thenReach, bodyDot); err != nil {
return err
}
if err := walker.visit(branch.ElseList, elseReach, dot); err != nil {
return err
}
if reach != requirementInactive && !condition.known && walker.dependencies != before {
walker.recordConditionLimitation(condition)
}
return nil
}
func (walker *requirementWalker) visit(node parse.Node, reach requirementReachability, dot dotIdentity) error {
if err := walker.ctx.Err(); err != nil {
return err
@@ -471,55 +499,9 @@ func (walker *requirementWalker) visit(node parse.Node, reach requirementReachab
case *parse.ActionNode:
return walker.visit(node.Pipe, reach, dot)
case *parse.IfNode:
if reach == requirementInactive {
if err := walker.visit(node.Pipe, requirementInactive, dot); err != nil {
return err
}
if err := walker.visit(node.List, requirementInactive, dot); err != nil {
return err
}
return walker.visit(node.ElseList, requirementInactive, dot)
}
condition := walker.evaluateCondition(node.Pipe, reach, dot)
before := walker.dependencies
thenReach := branchReach(reach, condition.known, condition.truth(), true)
elseReach := branchReach(reach, condition.known, condition.truth(), false)
if err := walker.visit(node.List, thenReach, dot); err != nil {
return err
}
if err := walker.visit(node.ElseList, elseReach, dot); err != nil {
return err
}
if !condition.known && walker.dependencies != before {
walker.recordConditionLimitation(condition)
}
return nil
return walker.visitBranch(&node.BranchNode, reach, dot, false)
case *parse.WithNode:
if reach == requirementInactive {
if err := walker.visit(node.Pipe, requirementInactive, dot); err != nil {
return err
}
bodyDot := walker.withDotIdentity(node.Pipe, dot, conditionEvaluation{})
if err := walker.visit(node.List, requirementInactive, bodyDot); err != nil {
return err
}
return walker.visit(node.ElseList, requirementInactive, dot)
}
condition := walker.evaluateCondition(node.Pipe, reach, dot)
before := walker.dependencies
thenReach := branchReach(reach, condition.known, condition.truth(), true)
elseReach := branchReach(reach, condition.known, condition.truth(), false)
bodyDot := walker.withDotIdentity(node.Pipe, dot, condition)
if err := walker.visit(node.List, thenReach, bodyDot); err != nil {
return err
}
if err := walker.visit(node.ElseList, elseReach, dot); err != nil {
return err
}
if !condition.known && walker.dependencies != before {
walker.recordConditionLimitation(condition)
}
return nil
return walker.visitBranch(&node.BranchNode, reach, dot, true)
case *parse.RangeNode:
if err := walker.visit(node.Pipe, reach, dot); err != nil {
return err