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# every `Bool.pick(..)` in a chain, at any depth, that recurses in both
69# branches or in one. The chain is argument nth of a group with quiet
70# (inside a branch of a reported pick) and hush (the group is a reported
71# pick, so its branches are quiet); a pick in the condition still counts.
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{}

Uses (19)

Used by (1)