def walk
bolt@1.27.0.0 · src/rules/pedantic/index.bend:43
import bolt@1.27.0.0/src/rules/pedantic/index.bend as Index
import Base
import bolt@1.27.0.0/src/finding.bend as F
import bolt@1.27.0.0/src/syntax/lex.bend as Lex
import bolt@1.27.0.0/src/syntax/tree.bend as Tree
import bolt@1.27.0.0/src/rules/calls.bend as Calls
43
44def walk(nn: Tree.Node, +path: String, +fixed: List<&2, String>, +self: String) -> List<&2, F.Finding>:
45 match nn:
46 case Tree.NCons{Tree.Leaf{Lex.Tok{k, +t, +l, +c}}, Tree.NCons{Tree.Group{Lex.Tok{_, +o, _, _}, +kids, _}, rest}}:
47 +list = named(t, self, "List.get")
48 +as = Calls.args(kids)
49 +get = Bool.and(String.eq(o, "("), Bool.or(list, named(t, self, "String.get")))
50 +fire = Bool.and(get, Bool.and(Bool.not(literal(Calls.arg(as, Bool.pick(Nat, list, 3n, 1n)))),
51 Bool.not(held(list, Calls.arg(as, 2n), fixed))))
52 +more = List.concat(&2, F.Finding, [walk(kids, path, fixed, self), walk(rest, path, fixed, self)])
53 Bool.pick(List<&2, F.Finding>, fire,
54 F.Finding{path, l, c, U32.from_nat(String.length(t)), "index",
55 t ++ " in a recursive def walks the list from its head on every step, which is quadratic; recurse over the list itself."} <> more,
56 more)
57 case Tree.NCons{Tree.Group{open, +kids, close}, rest}:
58 List.concat(&2, F.Finding, [walk(kids, path, fixed, self), walk(rest, path, fixed, self)])
59 case Tree.NCons{Tree.Stmt{kind, +kids, body}, rest}:
60 List.concat(&2, F.Finding, [walk(kids, path, fixed, self), walk(body, path, fixed, self),
61 walk(rest, path, fixed, self)])
62 case Tree.NCons{h, rest}:
63 walk(rest, path, fixed, self)
64 case other:
65 Nil{}