Summary
Two small divergences noticed while fixing
#1406, neither
introduced by it, both worth a decision rather than being left implicit.
1. Checker::is_call disagrees with abc.branches
C#'s Checker::is_call matches only the invocation aliases. abc.branches
counts those plus ObjectCreationExpression, ConstructorInitializer, and
since #1406 the primary-constructor base call
(PrimaryConstructorBaseType / a base_list-gated ArgumentList).
So bca find --filter call and abc.branches now disagree by one more
construct than they used to. .claude/rules/grammar-dispatch.md §7 asks for
exactly this cross-walk: two predicates classifying the same nodes through
parallel matches!() drift silently, and each reads as internally
consistent from its own side.
Decide which is intended — is_call is arguably answering a narrower
question ("is this a call site a reader navigates to") than ABC's
Fitzpatrick branch rule ("function invocation or object construction"). If
the divergence is deliberate, say so in a comment at both sites; if not,
widen is_call.
2. A primary constructor opens no FuncSpace
class Sub(int x) : Base(x) has no constructor body, so no function space
is opened and the base call lands on the class space. The classic
: base(x) spelling lands on a function space.
File-level sums agree, so nothing is wrong at the aggregate. But
per-function branches_max / branches_average, and a per-function
bca check --threshold abc=N, see the two spellings differently — the
primary-constructor form contributes to the class row and never to any
function row.
That may well be correct (there is no function there to attribute it to),
but it means a codebase that migrates to primary constructors will see its
per-function ABC distribution shift without any behaviour change. Worth
recording the decision either way.
Related
Resolution
Status: Fixed (pending merge)
Commit: 2463287c on branch fix/issue-1456
Root cause: Neither divergence is a defect. Both are deliberate and
both were undocumented. (1) is_call answers "where is this called" and
ABC's branches applies Fitzpatrick's wider "function invocation or
object creation" rule; the split is the workspace convention across 13
languages, stated only in a Groovy test since #430. (2) A primary
constructor's superclass call sits in the class header — a sibling of
its parameter list, not a child — so no function space encloses it and
the branch is the class's. Fixed as documentation (trait doc, both C#
sites, the Kotlin sibling, two book sections) plus
csharp_is_call_excludes_constructors and per-space assertions on the
Kotlin primary-constructor test. No metric or predicate behaviour
changed.
Summary
Two small divergences noticed while fixing
#1406, neither
introduced by it, both worth a decision rather than being left implicit.
1.
Checker::is_calldisagrees withabc.branchesC#'s
Checker::is_callmatches only the invocation aliases.abc.branchescounts those plus
ObjectCreationExpression,ConstructorInitializer, andsince #1406 the primary-constructor base call
(
PrimaryConstructorBaseType/ abase_list-gatedArgumentList).So
bca find --filter callandabc.branchesnow disagree by one moreconstruct than they used to.
.claude/rules/grammar-dispatch.md§7 asks forexactly this cross-walk: two predicates classifying the same nodes through
parallel
matches!()drift silently, and each reads as internallyconsistent from its own side.
Decide which is intended —
is_callis arguably answering a narrowerquestion ("is this a call site a reader navigates to") than ABC's
Fitzpatrick branch rule ("function invocation or object construction"). If
the divergence is deliberate, say so in a comment at both sites; if not,
widen
is_call.2. A primary constructor opens no
FuncSpaceclass Sub(int x) : Base(x)has no constructor body, so no function spaceis opened and the base call lands on the class space. The classic
: base(x)spelling lands on a function space.File-level sums agree, so nothing is wrong at the aggregate. But
per-function
branches_max/branches_average, and a per-functionbca check --threshold abc=N, see the two spellings differently — theprimary-constructor form contributes to the class row and never to any
function row.
That may well be correct (there is no function there to attribute it to),
but it means a codebase that migrates to primary constructors will see its
per-function ABC distribution shift without any behaviour change. Worth
recording the decision either way.
Related
Resolution
Status: Fixed (pending merge)
Commit:
2463287con branchfix/issue-1456Root cause: Neither divergence is a defect. Both are deliberate and
both were undocumented. (1)
is_callanswers "where is this called" andABC's
branchesapplies Fitzpatrick's wider "function invocation orobject creation" rule; the split is the workspace convention across 13
languages, stated only in a Groovy test since #430. (2) A primary
constructor's superclass call sits in the class header — a sibling of
its parameter list, not a child — so no function space encloses it and
the branch is the class's. Fixed as documentation (trait doc, both C#
sites, the Kotlin sibling, two book sections) plus
csharp_is_call_excludes_constructorsand per-space assertions on theKotlin primary-constructor test. No metric or predicate behaviour
changed.