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# every List.get / String.get call at a computed index, but self's own
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{}

Uses (20)

Used by (1)