A variable passed as an argument to a :-qualified method call is credited no read, so it looks unused or write-only and the count-gated rules report it. A plain function call credits the same argument correctly.
Repro
CLASS repro:
METHOD PUBLIC VOID go ():
DEFINE VARIABLE a AS Object NO-UNDO.
DEFINE VARIABLE r AS Object NO-UNDO.
r = b:Fetch(a).
END METHOD.
END CLASS.
warning[LINT0006]: value assigned to variable a is never read. Replace b:Fetch(a) with f(a) and the read is credited, which isolates the cause to the :-qualified call rather than to the argument or the assignment.
It is the call form, nothing narrower
Each of these loses the read, so none of the obvious narrower explanations holds:
| Shape |
Read credited |
r = b:Fetch(a). |
no |
r = b:Fetch(a):Accept(). |
no |
| chain split across lines |
no |
static receiver, r = Builder:Fetch(a). |
no |
a keyword as the method name, Builder:DELETE(a) |
no |
MESSAGE b:Fetch(a). |
no |
r = f(a). (plain call, control) |
yes |
So it is not chaining, not line wrapping, not the receiver form, and not a keyword method name — the argument expressions of a MethodCall are simply not visited.
Payoff, and why this outranks the typing half
This produces a false positive today on LINT0002 and LINT0006, in the ordinary OO-ABL spelling. Fluent-builder APIs make it worse than one finding per site: every variable handed to a link in a chain goes uncredited, so a correctly-used credential or body object is reported as a dead store.
Same underlying gap as the deferred work to type :-qualified member and method-call expressions (check.rs types every MethodCall/MemberAccess as Unknown regardless of what it resolved to; not yet filed separately). They are two halves of one under-modelled construct and probably want one plan. If they are sequenced, this half should go first: an uncredited read reports a finding that is wrong, while the untyped half only produces silence.
Deliberately kept out of PR #153. It removes findings from the two rules that PR moves most, so folding it in would have made that PR's A/B unattributable — the same reason the inactive-preprocessor-branch read crediting was pulled onto its own branch.
Relatives: #134 (reads inside skipped tails of modelled statements) and #131 (LINT0006 write-site walk breadth) are the other two places a real access goes unrecorded.
Pre-existing and independent of cross-file resolution: identical output before and after PR #153.
A variable passed as an argument to a
:-qualified method call is credited no read, so it looks unused or write-only and the count-gated rules report it. A plain function call credits the same argument correctly.Repro
warning[LINT0006]: value assigned to variableais never read. Replaceb:Fetch(a)withf(a)and the read is credited, which isolates the cause to the:-qualified call rather than to the argument or the assignment.It is the call form, nothing narrower
Each of these loses the read, so none of the obvious narrower explanations holds:
r = b:Fetch(a).r = b:Fetch(a):Accept().r = Builder:Fetch(a).Builder:DELETE(a)MESSAGE b:Fetch(a).r = f(a).(plain call, control)So it is not chaining, not line wrapping, not the receiver form, and not a keyword method name — the argument expressions of a
MethodCallare simply not visited.Payoff, and why this outranks the typing half
This produces a false positive today on LINT0002 and LINT0006, in the ordinary OO-ABL spelling. Fluent-builder APIs make it worse than one finding per site: every variable handed to a link in a chain goes uncredited, so a correctly-used credential or body object is reported as a dead store.
Same underlying gap as the deferred work to type
:-qualified member and method-call expressions (check.rstypes everyMethodCall/MemberAccessasUnknownregardless of what it resolved to; not yet filed separately). They are two halves of one under-modelled construct and probably want one plan. If they are sequenced, this half should go first: an uncredited read reports a finding that is wrong, while the untyped half only produces silence.Deliberately kept out of PR #153. It removes findings from the two rules that PR moves most, so folding it in would have made that PR's A/B unattributable — the same reason the inactive-preprocessor-branch read crediting was pulled onto its own branch.
Relatives: #134 (reads inside skipped tails of modelled statements) and #131 (LINT0006 write-site walk breadth) are the other two places a real access goes unrecorded.
Pre-existing and independent of cross-file resolution: identical output before and after PR #153.