gitnexus 1.6.6-rc.149 → 1.6.6-rc.150
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/field-extractors/configs/go.d.ts +0 -9
- package/dist/core/ingestion/field-extractors/configs/go.js +40 -1
- package/dist/core/ingestion/field-extractors/generic.d.ts +6 -0
- package/dist/core/ingestion/field-extractors/generic.js +5 -4
- package/dist/core/ingestion/languages/go/query.js +6 -2
- package/dist/core/ingestion/parsing-processor.d.ts +4 -0
- package/dist/core/ingestion/parsing-processor.js +33 -1
- package/dist/core/ingestion/tree-sitter-queries.d.ts +1 -1
- package/dist/core/ingestion/tree-sitter-queries.js +3 -2
- package/dist/core/ingestion/variable-extractors/configs/go.js +74 -7
- package/dist/core/ingestion/variable-extractors/generic.js +13 -10
- package/dist/core/ingestion/variable-types.d.ts +9 -0
- package/dist/core/ingestion/workers/parse-worker.js +30 -16
- package/package.json +1 -1
|
@@ -1,11 +1,2 @@
|
|
|
1
1
|
import type { FieldExtractionConfig } from '../generic.js';
|
|
2
|
-
/**
|
|
3
|
-
* Go field extraction config.
|
|
4
|
-
*
|
|
5
|
-
* Go struct fields live inside type_declaration > type_spec > struct_type >
|
|
6
|
-
* field_declaration_list > field_declaration.
|
|
7
|
-
*
|
|
8
|
-
* Visibility in Go is based on the first character: uppercase = exported (public),
|
|
9
|
-
* lowercase = unexported (package).
|
|
10
|
-
*/
|
|
11
2
|
export declare const goConfig: FieldExtractionConfig;
|
|
@@ -10,13 +10,48 @@ import { extractSimpleTypeName } from '../../type-extractors/shared.js';
|
|
|
10
10
|
* Visibility in Go is based on the first character: uppercase = exported (public),
|
|
11
11
|
* lowercase = unexported (package).
|
|
12
12
|
*/
|
|
13
|
+
function goVisibilityForName(name) {
|
|
14
|
+
const first = name.charAt(0);
|
|
15
|
+
return first === first.toUpperCase() && first !== first.toLowerCase() ? 'public' : 'package';
|
|
16
|
+
}
|
|
17
|
+
function extractGoFieldNames(node) {
|
|
18
|
+
const names = [];
|
|
19
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
20
|
+
const child = node.namedChild(i);
|
|
21
|
+
if (child?.type === 'field_identifier')
|
|
22
|
+
names.push(child.text);
|
|
23
|
+
}
|
|
24
|
+
return names;
|
|
25
|
+
}
|
|
13
26
|
export const goConfig = {
|
|
14
27
|
language: SupportedLanguages.Go,
|
|
15
|
-
typeDeclarationNodes: ['type_declaration'],
|
|
28
|
+
typeDeclarationNodes: ['type_declaration', 'struct_type'],
|
|
16
29
|
fieldNodeTypes: ['field_declaration'],
|
|
17
30
|
bodyNodeTypes: ['field_declaration_list'],
|
|
18
31
|
defaultVisibility: 'package',
|
|
32
|
+
extractOwnerName(node) {
|
|
33
|
+
if (node.type === 'struct_type') {
|
|
34
|
+
return node.parent?.type === 'type_spec'
|
|
35
|
+
? node.parent.childForFieldName('name')?.text
|
|
36
|
+
: undefined;
|
|
37
|
+
}
|
|
38
|
+
const typeSpec = node.namedChildren.find((child) => child.type === 'type_spec');
|
|
39
|
+
return typeSpec?.childForFieldName('name')?.text;
|
|
40
|
+
},
|
|
41
|
+
findBodyNodes(node) {
|
|
42
|
+
if (node.type === 'struct_type') {
|
|
43
|
+
const body = node.namedChildren.find((child) => child.type === 'field_declaration_list');
|
|
44
|
+
return body ? [body] : [];
|
|
45
|
+
}
|
|
46
|
+
const typeSpec = node.namedChildren.find((child) => child.type === 'type_spec');
|
|
47
|
+
const typeNode = typeSpec?.childForFieldName('type');
|
|
48
|
+
const body = typeNode?.namedChildren.find((child) => child.type === 'field_declaration_list');
|
|
49
|
+
return body ? [body] : [];
|
|
50
|
+
},
|
|
19
51
|
extractName(node) {
|
|
52
|
+
const firstName = extractGoFieldNames(node)[0];
|
|
53
|
+
if (firstName)
|
|
54
|
+
return firstName;
|
|
20
55
|
// field_declaration > name:(field_identifier)
|
|
21
56
|
const name = node.childForFieldName('name');
|
|
22
57
|
if (name)
|
|
@@ -29,6 +64,7 @@ export const goConfig = {
|
|
|
29
64
|
}
|
|
30
65
|
return undefined;
|
|
31
66
|
},
|
|
67
|
+
extractNames: extractGoFieldNames,
|
|
32
68
|
extractType(node) {
|
|
33
69
|
// field_declaration > type:(type_identifier | pointer_type | ...)
|
|
34
70
|
const typeNode = node.childForFieldName('type');
|
|
@@ -51,6 +87,9 @@ export const goConfig = {
|
|
|
51
87
|
}
|
|
52
88
|
return 'package';
|
|
53
89
|
},
|
|
90
|
+
extractVisibilityForName(_node, name) {
|
|
91
|
+
return goVisibilityForName(name);
|
|
92
|
+
},
|
|
54
93
|
isStatic(_node) {
|
|
55
94
|
return false; // Go has no static fields
|
|
56
95
|
},
|
|
@@ -19,6 +19,10 @@ export interface FieldExtractionConfig {
|
|
|
19
19
|
bodyNodeTypes: string[];
|
|
20
20
|
/** Default visibility when no modifier is present */
|
|
21
21
|
defaultVisibility: FieldVisibility;
|
|
22
|
+
/** Extract owner type name from a type declaration node. */
|
|
23
|
+
extractOwnerName?: (node: SyntaxNode) => string | undefined;
|
|
24
|
+
/** Find body nodes inside a type declaration node. */
|
|
25
|
+
findBodyNodes?: (node: SyntaxNode) => SyntaxNode[];
|
|
22
26
|
/**
|
|
23
27
|
* Extract field name from a field declaration node.
|
|
24
28
|
* Use this for nodes that declare exactly one field.
|
|
@@ -35,6 +39,8 @@ export interface FieldExtractionConfig {
|
|
|
35
39
|
extractType: (node: SyntaxNode) => string | undefined;
|
|
36
40
|
/** Extract visibility from a field declaration node */
|
|
37
41
|
extractVisibility: (node: SyntaxNode) => FieldVisibility;
|
|
42
|
+
/** Extract visibility for one field name from a multi-name declaration. */
|
|
43
|
+
extractVisibilityForName?: (node: SyntaxNode, name: string) => FieldVisibility;
|
|
38
44
|
/** Check if a field is static */
|
|
39
45
|
isStatic: (node: SyntaxNode) => boolean;
|
|
40
46
|
/** Check if a field is readonly/final/const */
|
|
@@ -21,10 +21,9 @@ export function createFieldExtractor(config) {
|
|
|
21
21
|
extract(node, context) {
|
|
22
22
|
if (!this.isTypeDeclaration(node))
|
|
23
23
|
return null;
|
|
24
|
-
const
|
|
25
|
-
if (!
|
|
24
|
+
const ownerFqn = config.extractOwnerName?.(node) ?? node.childForFieldName('name')?.text;
|
|
25
|
+
if (!ownerFqn)
|
|
26
26
|
return null;
|
|
27
|
-
const ownerFqn = nameNode.text;
|
|
28
27
|
const fields = [];
|
|
29
28
|
// Find body container(s)
|
|
30
29
|
const bodies = this.findBodies(node);
|
|
@@ -43,6 +42,8 @@ export function createFieldExtractor(config) {
|
|
|
43
42
|
// private helpers
|
|
44
43
|
// ------------------------------------------------------------------
|
|
45
44
|
findBodies(node) {
|
|
45
|
+
if (config.findBodyNodes)
|
|
46
|
+
return config.findBodyNodes(node);
|
|
46
47
|
const result = [];
|
|
47
48
|
// Try named 'body' field first
|
|
48
49
|
const bodyField = node.childForFieldName('body');
|
|
@@ -105,7 +106,7 @@ export function createFieldExtractor(config) {
|
|
|
105
106
|
return {
|
|
106
107
|
name,
|
|
107
108
|
type,
|
|
108
|
-
visibility: config.extractVisibility(node),
|
|
109
|
+
visibility: config.extractVisibilityForName?.(node, name) ?? config.extractVisibility(node),
|
|
109
110
|
isStatic: config.isStatic(node),
|
|
110
111
|
isReadonly: config.isReadonly(node),
|
|
111
112
|
sourceFile: context.filePath,
|
|
@@ -52,11 +52,15 @@ const GO_SCOPE_QUERY = `
|
|
|
52
52
|
;; Declarations — variables
|
|
53
53
|
(var_declaration
|
|
54
54
|
(var_spec
|
|
55
|
-
|
|
55
|
+
(identifier) @declaration.name)) @declaration.variable
|
|
56
|
+
(var_declaration
|
|
57
|
+
(var_spec_list
|
|
58
|
+
(var_spec
|
|
59
|
+
(identifier) @declaration.name))) @declaration.variable
|
|
56
60
|
|
|
57
61
|
(const_declaration
|
|
58
62
|
(const_spec
|
|
59
|
-
|
|
63
|
+
(identifier) @declaration.name)) @declaration.const
|
|
60
64
|
|
|
61
65
|
(short_var_declaration
|
|
62
66
|
left: (expression_list (identifier) @declaration.name)) @declaration.variable
|
|
@@ -41,6 +41,10 @@ export interface WorkerExtractedData {
|
|
|
41
41
|
* silently no-op'd by `KnowledgeGraph`).
|
|
42
42
|
*/
|
|
43
43
|
export declare const mergeChunkResults: (graph: KnowledgeGraph, symbolTable: SymbolTableWriter, chunkResults: readonly ParseWorkerResult[]) => WorkerExtractedData;
|
|
44
|
+
export declare const processParsingSequential: (graph: KnowledgeGraph, files: {
|
|
45
|
+
path: string;
|
|
46
|
+
content: string;
|
|
47
|
+
}[], symbolTable: SymbolTableWriter, astCache: ASTCache, scopeTreeCache: ASTCache | undefined, onFileProgress?: FileProgressCallback) => Promise<void>;
|
|
44
48
|
export declare const processParsing: (graph: KnowledgeGraph, files: {
|
|
45
49
|
path: string;
|
|
46
50
|
content: string;
|
|
@@ -263,7 +263,7 @@ function seqGetFieldInfo(classNode, provider, context) {
|
|
|
263
263
|
seqFieldInfoCache.set(cacheKey, cached);
|
|
264
264
|
return cached;
|
|
265
265
|
}
|
|
266
|
-
const processParsingSequential = async (graph, files, symbolTable, astCache, scopeTreeCache, onFileProgress) => {
|
|
266
|
+
export const processParsingSequential = async (graph, files, symbolTable, astCache, scopeTreeCache, onFileProgress) => {
|
|
267
267
|
const parser = await loadParser();
|
|
268
268
|
const total = files.length;
|
|
269
269
|
const logSkipped = isVerboseIngestionEnabled();
|
|
@@ -276,6 +276,7 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, sco
|
|
|
276
276
|
seqFieldInfoCache.clear();
|
|
277
277
|
seqMethodExtractCache.clear();
|
|
278
278
|
seqMethodMapCache.clear();
|
|
279
|
+
const seqVariableInfoCache = new Map();
|
|
279
280
|
onFileProgress?.(i + 1, total, file.path);
|
|
280
281
|
if (i % 20 === 0)
|
|
281
282
|
await yieldToEventLoop();
|
|
@@ -699,6 +700,31 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, sco
|
|
|
699
700
|
}
|
|
700
701
|
// All 15 tree-sitter languages register a FieldExtractor — no fallback needed.
|
|
701
702
|
}
|
|
703
|
+
if ((nodeLabel === 'Const' || nodeLabel === 'Static' || nodeLabel === 'Variable') &&
|
|
704
|
+
definitionNode &&
|
|
705
|
+
provider.variableExtractor) {
|
|
706
|
+
let variableInfoByName = seqVariableInfoCache.get(definitionNode.startIndex);
|
|
707
|
+
if (!variableInfoByName) {
|
|
708
|
+
const varCtx = {
|
|
709
|
+
filePath: file.path,
|
|
710
|
+
language,
|
|
711
|
+
};
|
|
712
|
+
variableInfoByName = new Map(provider.variableExtractor
|
|
713
|
+
.extractAll(definitionNode, varCtx)
|
|
714
|
+
.map((info) => [info.name, info]));
|
|
715
|
+
seqVariableInfoCache.set(definitionNode.startIndex, variableInfoByName);
|
|
716
|
+
}
|
|
717
|
+
const varInfo = variableInfoByName.get(nodeName);
|
|
718
|
+
if (varInfo) {
|
|
719
|
+
if (varInfo.type)
|
|
720
|
+
declaredType = varInfo.type;
|
|
721
|
+
seqVisibility = varInfo.visibility;
|
|
722
|
+
seqIsStatic = varInfo.isStatic;
|
|
723
|
+
methodProps.isConst = varInfo.isConst;
|
|
724
|
+
methodProps.isMutable = varInfo.isMutable;
|
|
725
|
+
methodProps.scope = varInfo.scope;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
702
728
|
// Apply field metadata to the graph node retroactively
|
|
703
729
|
if (seqVisibility !== undefined)
|
|
704
730
|
node.properties.visibility = seqVisibility;
|
|
@@ -708,6 +734,12 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, sco
|
|
|
708
734
|
node.properties.isReadonly = seqIsReadonly;
|
|
709
735
|
if (declaredType !== undefined)
|
|
710
736
|
node.properties.declaredType = declaredType;
|
|
737
|
+
if (methodProps.isConst !== undefined)
|
|
738
|
+
node.properties.isConst = methodProps.isConst;
|
|
739
|
+
if (methodProps.isMutable !== undefined)
|
|
740
|
+
node.properties.isMutable = methodProps.isMutable;
|
|
741
|
+
if (methodProps.scope !== undefined)
|
|
742
|
+
node.properties.scope = methodProps.scope;
|
|
711
743
|
symbolTable.add(file.path, nodeName, nodeId, nodeLabel, {
|
|
712
744
|
parameterCount: methodProps.parameterCount,
|
|
713
745
|
requiredParameterCount: methodProps.requiredParameterCount,
|
|
@@ -3,7 +3,7 @@ export declare const JAVASCRIPT_QUERIES: string;
|
|
|
3
3
|
export declare const PYTHON_QUERIES = "\n(class_definition\n name: (identifier) @name) @definition.class\n\n(function_definition\n name: (identifier) @name) @definition.function\n\n(import_statement\n name: (dotted_name) @import.source) @import\n\n; import numpy as np \u2192 aliased_import captures the module name so the\n; import path is resolved and named-binding extraction stores \"np\" \u2192 \"numpy\".\n(import_statement\n name: (aliased_import\n name: (dotted_name) @import.source)) @import\n\n(import_from_statement\n module_name: (dotted_name) @import.source) @import\n\n(import_from_statement\n module_name: (relative_import) @import.source) @import\n\n(call\n function: (identifier) @call.name) @call\n\n(call\n function: (attribute\n attribute: (identifier) @call.name)) @call\n\n; Class attribute type annotations \u2014 PEP 526: address: Address or address: Address = Address()\n; Both bare annotations (address: Address) and annotated assignments (name: str = \"test\")\n; are parsed as (assignment left: ... type: ...) in tree-sitter-python.\n(expression_statement\n (assignment\n left: (identifier) @name\n type: (type)) @definition.property)\n\n; Plain variable assignments without type annotation: x = 5, MAX_SIZE = 100\n; Overlap with @definition.property (typed) is handled by parse-worker dedup.\n(expression_statement\n (assignment\n left: (identifier) @name)) @definition.variable\n\n; Write access: obj.field = value\n(assignment\n left: (attribute\n object: (_) @assignment.receiver\n attribute: (identifier) @assignment.property)\n right: (_)) @assignment\n\n; Write access: obj.field += value (compound assignment)\n(augmented_assignment\n left: (attribute\n object: (_) @assignment.receiver\n attribute: (identifier) @assignment.property)\n right: (_)) @assignment\n\n; Python HTTP clients: requests.get('/path'), httpx.post('/path'), session.get('/path')\n(call\n function: (attribute\n attribute: (identifier) @http_client.method)\n arguments: (argument_list\n (string (string_content) @http_client.url))) @http_client\n\n; Python decorators: @app.route, @router.get, etc.\n(decorator\n (call\n function: (attribute\n object: (identifier) @decorator.receiver\n attribute: (identifier) @decorator.name)\n arguments: (argument_list\n (string (string_content) @decorator.arg)?))) @decorator\n";
|
|
4
4
|
export declare const JAVA_QUERIES = "\n; Classes, Interfaces, Enums, Annotations\n(class_declaration name: (identifier) @name) @definition.class\n(interface_declaration name: (identifier) @name) @definition.interface\n(enum_declaration name: (identifier) @name) @definition.enum\n(annotation_type_declaration name: (identifier) @name) @definition.annotation\n\n; Methods & Constructors\n(method_declaration name: (identifier) @name) @definition.method\n(constructor_declaration name: (identifier) @name) @definition.constructor\n\n; Fields \u2014 typed field declarations inside class bodies\n(field_declaration\n declarator: (variable_declarator\n name: (identifier) @name)) @definition.property\n\n; Imports - capture any import declaration child as source\n(import_declaration (_) @import.source) @import\n\n; Calls\n(method_invocation name: (identifier) @call.name) @call\n(method_invocation object: (_) name: (identifier) @call.name) @call\n(method_reference) @call\n\n; Constructor calls: new Foo()\n(object_creation_expression type: (type_identifier) @call.name) @call\n\n; Local variable declarations inside method bodies\n(local_variable_declaration\n declarator: (variable_declarator\n name: (identifier) @name)) @definition.variable\n\n; Write access: obj.field = value\n(assignment_expression\n left: (field_access\n object: (_) @assignment.receiver\n field: (identifier) @assignment.property)\n right: (_)) @assignment\n";
|
|
5
5
|
export declare const C_QUERIES = "\n; Functions (direct declarator)\n(function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function\n(declaration declarator: (function_declarator declarator: (identifier) @name)) @definition.function\n\n; Functions returning pointers (pointer_declarator wraps function_declarator)\n(function_definition declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @definition.function\n(declaration declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @definition.function\n\n; Functions returning double pointers (nested pointer_declarator)\n(function_definition declarator: (pointer_declarator declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name)))) @definition.function\n\n; Structs, Unions, Enums, Typedefs\n(struct_specifier name: (type_identifier) @name) @definition.struct\n(type_definition\n type: (struct_specifier\n body: (field_declaration_list))\n declarator: (type_identifier) @name) @definition.struct\n(union_specifier name: (type_identifier) @name) @definition.union\n(enum_specifier name: (type_identifier) @name) @definition.enum\n(type_definition\n type: (enum_specifier\n body: (enumerator_list))\n declarator: (type_identifier) @name) @definition.enum\n(enumerator name: (identifier) @name) @definition.const\n(type_definition declarator: (type_identifier) @name) @definition.typedef\n\n; Macros\n(preproc_function_def name: (identifier) @name) @definition.macro\n(preproc_def name: (identifier) @name) @definition.macro\n\n; Includes\n(preproc_include path: (_) @import.source) @import\n\n; Calls\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (field_expression field: (field_identifier) @call.name)) @call\n\n; Variable declarations: int x = 5; or int x;\n(declaration\n declarator: (init_declarator\n declarator: (identifier) @name)) @definition.variable\n";
|
|
6
|
-
export declare const GO_QUERIES = "\n; Functions & Methods\n(function_declaration name: (identifier) @name) @definition.function\n(method_declaration name: (field_identifier) @name) @definition.method\n(method_elem name: (field_identifier) @name) @definition.method\n\n; Types\n(type_declaration (type_spec name: (type_identifier) @name type: (struct_type))) @definition.struct\n(type_declaration (type_spec name: (type_identifier) @name type: (interface_type))) @definition.interface\n\n; Imports\n(import_declaration (import_spec path: (interpreted_string_literal) @import.source)) @import\n(import_declaration (import_spec_list (import_spec path: (interpreted_string_literal) @import.source))) @import\n\n; Struct fields \u2014 named field declarations inside struct types\n(field_declaration_list\n (field_declaration\n name: (field_identifier) @name) @definition.property)\n\n; Calls\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (selector_expression field: (field_identifier) @call.name)) @call\n\n; Const/var declarations\n(const_declaration (const_spec
|
|
6
|
+
export declare const GO_QUERIES = "\n; Functions & Methods\n(function_declaration name: (identifier) @name) @definition.function\n(method_declaration name: (field_identifier) @name) @definition.method\n(method_elem name: (field_identifier) @name) @definition.method\n\n; Types\n(type_declaration (type_spec name: (type_identifier) @name type: (struct_type))) @definition.struct\n(type_declaration (type_spec name: (type_identifier) @name type: (interface_type))) @definition.interface\n\n; Imports\n(import_declaration (import_spec path: (interpreted_string_literal) @import.source)) @import\n(import_declaration (import_spec_list (import_spec path: (interpreted_string_literal) @import.source))) @import\n\n; Struct fields \u2014 named field declarations inside struct types\n(field_declaration_list\n (field_declaration\n name: (field_identifier) @name) @definition.property)\n\n; Calls\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (selector_expression field: (field_identifier) @call.name)) @call\n\n; Const/var declarations\n(const_declaration (const_spec (identifier) @name)) @definition.const\n(var_declaration (var_spec (identifier) @name)) @definition.variable\n(var_declaration (var_spec_list (var_spec (identifier) @name))) @definition.variable\n\n; Short variable declaration: x := 5\n(short_var_declaration left: (expression_list (identifier) @name)) @definition.variable\n\n; Struct literal construction: User{Name: \"Alice\"}\n(composite_literal type: (type_identifier) @call.name) @call\n\n; Write access: obj.field = value\n(assignment_statement\n left: (expression_list\n (selector_expression\n operand: (_) @assignment.receiver\n field: (field_identifier) @assignment.property))\n right: (_)) @assignment\n\n; Write access: obj.field++ / obj.field--\n(inc_statement\n (selector_expression\n operand: (_) @assignment.receiver\n field: (field_identifier) @assignment.property)) @assignment\n(dec_statement\n (selector_expression\n operand: (_) @assignment.receiver\n field: (field_identifier) @assignment.property)) @assignment\n";
|
|
7
7
|
export declare const CPP_QUERIES = "\n; Classes, Structs, Namespaces\n(class_specifier name: (type_identifier) @name) @definition.class\n(class_specifier\n name: (template_type\n (type_identifier) @name\n (template_argument_list) @template-arguments)) @definition.class\n; Out-of-line nested definition: class Outer::Inner { ... } / struct Outer::Inner { ... }.\n; Key the node by the full qualified_identifier text so the def materializes a\n; node that matches the HAS_METHOD owner id (also the full qualified text) and\n; stays distinct from a same-tail type in another scope (#1975, #1978).\n(class_specifier name: (qualified_identifier) @name) @definition.class\n(struct_specifier name: (qualified_identifier) @name) @definition.struct\n(struct_specifier name: (type_identifier) @name) @definition.struct\n(struct_specifier\n name: (template_type\n (type_identifier) @name\n (template_argument_list) @template-arguments)) @definition.struct\n(namespace_definition name: (namespace_identifier) @name) @definition.namespace\n(enum_specifier name: (type_identifier) @name) @definition.enum\n\n; Typedefs and unions (common in C-style headers and mixed C/C++ code)\n(type_definition\n type: (struct_specifier\n body: (field_declaration_list))\n declarator: (type_identifier) @name) @definition.struct\n(type_definition\n type: (enum_specifier\n body: (enumerator_list))\n declarator: (type_identifier) @name) @definition.enum\n(enumerator name: (identifier) @name) @definition.const\n(type_definition declarator: (type_identifier) @name) @definition.typedef\n(union_specifier name: (type_identifier) @name) @definition.union\n\n; Macros\n(preproc_function_def name: (identifier) @name) @definition.macro\n(preproc_def name: (identifier) @name) @definition.macro\n\n; Functions & Methods (direct declarator)\n(function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function\n(function_definition declarator: (function_declarator declarator: (operator_name) @name)) @definition.function\n(function_definition declarator: (function_declarator declarator: (qualified_identifier name: (identifier) @name))) @definition.method\n(function_definition declarator: (function_declarator declarator: (qualified_identifier name: (operator_name) @name))) @definition.method\n\n; Functions/methods returning pointers (pointer_declarator wraps function_declarator)\n(function_definition declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @definition.function\n(function_definition declarator: (pointer_declarator declarator: (function_declarator declarator: (qualified_identifier name: (identifier) @name)))) @definition.method\n\n; Functions/methods returning double pointers (nested pointer_declarator)\n(function_definition declarator: (pointer_declarator declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name)))) @definition.function\n(function_definition declarator: (pointer_declarator declarator: (pointer_declarator declarator: (function_declarator declarator: (qualified_identifier name: (identifier) @name))))) @definition.method\n\n; Functions/methods returning references (reference_declarator wraps function_declarator)\n(function_definition declarator: (reference_declarator (function_declarator declarator: (identifier) @name))) @definition.function\n(function_definition declarator: (reference_declarator (function_declarator declarator: (operator_name) @name))) @definition.function\n(function_definition declarator: (reference_declarator (function_declarator declarator: (qualified_identifier name: (identifier) @name)))) @definition.method\n(function_definition declarator: (reference_declarator (function_declarator declarator: (qualified_identifier name: (operator_name) @name)))) @definition.method\n\n; Destructors (destructor_name is distinct from identifier in tree-sitter-cpp)\n(function_definition declarator: (function_declarator declarator: (qualified_identifier name: (destructor_name) @name))) @definition.method\n\n; Function declarations / prototypes (common in headers)\n(declaration declarator: (function_declarator declarator: (identifier) @name)) @definition.function\n(declaration declarator: (function_declarator declarator: (operator_name) @name)) @definition.function\n(declaration declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @definition.function\n(declaration declarator: (reference_declarator (function_declarator declarator: (operator_name) @name))) @definition.function\n\n; Class/struct data member fields (Address address; int count;)\n; Uses field_identifier to exclude method declarations (which use function_declarator)\n(field_declaration\n declarator: (field_identifier) @name) @definition.property\n\n; Pointer member fields (Address* address;)\n(field_declaration\n declarator: (pointer_declarator\n declarator: (field_identifier) @name)) @definition.property\n\n; Reference member fields (Address& address;)\n(field_declaration\n declarator: (reference_declarator\n (field_identifier) @name)) @definition.property\n\n; Inline class method declarations (inside class body, no body: void save();)\n; tree-sitter-cpp uses field_identifier (not identifier) for names inside class bodies\n(field_declaration declarator: (function_declarator declarator: [(field_identifier) (identifier) (operator_name)] @name)) @definition.method\n\n; Inline class method declarations returning a pointer (User* lookup();)\n(field_declaration declarator: (pointer_declarator declarator: (function_declarator declarator: [(field_identifier) (identifier)] @name))) @definition.method\n\n; Inline class method declarations returning a reference (User& lookup();)\n(field_declaration declarator: (reference_declarator (function_declarator declarator: [(field_identifier) (identifier) (operator_name)] @name))) @definition.method\n\n; Inline class method definitions (inside class body, with body: void Foo() { ... })\n(field_declaration_list\n (function_definition\n declarator: (function_declarator\n declarator: [(field_identifier) (identifier) (operator_name) (destructor_name)] @name)) @definition.method)\n\n; Inline class methods returning a pointer type (User* lookup(int id) { ... })\n(field_declaration_list\n (function_definition\n declarator: (pointer_declarator\n declarator: (function_declarator\n declarator: [(field_identifier) (identifier) (operator_name)] @name))) @definition.method)\n\n; Inline class methods returning a reference type (User& lookup(int id) { ... })\n(field_declaration_list\n (function_definition\n declarator: (reference_declarator\n (function_declarator\n declarator: [(field_identifier) (identifier) (operator_name)] @name))) @definition.method)\n\n; Templates\n(template_declaration (class_specifier name: (type_identifier) @name)) @definition.template\n(template_declaration\n (class_specifier\n name: (template_type\n (type_identifier) @name\n (template_argument_list) @template-arguments))) @definition.template\n(template_declaration (function_definition declarator: (function_declarator declarator: (identifier) @name))) @definition.template\n\n; Includes\n(preproc_include path: (_) @import.source) @import\n\n; Calls\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (field_expression field: (field_identifier) @call.name)) @call\n(call_expression function: (qualified_identifier name: (identifier) @call.name)) @call\n(call_expression function: (template_function name: (identifier) @call.name)) @call\n(binary_expression operator: \"+\" @call.name) @call\n(binary_expression operator: \"<<\" @call.name) @call\n\n; Constructor calls: new User()\n(new_expression type: (type_identifier) @call.name) @call\n\n; Variable declarations: int x = 5; or auto x = 5;\n(declaration\n declarator: (init_declarator\n declarator: (identifier) @name)) @definition.variable\n\n; Write access: obj.field = value\n(assignment_expression\n left: (field_expression\n argument: (_) @assignment.receiver\n field: (field_identifier) @assignment.property)\n right: (_)) @assignment\n\n";
|
|
8
8
|
export declare const CSHARP_QUERIES = "\n; Types\n(class_declaration name: (identifier) @name) @definition.class\n(interface_declaration name: (identifier) @name) @definition.interface\n(struct_declaration name: (identifier) @name) @definition.struct\n(enum_declaration name: (identifier) @name) @definition.enum\n(record_declaration name: (identifier) @name) @definition.record\n(delegate_declaration name: (identifier) @name) @definition.delegate\n\n; Namespaces (block form and C# 10+ file-scoped form)\n(namespace_declaration name: (identifier) @name) @definition.namespace\n(namespace_declaration name: (qualified_name) @name) @definition.namespace\n(file_scoped_namespace_declaration name: (identifier) @name) @definition.namespace\n(file_scoped_namespace_declaration name: (qualified_name) @name) @definition.namespace\n\n; Methods & Properties\n(method_declaration name: (identifier) @name) @definition.method\n(local_function_statement name: (identifier) @name) @definition.function\n(constructor_declaration name: (identifier) @name) @definition.constructor\n(property_declaration name: (identifier) @name) @definition.property\n\n; Primary constructors (C# 12): class User(string name, int age) { }\n(class_declaration name: (identifier) @name (parameter_list) @definition.constructor)\n(record_declaration name: (identifier) @name (parameter_list) @definition.constructor)\n\n; Using\n(using_directive (qualified_name) @import.source) @import\n(using_directive (identifier) @import.source) @import\n\n; Calls\n(invocation_expression function: (identifier) @call.name) @call\n(invocation_expression function: (member_access_expression name: (identifier) @call.name)) @call\n\n; Null-conditional method calls: user?.Save()\n; Parses as: invocation_expression \u2192 conditional_access_expression \u2192 member_binding_expression \u2192 identifier\n(invocation_expression\n function: (conditional_access_expression\n (member_binding_expression\n (identifier) @call.name))) @call\n\n; Constructor calls: new Foo() and new Foo { Props }\n(object_creation_expression type: (identifier) @call.name) @call\n\n; Target-typed new (C# 9): User u = new(\"x\", 5)\n(variable_declaration type: (identifier) @call.name (variable_declarator (implicit_object_creation_expression) @call))\n\n; Local variable declarations\n(local_declaration_statement\n (variable_declaration\n (variable_declarator\n (identifier) @name))) @definition.variable\n\n; Write access: obj.field = value\n(assignment_expression\n left: (member_access_expression\n expression: (_) @assignment.receiver\n name: (identifier) @assignment.property)\n right: (_)) @assignment\n";
|
|
9
9
|
export declare const RUST_QUERIES = "\n; Functions & Items\n(function_item name: (identifier) @name) @definition.function\n(function_signature_item name: (identifier) @name) @definition.function\n(struct_item name: (type_identifier) @name) @definition.struct\n; A union is materialized as a Struct node (same rationale as the\n; scope-resolution @declaration.struct in languages/rust/query.ts: every\n; registry-primary resolution gate includes Struct but excludes Union, so a\n; Union-labeled node would be an unresolvable orphan). #1934 F71.\n(union_item name: (type_identifier) @name) @definition.struct\n(enum_item name: (type_identifier) @name) @definition.enum\n(trait_item name: (type_identifier) @name) @definition.trait\n(impl_item type: (type_identifier) @name !trait) @definition.impl\n(impl_item type: (generic_type type: (type_identifier) @name) !trait) @definition.impl\n; Scoped inherent impl: impl path::Type { ... }. Key the Impl node by the full\n; scoped_type_identifier text so it matches the owner id (also full text) and\n; stays distinct from a same-tail type in another module (#1975).\n(impl_item type: (scoped_type_identifier) @name !trait) @definition.impl\n(mod_item name: (identifier) @name) @definition.module\n\n; Type aliases, const, static, macros\n(type_item name: (type_identifier) @name) @definition.type\n(const_item name: (identifier) @name) @definition.const\n(static_item name: (identifier) @name) @definition.static\n(macro_definition name: (identifier) @name) @definition.macro\n\n; Use statements\n(use_declaration argument: (_) @import.source) @import\n\n; Calls\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (field_expression field: (field_identifier) @call.name)) @call\n(call_expression function: (scoped_identifier name: (identifier) @call.name)) @call\n(call_expression function: (generic_function function: (identifier) @call.name)) @call\n\n; Struct literal construction: User { name: value }\n(struct_expression name: (type_identifier) @call.name) @call\n\n; Struct fields \u2014 named field declarations inside struct bodies\n(field_declaration_list\n (field_declaration\n name: (field_identifier) @name) @definition.property)\n\n; Write access: obj.field = value\n(assignment_expression\n left: (field_expression\n value: (_) @assignment.receiver\n field: (field_identifier) @assignment.property)\n right: (_)) @assignment\n\n; Write access: obj.field += value (compound assignment)\n(compound_assignment_expr\n left: (field_expression\n value: (_) @assignment.receiver\n field: (field_identifier) @assignment.property)\n right: (_)) @assignment\n";
|
|
@@ -828,8 +828,9 @@ export const GO_QUERIES = `
|
|
|
828
828
|
(call_expression function: (selector_expression field: (field_identifier) @call.name)) @call
|
|
829
829
|
|
|
830
830
|
; Const/var declarations
|
|
831
|
-
(const_declaration (const_spec
|
|
832
|
-
(var_declaration (var_spec
|
|
831
|
+
(const_declaration (const_spec (identifier) @name)) @definition.const
|
|
832
|
+
(var_declaration (var_spec (identifier) @name)) @definition.variable
|
|
833
|
+
(var_declaration (var_spec_list (var_spec (identifier) @name))) @definition.variable
|
|
833
834
|
|
|
834
835
|
; Short variable declaration: x := 5
|
|
835
836
|
(short_var_declaration left: (expression_list (identifier) @name)) @definition.variable
|
|
@@ -15,7 +15,69 @@ import { extractSimpleTypeName } from '../../type-extractors/shared.js';
|
|
|
15
15
|
*
|
|
16
16
|
* Visibility: uppercase first letter = exported (public), lowercase = unexported (package).
|
|
17
17
|
*/
|
|
18
|
+
function goVisibilityForName(name) {
|
|
19
|
+
const firstChar = name.charAt(0);
|
|
20
|
+
return firstChar === firstChar.toUpperCase() && firstChar !== firstChar.toLowerCase()
|
|
21
|
+
? 'public'
|
|
22
|
+
: 'package';
|
|
23
|
+
}
|
|
24
|
+
function collectGoSpecNames(spec) {
|
|
25
|
+
const names = [];
|
|
26
|
+
for (let i = 0; i < spec.namedChildCount; i++) {
|
|
27
|
+
const child = spec.namedChild(i);
|
|
28
|
+
if (!child)
|
|
29
|
+
continue;
|
|
30
|
+
if (child.type === 'identifier') {
|
|
31
|
+
names.push(child.text);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
return names;
|
|
37
|
+
}
|
|
38
|
+
function collectGoSpecs(node) {
|
|
39
|
+
const specs = [];
|
|
40
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
41
|
+
const child = node.namedChild(i);
|
|
42
|
+
if (child?.type === 'var_spec' || child?.type === 'const_spec') {
|
|
43
|
+
specs.push(child);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (child?.type === 'var_spec_list') {
|
|
47
|
+
specs.push(...collectGoSpecs(child));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return specs;
|
|
51
|
+
}
|
|
52
|
+
function collectGoDeclarationNames(node) {
|
|
53
|
+
if (node.type === 'short_var_declaration') {
|
|
54
|
+
const left = node.childForFieldName('left');
|
|
55
|
+
if (left?.type !== 'expression_list')
|
|
56
|
+
return [];
|
|
57
|
+
return left.namedChildren
|
|
58
|
+
.filter((child) => child.type === 'identifier')
|
|
59
|
+
.map((child) => child.text);
|
|
60
|
+
}
|
|
61
|
+
const names = [];
|
|
62
|
+
for (const spec of collectGoSpecs(node))
|
|
63
|
+
names.push(...collectGoSpecNames(spec));
|
|
64
|
+
return names;
|
|
65
|
+
}
|
|
66
|
+
function findGoSpecForName(node, name) {
|
|
67
|
+
for (const spec of collectGoSpecs(node)) {
|
|
68
|
+
if (collectGoSpecNames(spec).includes(name))
|
|
69
|
+
return spec;
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
function extractGoSpecType(spec) {
|
|
74
|
+
const typeNode = spec.childForFieldName('type');
|
|
75
|
+
return typeNode ? (extractSimpleTypeName(typeNode) ?? typeNode.text?.trim()) : undefined;
|
|
76
|
+
}
|
|
18
77
|
function extractGoVarName(node) {
|
|
78
|
+
const firstName = collectGoDeclarationNames(node)[0];
|
|
79
|
+
if (firstName)
|
|
80
|
+
return firstName;
|
|
19
81
|
// var_declaration/const_declaration → var_spec/const_spec → identifier
|
|
20
82
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
21
83
|
const child = node.namedChild(i);
|
|
@@ -43,13 +105,10 @@ function extractGoVarName(node) {
|
|
|
43
105
|
return undefined;
|
|
44
106
|
}
|
|
45
107
|
function extractGoVarType(node) {
|
|
46
|
-
for (
|
|
47
|
-
const
|
|
48
|
-
if (
|
|
49
|
-
|
|
50
|
-
if (typeNode)
|
|
51
|
-
return extractSimpleTypeName(typeNode) ?? typeNode.text?.trim();
|
|
52
|
-
}
|
|
108
|
+
for (const spec of collectGoSpecs(node)) {
|
|
109
|
+
const typeName = extractGoSpecType(spec);
|
|
110
|
+
if (typeName)
|
|
111
|
+
return typeName;
|
|
53
112
|
}
|
|
54
113
|
return undefined;
|
|
55
114
|
}
|
|
@@ -60,6 +119,10 @@ export const goVariableConfig = {
|
|
|
60
119
|
variableNodeTypes: ['var_declaration', 'short_var_declaration'],
|
|
61
120
|
extractName: extractGoVarName,
|
|
62
121
|
extractType: extractGoVarType,
|
|
122
|
+
extractTypeForName(node, name) {
|
|
123
|
+
const spec = findGoSpecForName(node, name);
|
|
124
|
+
return spec ? extractGoSpecType(spec) : undefined;
|
|
125
|
+
},
|
|
63
126
|
extractVisibility(node) {
|
|
64
127
|
const name = extractGoVarName(node);
|
|
65
128
|
if (!name)
|
|
@@ -70,6 +133,10 @@ export const goVariableConfig = {
|
|
|
70
133
|
? 'public'
|
|
71
134
|
: 'package';
|
|
72
135
|
},
|
|
136
|
+
extractNames: collectGoDeclarationNames,
|
|
137
|
+
extractVisibilityForName(_node, name) {
|
|
138
|
+
return goVisibilityForName(name);
|
|
139
|
+
},
|
|
73
140
|
isConst(node) {
|
|
74
141
|
return node.type === 'const_declaration';
|
|
75
142
|
},
|
|
@@ -50,13 +50,16 @@ export function createVariableExtractor(config) {
|
|
|
50
50
|
return allNodeTypes.has(node.type);
|
|
51
51
|
},
|
|
52
52
|
extract(node, context) {
|
|
53
|
+
return this.extractAll(node, context)[0] ?? null;
|
|
54
|
+
},
|
|
55
|
+
extractAll(node, context) {
|
|
53
56
|
if (!allNodeTypes.has(node.type))
|
|
54
|
-
return
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
return [];
|
|
58
|
+
const names = config.extractNames
|
|
59
|
+
? config.extractNames(node)
|
|
60
|
+
: [config.extractName(node)].filter((name) => Boolean(name));
|
|
61
|
+
if (names.length === 0)
|
|
62
|
+
return [];
|
|
60
63
|
// isConst/isStatic: node type membership is a hint, but config.isConst/isStatic
|
|
61
64
|
// has final say. For languages where const and non-const share a node type
|
|
62
65
|
// (e.g., TS lexical_declaration for both const and let), config.isConst disambiguates.
|
|
@@ -64,17 +67,17 @@ export function createVariableExtractor(config) {
|
|
|
64
67
|
const isStatic = staticNodeSet.has(node.type) || config.isStatic(node);
|
|
65
68
|
const isMutable = config.isMutable(node);
|
|
66
69
|
const scope = determineScope(node);
|
|
67
|
-
return {
|
|
70
|
+
return names.map((name) => ({
|
|
68
71
|
name,
|
|
69
|
-
type,
|
|
70
|
-
visibility,
|
|
72
|
+
type: config.extractTypeForName?.(node, name) ?? config.extractType(node) ?? null,
|
|
73
|
+
visibility: config.extractVisibilityForName?.(node, name) ?? config.extractVisibility(node),
|
|
71
74
|
isConst,
|
|
72
75
|
isStatic,
|
|
73
76
|
isMutable,
|
|
74
77
|
scope,
|
|
75
78
|
sourceFile: context.filePath,
|
|
76
79
|
line: node.startPosition.row + 1,
|
|
77
|
-
};
|
|
80
|
+
}));
|
|
78
81
|
},
|
|
79
82
|
};
|
|
80
83
|
}
|
|
@@ -51,6 +51,9 @@ export interface VariableExtractor {
|
|
|
51
51
|
/** Extract variable metadata from a declaration node.
|
|
52
52
|
* Returns null if the node is not a recognized variable declaration. */
|
|
53
53
|
extract(node: SyntaxNode, context: VariableExtractorContext): VariableInfo | null;
|
|
54
|
+
/** Extract every variable metadata entry from a declaration node.
|
|
55
|
+
* Returns [] if the node is not a recognized variable declaration. */
|
|
56
|
+
extractAll(node: SyntaxNode, context: VariableExtractorContext): VariableInfo[];
|
|
54
57
|
/** Check if a node is a recognized variable declaration type. */
|
|
55
58
|
isVariableDeclaration(node: SyntaxNode): boolean;
|
|
56
59
|
}
|
|
@@ -69,10 +72,16 @@ export interface VariableExtractionConfig {
|
|
|
69
72
|
variableNodeTypes: string[];
|
|
70
73
|
/** Extract the variable name from a declaration node */
|
|
71
74
|
extractName: (node: SyntaxNode) => string | undefined;
|
|
75
|
+
/** Extract multiple variable names from a declaration node. */
|
|
76
|
+
extractNames?: (node: SyntaxNode) => string[];
|
|
72
77
|
/** Extract type annotation from a declaration node */
|
|
73
78
|
extractType: (node: SyntaxNode) => string | undefined;
|
|
79
|
+
/** Extract type annotation for one variable name from a multi-name declaration. */
|
|
80
|
+
extractTypeForName?: (node: SyntaxNode, name: string) => string | undefined;
|
|
74
81
|
/** Extract visibility from a declaration node */
|
|
75
82
|
extractVisibility: (node: SyntaxNode) => VariableVisibility;
|
|
83
|
+
/** Extract visibility for one variable name from a multi-name declaration. */
|
|
84
|
+
extractVisibilityForName?: (node: SyntaxNode, name: string) => VariableVisibility;
|
|
76
85
|
/** Check if a declaration is const/immutable */
|
|
77
86
|
isConst: (node: SyntaxNode) => boolean;
|
|
78
87
|
/** Check if a declaration is static */
|
|
@@ -830,6 +830,7 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
830
830
|
// (e.g. @definition.function) to avoid duplicate nodes when @definition.const/@definition.variable
|
|
831
831
|
// patterns overlap with the same source range.
|
|
832
832
|
const processedDefinitionNodes = new Set();
|
|
833
|
+
const variableInfoCache = new Map();
|
|
833
834
|
for (const match of matches) {
|
|
834
835
|
const captureMap = {};
|
|
835
836
|
for (const c of match.captures) {
|
|
@@ -1223,17 +1224,6 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
1223
1224
|
}) === true) {
|
|
1224
1225
|
continue;
|
|
1225
1226
|
}
|
|
1226
|
-
// Dedup: variable captures (Const/Static/Variable) may overlap with higher-priority
|
|
1227
|
-
// captures (e.g. `const fn = () => {}` matches both @definition.function and @definition.const).
|
|
1228
|
-
// Skip variable captures whose definition node was already processed.
|
|
1229
|
-
if ((nodeLabel === 'Const' || nodeLabel === 'Static' || nodeLabel === 'Variable') &&
|
|
1230
|
-
definitionNode &&
|
|
1231
|
-
processedDefinitionNodes.has(definitionNode.startIndex)) {
|
|
1232
|
-
continue;
|
|
1233
|
-
}
|
|
1234
|
-
if (definitionNode) {
|
|
1235
|
-
processedDefinitionNodes.add(definitionNode.startIndex);
|
|
1236
|
-
}
|
|
1237
1227
|
const exportDefaultCall = nodeLabel === 'Function' && definitionNode?.type === 'export_statement'
|
|
1238
1228
|
? definitionNode.namedChildren.find((child) => child.type === 'call_expression')
|
|
1239
1229
|
: undefined;
|
|
@@ -1263,6 +1253,23 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
1263
1253
|
!defaultExportHocName)
|
|
1264
1254
|
continue;
|
|
1265
1255
|
const nodeName = extractedClassSymbol?.name ?? defaultExportHocName ?? (nameNode ? nameNode.text : 'init');
|
|
1256
|
+
// Dedup: variable captures (Const/Static/Variable) may overlap with higher-priority
|
|
1257
|
+
// captures (e.g. `const fn = () => {}` matches both @definition.function and @definition.const).
|
|
1258
|
+
// Multi-name declarations share the same definition node, so include the emitted name.
|
|
1259
|
+
if (definitionNode) {
|
|
1260
|
+
const definitionBaseKey = `${definitionNode.startIndex}`;
|
|
1261
|
+
if (nodeLabel === 'Const' || nodeLabel === 'Static' || nodeLabel === 'Variable') {
|
|
1262
|
+
const definitionNameKey = `${definitionBaseKey}:${nodeName}`;
|
|
1263
|
+
if (processedDefinitionNodes.has(definitionBaseKey) ||
|
|
1264
|
+
processedDefinitionNodes.has(definitionNameKey)) {
|
|
1265
|
+
continue;
|
|
1266
|
+
}
|
|
1267
|
+
processedDefinitionNodes.add(definitionNameKey);
|
|
1268
|
+
}
|
|
1269
|
+
else {
|
|
1270
|
+
processedDefinitionNodes.add(definitionBaseKey);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1266
1273
|
const startLine = definitionNode
|
|
1267
1274
|
? definitionNode.startPosition.row + lineOffset
|
|
1268
1275
|
: nameNode
|
|
@@ -1486,11 +1493,18 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
1486
1493
|
if ((nodeLabel === 'Const' || nodeLabel === 'Static' || nodeLabel === 'Variable') &&
|
|
1487
1494
|
definitionNode &&
|
|
1488
1495
|
provider.variableExtractor) {
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1496
|
+
let variableInfoByName = variableInfoCache.get(definitionNode.startIndex);
|
|
1497
|
+
if (!variableInfoByName) {
|
|
1498
|
+
const varCtx = {
|
|
1499
|
+
filePath: file.path,
|
|
1500
|
+
language,
|
|
1501
|
+
};
|
|
1502
|
+
variableInfoByName = new Map(provider.variableExtractor
|
|
1503
|
+
.extractAll(definitionNode, varCtx)
|
|
1504
|
+
.map((info) => [info.name, info]));
|
|
1505
|
+
variableInfoCache.set(definitionNode.startIndex, variableInfoByName);
|
|
1506
|
+
}
|
|
1507
|
+
const varInfo = variableInfoByName.get(nodeName);
|
|
1494
1508
|
if (varInfo) {
|
|
1495
1509
|
if (varInfo.type)
|
|
1496
1510
|
declaredType = varInfo.type;
|
package/package.json
CHANGED