docs(roles): correct hasActiveFileSiblings JSDoc to match population logic#2044
Conversation
…logic RoleClassificationNode.hasActiveFileSiblings claimed to be populated only for constant/TYPE_DEF_KINDS nodes, undefined for regular callables. In reality buildClassifierInput (features/structure.ts) also populates it for method/function kinds via a separate self-sibling-safe source set (calledActiveFiles), which classifyUnreferencedNode relies on to rescue functions/methods referenced only as values (logical-or defaults, interface-dispatch methods). The stale comment made those branches read as dead code. Added a regression test exercising the real population path (not just the pure classifier) for the positive method/function promotion case, complementing the existing self-sibling negative-boundary tests.
Greptile SummaryThis PR corrects a stale JSDoc comment on
Confidence Score: 5/5Safe to merge — the change is a JSDoc correction and a complementary regression test with no logic modifications. The rewritten JSDoc accurately reflects the implementation in buildActiveFilesSet/buildClassifierInput (verified against the source). The new test covers the previously undocumented positive promotion case and follows the same setup conventions as adjacent tests. No production logic is touched. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[buildActiveFilesSet] --> B[activeFiles\nfanIn>0 OR fanOut>0\nnon-annotation-only]
A --> C[calledActiveFiles\nfanIn>0 only\nnon-annotation-only]
D[buildClassifierInput] --> E{r.kind in\nANNOTATION_ONLY_KINDS?}
E -- yes\nconstant / TYPE_DEF_KINDS --> F[activeFiles.has file\nhasActiveFileSiblings]
E -- no --> G{r.kind === method\nor function?}
G -- yes --> H[calledActiveFiles.has file\nhasActiveFileSiblings\nstrict fanIn>0 only]
G -- no\ne.g. class --> I[undefined]
B --> F
C --> H
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[buildActiveFilesSet] --> B[activeFiles\nfanIn>0 OR fanOut>0\nnon-annotation-only]
A --> C[calledActiveFiles\nfanIn>0 only\nnon-annotation-only]
D[buildClassifierInput] --> E{r.kind in\nANNOTATION_ONLY_KINDS?}
E -- yes\nconstant / TYPE_DEF_KINDS --> F[activeFiles.has file\nhasActiveFileSiblings]
E -- no --> G{r.kind === method\nor function?}
G -- yes --> H[calledActiveFiles.has file\nhasActiveFileSiblings\nstrict fanIn>0 only]
G -- no\ne.g. class --> I[undefined]
B --> F
C --> H
Reviews (1): Last reviewed commit: "docs(roles): correct hasActiveFileSiblin..." | Re-trigger Greptile |
Summary
RoleClassificationNode.hasActiveFileSiblings(src/graph/classifiers/roles.ts) had a JSDoc comment claiming the field is "populated only forconstantandTYPE_DEF_KINDSnodes;undefinedfor regular callables (functions, methods, classes, etc.)".buildClassifierInputinsrc/features/structure.tsalso populates it formethod/functionkinds, using a different source set (calledActiveFiles, gated onfanIn > 0rather thanfanIn > 0 || fanOut > 0) to avoid a self-sibling false positive where a function would count its own fan-out as evidence of an "active sibling".classifyUnreferencedNode(thefanOut > 0rescue heuristic from Dispatch-table function references (resolve: fn) inconsistently flagged dead-unresolved depending on unrelated fanOut #1771) read as unreachable dead code to a future reader, when they are not.has_active_file_siblingsas a plain function parameter, not a documented struct field), so this is TS-only.Test plan
tests/unit/roles.test.ts) exercising the real population path (classifyNodeRoles→buildActiveFilesSet/buildClassifierInput) for the positive method/function promotion case — a function withfanIn=0, fanOut>0gets promoted toleafwhen the file has a genuine other active sibling (fanIn>0). This complements the existing self-sibling negative-boundary tests (bug(roles): three untraced call-site patterns cause dead-unresolved false positives (handler-table, conditional-interface-dispatch, logical-or default) #1586) which only covered the "must NOT promote itself" case.npx vitest run tests/unit/roles.test.ts tests/graph/classifiers/roles.test.ts— 69/69 passnpm run lint— clean on touched filesnpm run build— cleannpm test(full suite) — 3610 passed, 6 failed, all 6 failures (plus 19 "failed" test files) exclusively due to a pre-existing, unrelated environment condition in this fresh worktree:Cannot find module '@optave/codegraph-darwin-arm64'(native addon not built/linked for this worktree — a known gotcha, not something this docs-only change touches). No failure is related to role classification;codegraph diff-impact --stagedconfirms the change is isolated to the JSDoc comment.Fixes #1911