gitnexus 1.3.11 → 1.4.0
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/README.md +22 -2
- package/dist/cli/ai-context.d.ts +2 -1
- package/dist/cli/ai-context.js +15 -6
- package/dist/cli/analyze.d.ts +2 -0
- package/dist/cli/analyze.js +12 -2
- package/dist/cli/index.js +2 -0
- package/dist/cli/skill-gen.d.ts +26 -0
- package/dist/cli/skill-gen.js +549 -0
- package/dist/core/graph/types.d.ts +5 -2
- package/dist/core/ingestion/call-processor.d.ts +5 -5
- package/dist/core/ingestion/call-processor.js +173 -260
- package/dist/core/ingestion/constants.d.ts +16 -0
- package/dist/core/ingestion/constants.js +16 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +2 -1
- package/dist/core/ingestion/entry-point-scoring.js +81 -22
- package/dist/core/ingestion/export-detection.d.ts +18 -0
- package/dist/core/ingestion/export-detection.js +230 -0
- package/dist/core/ingestion/framework-detection.d.ts +5 -1
- package/dist/core/ingestion/framework-detection.js +39 -8
- package/dist/core/ingestion/heritage-processor.d.ts +13 -4
- package/dist/core/ingestion/heritage-processor.js +92 -28
- package/dist/core/ingestion/import-processor.d.ts +17 -19
- package/dist/core/ingestion/import-processor.js +170 -695
- package/dist/core/ingestion/language-config.d.ts +46 -0
- package/dist/core/ingestion/language-config.js +167 -0
- package/dist/core/ingestion/mro-processor.d.ts +45 -0
- package/dist/core/ingestion/mro-processor.js +369 -0
- package/dist/core/ingestion/named-binding-extraction.d.ts +61 -0
- package/dist/core/ingestion/named-binding-extraction.js +363 -0
- package/dist/core/ingestion/parsing-processor.d.ts +1 -10
- package/dist/core/ingestion/parsing-processor.js +41 -177
- package/dist/core/ingestion/pipeline.js +26 -24
- package/dist/core/ingestion/process-processor.js +2 -1
- package/dist/core/ingestion/resolvers/csharp.d.ts +22 -0
- package/dist/core/ingestion/resolvers/csharp.js +109 -0
- package/dist/core/ingestion/resolvers/go.d.ts +19 -0
- package/dist/core/ingestion/resolvers/go.js +42 -0
- package/dist/core/ingestion/resolvers/index.d.ts +16 -0
- package/dist/core/ingestion/resolvers/index.js +11 -0
- package/dist/core/ingestion/resolvers/jvm.d.ts +23 -0
- package/dist/core/ingestion/resolvers/jvm.js +87 -0
- package/dist/core/ingestion/resolvers/php.d.ts +15 -0
- package/dist/core/ingestion/resolvers/php.js +35 -0
- package/dist/core/ingestion/resolvers/rust.d.ts +15 -0
- package/dist/core/ingestion/resolvers/rust.js +73 -0
- package/dist/core/ingestion/resolvers/standard.d.ts +28 -0
- package/dist/core/ingestion/resolvers/standard.js +145 -0
- package/dist/core/ingestion/resolvers/utils.d.ts +33 -0
- package/dist/core/ingestion/resolvers/utils.js +120 -0
- package/dist/core/ingestion/symbol-resolver.d.ts +32 -0
- package/dist/core/ingestion/symbol-resolver.js +83 -0
- package/dist/core/ingestion/symbol-table.d.ts +12 -1
- package/dist/core/ingestion/symbol-table.js +19 -12
- package/dist/core/ingestion/tree-sitter-queries.d.ts +11 -11
- package/dist/core/ingestion/tree-sitter-queries.js +114 -9
- package/dist/core/ingestion/type-env.d.ts +27 -0
- package/dist/core/ingestion/type-env.js +86 -0
- package/dist/core/ingestion/type-extractors/c-cpp.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/c-cpp.js +60 -0
- package/dist/core/ingestion/type-extractors/csharp.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/csharp.js +89 -0
- package/dist/core/ingestion/type-extractors/go.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/go.js +105 -0
- package/dist/core/ingestion/type-extractors/index.d.ts +21 -0
- package/dist/core/ingestion/type-extractors/index.js +29 -0
- package/dist/core/ingestion/type-extractors/jvm.d.ts +3 -0
- package/dist/core/ingestion/type-extractors/jvm.js +121 -0
- package/dist/core/ingestion/type-extractors/php.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/php.js +31 -0
- package/dist/core/ingestion/type-extractors/python.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/python.js +41 -0
- package/dist/core/ingestion/type-extractors/rust.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/rust.js +39 -0
- package/dist/core/ingestion/type-extractors/shared.d.ts +17 -0
- package/dist/core/ingestion/type-extractors/shared.js +97 -0
- package/dist/core/ingestion/type-extractors/swift.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/swift.js +43 -0
- package/dist/core/ingestion/type-extractors/types.d.ts +14 -0
- package/dist/core/ingestion/type-extractors/types.js +1 -0
- package/dist/core/ingestion/type-extractors/typescript.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/typescript.js +46 -0
- package/dist/core/ingestion/utils.d.ts +67 -0
- package/dist/core/ingestion/utils.js +691 -4
- package/dist/core/ingestion/workers/parse-worker.d.ts +20 -3
- package/dist/core/ingestion/workers/parse-worker.js +84 -345
- package/dist/core/kuzu/csv-generator.js +19 -3
- package/dist/core/kuzu/kuzu-adapter.js +3 -0
- package/dist/core/kuzu/schema.d.ts +3 -3
- package/dist/core/kuzu/schema.js +16 -1
- package/dist/mcp/tools.js +12 -3
- package/package.json +1 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-language type extraction configurations.
|
|
3
|
+
* Assembled here into a dispatch map keyed by SupportedLanguages.
|
|
4
|
+
*/
|
|
5
|
+
import { SupportedLanguages } from '../../../config/supported-languages.js';
|
|
6
|
+
import { typeConfig as typescriptConfig } from './typescript.js';
|
|
7
|
+
import { javaTypeConfig, kotlinTypeConfig } from './jvm.js';
|
|
8
|
+
import { typeConfig as csharpConfig } from './csharp.js';
|
|
9
|
+
import { typeConfig as goConfig } from './go.js';
|
|
10
|
+
import { typeConfig as rustConfig } from './rust.js';
|
|
11
|
+
import { typeConfig as pythonConfig } from './python.js';
|
|
12
|
+
import { typeConfig as swiftConfig } from './swift.js';
|
|
13
|
+
import { typeConfig as cCppConfig } from './c-cpp.js';
|
|
14
|
+
import { typeConfig as phpConfig } from './php.js';
|
|
15
|
+
export const typeConfigs = {
|
|
16
|
+
[SupportedLanguages.JavaScript]: typescriptConfig,
|
|
17
|
+
[SupportedLanguages.TypeScript]: typescriptConfig,
|
|
18
|
+
[SupportedLanguages.Java]: javaTypeConfig,
|
|
19
|
+
[SupportedLanguages.Kotlin]: kotlinTypeConfig,
|
|
20
|
+
[SupportedLanguages.CSharp]: csharpConfig,
|
|
21
|
+
[SupportedLanguages.Go]: goConfig,
|
|
22
|
+
[SupportedLanguages.Rust]: rustConfig,
|
|
23
|
+
[SupportedLanguages.Python]: pythonConfig,
|
|
24
|
+
[SupportedLanguages.Swift]: swiftConfig,
|
|
25
|
+
[SupportedLanguages.C]: cCppConfig,
|
|
26
|
+
[SupportedLanguages.CPlusPlus]: cCppConfig,
|
|
27
|
+
[SupportedLanguages.PHP]: phpConfig,
|
|
28
|
+
};
|
|
29
|
+
export { TYPED_PARAMETER_TYPES, extractSimpleTypeName, extractVarName, findChildByType } from './shared.js';
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { extractSimpleTypeName, extractVarName, findChildByType } from './shared.js';
|
|
2
|
+
// ── Java ──────────────────────────────────────────────────────────────────
|
|
3
|
+
const JAVA_DECLARATION_NODE_TYPES = new Set([
|
|
4
|
+
'local_variable_declaration',
|
|
5
|
+
'field_declaration',
|
|
6
|
+
]);
|
|
7
|
+
/** Java: Type x = ...; Type x; */
|
|
8
|
+
const extractJavaDeclaration = (node, env) => {
|
|
9
|
+
const typeNode = node.childForFieldName('type');
|
|
10
|
+
if (!typeNode)
|
|
11
|
+
return;
|
|
12
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
13
|
+
if (!typeName)
|
|
14
|
+
return;
|
|
15
|
+
// Find variable_declarator children
|
|
16
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
17
|
+
const child = node.namedChild(i);
|
|
18
|
+
if (child?.type !== 'variable_declarator')
|
|
19
|
+
continue;
|
|
20
|
+
const nameNode = child.childForFieldName('name');
|
|
21
|
+
if (nameNode) {
|
|
22
|
+
const varName = extractVarName(nameNode);
|
|
23
|
+
if (varName)
|
|
24
|
+
env.set(varName, typeName);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
/** Java: formal_parameter → type name */
|
|
29
|
+
const extractJavaParameter = (node, env) => {
|
|
30
|
+
let nameNode = null;
|
|
31
|
+
let typeNode = null;
|
|
32
|
+
if (node.type === 'formal_parameter') {
|
|
33
|
+
typeNode = node.childForFieldName('type');
|
|
34
|
+
nameNode = node.childForFieldName('name');
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Generic fallback
|
|
38
|
+
nameNode = node.childForFieldName('name') ?? node.childForFieldName('pattern');
|
|
39
|
+
typeNode = node.childForFieldName('type');
|
|
40
|
+
}
|
|
41
|
+
if (!nameNode || !typeNode)
|
|
42
|
+
return;
|
|
43
|
+
const varName = extractVarName(nameNode);
|
|
44
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
45
|
+
if (varName && typeName)
|
|
46
|
+
env.set(varName, typeName);
|
|
47
|
+
};
|
|
48
|
+
export const javaTypeConfig = {
|
|
49
|
+
declarationNodeTypes: JAVA_DECLARATION_NODE_TYPES,
|
|
50
|
+
extractDeclaration: extractJavaDeclaration,
|
|
51
|
+
extractParameter: extractJavaParameter,
|
|
52
|
+
};
|
|
53
|
+
// ── Kotlin ────────────────────────────────────────────────────────────────
|
|
54
|
+
const KOTLIN_DECLARATION_NODE_TYPES = new Set([
|
|
55
|
+
'property_declaration',
|
|
56
|
+
'variable_declaration',
|
|
57
|
+
]);
|
|
58
|
+
/** Kotlin: val x: Foo = ... */
|
|
59
|
+
const extractKotlinDeclaration = (node, env) => {
|
|
60
|
+
if (node.type === 'property_declaration') {
|
|
61
|
+
// Kotlin property_declaration: name/type are inside a variable_declaration child
|
|
62
|
+
const varDecl = findChildByType(node, 'variable_declaration');
|
|
63
|
+
if (varDecl) {
|
|
64
|
+
const nameNode = findChildByType(varDecl, 'simple_identifier');
|
|
65
|
+
const typeNode = findChildByType(varDecl, 'user_type');
|
|
66
|
+
if (!nameNode || !typeNode)
|
|
67
|
+
return;
|
|
68
|
+
const varName = extractVarName(nameNode);
|
|
69
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
70
|
+
if (varName && typeName)
|
|
71
|
+
env.set(varName, typeName);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// Fallback: try direct fields
|
|
75
|
+
const nameNode = node.childForFieldName('name')
|
|
76
|
+
?? findChildByType(node, 'simple_identifier');
|
|
77
|
+
const typeNode = node.childForFieldName('type')
|
|
78
|
+
?? findChildByType(node, 'user_type');
|
|
79
|
+
if (!nameNode || !typeNode)
|
|
80
|
+
return;
|
|
81
|
+
const varName = extractVarName(nameNode);
|
|
82
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
83
|
+
if (varName && typeName)
|
|
84
|
+
env.set(varName, typeName);
|
|
85
|
+
}
|
|
86
|
+
else if (node.type === 'variable_declaration') {
|
|
87
|
+
// variable_declaration directly inside functions
|
|
88
|
+
const nameNode = findChildByType(node, 'simple_identifier');
|
|
89
|
+
const typeNode = findChildByType(node, 'user_type');
|
|
90
|
+
if (nameNode && typeNode) {
|
|
91
|
+
const varName = extractVarName(nameNode);
|
|
92
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
93
|
+
if (varName && typeName)
|
|
94
|
+
env.set(varName, typeName);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
/** Kotlin: formal_parameter → type name */
|
|
99
|
+
const extractKotlinParameter = (node, env) => {
|
|
100
|
+
let nameNode = null;
|
|
101
|
+
let typeNode = null;
|
|
102
|
+
if (node.type === 'formal_parameter') {
|
|
103
|
+
typeNode = node.childForFieldName('type');
|
|
104
|
+
nameNode = node.childForFieldName('name');
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
nameNode = node.childForFieldName('name') ?? node.childForFieldName('pattern');
|
|
108
|
+
typeNode = node.childForFieldName('type');
|
|
109
|
+
}
|
|
110
|
+
if (!nameNode || !typeNode)
|
|
111
|
+
return;
|
|
112
|
+
const varName = extractVarName(nameNode);
|
|
113
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
114
|
+
if (varName && typeName)
|
|
115
|
+
env.set(varName, typeName);
|
|
116
|
+
};
|
|
117
|
+
export const kotlinTypeConfig = {
|
|
118
|
+
declarationNodeTypes: KOTLIN_DECLARATION_NODE_TYPES,
|
|
119
|
+
extractDeclaration: extractKotlinDeclaration,
|
|
120
|
+
extractParameter: extractKotlinParameter,
|
|
121
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { extractSimpleTypeName, extractVarName } from './shared.js';
|
|
2
|
+
// PHP has no local variable type annotations; only params carry types
|
|
3
|
+
const DECLARATION_NODE_TYPES = new Set();
|
|
4
|
+
/** PHP: no typed local variable declarations */
|
|
5
|
+
const extractDeclaration = (_node, _env) => {
|
|
6
|
+
// PHP has no local variable type annotations
|
|
7
|
+
};
|
|
8
|
+
/** PHP: simple_parameter → type $name */
|
|
9
|
+
const extractParameter = (node, env) => {
|
|
10
|
+
let nameNode = null;
|
|
11
|
+
let typeNode = null;
|
|
12
|
+
if (node.type === 'simple_parameter') {
|
|
13
|
+
typeNode = node.childForFieldName('type');
|
|
14
|
+
nameNode = node.childForFieldName('name');
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
nameNode = node.childForFieldName('name') ?? node.childForFieldName('pattern');
|
|
18
|
+
typeNode = node.childForFieldName('type');
|
|
19
|
+
}
|
|
20
|
+
if (!nameNode || !typeNode)
|
|
21
|
+
return;
|
|
22
|
+
const varName = extractVarName(nameNode);
|
|
23
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
24
|
+
if (varName && typeName)
|
|
25
|
+
env.set(varName, typeName);
|
|
26
|
+
};
|
|
27
|
+
export const typeConfig = {
|
|
28
|
+
declarationNodeTypes: DECLARATION_NODE_TYPES,
|
|
29
|
+
extractDeclaration,
|
|
30
|
+
extractParameter,
|
|
31
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { extractSimpleTypeName, extractVarName } from './shared.js';
|
|
2
|
+
const DECLARATION_NODE_TYPES = new Set([
|
|
3
|
+
'assignment',
|
|
4
|
+
]);
|
|
5
|
+
/** Python: x: Foo = ... (PEP 484 annotations) */
|
|
6
|
+
const extractDeclaration = (node, env) => {
|
|
7
|
+
// Python annotated assignment: left : type = value
|
|
8
|
+
// tree-sitter represents this differently based on grammar version
|
|
9
|
+
const left = node.childForFieldName('left');
|
|
10
|
+
const typeNode = node.childForFieldName('type');
|
|
11
|
+
if (!left || !typeNode)
|
|
12
|
+
return;
|
|
13
|
+
const varName = extractVarName(left);
|
|
14
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
15
|
+
if (varName && typeName)
|
|
16
|
+
env.set(varName, typeName);
|
|
17
|
+
};
|
|
18
|
+
/** Python: parameter with type annotation */
|
|
19
|
+
const extractParameter = (node, env) => {
|
|
20
|
+
let nameNode = null;
|
|
21
|
+
let typeNode = null;
|
|
22
|
+
if (node.type === 'parameter') {
|
|
23
|
+
nameNode = node.childForFieldName('name');
|
|
24
|
+
typeNode = node.childForFieldName('type');
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
nameNode = node.childForFieldName('name') ?? node.childForFieldName('pattern');
|
|
28
|
+
typeNode = node.childForFieldName('type');
|
|
29
|
+
}
|
|
30
|
+
if (!nameNode || !typeNode)
|
|
31
|
+
return;
|
|
32
|
+
const varName = extractVarName(nameNode);
|
|
33
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
34
|
+
if (varName && typeName)
|
|
35
|
+
env.set(varName, typeName);
|
|
36
|
+
};
|
|
37
|
+
export const typeConfig = {
|
|
38
|
+
declarationNodeTypes: DECLARATION_NODE_TYPES,
|
|
39
|
+
extractDeclaration,
|
|
40
|
+
extractParameter,
|
|
41
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { extractSimpleTypeName, extractVarName } from './shared.js';
|
|
2
|
+
const DECLARATION_NODE_TYPES = new Set([
|
|
3
|
+
'let_declaration',
|
|
4
|
+
]);
|
|
5
|
+
/** Rust: let x: Foo = ... */
|
|
6
|
+
const extractDeclaration = (node, env) => {
|
|
7
|
+
const pattern = node.childForFieldName('pattern');
|
|
8
|
+
const typeNode = node.childForFieldName('type');
|
|
9
|
+
if (!pattern || !typeNode)
|
|
10
|
+
return;
|
|
11
|
+
const varName = extractVarName(pattern);
|
|
12
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
13
|
+
if (varName && typeName)
|
|
14
|
+
env.set(varName, typeName);
|
|
15
|
+
};
|
|
16
|
+
/** Rust: parameter → pattern: type */
|
|
17
|
+
const extractParameter = (node, env) => {
|
|
18
|
+
let nameNode = null;
|
|
19
|
+
let typeNode = null;
|
|
20
|
+
if (node.type === 'parameter') {
|
|
21
|
+
nameNode = node.childForFieldName('pattern');
|
|
22
|
+
typeNode = node.childForFieldName('type');
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
nameNode = node.childForFieldName('name') ?? node.childForFieldName('pattern');
|
|
26
|
+
typeNode = node.childForFieldName('type');
|
|
27
|
+
}
|
|
28
|
+
if (!nameNode || !typeNode)
|
|
29
|
+
return;
|
|
30
|
+
const varName = extractVarName(nameNode);
|
|
31
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
32
|
+
if (varName && typeName)
|
|
33
|
+
env.set(varName, typeName);
|
|
34
|
+
};
|
|
35
|
+
export const typeConfig = {
|
|
36
|
+
declarationNodeTypes: DECLARATION_NODE_TYPES,
|
|
37
|
+
extractDeclaration,
|
|
38
|
+
extractParameter,
|
|
39
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SyntaxNode } from '../utils.js';
|
|
2
|
+
/**
|
|
3
|
+
* Extract the simple type name from a type AST node.
|
|
4
|
+
* Handles generic types (e.g., List<User> → List), qualified names
|
|
5
|
+
* (e.g., models.User → User), and nullable types (e.g., User? → User).
|
|
6
|
+
* Returns undefined for complex types (unions, intersections, function types).
|
|
7
|
+
*/
|
|
8
|
+
export declare const extractSimpleTypeName: (typeNode: SyntaxNode) => string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Extract variable name from a declarator or pattern node.
|
|
11
|
+
* Returns the simple identifier text, or undefined for destructuring/complex patterns.
|
|
12
|
+
*/
|
|
13
|
+
export declare const extractVarName: (node: SyntaxNode) => string | undefined;
|
|
14
|
+
/** Node types for function/method parameters with type annotations */
|
|
15
|
+
export declare const TYPED_PARAMETER_TYPES: Set<string>;
|
|
16
|
+
/** Find the first named child with the given node type */
|
|
17
|
+
export declare const findChildByType: (node: SyntaxNode, type: string) => SyntaxNode | null;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract the simple type name from a type AST node.
|
|
3
|
+
* Handles generic types (e.g., List<User> → List), qualified names
|
|
4
|
+
* (e.g., models.User → User), and nullable types (e.g., User? → User).
|
|
5
|
+
* Returns undefined for complex types (unions, intersections, function types).
|
|
6
|
+
*/
|
|
7
|
+
export const extractSimpleTypeName = (typeNode) => {
|
|
8
|
+
// Direct type identifier
|
|
9
|
+
if (typeNode.type === 'type_identifier' || typeNode.type === 'identifier'
|
|
10
|
+
|| typeNode.type === 'simple_identifier') {
|
|
11
|
+
return typeNode.text;
|
|
12
|
+
}
|
|
13
|
+
// Qualified/scoped names: take the last segment (e.g., models.User → User)
|
|
14
|
+
if (typeNode.type === 'scoped_identifier' || typeNode.type === 'qualified_identifier'
|
|
15
|
+
|| typeNode.type === 'scoped_type_identifier' || typeNode.type === 'qualified_name'
|
|
16
|
+
|| typeNode.type === 'qualified_type'
|
|
17
|
+
|| typeNode.type === 'member_expression' || typeNode.type === 'attribute') {
|
|
18
|
+
const last = typeNode.lastNamedChild;
|
|
19
|
+
if (last && (last.type === 'type_identifier' || last.type === 'identifier'
|
|
20
|
+
|| last.type === 'simple_identifier' || last.type === 'name')) {
|
|
21
|
+
return last.text;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// Generic types: extract the base type (e.g., List<User> → List)
|
|
25
|
+
if (typeNode.type === 'generic_type' || typeNode.type === 'parameterized_type') {
|
|
26
|
+
const base = typeNode.childForFieldName('name')
|
|
27
|
+
?? typeNode.childForFieldName('type')
|
|
28
|
+
?? typeNode.firstNamedChild;
|
|
29
|
+
if (base)
|
|
30
|
+
return extractSimpleTypeName(base);
|
|
31
|
+
}
|
|
32
|
+
// Nullable types (Kotlin User?, C# User?)
|
|
33
|
+
if (typeNode.type === 'nullable_type') {
|
|
34
|
+
const inner = typeNode.firstNamedChild;
|
|
35
|
+
if (inner)
|
|
36
|
+
return extractSimpleTypeName(inner);
|
|
37
|
+
}
|
|
38
|
+
// Type annotations that wrap the actual type (TS/Python: `: Foo`, Kotlin: user_type)
|
|
39
|
+
if (typeNode.type === 'type_annotation' || typeNode.type === 'type'
|
|
40
|
+
|| typeNode.type === 'user_type') {
|
|
41
|
+
const inner = typeNode.firstNamedChild;
|
|
42
|
+
if (inner)
|
|
43
|
+
return extractSimpleTypeName(inner);
|
|
44
|
+
}
|
|
45
|
+
// Pointer/reference types (C++, Rust): User*, &User, &mut User
|
|
46
|
+
if (typeNode.type === 'pointer_type' || typeNode.type === 'reference_type') {
|
|
47
|
+
const inner = typeNode.firstNamedChild;
|
|
48
|
+
if (inner)
|
|
49
|
+
return extractSimpleTypeName(inner);
|
|
50
|
+
}
|
|
51
|
+
// PHP named_type / optional_type
|
|
52
|
+
if (typeNode.type === 'named_type' || typeNode.type === 'optional_type') {
|
|
53
|
+
const inner = typeNode.childForFieldName('name') ?? typeNode.firstNamedChild;
|
|
54
|
+
if (inner)
|
|
55
|
+
return extractSimpleTypeName(inner);
|
|
56
|
+
}
|
|
57
|
+
// Name node (PHP)
|
|
58
|
+
if (typeNode.type === 'name') {
|
|
59
|
+
return typeNode.text;
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Extract variable name from a declarator or pattern node.
|
|
65
|
+
* Returns the simple identifier text, or undefined for destructuring/complex patterns.
|
|
66
|
+
*/
|
|
67
|
+
export const extractVarName = (node) => {
|
|
68
|
+
if (node.type === 'identifier' || node.type === 'simple_identifier'
|
|
69
|
+
|| node.type === 'variable_name' || node.type === 'name') {
|
|
70
|
+
return node.text;
|
|
71
|
+
}
|
|
72
|
+
// variable_declarator (Java/C#): has a 'name' field
|
|
73
|
+
if (node.type === 'variable_declarator') {
|
|
74
|
+
const nameChild = node.childForFieldName('name');
|
|
75
|
+
if (nameChild)
|
|
76
|
+
return extractVarName(nameChild);
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
};
|
|
80
|
+
/** Node types for function/method parameters with type annotations */
|
|
81
|
+
export const TYPED_PARAMETER_TYPES = new Set([
|
|
82
|
+
'required_parameter', // TS: (x: Foo)
|
|
83
|
+
'optional_parameter', // TS: (x?: Foo)
|
|
84
|
+
'formal_parameter', // Java/Kotlin
|
|
85
|
+
'parameter', // C#/Rust/Go/Python/Swift
|
|
86
|
+
'parameter_declaration', // C/C++ void f(Type name)
|
|
87
|
+
'simple_parameter', // PHP function(Foo $x)
|
|
88
|
+
]);
|
|
89
|
+
/** Find the first named child with the given node type */
|
|
90
|
+
export const findChildByType = (node, type) => {
|
|
91
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
92
|
+
const child = node.namedChild(i);
|
|
93
|
+
if (child?.type === type)
|
|
94
|
+
return child;
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { extractSimpleTypeName, extractVarName, findChildByType } from './shared.js';
|
|
2
|
+
const DECLARATION_NODE_TYPES = new Set([
|
|
3
|
+
'property_declaration',
|
|
4
|
+
]);
|
|
5
|
+
/** Swift: let x: Foo = ... */
|
|
6
|
+
const extractDeclaration = (node, env) => {
|
|
7
|
+
// Swift property_declaration has pattern and type_annotation
|
|
8
|
+
const pattern = node.childForFieldName('pattern')
|
|
9
|
+
?? findChildByType(node, 'pattern');
|
|
10
|
+
const typeAnnotation = node.childForFieldName('type')
|
|
11
|
+
?? findChildByType(node, 'type_annotation');
|
|
12
|
+
if (!pattern || !typeAnnotation)
|
|
13
|
+
return;
|
|
14
|
+
const varName = extractVarName(pattern) ?? pattern.text;
|
|
15
|
+
const typeName = extractSimpleTypeName(typeAnnotation);
|
|
16
|
+
if (varName && typeName)
|
|
17
|
+
env.set(varName, typeName);
|
|
18
|
+
};
|
|
19
|
+
/** Swift: parameter → name: type */
|
|
20
|
+
const extractParameter = (node, env) => {
|
|
21
|
+
let nameNode = null;
|
|
22
|
+
let typeNode = null;
|
|
23
|
+
if (node.type === 'parameter') {
|
|
24
|
+
nameNode = node.childForFieldName('name')
|
|
25
|
+
?? node.childForFieldName('internal_name');
|
|
26
|
+
typeNode = node.childForFieldName('type');
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
nameNode = node.childForFieldName('name') ?? node.childForFieldName('pattern');
|
|
30
|
+
typeNode = node.childForFieldName('type');
|
|
31
|
+
}
|
|
32
|
+
if (!nameNode || !typeNode)
|
|
33
|
+
return;
|
|
34
|
+
const varName = extractVarName(nameNode);
|
|
35
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
36
|
+
if (varName && typeName)
|
|
37
|
+
env.set(varName, typeName);
|
|
38
|
+
};
|
|
39
|
+
export const typeConfig = {
|
|
40
|
+
declarationNodeTypes: DECLARATION_NODE_TYPES,
|
|
41
|
+
extractDeclaration,
|
|
42
|
+
extractParameter,
|
|
43
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SyntaxNode } from '../utils.js';
|
|
2
|
+
/** Extracts type bindings from a declaration node into the env map */
|
|
3
|
+
export type TypeBindingExtractor = (node: SyntaxNode, env: Map<string, string>) => void;
|
|
4
|
+
/** Extracts type bindings from a parameter node into the env map */
|
|
5
|
+
export type ParameterExtractor = (node: SyntaxNode, env: Map<string, string>) => void;
|
|
6
|
+
/** Per-language type extraction configuration */
|
|
7
|
+
export interface LanguageTypeConfig {
|
|
8
|
+
/** Node types that represent typed declarations for this language */
|
|
9
|
+
declarationNodeTypes: ReadonlySet<string>;
|
|
10
|
+
/** Extract a (varName → typeName) binding from a declaration node */
|
|
11
|
+
extractDeclaration: TypeBindingExtractor;
|
|
12
|
+
/** Extract a (varName → typeName) binding from a parameter node */
|
|
13
|
+
extractParameter: ParameterExtractor;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { extractSimpleTypeName, extractVarName } from './shared.js';
|
|
2
|
+
const DECLARATION_NODE_TYPES = new Set([
|
|
3
|
+
'lexical_declaration',
|
|
4
|
+
'variable_declaration',
|
|
5
|
+
]);
|
|
6
|
+
/** TypeScript: const x: Foo = ..., let x: Foo */
|
|
7
|
+
const extractDeclaration = (node, env) => {
|
|
8
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
9
|
+
const declarator = node.namedChild(i);
|
|
10
|
+
if (declarator?.type !== 'variable_declarator')
|
|
11
|
+
continue;
|
|
12
|
+
const nameNode = declarator.childForFieldName('name');
|
|
13
|
+
const typeAnnotation = declarator.childForFieldName('type');
|
|
14
|
+
if (!nameNode || !typeAnnotation)
|
|
15
|
+
continue;
|
|
16
|
+
const varName = extractVarName(nameNode);
|
|
17
|
+
const typeName = extractSimpleTypeName(typeAnnotation);
|
|
18
|
+
if (varName && typeName)
|
|
19
|
+
env.set(varName, typeName);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/** TypeScript: required_parameter / optional_parameter → name: type */
|
|
23
|
+
const extractParameter = (node, env) => {
|
|
24
|
+
let nameNode = null;
|
|
25
|
+
let typeNode = null;
|
|
26
|
+
if (node.type === 'required_parameter' || node.type === 'optional_parameter') {
|
|
27
|
+
nameNode = node.childForFieldName('pattern') ?? node.childForFieldName('name');
|
|
28
|
+
typeNode = node.childForFieldName('type');
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Generic fallback
|
|
32
|
+
nameNode = node.childForFieldName('name') ?? node.childForFieldName('pattern');
|
|
33
|
+
typeNode = node.childForFieldName('type');
|
|
34
|
+
}
|
|
35
|
+
if (!nameNode || !typeNode)
|
|
36
|
+
return;
|
|
37
|
+
const varName = extractVarName(nameNode);
|
|
38
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
39
|
+
if (varName && typeName)
|
|
40
|
+
env.set(varName, typeName);
|
|
41
|
+
};
|
|
42
|
+
export const typeConfig = {
|
|
43
|
+
declarationNodeTypes: DECLARATION_NODE_TYPES,
|
|
44
|
+
extractDeclaration,
|
|
45
|
+
extractParameter,
|
|
46
|
+
};
|
|
@@ -1,4 +1,45 @@
|
|
|
1
|
+
import type Parser from 'tree-sitter';
|
|
1
2
|
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
3
|
+
/** Tree-sitter AST node. Re-exported for use across ingestion modules. */
|
|
4
|
+
export type SyntaxNode = Parser.SyntaxNode;
|
|
5
|
+
/**
|
|
6
|
+
* Ordered list of definition capture keys for tree-sitter query matches.
|
|
7
|
+
* Used to extract the definition node from a capture map.
|
|
8
|
+
*/
|
|
9
|
+
export declare const DEFINITION_CAPTURE_KEYS: readonly ["definition.function", "definition.class", "definition.interface", "definition.method", "definition.struct", "definition.enum", "definition.namespace", "definition.module", "definition.trait", "definition.impl", "definition.type", "definition.const", "definition.static", "definition.typedef", "definition.macro", "definition.union", "definition.property", "definition.record", "definition.delegate", "definition.annotation", "definition.constructor", "definition.template"];
|
|
10
|
+
/** Extract the definition node from a tree-sitter query capture map. */
|
|
11
|
+
export declare const getDefinitionNodeFromCaptures: (captureMap: Record<string, any>) => any | null;
|
|
12
|
+
/**
|
|
13
|
+
* Node types that represent function/method definitions across languages.
|
|
14
|
+
* Used to find the enclosing function for a call site.
|
|
15
|
+
*/
|
|
16
|
+
export declare const FUNCTION_NODE_TYPES: Set<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Node types for standard function declarations that need C/C++ declarator handling.
|
|
19
|
+
* Used by extractFunctionName to determine how to extract the function name.
|
|
20
|
+
*/
|
|
21
|
+
export declare const FUNCTION_DECLARATION_TYPES: Set<string>;
|
|
22
|
+
/**
|
|
23
|
+
* Built-in function/method names that should not be tracked as call targets.
|
|
24
|
+
* Covers JS/TS, Python, Kotlin, C/C++, PHP, Swift standard library functions.
|
|
25
|
+
*/
|
|
26
|
+
export declare const BUILT_IN_NAMES: Set<string>;
|
|
27
|
+
/** Check if a name is a built-in function or common noise that should be filtered out */
|
|
28
|
+
export declare const isBuiltInOrNoise: (name: string) => boolean;
|
|
29
|
+
/** AST node types that represent a class-like container (for HAS_METHOD edge extraction) */
|
|
30
|
+
export declare const CLASS_CONTAINER_TYPES: Set<string>;
|
|
31
|
+
export declare const CONTAINER_TYPE_TO_LABEL: Record<string, string>;
|
|
32
|
+
/** Walk up AST to find enclosing class/struct/interface/impl, return its generateId or null.
|
|
33
|
+
* For Go method_declaration nodes, extracts receiver type (e.g. `func (u *User) Save()` → User struct). */
|
|
34
|
+
export declare const findEnclosingClassId: (node: any, filePath: string) => string | null;
|
|
35
|
+
/**
|
|
36
|
+
* Extract function name and label from a function_definition or similar AST node.
|
|
37
|
+
* Handles C/C++ qualified_identifier (ClassName::MethodName) and other language patterns.
|
|
38
|
+
*/
|
|
39
|
+
export declare const extractFunctionName: (node: any) => {
|
|
40
|
+
funcName: string | null;
|
|
41
|
+
label: string;
|
|
42
|
+
};
|
|
2
43
|
/**
|
|
3
44
|
* Yield control to the event loop so spinners/progress can render.
|
|
4
45
|
* Call periodically in hot loops to prevent UI freezes.
|
|
@@ -13,3 +54,29 @@ export declare const findSiblingChild: (parent: any, siblingType: string, childT
|
|
|
13
54
|
* Map file extension to SupportedLanguage enum
|
|
14
55
|
*/
|
|
15
56
|
export declare const getLanguageFromFilename: (filename: string) => SupportedLanguages | null;
|
|
57
|
+
export interface MethodSignature {
|
|
58
|
+
parameterCount: number | undefined;
|
|
59
|
+
returnType: string | undefined;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Extract parameter count and return type text from an AST method/function node.
|
|
63
|
+
* Works across languages by looking for common AST patterns.
|
|
64
|
+
*/
|
|
65
|
+
export declare const extractMethodSignature: (node: SyntaxNode | null | undefined) => MethodSignature;
|
|
66
|
+
/**
|
|
67
|
+
* Count direct arguments for a call expression across common tree-sitter grammars.
|
|
68
|
+
* Returns undefined when the argument container cannot be located cheaply.
|
|
69
|
+
*/
|
|
70
|
+
export declare const countCallArguments: (callNode: SyntaxNode | null | undefined) => number | undefined;
|
|
71
|
+
type CallForm = 'free' | 'member' | 'constructor';
|
|
72
|
+
/**
|
|
73
|
+
* Infer whether a captured call site is a free call, member call, or constructor.
|
|
74
|
+
* Returns undefined if the form cannot be determined.
|
|
75
|
+
*
|
|
76
|
+
* Works by inspecting the AST structure between callNode (@call) and nameNode (@call.name).
|
|
77
|
+
* No tree-sitter query changes needed — the distinction is in the node types.
|
|
78
|
+
*/
|
|
79
|
+
export declare const inferCallForm: (callNode: SyntaxNode, nameNode: SyntaxNode) => CallForm | undefined;
|
|
80
|
+
export declare const extractReceiverName: (nameNode: SyntaxNode) => string | undefined;
|
|
81
|
+
export declare const isVerboseIngestionEnabled: () => boolean;
|
|
82
|
+
export {};
|