def walk
bolt@1.27.0.0 · src/rules/correctness/pick.bend:68
import bolt@1.27.0.0/src/rules/correctness/pick.bend as Pick
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
68
69
70
71
72def walk(nn: Tree.Node, +name: String, +path: String, +quiet: Bool, +hush: Bool, +nth: Nat) -> List<&2, F.Finding>:
73 match nn:
74 case Tree.NCons{Tree.Leaf{Lex.Tok{k, +t, +l, +c}}, Tree.NCons{Tree.Group{open, +kids, close}, rest}}:
75 +at = next(k, nth)
76 +q = mute(quiet, hush, at)
77 +as = Calls.args(kids)
78 +ispick = String.eq(t, "Bool.pick")
79 +two = Bool.and(Bool.and(ispick, Bool.not(q)), both(as, name))
80 +one = Bool.and(Bool.and(ispick, Bool.not(two)), Bool.and(Bool.not(q), once(as, name)))
81 +more = List.concat(&2, F.Finding, [walk(kids, name, path, q, Bool.or(two, one), 0n),
82 walk(rest, name, path, quiet, hush, at)])
83 Bool.pick(List<&2, F.Finding>, two,
84 F.Finding{path, l, c, 9, "pick",
85 name ++ " calls itself in both branches of Bool.pick, which evaluates both, so both calls run; bind the call once above the pick."}
86 <> more,
87 Bool.pick(List<&2, F.Finding>, one,
88 F.Finding{path, l, c, 9, "pick",
89 name ++ " calls itself in one branch of Bool.pick, which evaluates both, so the call always runs and never exits early; branch with `match` on the condition instead."}
90 <> more,
91 more))
92 case Tree.NCons{Tree.Leaf{Lex.Tok{k, t, l, c}}, rest}:
93 walk(rest, name, path, quiet, hush, next(k, nth))
94 case Tree.NCons{Tree.Group{open, kids, close}, rest}:
95 List.concat(&2, F.Finding, [walk(kids, name, path, mute(quiet, hush, nth), False{}, 0n),
96 walk(rest, name, path, quiet, hush, nth)])
97 case Tree.NCons{Tree.Stmt{kind, kids, body}, rest}:
98 List.concat(&2, F.Finding, [walk(kids, name, path, mute(quiet, hush, nth), False{}, 0n),
99 walk(body, name, path, mute(quiet, hush, nth), False{}, 0n), walk(rest, name, path, quiet, hush, nth)])
100 case Tree.NCons{h, rest}:
101 walk(rest, name, path, quiet, hush, nth)
102 case other:
103 Nil{}