Skip to content

v4.187.0

@jessegall jessegall tagged this 25 Jul 04:59
ComputedBooleanArgumentDetector — a chooser taking only bool(s) that every caller
derives from the SAME object. The rule then lives at N call sites instead of in the
class that owns the decision, and they drift: one site forgets an arm and the answers
disagree. Take the subject and ask it.

Three signals have to agree, so a flag argument on its own is never enough:
- the callee is a pure chooser — every parameter `bool`, and it BRANCHES on each one
  (a setter storing a flag is a sink, not a chooser; a constructor is fields being born)
- every argument at a call site is an answer some object gave, never a literal
- ≥2 call sites, all asking the same TYPE — one caller cannot drift from itself, and
  callers holding different types are not re-deriving one shared rule

The call graph had to learn static calls first: `callersOf` bucketed only `->m()`, so
`X::of(...)` had no callers at all and a static factory looked unreachable. Both
spellings reach the same declaration, so both are now in the graph, and
`staticCallClass()` resolves `self`/`static` to the enclosing class.

Also new on the engine: `NodeMatch::argumentSubjectType()` (the one type a whole call's
arguments were asked of), `AstNode::decidesOnBoolsAlone()`, `paramTypeNames()`,
`readsAsCondition()`.

Calibrated over 13 real trees: no false positives, and the near-miss family it must not
flag — settings setters storing a flag pulled off a Request — is correctly rejected.

Closes #400
Assets 2
Loading