def walk

bolt@1.27.0.0 · src/rules/pedantic/tail.bend:30

import bolt@1.27.0.0/src/rules/pedantic/tail.bend as Tail
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

30# the self-calls not in tail position; skip: the chain is a bare self-call
31def walk(nn: Tree.Node, +name: String, +path: String, skip: Bool) -> List<&2, F.Finding>:
32  match nn:
33    case Tree.NCons{Tree.Leaf{Lex.Tok{k, +t, +l, +c}}, Tree.NCons{Tree.Group{Lex.Tok{_, +o, _, _}, +kids, _}, rest}}:
34      +call = String.eq(o, "(")
35      +me = Bool.and(Bool.and(call, String.eq(t, name)), Bool.not(skip))
36      +inside = walk(kids, name, path, False{})
37      +more = List.concat(&2, F.Finding, [
38        Bool.pick(List<&2, F.Finding>, Bool.and(call, String.eq(t, "Bool.pick")), [], inside),
39        walk(rest, name, path, False{})])
40      Bool.pick(List<&2, F.Finding>, me,
41        F.Finding{path, l, c, U32.from_nat(String.length(name)), "tail",
42          "This call to " ++ name ++ " is not a tail call, so a long list or string overflows the stack on the JS lane; carry an accumulator."}
43          <> more,
44        more)
45    case Tree.NCons{Tree.Group{open, kids, close}, rest}:
46      List.concat(&2, F.Finding, [walk(kids, name, path, False{}), walk(rest, name, path, False{})])
47    case Tree.NCons{Tree.Stmt{kind, +kids, body}, rest}:
48      List.concat(&2, F.Finding, [walk(kids, name, path, bare(kids, name)), walk(body, name, path, False{}),
49        walk(rest, name, path, False{})])
50    case Tree.NCons{h, rest}:
51      walk(rest, name, path, False{})
52    case other:
53      Nil{}

Uses (15)

Used by (1)