gitnexus 1.4.0 → 1.4.1
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 +194 -214
- package/dist/cli/ai-context.d.ts +1 -2
- package/dist/cli/ai-context.js +90 -117
- package/dist/cli/analyze.d.ts +0 -2
- package/dist/cli/analyze.js +2 -20
- package/dist/cli/index.js +25 -17
- package/dist/cli/setup.js +19 -17
- package/dist/core/augmentation/engine.js +20 -20
- package/dist/core/embeddings/embedding-pipeline.js +26 -26
- package/dist/core/graph/types.d.ts +2 -5
- package/dist/core/ingestion/ast-cache.js +2 -3
- package/dist/core/ingestion/call-processor.d.ts +5 -5
- package/dist/core/ingestion/call-processor.js +258 -173
- package/dist/core/ingestion/cluster-enricher.js +16 -16
- package/dist/core/ingestion/entry-point-scoring.d.ts +1 -2
- package/dist/core/ingestion/entry-point-scoring.js +22 -81
- package/dist/core/ingestion/framework-detection.d.ts +1 -5
- package/dist/core/ingestion/framework-detection.js +8 -39
- package/dist/core/ingestion/heritage-processor.d.ts +4 -13
- package/dist/core/ingestion/heritage-processor.js +28 -92
- package/dist/core/ingestion/import-processor.d.ts +19 -17
- package/dist/core/ingestion/import-processor.js +695 -170
- package/dist/core/ingestion/parsing-processor.d.ts +10 -1
- package/dist/core/ingestion/parsing-processor.js +177 -41
- package/dist/core/ingestion/pipeline.js +26 -49
- package/dist/core/ingestion/process-processor.js +1 -2
- package/dist/core/ingestion/symbol-table.d.ts +1 -12
- package/dist/core/ingestion/symbol-table.js +12 -19
- package/dist/core/ingestion/tree-sitter-queries.d.ts +11 -11
- package/dist/core/ingestion/tree-sitter-queries.js +485 -590
- package/dist/core/ingestion/utils.d.ts +0 -67
- package/dist/core/ingestion/utils.js +9 -692
- package/dist/core/ingestion/workers/parse-worker.d.ts +3 -20
- package/dist/core/ingestion/workers/parse-worker.js +345 -84
- package/dist/core/ingestion/workers/worker-pool.js +0 -8
- package/dist/core/kuzu/csv-generator.js +3 -19
- package/dist/core/kuzu/kuzu-adapter.js +19 -14
- package/dist/core/kuzu/schema.d.ts +3 -3
- package/dist/core/kuzu/schema.js +288 -303
- package/dist/core/search/bm25-index.js +6 -7
- package/dist/core/search/hybrid-search.js +3 -3
- package/dist/core/wiki/diagrams.d.ts +27 -0
- package/dist/core/wiki/diagrams.js +163 -0
- package/dist/core/wiki/generator.d.ts +50 -2
- package/dist/core/wiki/generator.js +548 -49
- package/dist/core/wiki/graph-queries.d.ts +42 -0
- package/dist/core/wiki/graph-queries.js +276 -97
- package/dist/core/wiki/html-viewer.js +192 -192
- package/dist/core/wiki/llm-client.js +73 -11
- package/dist/core/wiki/prompts.d.ts +52 -8
- package/dist/core/wiki/prompts.js +200 -86
- package/dist/mcp/core/kuzu-adapter.d.ts +3 -1
- package/dist/mcp/core/kuzu-adapter.js +44 -13
- package/dist/mcp/local/local-backend.js +128 -128
- package/dist/mcp/resources.js +42 -42
- package/dist/mcp/server.js +19 -18
- package/dist/mcp/tools.js +104 -103
- package/hooks/claude/gitnexus-hook.cjs +155 -238
- package/hooks/claude/pre-tool-use.sh +79 -79
- package/hooks/claude/session-start.sh +42 -42
- package/package.json +96 -96
- package/scripts/patch-tree-sitter-swift.cjs +74 -74
- package/skills/gitnexus-cli.md +82 -82
- package/skills/gitnexus-debugging.md +89 -89
- package/skills/gitnexus-exploring.md +78 -78
- package/skills/gitnexus-guide.md +64 -64
- package/skills/gitnexus-impact-analysis.md +97 -97
- package/skills/gitnexus-pr-review.md +163 -163
- package/skills/gitnexus-refactoring.md +121 -121
- package/vendor/leiden/index.cjs +355 -355
- package/vendor/leiden/utils.cjs +392 -392
- package/dist/cli/lazy-action.d.ts +0 -6
- package/dist/cli/lazy-action.js +0 -18
- package/dist/cli/skill-gen.d.ts +0 -26
- package/dist/cli/skill-gen.js +0 -549
- package/dist/core/ingestion/constants.d.ts +0 -16
- package/dist/core/ingestion/constants.js +0 -16
- package/dist/core/ingestion/export-detection.d.ts +0 -18
- package/dist/core/ingestion/export-detection.js +0 -230
- package/dist/core/ingestion/language-config.d.ts +0 -46
- package/dist/core/ingestion/language-config.js +0 -167
- package/dist/core/ingestion/mro-processor.d.ts +0 -45
- package/dist/core/ingestion/mro-processor.js +0 -369
- package/dist/core/ingestion/named-binding-extraction.d.ts +0 -61
- package/dist/core/ingestion/named-binding-extraction.js +0 -363
- package/dist/core/ingestion/resolvers/csharp.d.ts +0 -22
- package/dist/core/ingestion/resolvers/csharp.js +0 -109
- package/dist/core/ingestion/resolvers/go.d.ts +0 -19
- package/dist/core/ingestion/resolvers/go.js +0 -42
- package/dist/core/ingestion/resolvers/index.d.ts +0 -16
- package/dist/core/ingestion/resolvers/index.js +0 -11
- package/dist/core/ingestion/resolvers/jvm.d.ts +0 -23
- package/dist/core/ingestion/resolvers/jvm.js +0 -87
- package/dist/core/ingestion/resolvers/php.d.ts +0 -15
- package/dist/core/ingestion/resolvers/php.js +0 -35
- package/dist/core/ingestion/resolvers/rust.d.ts +0 -15
- package/dist/core/ingestion/resolvers/rust.js +0 -73
- package/dist/core/ingestion/resolvers/standard.d.ts +0 -28
- package/dist/core/ingestion/resolvers/standard.js +0 -145
- package/dist/core/ingestion/resolvers/utils.d.ts +0 -33
- package/dist/core/ingestion/resolvers/utils.js +0 -120
- package/dist/core/ingestion/symbol-resolver.d.ts +0 -32
- package/dist/core/ingestion/symbol-resolver.js +0 -83
- package/dist/core/ingestion/type-env.d.ts +0 -27
- package/dist/core/ingestion/type-env.js +0 -86
- package/dist/core/ingestion/type-extractors/c-cpp.d.ts +0 -2
- package/dist/core/ingestion/type-extractors/c-cpp.js +0 -60
- package/dist/core/ingestion/type-extractors/csharp.d.ts +0 -2
- package/dist/core/ingestion/type-extractors/csharp.js +0 -89
- package/dist/core/ingestion/type-extractors/go.d.ts +0 -2
- package/dist/core/ingestion/type-extractors/go.js +0 -105
- package/dist/core/ingestion/type-extractors/index.d.ts +0 -21
- package/dist/core/ingestion/type-extractors/index.js +0 -29
- package/dist/core/ingestion/type-extractors/jvm.d.ts +0 -3
- package/dist/core/ingestion/type-extractors/jvm.js +0 -121
- package/dist/core/ingestion/type-extractors/php.d.ts +0 -2
- package/dist/core/ingestion/type-extractors/php.js +0 -31
- package/dist/core/ingestion/type-extractors/python.d.ts +0 -2
- package/dist/core/ingestion/type-extractors/python.js +0 -41
- package/dist/core/ingestion/type-extractors/rust.d.ts +0 -2
- package/dist/core/ingestion/type-extractors/rust.js +0 -39
- package/dist/core/ingestion/type-extractors/shared.d.ts +0 -17
- package/dist/core/ingestion/type-extractors/shared.js +0 -97
- package/dist/core/ingestion/type-extractors/swift.d.ts +0 -2
- package/dist/core/ingestion/type-extractors/swift.js +0 -43
- package/dist/core/ingestion/type-extractors/types.d.ts +0 -14
- package/dist/core/ingestion/type-extractors/types.js +0 -1
- package/dist/core/ingestion/type-extractors/typescript.d.ts +0 -2
- package/dist/core/ingestion/type-extractors/typescript.js +0 -46
- package/dist/mcp/compatible-stdio-transport.d.ts +0 -25
- package/dist/mcp/compatible-stdio-transport.js +0 -200
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Symbol Resolver
|
|
3
|
-
*
|
|
4
|
-
* Import-filtered candidate narrowing for bare identifier resolution.
|
|
5
|
-
* NOT FQN resolution — does not parse qualifiers (ns::Bar, com.foo.Bar).
|
|
6
|
-
*
|
|
7
|
-
* Shared between heritage-processor.ts and call-processor.ts.
|
|
8
|
-
*/
|
|
9
|
-
import { isFileInPackageDir } from './import-processor.js';
|
|
10
|
-
import { walkBindingChain } from './named-binding-extraction.js';
|
|
11
|
-
/**
|
|
12
|
-
* Resolve a bare identifier to its best-matching definition using import context.
|
|
13
|
-
*
|
|
14
|
-
* Resolution tiers (highest confidence first):
|
|
15
|
-
* 1. Same file (lookupExactFull — authoritative)
|
|
16
|
-
* 2. Import-scoped (lookupFuzzy filtered by importMap — acceptable)
|
|
17
|
-
* 3. Unique global (lookupFuzzy with exactly 1 match — acceptable fallback)
|
|
18
|
-
*
|
|
19
|
-
* If multiple global candidates remain after filtering, returns null.
|
|
20
|
-
* A wrong edge is worse than no edge.
|
|
21
|
-
*/
|
|
22
|
-
export const resolveSymbol = (name, currentFilePath, symbolTable, importMap, packageMap, namedImportMap) => {
|
|
23
|
-
return resolveSymbolInternal(name, currentFilePath, symbolTable, importMap, packageMap, namedImportMap)?.definition ?? null;
|
|
24
|
-
};
|
|
25
|
-
/** Internal resolver preserving tier metadata for logging and test assertions. */
|
|
26
|
-
export const resolveSymbolInternal = (name, currentFilePath, symbolTable, importMap, packageMap, namedImportMap) => {
|
|
27
|
-
// Tier 1: Same file — authoritative match
|
|
28
|
-
const localDef = symbolTable.lookupExactFull(currentFilePath, name);
|
|
29
|
-
if (localDef)
|
|
30
|
-
return { definition: localDef, tier: 'same-file', candidateCount: 1 };
|
|
31
|
-
// Get all global definitions for subsequent tiers
|
|
32
|
-
const allDefs = symbolTable.lookupFuzzy(name);
|
|
33
|
-
// Tier 2a-named: Check named bindings BEFORE the empty-allDefs early return,
|
|
34
|
-
// because aliased imports (import { User as U }) mean lookupFuzzy('U') returns
|
|
35
|
-
// empty but we can resolve via the exported name.
|
|
36
|
-
if (namedImportMap) {
|
|
37
|
-
const result = resolveNamedBindingChain(name, currentFilePath, symbolTable, namedImportMap, allDefs);
|
|
38
|
-
if (result)
|
|
39
|
-
return result;
|
|
40
|
-
}
|
|
41
|
-
if (allDefs.length === 0)
|
|
42
|
-
return null;
|
|
43
|
-
// Tier 2a: Import-scoped — check if any definition is in a file imported by currentFile
|
|
44
|
-
const importedFiles = importMap.get(currentFilePath);
|
|
45
|
-
if (importedFiles) {
|
|
46
|
-
for (const def of allDefs) {
|
|
47
|
-
if (importedFiles.has(def.filePath)) {
|
|
48
|
-
return { definition: def, tier: 'import-scoped', candidateCount: allDefs.length };
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
// Tier 2b: Package-scoped — check if any definition is in a package/namespace dir imported by currentFile
|
|
53
|
-
// Used for Go packages and C# namespace imports to avoid ImportMap expansion bloat
|
|
54
|
-
const importedPackages = packageMap?.get(currentFilePath);
|
|
55
|
-
if (importedPackages) {
|
|
56
|
-
for (const def of allDefs) {
|
|
57
|
-
for (const dirSuffix of importedPackages) {
|
|
58
|
-
if (isFileInPackageDir(def.filePath, dirSuffix)) {
|
|
59
|
-
return { definition: def, tier: 'import-scoped', candidateCount: allDefs.length };
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
// Tier 3: Unique global — ONLY if exactly one candidate exists
|
|
65
|
-
// Ambiguous global matches are refused. A wrong edge is worse than no edge.
|
|
66
|
-
if (allDefs.length === 1) {
|
|
67
|
-
return { definition: allDefs[0], tier: 'unique-global', candidateCount: 1 };
|
|
68
|
-
}
|
|
69
|
-
// Ambiguous: multiple global candidates, no import or same-file match → refuse
|
|
70
|
-
return null;
|
|
71
|
-
};
|
|
72
|
-
/**
|
|
73
|
-
* Follow re-export chains through NamedImportMap.
|
|
74
|
-
* Delegates chain-walking to the shared walkBindingChain utility, then
|
|
75
|
-
* applies symbol-resolver semantics: exactly one match required.
|
|
76
|
-
*/
|
|
77
|
-
const resolveNamedBindingChain = (name, currentFilePath, symbolTable, namedImportMap, allDefs) => {
|
|
78
|
-
const defs = walkBindingChain(name, currentFilePath, symbolTable, namedImportMap, allDefs);
|
|
79
|
-
if (defs?.length === 1) {
|
|
80
|
-
return { definition: defs[0], tier: 'import-scoped', candidateCount: defs.length };
|
|
81
|
-
}
|
|
82
|
-
return null;
|
|
83
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { SyntaxNode } from './utils.js';
|
|
2
|
-
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
3
|
-
/**
|
|
4
|
-
* Per-file scoped type environment: maps (scope, variableName) → typeName.
|
|
5
|
-
* Scope-aware: variables inside functions are keyed by function name,
|
|
6
|
-
* file-level variables use the '' (empty string) scope.
|
|
7
|
-
*
|
|
8
|
-
* Design constraints:
|
|
9
|
-
* - Explicit-only: only type annotations, never inferred types
|
|
10
|
-
* - Scope-aware: function-local variables don't collide across functions
|
|
11
|
-
* - Conservative: complex/generic types extract the base name only
|
|
12
|
-
* - Per-file: built once, used for receiver resolution, then discarded
|
|
13
|
-
*/
|
|
14
|
-
export type TypeEnv = Map<string, Map<string, string>>;
|
|
15
|
-
/**
|
|
16
|
-
* Look up a variable's type in the TypeEnv, trying the call's enclosing
|
|
17
|
-
* function scope first, then falling back to file-level scope.
|
|
18
|
-
*/
|
|
19
|
-
export declare const lookupTypeEnv: (env: TypeEnv, varName: string, callNode: SyntaxNode) => string | undefined;
|
|
20
|
-
/**
|
|
21
|
-
* Build a scoped TypeEnv from a tree-sitter AST for a given language.
|
|
22
|
-
* Walks the tree tracking enclosing function scopes, so that variables
|
|
23
|
-
* inside different functions don't collide.
|
|
24
|
-
*/
|
|
25
|
-
export declare const buildTypeEnv: (tree: {
|
|
26
|
-
rootNode: SyntaxNode;
|
|
27
|
-
}, language: SupportedLanguages) => TypeEnv;
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { FUNCTION_NODE_TYPES, extractFunctionName } from './utils.js';
|
|
2
|
-
import { typeConfigs, TYPED_PARAMETER_TYPES } from './type-extractors/index.js';
|
|
3
|
-
/** File-level scope key */
|
|
4
|
-
const FILE_SCOPE = '';
|
|
5
|
-
/**
|
|
6
|
-
* Look up a variable's type in the TypeEnv, trying the call's enclosing
|
|
7
|
-
* function scope first, then falling back to file-level scope.
|
|
8
|
-
*/
|
|
9
|
-
export const lookupTypeEnv = (env, varName, callNode) => {
|
|
10
|
-
// Determine the enclosing function scope for the call
|
|
11
|
-
const scopeKey = findEnclosingScopeKey(callNode);
|
|
12
|
-
// Try function-local scope first
|
|
13
|
-
if (scopeKey) {
|
|
14
|
-
const scopeEnv = env.get(scopeKey);
|
|
15
|
-
if (scopeEnv) {
|
|
16
|
-
const result = scopeEnv.get(varName);
|
|
17
|
-
if (result)
|
|
18
|
-
return result;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
// Fall back to file-level scope
|
|
22
|
-
const fileEnv = env.get(FILE_SCOPE);
|
|
23
|
-
return fileEnv?.get(varName);
|
|
24
|
-
};
|
|
25
|
-
/** Find the enclosing function name for scope lookup. */
|
|
26
|
-
const findEnclosingScopeKey = (node) => {
|
|
27
|
-
let current = node.parent;
|
|
28
|
-
while (current) {
|
|
29
|
-
if (FUNCTION_NODE_TYPES.has(current.type)) {
|
|
30
|
-
const { funcName } = extractFunctionName(current);
|
|
31
|
-
if (funcName)
|
|
32
|
-
return `${funcName}@${current.startIndex}`;
|
|
33
|
-
}
|
|
34
|
-
current = current.parent;
|
|
35
|
-
}
|
|
36
|
-
return undefined;
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* Build a scoped TypeEnv from a tree-sitter AST for a given language.
|
|
40
|
-
* Walks the tree tracking enclosing function scopes, so that variables
|
|
41
|
-
* inside different functions don't collide.
|
|
42
|
-
*/
|
|
43
|
-
export const buildTypeEnv = (tree, language) => {
|
|
44
|
-
const env = new Map();
|
|
45
|
-
walkForTypes(tree.rootNode, language, env, FILE_SCOPE);
|
|
46
|
-
return env;
|
|
47
|
-
};
|
|
48
|
-
const walkForTypes = (node, language, env, currentScope) => {
|
|
49
|
-
// Detect scope boundaries (function/method definitions)
|
|
50
|
-
let scope = currentScope;
|
|
51
|
-
if (FUNCTION_NODE_TYPES.has(node.type)) {
|
|
52
|
-
const { funcName } = extractFunctionName(node);
|
|
53
|
-
if (funcName)
|
|
54
|
-
scope = `${funcName}@${node.startIndex}`;
|
|
55
|
-
}
|
|
56
|
-
// Get or create the sub-map for this scope
|
|
57
|
-
if (!env.has(scope))
|
|
58
|
-
env.set(scope, new Map());
|
|
59
|
-
const scopeEnv = env.get(scope);
|
|
60
|
-
// Check if this node provides type information
|
|
61
|
-
extractTypeBinding(node, language, scopeEnv);
|
|
62
|
-
// Recurse into children
|
|
63
|
-
for (let i = 0; i < node.childCount; i++) {
|
|
64
|
-
const child = node.child(i);
|
|
65
|
-
if (child)
|
|
66
|
-
walkForTypes(child, language, env, scope);
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
* Try to extract a (variableName → typeName) binding from a single AST node.
|
|
71
|
-
* Delegates to per-language type configurations.
|
|
72
|
-
*/
|
|
73
|
-
const extractTypeBinding = (node, language, env) => {
|
|
74
|
-
// === PARAMETERS (most languages) ===
|
|
75
|
-
// This guard eliminates 90%+ of calls before any language dispatch.
|
|
76
|
-
if (TYPED_PARAMETER_TYPES.has(node.type)) {
|
|
77
|
-
const config = typeConfigs[language];
|
|
78
|
-
config.extractParameter(node, env);
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
// === Per-language declaration extraction ===
|
|
82
|
-
const config = typeConfigs[language];
|
|
83
|
-
if (config.declarationNodeTypes.has(node.type)) {
|
|
84
|
-
config.extractDeclaration(node, env);
|
|
85
|
-
}
|
|
86
|
-
};
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { extractSimpleTypeName, extractVarName } from './shared.js';
|
|
2
|
-
const DECLARATION_NODE_TYPES = new Set([
|
|
3
|
-
'declaration',
|
|
4
|
-
]);
|
|
5
|
-
/** C++: Type x = ...; Type* x; Type& x; */
|
|
6
|
-
const extractDeclaration = (node, env) => {
|
|
7
|
-
const typeNode = node.childForFieldName('type');
|
|
8
|
-
if (!typeNode)
|
|
9
|
-
return;
|
|
10
|
-
const typeName = extractSimpleTypeName(typeNode);
|
|
11
|
-
if (!typeName)
|
|
12
|
-
return;
|
|
13
|
-
const declarator = node.childForFieldName('declarator');
|
|
14
|
-
if (!declarator)
|
|
15
|
-
return;
|
|
16
|
-
// init_declarator: Type x = value
|
|
17
|
-
const nameNode = declarator.type === 'init_declarator'
|
|
18
|
-
? declarator.childForFieldName('declarator')
|
|
19
|
-
: declarator;
|
|
20
|
-
if (!nameNode)
|
|
21
|
-
return;
|
|
22
|
-
// Handle pointer/reference declarators
|
|
23
|
-
const finalName = nameNode.type === 'pointer_declarator' || nameNode.type === 'reference_declarator'
|
|
24
|
-
? nameNode.firstNamedChild
|
|
25
|
-
: nameNode;
|
|
26
|
-
if (!finalName)
|
|
27
|
-
return;
|
|
28
|
-
const varName = extractVarName(finalName);
|
|
29
|
-
if (varName)
|
|
30
|
-
env.set(varName, typeName);
|
|
31
|
-
};
|
|
32
|
-
/** C/C++: parameter_declaration → type declarator */
|
|
33
|
-
const extractParameter = (node, env) => {
|
|
34
|
-
let nameNode = null;
|
|
35
|
-
let typeNode = null;
|
|
36
|
-
if (node.type === 'parameter_declaration') {
|
|
37
|
-
typeNode = node.childForFieldName('type');
|
|
38
|
-
const declarator = node.childForFieldName('declarator');
|
|
39
|
-
if (declarator) {
|
|
40
|
-
nameNode = declarator.type === 'pointer_declarator' || declarator.type === 'reference_declarator'
|
|
41
|
-
? declarator.firstNamedChild
|
|
42
|
-
: declarator;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
nameNode = node.childForFieldName('name') ?? node.childForFieldName('pattern');
|
|
47
|
-
typeNode = node.childForFieldName('type');
|
|
48
|
-
}
|
|
49
|
-
if (!nameNode || !typeNode)
|
|
50
|
-
return;
|
|
51
|
-
const varName = extractVarName(nameNode);
|
|
52
|
-
const typeName = extractSimpleTypeName(typeNode);
|
|
53
|
-
if (varName && typeName)
|
|
54
|
-
env.set(varName, typeName);
|
|
55
|
-
};
|
|
56
|
-
export const typeConfig = {
|
|
57
|
-
declarationNodeTypes: DECLARATION_NODE_TYPES,
|
|
58
|
-
extractDeclaration,
|
|
59
|
-
extractParameter,
|
|
60
|
-
};
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { extractSimpleTypeName, extractVarName, findChildByType } from './shared.js';
|
|
2
|
-
const DECLARATION_NODE_TYPES = new Set([
|
|
3
|
-
'local_declaration_statement',
|
|
4
|
-
'variable_declaration',
|
|
5
|
-
'field_declaration',
|
|
6
|
-
]);
|
|
7
|
-
/** C#: Type x = ...; var x = new Type(); */
|
|
8
|
-
const extractDeclaration = (node, env) => {
|
|
9
|
-
// C# tree-sitter: local_declaration_statement > variable_declaration > ...
|
|
10
|
-
// Recursively descend through wrapper nodes
|
|
11
|
-
for (let i = 0; i < node.namedChildCount; i++) {
|
|
12
|
-
const child = node.namedChild(i);
|
|
13
|
-
if (!child)
|
|
14
|
-
continue;
|
|
15
|
-
if (child.type === 'variable_declaration' || child.type === 'local_declaration_statement') {
|
|
16
|
-
extractDeclaration(child, env);
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
// At variable_declaration level: first child is type, rest are variable_declarators
|
|
21
|
-
let typeNode = null;
|
|
22
|
-
const declarators = [];
|
|
23
|
-
for (let i = 0; i < node.namedChildCount; i++) {
|
|
24
|
-
const child = node.namedChild(i);
|
|
25
|
-
if (!child)
|
|
26
|
-
continue;
|
|
27
|
-
if (!typeNode && child.type !== 'variable_declarator' && child.type !== 'equals_value_clause') {
|
|
28
|
-
// First non-declarator child is the type (identifier, implicit_type, generic_name, etc.)
|
|
29
|
-
typeNode = child;
|
|
30
|
-
}
|
|
31
|
-
if (child.type === 'variable_declarator') {
|
|
32
|
-
declarators.push(child);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
if (!typeNode || declarators.length === 0)
|
|
36
|
-
return;
|
|
37
|
-
// Handle 'var x = new Foo()' — infer from object_creation_expression
|
|
38
|
-
let typeName;
|
|
39
|
-
if (typeNode.type === 'implicit_type' && typeNode.text === 'var') {
|
|
40
|
-
// Try to infer from initializer: var x = new Foo()
|
|
41
|
-
// C# tree-sitter puts object_creation_expression as direct child of variable_declarator
|
|
42
|
-
if (declarators.length === 1) {
|
|
43
|
-
const initializer = findChildByType(declarators[0], 'object_creation_expression')
|
|
44
|
-
?? findChildByType(declarators[0], 'equals_value_clause')?.firstNamedChild;
|
|
45
|
-
if (initializer?.type === 'object_creation_expression') {
|
|
46
|
-
const ctorType = initializer.childForFieldName('type');
|
|
47
|
-
if (ctorType)
|
|
48
|
-
typeName = extractSimpleTypeName(ctorType);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
typeName = extractSimpleTypeName(typeNode);
|
|
54
|
-
}
|
|
55
|
-
if (!typeName)
|
|
56
|
-
return;
|
|
57
|
-
for (const decl of declarators) {
|
|
58
|
-
const nameNode = decl.childForFieldName('name') ?? decl.firstNamedChild;
|
|
59
|
-
if (nameNode) {
|
|
60
|
-
const varName = extractVarName(nameNode);
|
|
61
|
-
if (varName)
|
|
62
|
-
env.set(varName, typeName);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
/** C#: parameter → type name */
|
|
67
|
-
const extractParameter = (node, env) => {
|
|
68
|
-
let nameNode = null;
|
|
69
|
-
let typeNode = null;
|
|
70
|
-
if (node.type === 'parameter') {
|
|
71
|
-
typeNode = node.childForFieldName('type');
|
|
72
|
-
nameNode = node.childForFieldName('name');
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
nameNode = node.childForFieldName('name') ?? node.childForFieldName('pattern');
|
|
76
|
-
typeNode = node.childForFieldName('type');
|
|
77
|
-
}
|
|
78
|
-
if (!nameNode || !typeNode)
|
|
79
|
-
return;
|
|
80
|
-
const varName = extractVarName(nameNode);
|
|
81
|
-
const typeName = extractSimpleTypeName(typeNode);
|
|
82
|
-
if (varName && typeName)
|
|
83
|
-
env.set(varName, typeName);
|
|
84
|
-
};
|
|
85
|
-
export const typeConfig = {
|
|
86
|
-
declarationNodeTypes: DECLARATION_NODE_TYPES,
|
|
87
|
-
extractDeclaration,
|
|
88
|
-
extractParameter,
|
|
89
|
-
};
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { extractSimpleTypeName, extractVarName } from './shared.js';
|
|
2
|
-
const DECLARATION_NODE_TYPES = new Set([
|
|
3
|
-
'var_declaration',
|
|
4
|
-
'var_spec',
|
|
5
|
-
'short_var_declaration',
|
|
6
|
-
]);
|
|
7
|
-
/** Go: var x Foo */
|
|
8
|
-
const extractGoVarDeclaration = (node, env) => {
|
|
9
|
-
// Go var_declaration contains var_spec children
|
|
10
|
-
if (node.type === 'var_declaration') {
|
|
11
|
-
for (let i = 0; i < node.namedChildCount; i++) {
|
|
12
|
-
const spec = node.namedChild(i);
|
|
13
|
-
if (spec?.type === 'var_spec')
|
|
14
|
-
extractGoVarDeclaration(spec, env);
|
|
15
|
-
}
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
// var_spec: name type [= value]
|
|
19
|
-
const nameNode = node.childForFieldName('name');
|
|
20
|
-
const typeNode = node.childForFieldName('type');
|
|
21
|
-
if (!nameNode || !typeNode)
|
|
22
|
-
return;
|
|
23
|
-
const varName = extractVarName(nameNode);
|
|
24
|
-
const typeName = extractSimpleTypeName(typeNode);
|
|
25
|
-
if (varName && typeName)
|
|
26
|
-
env.set(varName, typeName);
|
|
27
|
-
};
|
|
28
|
-
/** Go: x := Foo{...} — infer type from composite literal (handles multi-assignment) */
|
|
29
|
-
const extractGoShortVarDeclaration = (node, env) => {
|
|
30
|
-
const left = node.childForFieldName('left');
|
|
31
|
-
const right = node.childForFieldName('right');
|
|
32
|
-
if (!left || !right)
|
|
33
|
-
return;
|
|
34
|
-
// Collect LHS names and RHS values (may be expression_lists for multi-assignment)
|
|
35
|
-
const lhsNodes = [];
|
|
36
|
-
const rhsNodes = [];
|
|
37
|
-
if (left.type === 'expression_list') {
|
|
38
|
-
for (let i = 0; i < left.namedChildCount; i++) {
|
|
39
|
-
const c = left.namedChild(i);
|
|
40
|
-
if (c)
|
|
41
|
-
lhsNodes.push(c);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
lhsNodes.push(left);
|
|
46
|
-
}
|
|
47
|
-
if (right.type === 'expression_list') {
|
|
48
|
-
for (let i = 0; i < right.namedChildCount; i++) {
|
|
49
|
-
const c = right.namedChild(i);
|
|
50
|
-
if (c)
|
|
51
|
-
rhsNodes.push(c);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
rhsNodes.push(right);
|
|
56
|
-
}
|
|
57
|
-
// Pair each LHS name with its corresponding RHS value
|
|
58
|
-
const count = Math.min(lhsNodes.length, rhsNodes.length);
|
|
59
|
-
for (let i = 0; i < count; i++) {
|
|
60
|
-
const valueNode = rhsNodes[i];
|
|
61
|
-
if (valueNode.type !== 'composite_literal')
|
|
62
|
-
continue;
|
|
63
|
-
const typeNode = valueNode.childForFieldName('type');
|
|
64
|
-
if (!typeNode)
|
|
65
|
-
continue;
|
|
66
|
-
const typeName = extractSimpleTypeName(typeNode);
|
|
67
|
-
if (!typeName)
|
|
68
|
-
continue;
|
|
69
|
-
const varName = extractVarName(lhsNodes[i]);
|
|
70
|
-
if (varName)
|
|
71
|
-
env.set(varName, typeName);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
const extractDeclaration = (node, env) => {
|
|
75
|
-
if (node.type === 'var_declaration' || node.type === 'var_spec') {
|
|
76
|
-
extractGoVarDeclaration(node, env);
|
|
77
|
-
}
|
|
78
|
-
else if (node.type === 'short_var_declaration') {
|
|
79
|
-
extractGoShortVarDeclaration(node, env);
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
/** Go: parameter → name type */
|
|
83
|
-
const extractParameter = (node, env) => {
|
|
84
|
-
let nameNode = null;
|
|
85
|
-
let typeNode = null;
|
|
86
|
-
if (node.type === 'parameter') {
|
|
87
|
-
nameNode = node.childForFieldName('name');
|
|
88
|
-
typeNode = node.childForFieldName('type');
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
nameNode = node.childForFieldName('name') ?? node.childForFieldName('pattern');
|
|
92
|
-
typeNode = node.childForFieldName('type');
|
|
93
|
-
}
|
|
94
|
-
if (!nameNode || !typeNode)
|
|
95
|
-
return;
|
|
96
|
-
const varName = extractVarName(nameNode);
|
|
97
|
-
const typeName = extractSimpleTypeName(typeNode);
|
|
98
|
-
if (varName && typeName)
|
|
99
|
-
env.set(varName, typeName);
|
|
100
|
-
};
|
|
101
|
-
export const typeConfig = {
|
|
102
|
-
declarationNodeTypes: DECLARATION_NODE_TYPES,
|
|
103
|
-
extractDeclaration,
|
|
104
|
-
extractParameter,
|
|
105
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-language type extraction configurations.
|
|
3
|
-
* Assembled here into a dispatch map keyed by SupportedLanguages.
|
|
4
|
-
*/
|
|
5
|
-
import type { LanguageTypeConfig } from './types.js';
|
|
6
|
-
export declare const typeConfigs: {
|
|
7
|
-
javascript: LanguageTypeConfig;
|
|
8
|
-
typescript: LanguageTypeConfig;
|
|
9
|
-
java: LanguageTypeConfig;
|
|
10
|
-
kotlin: LanguageTypeConfig;
|
|
11
|
-
csharp: LanguageTypeConfig;
|
|
12
|
-
go: LanguageTypeConfig;
|
|
13
|
-
rust: LanguageTypeConfig;
|
|
14
|
-
python: LanguageTypeConfig;
|
|
15
|
-
swift: LanguageTypeConfig;
|
|
16
|
-
c: LanguageTypeConfig;
|
|
17
|
-
cpp: LanguageTypeConfig;
|
|
18
|
-
php: LanguageTypeConfig;
|
|
19
|
-
};
|
|
20
|
-
export type { LanguageTypeConfig, TypeBindingExtractor, ParameterExtractor } from './types.js';
|
|
21
|
-
export { TYPED_PARAMETER_TYPES, extractSimpleTypeName, extractVarName, findChildByType } from './shared.js';
|
|
@@ -1,29 +0,0 @@
|
|
|
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';
|
|
@@ -1,121 +0,0 @@
|
|
|
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
|
-
};
|