Use same-file module variable initializers to filter builtin collection calls before class-name heuristics, and require a Python type node for the class escape. Preserve imported project module calls. Add callers/callees regressions for dict, list, set, tuple, and frozenset, with a real instance control and same-name bindings across files. Validation on Linux with Node 22.19.0: the new suite had 14 failures and one passing control on main at 8733c288; all 216 tests in the new suite, call-receiver-no-fabrication, and resolution now pass. TypeScript and copy-assets pass. Re-indexed /tmp/cg-1652-repro: callers get is empty and read_setting no longer calls a cache.py method. Co-authored-by: Colby McHenry <colbymchenry@users.noreply.github.com>
This commit is contained in:
co-authored by
Colby McHenry
parent
8733c2880f
commit
195888d71f
+17
-4
@@ -2104,8 +2104,22 @@ export class ReferenceResolver {
|
||||
// project dependency, not `list.append` (#1681). Without this, the
|
||||
// qualified ref never reaches resolveViaImport / resolvePythonModuleMember.
|
||||
if (PYTHON_BUILT_IN_METHODS.has(method)) {
|
||||
// A module-scope collection binding is stronger evidence than a
|
||||
// coincidentally matching class name (#1652). Only use this file's
|
||||
// binding: an unrelated module may reuse the receiver for a collection.
|
||||
const isCollection = this.context.getNodesByName(receiver).some((node) =>
|
||||
node.language === 'python' && node.filePath === ref.filePath &&
|
||||
(node.kind === 'variable' || node.kind === 'constant') &&
|
||||
node.qualifiedName === receiver &&
|
||||
/^=\s*(?:[\[{]|(?:dict|list|set|tuple|frozenset)\s*\(|\(\s*\)|\([^()]*,)/.test(node.signature ?? '')
|
||||
);
|
||||
if (isCollection) return true;
|
||||
|
||||
const capitalized = receiver.charAt(0).toUpperCase() + receiver.slice(1);
|
||||
const isKnownClass = this.knownNames?.has(capitalized) ?? false;
|
||||
const isKnownClass = this.context.getNodesByName(capitalized).some((node) =>
|
||||
node.language === 'python' &&
|
||||
(node.kind === 'class' || node.kind === 'struct' || node.kind === 'interface')
|
||||
);
|
||||
const isProjectModule =
|
||||
!isKnownClass && this.isPythonProjectModule(ref, receiver);
|
||||
if (!isKnownClass && !isProjectModule) {
|
||||
@@ -2116,9 +2130,8 @@ export class ReferenceResolver {
|
||||
// A bare name colliding with a builtin method (index, get, update, count…)
|
||||
// is only a builtin when NOTHING in the codebase declares it. A declared
|
||||
// symbol with that exact name — e.g. a Flask/FastAPI view `def index()` or
|
||||
// `def get()` — is a real reference target. Mirrors the knownNames guard on
|
||||
// the dotted branch above; without it, every handler named after a builtin
|
||||
// method silently loses its route→handler edge.
|
||||
// `def get()` — is a real reference target. Without this guard, every
|
||||
// handler named after a builtin method silently loses its route→handler edge.
|
||||
if (PYTHON_BUILT_IN_METHODS.has(name) && !this.knownNames?.has(name)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user