diff options
Diffstat (limited to 'internal/cond/compile.go')
| -rw-r--r-- | internal/cond/compile.go | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/internal/cond/compile.go b/internal/cond/compile.go index 4fdc75f..590d61a 100644 --- a/internal/cond/compile.go +++ b/internal/cond/compile.go @@ -362,6 +362,28 @@ func (c *compiler) compileMatched(n *sexp.Node) *node { return &node{kind: kMatched, pos: n.Pos, label: "matched", cost: costCheap} } +// collectNameGroups walks n and its children — and and or included, not +// excluded — appending the capture-group count of every pattern of every +// kName node reachable without crossing a not, in compile order. B1: a +// name test under a not never supplies Result.Captures (eval.go's negated +// tracking takes captures only when !negated), so it must not count toward +// checkCaptures' "does some name test in this rule have enough groups" +// either - a rule combining a capturing name test with an unrelated +// (not (name ...)) must still pass. +func collectNameGroups(n *node, out *[]int) { + if n == nil || n.kind == kNot { + return + } + if n.kind == kName { + for _, p := range n.patterns { + *out = append(*out, p.re.NumSubexp()) + } + } + for _, ch := range n.children { + collectNameGroups(ch, out) + } +} + // quotedExampleErr records the shared "takes X in quotes: write (test // "arg")" diagnostic used by name, path, content and duplicate. func (c *compiler) quotedExampleErr(a *sexp.Node, test, noun string) { |
