mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-18 22:02:49 +08:00
fix(resolution): a receiver declared with an outside type calls that type (#2169)
When a receiver's type is inferred from its declaration or initializer and the method isn't on it, the matcher used to fall through to its capitalized-name and name-overlap guesses. If the inferred name is a type (capitalized last segment) that nothing in the project declares — JDK / BCL / okhttp / Django types — it now stops: the method is that outside type's. Python's initializer pattern no longer reads a keyword argument (`prefix=IPNetwork(…),` inside a call) as a binding of `prefix`. A/B (edges removed): commons-lang -1296 (`append` / `length` / `charAt` on JDK types), Newtonsoft.Json -496 (`MemoryStream.ToArray`, `ToString`), gson -367 (`List.add`, `Map.put`), retrofit -321 (okhttp `Request.headers()` / `method()`), jsoup -130, okio -26, pytest -44 (pathlib / io), netbox -25, healthchecks -9 (`TimestampSigner.sign`), flask -9, zod -1. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3984,7 +3984,9 @@ function buildLocalReceiverTypePatterns(language: Language, r: string): RegExp[]
|
||||
];
|
||||
case 'python':
|
||||
return [
|
||||
new RegExp(`\\b${r}\\b\\s*=\\s*([A-Z][\\w.]*)\\s*\\(`), // lg = Logger(...)
|
||||
// lg = Logger(...) — a statement of its own: `prefix=IPNetwork(…),`
|
||||
// inside a call's arguments is a keyword argument, not a binding.
|
||||
new RegExp(`(?:^|;)\\s*${r}\\s*=(?!=)\\s*([A-Z][\\w.]*)\\s*\\((?![^\\n]*,\\s*$)`),
|
||||
// A quoted forward reference (`lg: "Logger"`, `lg: 'pkg.Logger'`) is the
|
||||
// same annotation — and what every file under `from __future__ import
|
||||
// annotations` or with a not-yet-defined class writes. The unquoted
|
||||
@@ -4681,6 +4683,17 @@ export function matchMethodCall(
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
// The receiver's declared type is one the project doesn't declare —
|
||||
// `List<Roshambo> list`, `String s`, `val sb = StringBuilder()` — so the
|
||||
// method is that outside type's. gson's `list.add(…)` went to a project
|
||||
// list wrapper's `add`, commons-lang's `s.length()` to a writer's.
|
||||
// (Only a type name — `java.util.List`, not a call chain like Python's
|
||||
// `Device.objects.create(…)` the initializer pattern also captures.)
|
||||
const typeName = inferredType.split('.').pop()!;
|
||||
if (/^[A-Z]/.test(typeName) &&
|
||||
!context.getNodesByName(typeName).some((n) => isMethodOwnerKind(n) && sameLanguageFamily(n.language, ref.language))) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user