Summary
setupComplexityVisitorForFile (src/ast-analysis/engine.ts) and the analogous initWasmParsersIfNeeded/setupCfgVisitorForFile gates decide whether to run the WASM complexity/CFG visitor for a file using:
const needsWasmComplexity = defs.some((d) => hasFuncBody(d) && !d.complexity);
hasFuncBody requires d.endLine > d.line (a multi-line span) in addition to !d.bodyless. If every function/method definition in a file happens to have its entire body on one line (a common style for simple getters, one-line guard returns, or C# expression-bodied members => expr;), every definition fails hasFuncBody, needsWasmComplexity evaluates to false for the whole file, and the complexity/CFG visitor is never added to the walk at all — the file gets zero complexity/CFG data under the WASM engine, even though every function in it has a real, bodied, computable implementation.
Reproduction
interface IRepo2 {
bool Save(string id, int value);
bool SaveOneLine(string id, int value) => value >= 0;
}
class Repo2 : IRepo2 {
public bool Save(string id, int value) { return true; }
public bool SaveOneLine(string id, int value) => value >= 0;
}
$ codegraph where --file Repo2.cs
Symbols: IRepo2:1, IRepo2.Save:2, IRepo2.SaveOneLine:3, Repo2:5, Repo2.Save:6, ..., Repo2.SaveOneLine:7, ...
$ codegraph complexity --engine wasm --json
functions: 0 for anything in Repo2.cs
All four real definitions (two abstract signatures aside) are single-line, so the file-level gate never fires and none of them — including the two genuinely bodied methods — get complexity data.
This is a pre-existing, independent bug from #2055 (confirmed present before any of that issue's fix — setupComplexityVisitorForFile was not touched by that PR). It's the same hasFuncBody endLine > line heuristic, but misapplied at the file-scoping layer rather than the per-definition merge layer #2055 fixed.
Suggested fix
The file-level gate only needs to know "does this file contain at least one definition that plausibly has a body and is missing complexity" — the endLine > line heuristic is the wrong tool for that, for the same reason #2055 found it wrong for the per-definition merge: it's a proxy for "multi-line", not "has a body". Consider gating on !d.bodyless && !d.complexity directly (mirroring the def.bodyless !== true fix in #2055) instead of the stricter hasFuncBody, or auditing whether hasFuncBody's endLine > line requirement is still needed anywhere now that bodyless is a reliable direct signal from every extractor (added in #1922).
Discovery context
Found while stress-testing edge cases for #2055 (WASM complexity wrongly computed for bodyless interface methods) — that PR's own fix is unaffected by this; this is a distinct, pre-existing latent bug in the file-level visitor-setup gate, not introduced by it.
Summary
setupComplexityVisitorForFile(src/ast-analysis/engine.ts) and the analogousinitWasmParsersIfNeeded/setupCfgVisitorForFilegates decide whether to run the WASM complexity/CFG visitor for a file using:hasFuncBodyrequiresd.endLine > d.line(a multi-line span) in addition to!d.bodyless. If every function/method definition in a file happens to have its entire body on one line (a common style for simple getters, one-line guard returns, or C# expression-bodied members=> expr;), every definition failshasFuncBody,needsWasmComplexityevaluates tofalsefor the whole file, and the complexity/CFG visitor is never added to the walk at all — the file gets zero complexity/CFG data under the WASM engine, even though every function in it has a real, bodied, computable implementation.Reproduction
All four real definitions (two abstract signatures aside) are single-line, so the file-level gate never fires and none of them — including the two genuinely bodied methods — get complexity data.
This is a pre-existing, independent bug from #2055 (confirmed present before any of that issue's fix —
setupComplexityVisitorForFilewas not touched by that PR). It's the samehasFuncBodyendLine > lineheuristic, but misapplied at the file-scoping layer rather than the per-definition merge layer #2055 fixed.Suggested fix
The file-level gate only needs to know "does this file contain at least one definition that plausibly has a body and is missing complexity" — the
endLine > lineheuristic is the wrong tool for that, for the same reason #2055 found it wrong for the per-definition merge: it's a proxy for "multi-line", not "has a body". Consider gating on!d.bodyless && !d.complexitydirectly (mirroring thedef.bodyless !== truefix in #2055) instead of the stricterhasFuncBody, or auditing whetherhasFuncBody'sendLine > linerequirement is still needed anywhere now thatbodylessis a reliable direct signal from every extractor (added in #1922).Discovery context
Found while stress-testing edge cases for #2055 (WASM complexity wrongly computed for bodyless interface methods) — that PR's own fix is unaffected by this; this is a distinct, pre-existing latent bug in the file-level visitor-setup gate, not introduced by it.