gitnexus 1.6.13-rc.52 → 1.6.13-rc.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -595,7 +595,7 @@ export interface TypeRef {
595
595
  readonly declaredSpelling?: string;
596
596
  /** Anchor for resolving `rawName` — the scope where the annotation/inference was written. */
597
597
  readonly declaredAtScope: ScopeId;
598
- readonly source: 'annotation' | 'parameter-annotation' | 'return-annotation' | 'self' | 'assignment-inferred' | 'constructor-inferred' | 'receiver-propagated';
598
+ readonly source: 'annotation' | 'parameter-annotation' | 'return-annotation' | 'self' | 'decorator-unknown' | 'assignment-inferred' | 'constructor-inferred' | 'receiver-propagated';
599
599
  /** Reserved for V2+: generic type arguments (`List<User>` → `[TypeRef('User')]`). V1 ignores. */
600
600
  readonly typeArgs?: readonly TypeRef[];
601
601
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Decide whether a method decorator names one of Python's builtin descriptor
3
+ * types, following CPython's evaluation of the decorator expression.
4
+ *
5
+ * A decorator in a class body is evaluated with LOAD_NAME: the class
6
+ * namespace first, then module globals, then builtins, each as bound at the
7
+ * moment the `def` statement runs. Aliases, dotted names and decorator calls
8
+ * have no known descriptor contract without import resolution, so only bare
9
+ * spellings qualify.
10
+ */
11
+ import type { SyntaxNode } from '../../utils/ast-helpers.js';
12
+ declare const BUILTIN_DESCRIPTOR_NAMES: readonly ['classmethod', 'staticmethod', 'property'];
13
+ export type BuiltinDescriptor = (typeof BUILTIN_DESCRIPTOR_NAMES)[number];
14
+ /** Decorator expressions, outermost first. Tree-sitter keeps a trailing
15
+ * comment inside the decorator node, so read the expression child only. */
16
+ export declare function decoratorNames(fnNode: SyntaxNode): string[];
17
+ /** Does `expression` denote a builtin descriptor type (or `kind`) at `fnNode`? */
18
+ export declare function isBuiltinDescriptor(fnNode: SyntaxNode, expression: string, kind?: BuiltinDescriptor): boolean;
19
+ export {};
@@ -0,0 +1,314 @@
1
+ /**
2
+ * Decide whether a method decorator names one of Python's builtin descriptor
3
+ * types, following CPython's evaluation of the decorator expression.
4
+ *
5
+ * A decorator in a class body is evaluated with LOAD_NAME: the class
6
+ * namespace first, then module globals, then builtins, each as bound at the
7
+ * moment the `def` statement runs. Aliases, dotted names and decorator calls
8
+ * have no known descriptor contract without import resolution, so only bare
9
+ * spellings qualify.
10
+ */
11
+ const BUILTIN_DESCRIPTOR_NAMES = ['classmethod', 'staticmethod', 'property'];
12
+ const BUILTIN_DESCRIPTORS = new Set(BUILTIN_DESCRIPTOR_NAMES);
13
+ /** Decorator expressions, outermost first. Tree-sitter keeps a trailing
14
+ * comment inside the decorator node, so read the expression child only. */
15
+ export function decoratorNames(fnNode) {
16
+ const parent = fnNode.parent;
17
+ if (parent === null || parent.type !== 'decorated_definition')
18
+ return [];
19
+ const names = [];
20
+ for (const child of parent.namedChildren) {
21
+ if (child.type !== 'decorator')
22
+ continue;
23
+ // An empty name matches nothing, so a malformed decorator stays unknown.
24
+ names.push(child.namedChildren.find((part) => part.type !== 'comment')?.text ?? '');
25
+ }
26
+ return names;
27
+ }
28
+ /** Does `expression` denote a builtin descriptor type (or `kind`) at `fnNode`? */
29
+ export function isBuiltinDescriptor(fnNode, expression, kind) {
30
+ if (kind === undefined ? !BUILTIN_DESCRIPTORS.has(expression) : expression !== kind)
31
+ return false;
32
+ // Decorators are evaluated as the `def` statement runs, so its wrapper is the
33
+ // use site. No statement can rebind the name between stacked decorators.
34
+ const use = fnNode.parent?.type === 'decorated_definition' ? fnNode.parent : fnNode;
35
+ return lookupName(descriptorBindings(fnNode).get(expression) ?? [], use) !== 'shadow';
36
+ }
37
+ const FUNCTION_SCOPES = new Set(['function_definition', 'lambda']);
38
+ const COMPREHENSIONS = new Set([
39
+ 'list_comprehension',
40
+ 'set_comprehension',
41
+ 'dictionary_comprehension',
42
+ 'generator_expression',
43
+ ]);
44
+ const TARGET_WRAPPERS = new Set([
45
+ 'pattern_list',
46
+ 'tuple_pattern',
47
+ 'list_pattern',
48
+ 'list_splat_pattern',
49
+ 'dictionary_splat_pattern',
50
+ 'as_pattern_target',
51
+ 'expression_list',
52
+ 'parenthesized_expression',
53
+ ]);
54
+ /** Simple statements whose effect always happens once execution reaches them. */
55
+ const SIMPLE_STATEMENTS = new Set([
56
+ 'expression_statement',
57
+ 'import_statement',
58
+ 'import_from_statement',
59
+ 'delete_statement',
60
+ ]);
61
+ /** Is `node` the `field` child of its parent? */
62
+ function isField(node, field) {
63
+ return node.parent?.childForFieldName(field)?.id === node.id;
64
+ }
65
+ /** Does `statement` import from the `builtins` module? */
66
+ function importsFromBuiltins(statement) {
67
+ return statement?.childForFieldName('module_name')?.text === 'builtins';
68
+ }
69
+ /**
70
+ * The binding this identifier performs, following the binding constructs of
71
+ * Language Reference 4.2.1, or `null` for a plain read.
72
+ */
73
+ function bindingOf(identifier) {
74
+ let node = identifier;
75
+ let parent = node.parent;
76
+ while (parent !== null && TARGET_WRAPPERS.has(parent.type)) {
77
+ node = parent;
78
+ parent = node.parent;
79
+ }
80
+ if (parent === null)
81
+ return null;
82
+ const shadow = { node: identifier, effect: 'shadow' };
83
+ switch (parent.type) {
84
+ case 'assignment':
85
+ case 'augmented_assignment':
86
+ case 'for_statement':
87
+ case 'for_in_clause':
88
+ return isField(node, 'left') ? shadow : null;
89
+ case 'named_expression':
90
+ case 'function_definition':
91
+ case 'class_definition':
92
+ case 'default_parameter':
93
+ case 'typed_default_parameter':
94
+ return isField(node, 'name') ? shadow : null;
95
+ case 'as_pattern':
96
+ return isField(node, 'alias') ? shadow : null;
97
+ case 'aliased_import': {
98
+ if (!isField(node, 'alias'))
99
+ return null;
100
+ // `from builtins import staticmethod as staticmethod` binds the builtin.
101
+ const source = parent.childForFieldName('name')?.text;
102
+ return importsFromBuiltins(parent.parent) && source === identifier.text
103
+ ? { node: identifier, effect: 'builtin' }
104
+ : shadow;
105
+ }
106
+ case 'typed_parameter':
107
+ return node.type === 'identifier' ? shadow : null;
108
+ case 'parameters':
109
+ case 'lambda_parameters':
110
+ return shadow;
111
+ case 'delete_statement':
112
+ return { node: identifier, effect: 'unbind' };
113
+ case 'type':
114
+ return parent.parent?.type === 'type_parameter' ||
115
+ (parent.parent?.type === 'type_alias_statement' && isField(parent, 'left'))
116
+ ? shadow
117
+ : null;
118
+ case 'dotted_name': {
119
+ const owner = parent.parent;
120
+ // `import a.b` binds `a`; `case name:` captures a single name.
121
+ if (owner?.type === 'import_statement')
122
+ return parent.firstNamedChild?.id === node.id ? shadow : null;
123
+ if (owner?.type === 'case_pattern')
124
+ return parent.namedChildCount === 1 ? shadow : null;
125
+ if (owner?.type !== 'import_from_statement' || !isField(parent, 'name'))
126
+ return null;
127
+ return importsFromBuiltins(owner) ? { node: identifier, effect: 'builtin' } : shadow;
128
+ }
129
+ default:
130
+ return null;
131
+ }
132
+ }
133
+ const bindingsByTree = new WeakMap();
134
+ /** Every binding of a builtin descriptor name in the file, in source order. */
135
+ function descriptorBindings(node) {
136
+ const tree = node.tree;
137
+ const cached = bindingsByTree.get(tree);
138
+ if (cached !== undefined)
139
+ return cached;
140
+ // `global x` / `nonlocal x` bind nothing themselves; they redirect the
141
+ // declaring scope's own bindings of `x` to an outer namespace.
142
+ const redirected = new Map();
143
+ for (const statement of tree.rootNode.descendantsOfType([
144
+ 'global_statement',
145
+ 'nonlocal_statement',
146
+ ])) {
147
+ const scope = scopeOf(statement)?.id;
148
+ const kind = statement.type === 'global_statement' ? 'global' : 'nonlocal';
149
+ for (const name of statement.namedChildren)
150
+ redirected.set(`${name.text}@${scope}`, kind);
151
+ }
152
+ const bindings = new Map();
153
+ const add = (name, binding) => {
154
+ const list = bindings.get(name);
155
+ if (list === undefined)
156
+ bindings.set(name, [binding]);
157
+ else
158
+ list.push(binding);
159
+ };
160
+ for (const found of tree.rootNode.descendantsOfType(['identifier', 'wildcard_import'])) {
161
+ if (found.type === 'wildcard_import') {
162
+ // `from m import *` binds every public name m defines. Unless m is
163
+ // `builtins`, whether that includes a descriptor name is unknown here.
164
+ const effect = importsFromBuiltins(found.parent) ? 'builtin' : 'shadow';
165
+ for (const name of BUILTIN_DESCRIPTORS)
166
+ add(name, { node: found, effect, redirect: null });
167
+ continue;
168
+ }
169
+ if (!BUILTIN_DESCRIPTORS.has(found.text))
170
+ continue;
171
+ const binding = bindingOf(found);
172
+ if (binding === null)
173
+ continue;
174
+ const redirect = redirected.get(`${found.text}@${scopeOf(found)?.id}`) ?? null;
175
+ add(found.text, { ...binding, redirect });
176
+ }
177
+ bindingsByTree.set(tree, bindings);
178
+ return bindings;
179
+ }
180
+ /**
181
+ * The scope that owns names bound at `node`: a function or lambda body, a
182
+ * class body, a comprehension, or the module (`null`). A walrus target skips
183
+ * comprehensions, as PEP 572 binds it in the enclosing scope.
184
+ */
185
+ function scopeOf(node) {
186
+ const skipComprehensions = node.parent?.type === 'named_expression';
187
+ let child = node;
188
+ for (let parent = node.parent; parent !== null; child = parent, parent = parent.parent) {
189
+ if (FUNCTION_SCOPES.has(parent.type)) {
190
+ if (isField(child, 'body') || isField(child, 'parameters'))
191
+ return parent;
192
+ }
193
+ else if (parent.type === 'class_definition') {
194
+ if (isField(child, 'body'))
195
+ return parent;
196
+ }
197
+ else if (COMPREHENSIONS.has(parent.type) && !skipComprehensions) {
198
+ return parent;
199
+ }
200
+ }
201
+ return null;
202
+ }
203
+ /** The statement containing `node` that sits directly in `body`. */
204
+ function statementIn(node, body) {
205
+ let current = node;
206
+ while (current.parent !== null && current.parent.id !== body.id)
207
+ current = current.parent;
208
+ return current.parent === null ? null : current;
209
+ }
210
+ /** Can `binding` run before `use` in the same scope, including an earlier
211
+ * iteration of an enclosing loop? */
212
+ function mayRunBefore(binding, use, scope) {
213
+ if (binding.startIndex < use.startIndex)
214
+ return true;
215
+ for (let loop = use.parent; loop !== null && loop.id !== scope?.id; loop = loop.parent) {
216
+ if ((loop.type === 'for_statement' || loop.type === 'while_statement') &&
217
+ binding.startIndex >= loop.startIndex &&
218
+ binding.endIndex <= loop.endIndex) {
219
+ return true;
220
+ }
221
+ }
222
+ return false;
223
+ }
224
+ /**
225
+ * What a module, class or function namespace holds for the name when
226
+ * execution reaches `use`. A `shadow` that may have run wins. A restoring
227
+ * effect (`builtin`, `unbind`) counts only when it is a simple statement
228
+ * directly in the scope body that runs before `use`, so it runs exactly once
229
+ * in order.
230
+ */
231
+ function namespaceState(bindings, scope, use) {
232
+ const body = scope === null ? null : scope.childForFieldName('body');
233
+ let state = 'unbind';
234
+ for (const binding of bindings) {
235
+ if (binding.redirect !== null || scopeOf(binding.node)?.id !== scope?.id)
236
+ continue;
237
+ if (!mayRunBefore(binding.node, use, scope))
238
+ continue;
239
+ if (binding.effect === 'shadow') {
240
+ state = 'shadow';
241
+ continue;
242
+ }
243
+ const statement = statementIn(binding.node, body ?? binding.node.tree.rootNode);
244
+ const ordered = binding.node.startIndex < use.startIndex;
245
+ if (ordered && statement !== null && SIMPLE_STATEMENTS.has(statement.type)) {
246
+ state = binding.effect;
247
+ }
248
+ }
249
+ return state;
250
+ }
251
+ /**
252
+ * Resolve the decorator name at `use` as a class body does (Language
253
+ * Reference 4.2.2): the class namespace first, then the innermost enclosing
254
+ * function that binds the name, then module globals, then builtins.
255
+ */
256
+ function lookupName(bindings, use) {
257
+ // Enclosing scopes, innermost first, ending with the module (`null`).
258
+ const chain = [];
259
+ for (let scope = scopeOf(use); scope !== null; scope = scopeOf(scope))
260
+ chain.push(scope);
261
+ chain.push(null);
262
+ const classScope = chain[0]?.type === 'class_definition' ? chain[0] : null;
263
+ if (classScope !== null) {
264
+ const state = namespaceState(bindings, classScope, use);
265
+ if (state !== 'unbind')
266
+ return state;
267
+ }
268
+ const functions = chain.filter((scope) => scope !== null && FUNCTION_SCOPES.has(scope.type));
269
+ for (const fn of functions) {
270
+ const owned = bindings.some((binding) => binding.redirect === null && scopeOf(binding.node)?.id === fn.id);
271
+ if (!owned)
272
+ continue;
273
+ // Any binding makes the name local to this function, so the class body
274
+ // reads that cell. An unbound cell raises NameError, not the builtin.
275
+ return namespaceState(bindings, fn, use) === 'builtin' ? 'builtin' : 'shadow';
276
+ }
277
+ // A class body inside a function runs whenever that function is called,
278
+ // which can be any time after its top-level statement starts. Module state
279
+ // is therefore read at that statement, and any later module override may
280
+ // also have run first.
281
+ const deferred = functions.length > 0;
282
+ const moduleUse = deferred ? (statementIn(use, use.tree.rootNode) ?? use) : use;
283
+ for (const binding of bindings) {
284
+ if (binding.effect !== 'shadow')
285
+ continue;
286
+ // A nested function can rebind an enclosing function's cell whenever it
287
+ // is called; that order is not modelled, so assume it ran.
288
+ if (binding.redirect === 'nonlocal') {
289
+ const outer = functions[functions.length - 1];
290
+ const inside = outer !== undefined &&
291
+ binding.node.startIndex >= outer.startIndex &&
292
+ binding.node.endIndex <= outer.endIndex;
293
+ if (inside)
294
+ return 'shadow';
295
+ }
296
+ if (binding.redirect === 'global') {
297
+ // The function can only be called once the top-level statement that
298
+ // defines it has run. Whether a call happens is unknown, so a restoring
299
+ // `global` delete is ignored and a rebinding one is assumed.
300
+ const top = statementIn(binding.node, binding.node.tree.rootNode);
301
+ if (deferred || (top !== null && mayRunBefore(top, use, null)))
302
+ return 'shadow';
303
+ }
304
+ }
305
+ if (deferred) {
306
+ const laterOverride = bindings.some((binding) => binding.effect === 'shadow' &&
307
+ binding.redirect === null &&
308
+ scopeOf(binding.node) === null &&
309
+ binding.node.startIndex > moduleUse.startIndex);
310
+ if (laterOverride)
311
+ return 'shadow';
312
+ }
313
+ return namespaceState(bindings, null, moduleUse);
314
+ }
@@ -43,13 +43,11 @@
43
43
  * and emit a single edge rather than branching. `List[T]` /
44
44
  * `Dict[K, V]` strip the outer generic for receiver typing (see
45
45
  * `interpret.ts`).
46
- * 5. **Decorators that rewrite signatures** — `@dataclass`,
47
- * `@property`, `@classmethod`, `@staticmethod` are recognized
48
- * by `receiver-binding.ts`. Arbitrary decorators (e.g.
49
- * `functools.wraps`, custom retry wrappers) preserve the wrapped
50
- * function's declared signature; a decorator that returns a
51
- * different callable is followed only through the declared
52
- * return type.
46
+ * 5. **Decorators that rewrite signatures** — Known descriptor
47
+ * spellings (`@property`, `@classmethod`, `@staticmethod`) are
48
+ * recognized by `receiver-binding.ts`. Unknown decorator expressions
49
+ * leave implicit receiver binding unresolved. Calls through wrappers
50
+ * are followed only through their declared return type.
53
51
  * 6. **`typing.TYPE_CHECKING`-guarded imports** — treated like any
54
52
  * other `import` for reference resolution. We do not distinguish
55
53
  * runtime-visible from type-checker-only imports; this is
@@ -43,13 +43,11 @@
43
43
  * and emit a single edge rather than branching. `List[T]` /
44
44
  * `Dict[K, V]` strip the outer generic for receiver typing (see
45
45
  * `interpret.ts`).
46
- * 5. **Decorators that rewrite signatures** — `@dataclass`,
47
- * `@property`, `@classmethod`, `@staticmethod` are recognized
48
- * by `receiver-binding.ts`. Arbitrary decorators (e.g.
49
- * `functools.wraps`, custom retry wrappers) preserve the wrapped
50
- * function's declared signature; a decorator that returns a
51
- * different callable is followed only through the declared
52
- * return type.
46
+ * 5. **Decorators that rewrite signatures** — Known descriptor
47
+ * spellings (`@property`, `@classmethod`, `@staticmethod`) are
48
+ * recognized by `receiver-binding.ts`. Unknown decorator expressions
49
+ * leave implicit receiver binding unresolved. Calls through wrappers
50
+ * are followed only through their declared return type.
53
51
  * 6. **`typing.TYPE_CHECKING`-guarded imports** — treated like any
54
52
  * other `import` for reference resolution. We do not distinguish
55
53
  * runtime-visible from type-checker-only imports; this is
@@ -124,7 +124,9 @@ export function interpretPythonTypeBinding(captures) {
124
124
  // the variable-annotation and constructor-inferred forms from the
125
125
  // classic parameter annotation.
126
126
  let source = 'parameter-annotation';
127
- if (captures['@type-binding.self'] !== undefined)
127
+ if (captures['@type-binding.uncertain-receiver'] !== undefined)
128
+ source = 'decorator-unknown';
129
+ else if (captures['@type-binding.self'] !== undefined)
128
130
  source = 'self';
129
131
  // `cls` is a self-like receiver; share the source label so downstream
130
132
  // `Registry.lookup` Step 2 treats them identically.
@@ -13,6 +13,13 @@ import type { CaptureMatch } from '../../../../_shared/index.js';
13
13
  import { type SyntaxNode } from '../../utils/ast-helpers.js';
14
14
  /** Static-like descriptors do not inject an instance on attribute access. */
15
15
  export declare function isPythonStaticLikeMethod(fnNode: SyntaxNode): boolean;
16
+ /**
17
+ * Can the method's parameter list prove its call shape? Only a plain function
18
+ * or one builtin `staticmethod` / `classmethod` wrapper qualifies. Any other
19
+ * decorator may replace the callable, and a descriptor stack can make it
20
+ * uncallable: `staticmethod(classmethod(f))` yields a classmethod object.
21
+ */
22
+ export declare function hasPythonProvenCallShape(fnNode: SyntaxNode): boolean;
16
23
  export interface PythonBoundReceiver {
17
24
  readonly kind: 'instance' | 'class';
18
25
  readonly parameter: SyntaxNode;
@@ -34,6 +41,11 @@ export declare function classifyPythonBoundReceiver(fnNode: SyntaxNode): PythonB
34
41
  * The caller is responsible for guaranteeing `fnNode.type ===
35
42
  * 'function_definition'`.
36
43
  */
44
+ /**
45
+ * The first parameter of a class method under an unrecognized decorator.
46
+ * Python may still bind it implicitly, but its receiver kind is unproven.
47
+ */
48
+ export declare function classifyPythonUncertainReceiver(fnNode: SyntaxNode): PythonBoundReceiver | null;
37
49
  export declare function synthesizeReceiverTypeBinding(fnNode: SyntaxNode): CaptureMatch | null;
38
50
  /**
39
51
  * Synthesize class-scope field bindings for the common Python constructor
@@ -10,6 +10,7 @@
10
10
  * awareness that Python's runtime depends on.
11
11
  */
12
12
  import { nodeToCapture, syntheticCapture } from '../../utils/ast-helpers.js';
13
+ import { decoratorNames, isBuiltinDescriptor } from './builtin-descriptors.js';
13
14
  /** Walk up to the enclosing `class_definition`, ignoring the immediate
14
15
  * `decorated_definition` wrapper. Returns `null` when the function is
15
16
  * free, lambda-bodied, or nested inside another function. */
@@ -27,26 +28,76 @@ function findEnclosingClassDefinition(node) {
27
28
  function classDefinitionName(classNode) {
28
29
  return classNode.childForFieldName('name')?.text ?? null;
29
30
  }
30
- /** Does the function carry a `@<decoratorName>` decorator? Matches both
31
- * bare `@classmethod` and module-qualified `@functools.classmethod`. */
32
- function hasDecorator(fnNode, decoratorName) {
33
- const parent = fnNode.parent;
34
- if (parent === null || parent.type !== 'decorated_definition')
31
+ /** Accept a local `@property` accessor chain, skipping only plain unrelated
32
+ * methods. Other intervening class-suite statements may rebind the descriptor,
33
+ * including tuple assignment or control flow. */
34
+ function isLocalPropertyAccessor(fnNode, expression) {
35
+ const methodName = fnNode.childForFieldName('name')?.text;
36
+ if (methodName === undefined ||
37
+ !['getter', 'setter', 'deleter'].some((kind) => expression === `${methodName}.${kind}`))
35
38
  return false;
36
- for (let i = 0; i < parent.namedChildCount; i++) {
37
- const child = parent.namedChild(i);
38
- if (child === null || child.type !== 'decorator')
39
+ const wrapper = fnNode.parent;
40
+ const classBody = findEnclosingClassDefinition(fnNode)?.childForFieldName('body');
41
+ if (wrapper?.type !== 'decorated_definition' || classBody === null || classBody === undefined) {
42
+ return false;
43
+ }
44
+ let wrapperIndex = -1;
45
+ for (let i = 0; i < classBody.namedChildCount; i++) {
46
+ const sibling = classBody.namedChild(i);
47
+ if (sibling?.id === wrapper.id) {
48
+ wrapperIndex = i;
49
+ break;
50
+ }
51
+ }
52
+ for (let i = wrapperIndex - 1; i >= 0; i--) {
53
+ const sibling = classBody.namedChild(i);
54
+ if (sibling?.type === 'function_definition' &&
55
+ sibling.childForFieldName('name')?.text !== methodName) {
56
+ // A plain function definition binds only its own name in the class suite.
39
57
  continue;
40
- const text = child.text.replace(/^@/, '').split('(')[0].trim();
41
- const tail = text.split('.').pop();
42
- if (tail === decoratorName)
58
+ }
59
+ if (sibling?.type !== 'decorated_definition')
60
+ return false;
61
+ let candidate = null;
62
+ for (let j = 0; j < sibling.namedChildCount; j++) {
63
+ const child = sibling.namedChild(j);
64
+ if (child?.type === 'function_definition')
65
+ candidate = child;
66
+ }
67
+ if (candidate?.childForFieldName('name')?.text !== methodName)
68
+ return false;
69
+ const [decorator, ...rest] = decoratorNames(candidate);
70
+ if (decorator === undefined || rest.length > 0)
71
+ return false;
72
+ if (isBuiltinDescriptor(candidate, decorator, 'property'))
43
73
  return true;
74
+ if (!['getter', 'setter', 'deleter'].some((kind) => decorator === `${methodName}.${kind}`)) {
75
+ return false;
76
+ }
44
77
  }
45
78
  return false;
46
79
  }
47
80
  /** Static-like descriptors do not inject an instance on attribute access. */
48
81
  export function isPythonStaticLikeMethod(fnNode) {
49
- return (fnNode.childForFieldName('name')?.text === '__new__' || hasDecorator(fnNode, 'staticmethod'));
82
+ return (fnNode.childForFieldName('name')?.text === '__new__' ||
83
+ decoratorNames(fnNode).some((name) => isBuiltinDescriptor(fnNode, name, 'staticmethod')));
84
+ }
85
+ /**
86
+ * Can the method's parameter list prove its call shape? Only a plain function
87
+ * or one builtin `staticmethod` / `classmethod` wrapper qualifies. Any other
88
+ * decorator may replace the callable, and a descriptor stack can make it
89
+ * uncallable: `staticmethod(classmethod(f))` yields a classmethod object.
90
+ */
91
+ export function hasPythonProvenCallShape(fnNode) {
92
+ const [decorator, ...rest] = decoratorNames(fnNode);
93
+ if (decorator === undefined)
94
+ return true;
95
+ return (rest.length === 0 &&
96
+ (isBuiltinDescriptor(fnNode, decorator, 'staticmethod') ||
97
+ isBuiltinDescriptor(fnNode, decorator, 'classmethod')));
98
+ }
99
+ function isKnownReceiverDecorator(fnNode, expression) {
100
+ return isBuiltinDescriptor(fnNode, expression) || isLocalPropertyAccessor(fnNode, expression);
50
101
  }
51
102
  function firstBoundReceiverParameter(parameters) {
52
103
  for (let i = 0; i < parameters.namedChildCount; i++) {
@@ -86,12 +137,17 @@ function firstParameterName(param) {
86
137
  */
87
138
  export function classifyPythonBoundReceiver(fnNode) {
88
139
  const enclosingClass = findEnclosingClassDefinition(fnNode);
89
- if (enclosingClass === null || isPythonStaticLikeMethod(fnNode))
140
+ if (enclosingClass === null)
90
141
  return null;
142
+ const decorators = decoratorNames(fnNode);
143
+ if (isPythonStaticLikeMethod(fnNode) ||
144
+ decorators.some((name) => !isKnownReceiverDecorator(fnNode, name))) {
145
+ // Python evaluates decorators as expressions. An unrecognized one may
146
+ // replace the function with a class/static descriptor, so its first
147
+ // parameter is not proven to receive an instance.
148
+ return null;
149
+ }
91
150
  const functionName = fnNode.childForFieldName('name')?.text;
92
- // Python applies these descriptor kinds implicitly even without decorators.
93
- // __new__ is static-like (its class argument is explicit), while
94
- // __init_subclass__ and __class_getitem__ receive the class implicitly.
95
151
  const params = fnNode.childForFieldName('parameters');
96
152
  if (params === null)
97
153
  return null;
@@ -103,7 +159,9 @@ export function classifyPythonBoundReceiver(fnNode) {
103
159
  if (name === null || className === null)
104
160
  return null;
105
161
  return {
106
- kind: hasDecorator(fnNode, 'classmethod') ||
162
+ // Python makes __init_subclass__ and __class_getitem__ implicit
163
+ // classmethods, so they receive the class even without a decorator.
164
+ kind: decorators.includes('classmethod') ||
107
165
  functionName === '__init_subclass__' ||
108
166
  functionName === '__class_getitem__'
109
167
  ? 'class'
@@ -142,10 +200,45 @@ function classifyPythonExplicitNewReceiver(fnNode) {
142
200
  * The caller is responsible for guaranteeing `fnNode.type ===
143
201
  * 'function_definition'`.
144
202
  */
203
+ /**
204
+ * The first parameter of a class method under an unrecognized decorator.
205
+ * Python may still bind it implicitly, but its receiver kind is unproven.
206
+ */
207
+ export function classifyPythonUncertainReceiver(fnNode) {
208
+ const decorators = decoratorNames(fnNode);
209
+ // Python applies decorators bottom-up. An outer built-in staticmethod
210
+ // guarantees no implicit receiver even when an inner decorator is opaque.
211
+ // The first parameter remains explicit and can keep its annotation.
212
+ const outermost = decorators[0];
213
+ if (outermost !== undefined && isBuiltinDescriptor(fnNode, outermost, 'staticmethod')) {
214
+ return null;
215
+ }
216
+ if (decorators.every((name) => isKnownReceiverDecorator(fnNode, name)))
217
+ return null;
218
+ const enclosingClass = findEnclosingClassDefinition(fnNode);
219
+ const parameters = fnNode.childForFieldName('parameters');
220
+ const parameter = parameters === null ? null : firstBoundReceiverParameter(parameters);
221
+ const name = parameter === null ? null : firstParameterName(parameter);
222
+ const className = enclosingClass === null ? null : classDefinitionName(enclosingClass);
223
+ if (parameter === null || name === null || className === null)
224
+ return null;
225
+ return { kind: 'instance', parameter, name, className };
226
+ }
145
227
  export function synthesizeReceiverTypeBinding(fnNode) {
146
228
  const receiver = classifyPythonBoundReceiver(fnNode) ?? classifyPythonExplicitNewReceiver(fnNode);
147
- if (receiver === null)
148
- return null;
229
+ if (receiver === null) {
230
+ // Keep an uncertain receiver anchored to its enclosing class so the
231
+ // resolver can report the missing member without treating it as `self`.
232
+ const uncertain = classifyPythonUncertainReceiver(fnNode);
233
+ if (uncertain === null)
234
+ return null;
235
+ const { parameter: first, name, className } = uncertain;
236
+ return {
237
+ '@type-binding.uncertain-receiver': nodeToCapture('@type-binding.uncertain-receiver', first),
238
+ '@type-binding.name': syntheticCapture('@type-binding.name', first, name),
239
+ '@type-binding.type': syntheticCapture('@type-binding.type', first, className),
240
+ };
241
+ }
149
242
  // Receiver convention: instance methods get `self`, classmethods get `cls`.
150
243
  // The capture tag records the descriptor kind; the variable may use any
151
244
  // spelling.
@@ -241,8 +334,6 @@ export function synthesizeConstructorFieldTypeBindings(fnNode) {
241
334
  return [];
242
335
  if (findEnclosingClassDefinition(fnNode) === null)
243
336
  return [];
244
- if (hasDecorator(fnNode, 'staticmethod') || hasDecorator(fnNode, 'classmethod'))
245
- return [];
246
337
  const receiver = synthesizeReceiverTypeBinding(fnNode);
247
338
  const receiverName = receiver?.['@type-binding.self']?.text;
248
339
  if (receiverName === undefined)
@@ -50,6 +50,7 @@ const pythonScopeResolver = {
50
50
  // A free call naming a class constructs it: `Service(db).do_work()` (#2708).
51
51
  constructionSyntax: { bare: true },
52
52
  language: SupportedLanguages.Python,
53
+ suppressReceiverLookup: (typeRef) => typeRef.source === 'decorator-unknown',
53
54
  languageProvider: pythonProvider,
54
55
  importEdgeReason: 'python-scope: import',
55
56
  resolveImportTarget: (targetRaw, fromFile, allFilePaths, _resolutionConfig, context) => {
@@ -1,5 +1,5 @@
1
1
  import { definitionIdPosition } from '../../scope-resolution/utils/definition-id.js';
2
- import { classifyPythonBoundReceiver, isPythonStaticLikeMethod } from './receiver-binding.js';
2
+ import { classifyPythonBoundReceiver, hasPythonProvenCallShape, isPythonStaticLikeMethod, } from './receiver-binding.js';
3
3
  const simplePositionalCallsByFile = new Map();
4
4
  const positionalCapacitiesByFile = new Map();
5
5
  const positionKey = (line, column) => `${line}:${column}`;
@@ -87,19 +87,10 @@ function positionalCapacity(fnNode) {
87
87
  }
88
88
  /** Record a method's exact fixed positional capacity when the AST proves it. */
89
89
  export function recordPythonSubtypeMethodShape(filePath, fnNode, mapLine) {
90
- // An unknown decorator may replace the function or mark it abstract.
91
- // Positional shape alone cannot prove a concrete subtype dispatch target.
92
- // The two built-in descriptor decorators are handled by receiver binding.
93
- const wrapper = fnNode.parent;
94
- if (wrapper?.type === 'decorated_definition' &&
95
- wrapper.namedChildren.some((child) => {
96
- if (child.type !== 'decorator')
97
- return false;
98
- const name = child.firstNamedChild?.text;
99
- return name !== 'staticmethod' && name !== 'classmethod';
100
- })) {
90
+ // An unknown decorator may replace the function or mark it abstract, so
91
+ // its parameter list cannot prove a concrete subtype dispatch target.
92
+ if (!hasPythonProvenCallShape(fnNode))
101
93
  return;
102
- }
103
94
  const capacity = positionalCapacity(fnNode);
104
95
  if (capacity === undefined)
105
96
  return;
@@ -2,7 +2,7 @@
2
2
  // Verified against tree-sitter-python 0.23.4
3
3
  import { SupportedLanguages } from '../../../../_shared/index.js';
4
4
  import { hasKeyword } from '../../field-extractors/configs/helpers.js';
5
- import { classifyPythonBoundReceiver } from '../../languages/python/receiver-binding.js';
5
+ import { classifyPythonBoundReceiver, classifyPythonUncertainReceiver, isPythonStaticLikeMethod, } from '../../languages/python/receiver-binding.js';
6
6
  import { extractSimpleTypeName } from '../../type-extractors/shared.js';
7
7
  // ---------------------------------------------------------------------------
8
8
  // Python helpers
@@ -92,7 +92,10 @@ function extractPythonParameters(node) {
92
92
  return [];
93
93
  const params = [];
94
94
  let isFirst = true;
95
- const boundReceiverId = classifyPythonBoundReceiver(funcNode)?.parameter.id;
95
+ // An opaque decorator leaves the receiver kind unproven, not the slot: keep
96
+ // stripping it so arity matches ordinary bound calls.
97
+ const boundReceiverId = (classifyPythonBoundReceiver(funcNode) ??
98
+ (isPythonStaticLikeMethod(funcNode) ? null : classifyPythonUncertainReceiver(funcNode)))?.parameter.id;
96
99
  for (let i = 0; i < paramList.namedChildCount; i++) {
97
100
  const param = paramList.namedChild(i);
98
101
  if (!param)
@@ -1009,6 +1009,11 @@ function followChainedRef(start, draftById) {
1009
1009
  */
1010
1010
  function typeBindingStrength(source) {
1011
1011
  switch (source) {
1012
+ // A method decorator may change what the first parameter receives. An
1013
+ // annotation describes intent, not descriptor binding, so it cannot
1014
+ // override this uncertainty for that parameter.
1015
+ case 'decorator-unknown':
1016
+ return 4;
1012
1017
  case 'annotation':
1013
1018
  return 3;
1014
1019
  case 'parameter-annotation':
@@ -1235,6 +1235,10 @@ export interface ScopeResolver {
1235
1235
  * return undefined to retain the shared behavior.
1236
1236
  */
1237
1237
  readonly resolveReceiverMember?: (ownerDef: SymbolDefinition, memberName: string, callsite: Callsite, scopes: ScopeResolutionIndexes, model: SemanticModel) => ReceiverMemberResolution | undefined;
1238
+ /** Suppress all receiver dispatch when a captured type cannot prove its
1239
+ * runtime binding. Runs before compound and simple receiver lookup; the
1240
+ * caller records a receiver-unresolved outcome. */
1241
+ readonly suppressReceiverLookup?: (typeRef: TypeRef) => boolean;
1238
1242
  /**
1239
1243
  * Enable the receiver-bound Case 0.5 fallback for explicit `this`
1240
1244
  * receivers (`this->m()` / `this.m()`) that resolves against the
@@ -72,7 +72,7 @@ import { type HeritageTypeArguments } from '../utils/generic-instantiation.js';
72
72
  import type { ResolutionOutcomeRecorder } from '../resolution-outcome.js';
73
73
  import type { ReceiverOrigin } from '../resolution-outcome.js';
74
74
  import type { DecodedReceiverChain } from '../../utils/receiver-chain-codec.js';
75
- type ReceiverBoundProviderSubset = Pick<ScopeResolver, 'isSuperReceiver' | 'isSuperReceiverInContext' | 'fieldFallbackOnMethodLookup' | 'collapseMemberCallsByCallerTarget' | 'elementTypeOf' | 'hoistTypeBindingsToModule' | 'stripReceiverCastExpressions' | 'constructionSyntax' | 'stripTypePreservingDecoration' | 'resolveQualifiedReceiverMember' | 'namespaceReceiverPaths' | 'resolveReceiverMember' | 'resolveThisViaEnclosingClass' | 'resolveMissingReceiverMembersFromSubtypes' | 'missingReceiverSubtypeCandidateCompatibility' | 'arityCompatibility' | 'conversionRankFn' | 'conversionOnlyArgTypePrefixes' | 'constraintCompatibility' | 'isStaticOnly' | 'normalizeTypeArgument' | 'markConstructionSites' | 'namespaceExportsIncludeImportedNames' | 'resolveNamespaceChains'>;
75
+ type ReceiverBoundProviderSubset = Pick<ScopeResolver, 'isSuperReceiver' | 'isSuperReceiverInContext' | 'fieldFallbackOnMethodLookup' | 'collapseMemberCallsByCallerTarget' | 'elementTypeOf' | 'hoistTypeBindingsToModule' | 'stripReceiverCastExpressions' | 'constructionSyntax' | 'stripTypePreservingDecoration' | 'resolveQualifiedReceiverMember' | 'namespaceReceiverPaths' | 'resolveReceiverMember' | 'suppressReceiverLookup' | 'resolveThisViaEnclosingClass' | 'resolveMissingReceiverMembersFromSubtypes' | 'missingReceiverSubtypeCandidateCompatibility' | 'arityCompatibility' | 'conversionRankFn' | 'conversionOnlyArgTypePrefixes' | 'constraintCompatibility' | 'isStaticOnly' | 'normalizeTypeArgument' | 'markConstructionSites' | 'namespaceExportsIncludeImportedNames' | 'resolveNamespaceChains'>;
76
76
  /**
77
77
  * Is this dropped receiver rooted inside the analyzed program?
78
78
  *
@@ -849,6 +849,27 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
849
849
  const receiverName = site.explicitReceiver.name;
850
850
  const memberName = site.name;
851
851
  const siteKey = `${parsed.filePath}:${site.atRange.startLine}:${site.atRange.startCol}`;
852
+ if (provider.suppressReceiverLookup !== undefined) {
853
+ const baseName = decodeReceiverChain(site.receiverChain)?.baseReceiverName ??
854
+ receiverName.split(/[.([\s]/, 1)[0];
855
+ const baseTypeRef = baseName === undefined
856
+ ? undefined
857
+ : findReceiverTypeBinding(site.inScope, baseName, scopes);
858
+ if (baseTypeRef !== undefined && provider.suppressReceiverLookup(baseTypeRef)) {
859
+ options.recordResolutionOutcome?.({
860
+ kind: 'suppressed',
861
+ reason: 'receiver-unresolved',
862
+ candidateIds: [],
863
+ phase: 'receiver-bound-calls',
864
+ filePath: parsed.filePath,
865
+ name: site.name,
866
+ range: site.atRange,
867
+ siteKind: site.kind,
868
+ });
869
+ handledSites.add(siteKey);
870
+ continue;
871
+ }
872
+ }
852
873
  // ── owned-but-unbound receiver ───────────────────────────────
853
874
  // The language declared this scope REBINDS the receiver and gave
854
875
  // it no type — a JS/TS ordinary `function`, whose `this` comes
@@ -1871,9 +1892,7 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
1871
1892
  if (picked === undefined) {
1872
1893
  // This runtime subtype has no proven binding. Preserve
1873
1894
  // partial coverage even when a sibling supplies a target.
1874
- if (!incompleteInheritanceSubtypeIds.has(subtype.nodeId)) {
1875
- missingMemberSubtypeIds.add(subtype.nodeId);
1876
- }
1895
+ missingMemberSubtypeIds.add(subtype.nodeId);
1877
1896
  continue;
1878
1897
  }
1879
1898
  subtypeTargets.set(picked.nodeId, picked);
@@ -800,7 +800,14 @@ import { copyV8CacheIfPresent, tryLoadV8Cache, writeV8CacheFile } from './v8-sid
800
800
  // would retain that capacity and could emit a false concrete call target.
801
801
  // v119 (#3396): Python subtype method capacities now omit receiverless ordinary
802
802
  // methods. Warm v118 ParsedFiles would replay a false compatible target.
803
- const SCHEMA_BUMP = 119;
803
+ // v120 (#3394): decorated Python method receiver bindings now distinguish
804
+ // unproven decorators from instance receivers. Warm v119 ParsedFiles would
805
+ // replay a fabricated `self` binding or lack the uncertainty marker entirely.
806
+ // v121 (#3399 follow-up): Python decorator identity now ignores trailing
807
+ // comments, honors rebinding of builtin descriptor names visible where the
808
+ // decorator is evaluated, and withholds subtype capacity from descriptor
809
+ // stacks. Warm v120 captures carry the old verdicts.
810
+ const SCHEMA_BUMP = 121;
804
811
  const GITNEXUS_PKG_VERSION = (() => {
805
812
  try {
806
813
  // package.json sits at gitnexus/package.json — two levels up from
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.13-rc.52",
3
+ "version": "1.6.13-rc.54",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",