gitnexus 1.6.4-rc.6 → 1.6.4-rc.8
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.
- package/dist/core/ingestion/languages/python/captures.js +5 -0
- package/dist/core/ingestion/languages/python/index.d.ts +1 -1
- package/dist/core/ingestion/languages/python/index.js +1 -1
- package/dist/core/ingestion/languages/python/simple-hooks.d.ts +3 -1
- package/dist/core/ingestion/languages/python/simple-hooks.js +8 -0
- package/dist/core/ingestion/languages/python.js +2 -1
- package/dist/core/ingestion/scope-extractor-bridge.d.ts +5 -2
- package/dist/core/ingestion/scope-extractor-bridge.js +7 -2
- package/dist/core/ingestion/utils/ast-helpers.d.ts +2 -0
- package/dist/core/ingestion/utils/ast-helpers.js +12 -0
- package/package.json +1 -1
|
@@ -22,6 +22,7 @@ import { synthesizeReceiverTypeBinding } from './receiver-binding.js';
|
|
|
22
22
|
import { computePythonArityMetadata } from './arity-metadata.js';
|
|
23
23
|
import { recordCacheHit, recordCacheMiss } from './cache-stats.js';
|
|
24
24
|
import { getTreeSitterBufferSize } from '../../constants.js';
|
|
25
|
+
import { pythonFunctionDefinitionLabel } from './simple-hooks.js';
|
|
25
26
|
export function emitPythonScopeCaptures(sourceText, _filePath, cachedTree) {
|
|
26
27
|
// Skip the parse when the caller (parse phase's ASTCache) already
|
|
27
28
|
// produced a Tree for this source. Cache miss = re-parse, same as
|
|
@@ -86,6 +87,10 @@ export function emitPythonScopeCaptures(sourceText, _filePath, cachedTree) {
|
|
|
86
87
|
const anchorCap = grouped['@declaration.function'];
|
|
87
88
|
const fnNode = findNodeAtRange(tree.rootNode, anchorCap.range, 'function_definition');
|
|
88
89
|
if (fnNode !== null) {
|
|
90
|
+
if (pythonFunctionDefinitionLabel(fnNode, 'Function') === 'Method') {
|
|
91
|
+
delete grouped['@declaration.function'];
|
|
92
|
+
grouped['@declaration.method'] = { ...anchorCap, name: '@declaration.method' };
|
|
93
|
+
}
|
|
89
94
|
const arity = computePythonArityMetadata(fnNode);
|
|
90
95
|
if (arity.parameterCount !== undefined) {
|
|
91
96
|
grouped['@declaration.parameter-count'] = syntheticCapture('@declaration.parameter-count', fnNode, String(arity.parameterCount));
|
|
@@ -77,4 +77,4 @@ export { interpretPythonImport, interpretPythonTypeBinding } from './interpret.j
|
|
|
77
77
|
export { pythonMergeBindings } from './merge-bindings.js';
|
|
78
78
|
export { pythonArityCompatibility } from './arity.js';
|
|
79
79
|
export { resolvePythonImportTarget, type PythonResolveContext } from './import-target.js';
|
|
80
|
-
export { pythonBindingScopeFor, pythonImportOwningScope, pythonReceiverBinding, } from './simple-hooks.js';
|
|
80
|
+
export { pythonBindingScopeFor, pythonFunctionDefinitionLabel, pythonImportOwningScope, pythonReceiverBinding, } from './simple-hooks.js';
|
|
@@ -77,4 +77,4 @@ export { interpretPythonImport, interpretPythonTypeBinding } from './interpret.j
|
|
|
77
77
|
export { pythonMergeBindings } from './merge-bindings.js';
|
|
78
78
|
export { pythonArityCompatibility } from './arity.js';
|
|
79
79
|
export { resolvePythonImportTarget } from './import-target.js';
|
|
80
|
-
export { pythonBindingScopeFor, pythonImportOwningScope, pythonReceiverBinding, } from './simple-hooks.js';
|
|
80
|
+
export { pythonBindingScopeFor, pythonFunctionDefinitionLabel, pythonImportOwningScope, pythonReceiverBinding, } from './simple-hooks.js';
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* "absence == default") so reviewers don't have to re-derive the
|
|
6
6
|
* analysis.
|
|
7
7
|
*/
|
|
8
|
-
import type { CaptureMatch, ParsedImport, Scope, ScopeId, ScopeTree, TypeRef } from '../../../../_shared/index.js';
|
|
8
|
+
import type { CaptureMatch, NodeLabel, ParsedImport, Scope, ScopeId, ScopeTree, TypeRef } from '../../../../_shared/index.js';
|
|
9
|
+
import type { SyntaxNode } from 'tree-sitter';
|
|
10
|
+
export declare function pythonFunctionDefinitionLabel(functionNode: SyntaxNode, defaultLabel: NodeLabel): NodeLabel;
|
|
9
11
|
/** Python has no block scope, so the central extractor's "innermost
|
|
10
12
|
* enclosing scope" default is already correct: `for x in …` creates
|
|
11
13
|
* `x` in the enclosing function/module scope (because we never emit a
|
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
* "absence == default") so reviewers don't have to re-derive the
|
|
6
6
|
* analysis.
|
|
7
7
|
*/
|
|
8
|
+
import { findAncestorBeforeBoundary, FUNCTION_NODE_TYPES } from '../../utils/ast-helpers.js';
|
|
9
|
+
const PYTHON_METHOD_CONTAINER_TYPES = new Set(['class_definition']);
|
|
10
|
+
export function pythonFunctionDefinitionLabel(functionNode, defaultLabel) {
|
|
11
|
+
if (defaultLabel !== 'Function')
|
|
12
|
+
return defaultLabel;
|
|
13
|
+
const ancestor = findAncestorBeforeBoundary(functionNode, PYTHON_METHOD_CONTAINER_TYPES, FUNCTION_NODE_TYPES);
|
|
14
|
+
return ancestor === null ? 'Function' : 'Method';
|
|
15
|
+
}
|
|
8
16
|
// ─── bindingScopeFor ──────────────────────────────────────────────────────
|
|
9
17
|
/** Python has no block scope, so the central extractor's "innermost
|
|
10
18
|
* enclosing scope" default is already correct: `for x in …` creates
|
|
@@ -28,7 +28,7 @@ import { pythonVariableConfig } from '../variable-extractors/configs/python.js';
|
|
|
28
28
|
import { createCallExtractor } from '../call-extractors/generic.js';
|
|
29
29
|
import { pythonCallConfig } from '../call-extractors/configs/python.js';
|
|
30
30
|
import { createHeritageExtractor } from '../heritage-extractors/generic.js';
|
|
31
|
-
import { emitPythonScopeCaptures, interpretPythonImport, interpretPythonTypeBinding, pythonArityCompatibility, pythonBindingScopeFor, pythonImportOwningScope, pythonMergeBindings, pythonReceiverBinding, resolvePythonImportTarget, } from './python/index.js';
|
|
31
|
+
import { emitPythonScopeCaptures, pythonFunctionDefinitionLabel, interpretPythonImport, interpretPythonTypeBinding, pythonArityCompatibility, pythonBindingScopeFor, pythonImportOwningScope, pythonMergeBindings, pythonReceiverBinding, resolvePythonImportTarget, } from './python/index.js';
|
|
32
32
|
const BUILT_INS = new Set([
|
|
33
33
|
'print',
|
|
34
34
|
'len',
|
|
@@ -75,6 +75,7 @@ export const pythonProvider = defineLanguage({
|
|
|
75
75
|
classExtractor: createClassExtractor(pythonClassConfig),
|
|
76
76
|
heritageExtractor: createHeritageExtractor(SupportedLanguages.Python),
|
|
77
77
|
builtInNames: BUILT_INS,
|
|
78
|
+
labelOverride: pythonFunctionDefinitionLabel,
|
|
78
79
|
// ── RFC #909 Ring 3: scope-based resolution hooks (RFC §5) ──────────
|
|
79
80
|
// Python is the first migration. See ./python/index.ts for the
|
|
80
81
|
// full per-hook rationale and the canonical capture vocabulary in
|
|
@@ -13,8 +13,11 @@
|
|
|
13
13
|
* `emitScopeCaptures`. Returns `undefined`; zero work done. This is
|
|
14
14
|
* the state of every language today — `ParsedFile` production stays
|
|
15
15
|
* dormant until a language migrates.
|
|
16
|
-
* 2.
|
|
17
|
-
*
|
|
16
|
+
* 2. Short-circuits empty / whitespace-only files. There is no scope
|
|
17
|
+
* content to extract, and some tree-sitter queries do not match an
|
|
18
|
+
* otherwise valid empty root node.
|
|
19
|
+
* 3. Invokes the hook + feeds its output to `ScopeExtractor.extract`.
|
|
20
|
+
* 4. **Swallows exceptions from either side.** A failure here returns
|
|
18
21
|
* `undefined` and emits a warning via `onWarn`; legacy parsing on
|
|
19
22
|
* the same file continues unaffected by the scope-extraction miss.
|
|
20
23
|
* Scope-based resolution is the new path under construction — it
|
|
@@ -13,8 +13,11 @@
|
|
|
13
13
|
* `emitScopeCaptures`. Returns `undefined`; zero work done. This is
|
|
14
14
|
* the state of every language today — `ParsedFile` production stays
|
|
15
15
|
* dormant until a language migrates.
|
|
16
|
-
* 2.
|
|
17
|
-
*
|
|
16
|
+
* 2. Short-circuits empty / whitespace-only files. There is no scope
|
|
17
|
+
* content to extract, and some tree-sitter queries do not match an
|
|
18
|
+
* otherwise valid empty root node.
|
|
19
|
+
* 3. Invokes the hook + feeds its output to `ScopeExtractor.extract`.
|
|
20
|
+
* 4. **Swallows exceptions from either side.** A failure here returns
|
|
18
21
|
* `undefined` and emits a warning via `onWarn`; legacy parsing on
|
|
19
22
|
* the same file continues unaffected by the scope-extraction miss.
|
|
20
23
|
* Scope-based resolution is the new path under construction — it
|
|
@@ -29,6 +32,8 @@ import { extract as extractScope } from './scope-extractor.js';
|
|
|
29
32
|
export function extractParsedFile(provider, sourceText, filePath, onWarn, cachedTree) {
|
|
30
33
|
if (provider.emitScopeCaptures === undefined)
|
|
31
34
|
return undefined;
|
|
35
|
+
if (sourceText.trim().length === 0)
|
|
36
|
+
return undefined;
|
|
32
37
|
try {
|
|
33
38
|
const captures = provider.emitScopeCaptures(sourceText, filePath, cachedTree);
|
|
34
39
|
return extractScope(captures, filePath, provider);
|
|
@@ -31,6 +31,8 @@ export declare const FUNCTION_NODE_TYPES: Set<string>;
|
|
|
31
31
|
*/
|
|
32
32
|
export declare const CLASS_CONTAINER_TYPES: Set<string>;
|
|
33
33
|
export declare const CONTAINER_TYPE_TO_LABEL: Record<string, string>;
|
|
34
|
+
/** Return the first matching ancestor unless a boundary ancestor is reached first. */
|
|
35
|
+
export declare function findAncestorBeforeBoundary(node: SyntaxNode, targetTypes: ReadonlySet<string>, boundaryTypes: ReadonlySet<string>): SyntaxNode | null;
|
|
34
36
|
/**
|
|
35
37
|
* Determine the graph node label from a tree-sitter capture map.
|
|
36
38
|
* Handles language-specific reclassification via the provider's labelOverride hook
|
|
@@ -153,6 +153,18 @@ export const CONTAINER_TYPE_TO_LABEL = {
|
|
|
153
153
|
object_declaration: 'Class',
|
|
154
154
|
companion_object: 'Class',
|
|
155
155
|
};
|
|
156
|
+
/** Return the first matching ancestor unless a boundary ancestor is reached first. */
|
|
157
|
+
export function findAncestorBeforeBoundary(node, targetTypes, boundaryTypes) {
|
|
158
|
+
let current = node.parent;
|
|
159
|
+
while (current !== null) {
|
|
160
|
+
if (boundaryTypes.has(current.type))
|
|
161
|
+
return null;
|
|
162
|
+
if (targetTypes.has(current.type))
|
|
163
|
+
return current;
|
|
164
|
+
current = current.parent;
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
156
168
|
/**
|
|
157
169
|
* Determine the graph node label from a tree-sitter capture map.
|
|
158
170
|
* Handles language-specific reclassification via the provider's labelOverride hook
|
package/package.json
CHANGED