fix(analysis): method attribution on name collision + parser timeout#30
Conversation
…se time - #21: when two classes in a file define a method with the same name (e.g. __init__), don't attribute the node to an arbitrary class; mark it ambiguous so it stays at module level instead of the wrong class. - #23: set parser.setTimeoutMicros(5s) and skip a file whose parse times out, so a pathological input can't block the Node event loop. - Add a regression test for the method-name collision case.
📝 WalkthroughWalkthrough
ChangesParser timeout and ambiguous method attribution
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lib/analysis/analyzers/shared.ts`:
- Around line 118-126: The ambiguity detection in the methodClass.set call only
handles class-vs-class collisions but misses the case where the same name
appears both at module-level and in a class. Update the condition that currently
checks if methodClass.has(name) and methodClass.get(name) !== cls to also
account for the scenario where one of the definitions is at module-level (cls is
null/falsy) and another is in a class, treating this as an ambiguous case by
setting methodClass to null whenever a name is seen in different class contexts
or between module-level and class-level definitions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: f64a1600-40d5-4887-b868-3ef4dd5bcbb5
📒 Files selected for processing (2)
src/lib/analysis/analyzers/analyzers.test.tssrc/lib/analysis/analyzers/shared.ts
| for (const { node } of defQuery.captures(root)) { | ||
| const name = resolveName(node); | ||
| if (!name) continue; | ||
| defs.add(name); | ||
| const cls = enclosingClassName(node, classNodeTypes); | ||
| if (cls) methodClass.set(name, cls); | ||
| if (!cls) continue; | ||
| // Same method name in two classes (e.g. __init__) -> ambiguous, mark null. | ||
| methodClass.set(name, methodClass.has(name) && methodClass.get(name) !== cls ? null : cls); | ||
| } |
There was a problem hiding this comment.
Class-vs-module same-name defs are still mis-attributed to class parents.
The ambiguity rule currently handles only class-vs-class collisions. If a module-level function and a class method share the same name in one file, the merged node can still be parented to a class (wrong ownership).
💡 Proposed fix
const defs = new Set<string>();
const methodClass = new Map<string, string | null>();
+ const moduleLevelDefs = new Set<string>();
const defQuery = language.query(spec.funcDefQuery);
for (const { node } of defQuery.captures(root)) {
const name = resolveName(node);
if (!name) continue;
defs.add(name);
const cls = enclosingClassName(node, classNodeTypes);
- if (!cls) continue;
+ if (!cls) {
+ moduleLevelDefs.add(name);
+ if (methodClass.has(name)) methodClass.set(name, null);
+ continue;
+ }
+ if (moduleLevelDefs.has(name)) {
+ methodClass.set(name, null);
+ continue;
+ }
// Same method name in two classes (e.g. __init__) -> ambiguous, mark null.
methodClass.set(name, methodClass.has(name) && methodClass.get(name) !== cls ? null : cls);
}Also applies to: 264-272
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/lib/analysis/analyzers/shared.ts` around lines 118 - 126, The ambiguity
detection in the methodClass.set call only handles class-vs-class collisions but
misses the case where the same name appears both at module-level and in a class.
Update the condition that currently checks if methodClass.has(name) and
methodClass.get(name) !== cls to also account for the scenario where one of the
definitions is at module-level (cls is null/falsy) and another is in a class,
treating this as an ambiguous case by setting methodClass to null whenever a
name is seen in different class contexts or between module-level and class-level
definitions.
Fixes two findings from the project audit.
Closes #21 — method-to-class attribution on name collision
shared.tskeptmethodClassasMap<name, class>(last write wins), so two classes in the same file with a method of the same name (e.g.__init__,render) attached the node to the wrong class. Now a name owned by more than one class in the file is marked ambiguous and the node stays at module level instead of being mis-attributed.Closes #23 — parser timeout
parseFilenow callsparser.setTimeoutMicros(5_000_000)beforeparse()and skips the file ifparse()returnsnull(timeout), so a pathological input can't block the event loop.Test plan
pnpm test— 22 pass, incl. new regression test (two classes sharing__init__)pnpm typecheckpnpm lintSummary by CodeRabbit
Bug Fixes
Tests