gitnexus 1.4.7 → 1.4.9
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 +29 -1
- package/dist/cli/ai-context.d.ts +1 -1
- package/dist/cli/ai-context.js +1 -1
- package/dist/cli/analyze.d.ts +2 -0
- package/dist/cli/analyze.js +54 -21
- package/dist/cli/index-repo.d.ts +15 -0
- package/dist/cli/index-repo.js +115 -0
- package/dist/cli/index.js +13 -3
- package/dist/cli/setup.js +90 -10
- package/dist/cli/wiki.d.ts +4 -0
- package/dist/cli/wiki.js +174 -53
- package/dist/config/supported-languages.d.ts +33 -1
- package/dist/config/supported-languages.js +32 -0
- package/dist/core/embeddings/embedder.d.ts +6 -1
- package/dist/core/embeddings/embedder.js +65 -5
- package/dist/core/embeddings/embedding-pipeline.js +11 -9
- package/dist/core/embeddings/http-client.d.ts +31 -0
- package/dist/core/embeddings/http-client.js +179 -0
- package/dist/core/embeddings/index.d.ts +1 -0
- package/dist/core/embeddings/index.js +1 -0
- package/dist/core/embeddings/types.d.ts +1 -1
- package/dist/core/graph/graph.js +9 -1
- package/dist/core/graph/types.d.ts +11 -2
- package/dist/core/ingestion/call-processor.d.ts +66 -2
- package/dist/core/ingestion/call-processor.js +650 -30
- package/dist/core/ingestion/call-routing.d.ts +9 -18
- package/dist/core/ingestion/call-routing.js +0 -19
- package/dist/core/ingestion/cobol/cobol-copy-expander.d.ts +57 -0
- package/dist/core/ingestion/cobol/cobol-copy-expander.js +385 -0
- package/dist/core/ingestion/cobol/cobol-preprocessor.d.ts +210 -0
- package/dist/core/ingestion/cobol/cobol-preprocessor.js +1509 -0
- package/dist/core/ingestion/cobol/jcl-parser.d.ts +68 -0
- package/dist/core/ingestion/cobol/jcl-parser.js +217 -0
- package/dist/core/ingestion/cobol/jcl-processor.d.ts +33 -0
- package/dist/core/ingestion/cobol/jcl-processor.js +229 -0
- package/dist/core/ingestion/cobol-processor.d.ts +54 -0
- package/dist/core/ingestion/cobol-processor.js +1186 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +17 -0
- package/dist/core/ingestion/entry-point-scoring.js +52 -28
- package/dist/core/ingestion/export-detection.d.ts +47 -8
- package/dist/core/ingestion/export-detection.js +29 -50
- package/dist/core/ingestion/field-extractor.d.ts +29 -0
- package/dist/core/ingestion/field-extractor.js +25 -0
- package/dist/core/ingestion/field-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/field-extractors/configs/c-cpp.js +108 -0
- package/dist/core/ingestion/field-extractors/configs/csharp.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/csharp.js +73 -0
- package/dist/core/ingestion/field-extractors/configs/dart.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/dart.js +76 -0
- package/dist/core/ingestion/field-extractors/configs/go.d.ts +11 -0
- package/dist/core/ingestion/field-extractors/configs/go.js +64 -0
- package/dist/core/ingestion/field-extractors/configs/helpers.d.ts +44 -0
- package/dist/core/ingestion/field-extractors/configs/helpers.js +134 -0
- package/dist/core/ingestion/field-extractors/configs/jvm.d.ts +3 -0
- package/dist/core/ingestion/field-extractors/configs/jvm.js +118 -0
- package/dist/core/ingestion/field-extractors/configs/php.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/php.js +67 -0
- package/dist/core/ingestion/field-extractors/configs/python.d.ts +12 -0
- package/dist/core/ingestion/field-extractors/configs/python.js +91 -0
- package/dist/core/ingestion/field-extractors/configs/ruby.d.ts +16 -0
- package/dist/core/ingestion/field-extractors/configs/ruby.js +75 -0
- package/dist/core/ingestion/field-extractors/configs/rust.d.ts +9 -0
- package/dist/core/ingestion/field-extractors/configs/rust.js +55 -0
- package/dist/core/ingestion/field-extractors/configs/swift.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/swift.js +63 -0
- package/dist/core/ingestion/field-extractors/configs/typescript-javascript.d.ts +3 -0
- package/dist/core/ingestion/field-extractors/configs/typescript-javascript.js +60 -0
- package/dist/core/ingestion/field-extractors/generic.d.ts +46 -0
- package/dist/core/ingestion/field-extractors/generic.js +111 -0
- package/dist/core/ingestion/field-extractors/typescript.d.ts +77 -0
- package/dist/core/ingestion/field-extractors/typescript.js +291 -0
- package/dist/core/ingestion/field-types.d.ts +59 -0
- package/dist/core/ingestion/field-types.js +2 -0
- package/dist/core/ingestion/framework-detection.d.ts +97 -2
- package/dist/core/ingestion/framework-detection.js +114 -14
- package/dist/core/ingestion/heritage-processor.js +62 -66
- package/dist/core/ingestion/import-processor.d.ts +9 -10
- package/dist/core/ingestion/import-processor.js +150 -196
- package/dist/core/ingestion/{resolvers → import-resolvers}/csharp.d.ts +6 -9
- package/dist/core/ingestion/{resolvers → import-resolvers}/csharp.js +20 -2
- package/dist/core/ingestion/import-resolvers/dart.d.ts +7 -0
- package/dist/core/ingestion/import-resolvers/dart.js +44 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/go.d.ts +4 -5
- package/dist/core/ingestion/{resolvers → import-resolvers}/go.js +17 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/jvm.d.ts +10 -1
- package/dist/core/ingestion/import-resolvers/jvm.js +159 -0
- package/dist/core/ingestion/import-resolvers/php.d.ts +25 -0
- package/dist/core/ingestion/import-resolvers/php.js +80 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/python.d.ts +9 -3
- package/dist/core/ingestion/{resolvers → import-resolvers}/python.js +35 -3
- package/dist/core/ingestion/{resolvers → import-resolvers}/ruby.d.ts +5 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/ruby.js +7 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/rust.d.ts +5 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/rust.js +41 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/standard.d.ts +15 -7
- package/dist/core/ingestion/{resolvers → import-resolvers}/standard.js +22 -3
- package/dist/core/ingestion/import-resolvers/swift.d.ts +7 -0
- package/dist/core/ingestion/import-resolvers/swift.js +23 -0
- package/dist/core/ingestion/import-resolvers/types.d.ts +44 -0
- package/dist/core/ingestion/import-resolvers/types.js +6 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/utils.d.ts +2 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/utils.js +7 -0
- package/dist/core/ingestion/language-config.d.ts +6 -0
- package/dist/core/ingestion/language-config.js +13 -0
- package/dist/core/ingestion/language-provider.d.ts +121 -0
- package/dist/core/ingestion/language-provider.js +24 -0
- package/dist/core/ingestion/languages/c-cpp.d.ts +12 -0
- package/dist/core/ingestion/languages/c-cpp.js +71 -0
- package/dist/core/ingestion/languages/cobol.d.ts +1 -0
- package/dist/core/ingestion/languages/cobol.js +26 -0
- package/dist/core/ingestion/languages/csharp.d.ts +8 -0
- package/dist/core/ingestion/languages/csharp.js +49 -0
- package/dist/core/ingestion/languages/dart.d.ts +12 -0
- package/dist/core/ingestion/languages/dart.js +58 -0
- package/dist/core/ingestion/languages/go.d.ts +11 -0
- package/dist/core/ingestion/languages/go.js +28 -0
- package/dist/core/ingestion/languages/index.d.ts +38 -0
- package/dist/core/ingestion/languages/index.js +63 -0
- package/dist/core/ingestion/languages/java.d.ts +9 -0
- package/dist/core/ingestion/languages/java.js +29 -0
- package/dist/core/ingestion/languages/kotlin.d.ts +9 -0
- package/dist/core/ingestion/languages/kotlin.js +53 -0
- package/dist/core/ingestion/languages/php.d.ts +8 -0
- package/dist/core/ingestion/languages/php.js +145 -0
- package/dist/core/ingestion/languages/python.d.ts +12 -0
- package/dist/core/ingestion/languages/python.js +39 -0
- package/dist/core/ingestion/languages/ruby.d.ts +9 -0
- package/dist/core/ingestion/languages/ruby.js +44 -0
- package/dist/core/ingestion/languages/rust.d.ts +12 -0
- package/dist/core/ingestion/languages/rust.js +44 -0
- package/dist/core/ingestion/languages/swift.d.ts +12 -0
- package/dist/core/ingestion/languages/swift.js +133 -0
- package/dist/core/ingestion/languages/typescript.d.ts +10 -0
- package/dist/core/ingestion/languages/typescript.js +60 -0
- package/dist/core/ingestion/markdown-processor.d.ts +17 -0
- package/dist/core/ingestion/markdown-processor.js +124 -0
- package/dist/core/ingestion/mro-processor.js +22 -18
- package/dist/core/ingestion/named-binding-processor.d.ts +18 -0
- package/dist/core/ingestion/named-binding-processor.js +42 -0
- package/dist/core/ingestion/named-bindings/csharp.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/csharp.js +37 -0
- package/dist/core/ingestion/named-bindings/java.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/java.js +29 -0
- package/dist/core/ingestion/named-bindings/kotlin.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/kotlin.js +36 -0
- package/dist/core/ingestion/named-bindings/php.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/php.js +61 -0
- package/dist/core/ingestion/named-bindings/python.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/python.js +49 -0
- package/dist/core/ingestion/named-bindings/rust.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/rust.js +64 -0
- package/dist/core/ingestion/named-bindings/types.d.ts +16 -0
- package/dist/core/ingestion/named-bindings/types.js +6 -0
- package/dist/core/ingestion/named-bindings/typescript.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/typescript.js +58 -0
- package/dist/core/ingestion/parsing-processor.d.ts +6 -2
- package/dist/core/ingestion/parsing-processor.js +125 -85
- package/dist/core/ingestion/pipeline.d.ts +10 -0
- package/dist/core/ingestion/pipeline.js +1235 -317
- package/dist/core/ingestion/resolution-context.d.ts +5 -0
- package/dist/core/ingestion/resolution-context.js +8 -5
- package/dist/core/ingestion/route-extractors/expo.d.ts +1 -0
- package/dist/core/ingestion/route-extractors/expo.js +36 -0
- package/dist/core/ingestion/route-extractors/middleware.d.ts +47 -0
- package/dist/core/ingestion/route-extractors/middleware.js +143 -0
- package/dist/core/ingestion/route-extractors/nextjs.d.ts +3 -0
- package/dist/core/ingestion/route-extractors/nextjs.js +76 -0
- package/dist/core/ingestion/route-extractors/php.d.ts +7 -0
- package/dist/core/ingestion/route-extractors/php.js +21 -0
- package/dist/core/ingestion/route-extractors/response-shapes.d.ts +20 -0
- package/dist/core/ingestion/route-extractors/response-shapes.js +290 -0
- package/dist/core/ingestion/symbol-table.d.ts +16 -0
- package/dist/core/ingestion/symbol-table.js +20 -6
- package/dist/core/ingestion/tree-sitter-queries.d.ts +10 -9
- package/dist/core/ingestion/tree-sitter-queries.js +274 -11
- package/dist/core/ingestion/type-env.d.ts +42 -18
- package/dist/core/ingestion/type-env.js +481 -106
- package/dist/core/ingestion/type-extractors/c-cpp.d.ts +5 -0
- package/dist/core/ingestion/type-extractors/c-cpp.js +119 -0
- package/dist/core/ingestion/type-extractors/csharp.js +149 -16
- package/dist/core/ingestion/type-extractors/dart.d.ts +15 -0
- package/dist/core/ingestion/type-extractors/dart.js +371 -0
- package/dist/core/ingestion/type-extractors/jvm.js +169 -66
- package/dist/core/ingestion/type-extractors/rust.js +35 -1
- package/dist/core/ingestion/type-extractors/shared.d.ts +1 -15
- package/dist/core/ingestion/type-extractors/shared.js +14 -112
- package/dist/core/ingestion/type-extractors/swift.js +338 -7
- package/dist/core/ingestion/type-extractors/types.d.ts +40 -8
- package/dist/core/ingestion/type-extractors/typescript.js +141 -9
- package/dist/core/ingestion/utils/ast-helpers.d.ts +83 -0
- package/dist/core/ingestion/utils/ast-helpers.js +817 -0
- package/dist/core/ingestion/utils/call-analysis.d.ts +73 -0
- package/dist/core/ingestion/utils/call-analysis.js +527 -0
- package/dist/core/ingestion/utils/event-loop.d.ts +5 -0
- package/dist/core/ingestion/utils/event-loop.js +5 -0
- package/dist/core/ingestion/utils/language-detection.d.ts +9 -0
- package/dist/core/ingestion/utils/language-detection.js +70 -0
- package/dist/core/ingestion/utils/verbose.d.ts +1 -0
- package/dist/core/ingestion/utils/verbose.js +7 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +55 -5
- package/dist/core/ingestion/workers/parse-worker.js +415 -225
- package/dist/core/lbug/csv-generator.js +51 -1
- package/dist/core/lbug/lbug-adapter.d.ts +10 -0
- package/dist/core/lbug/lbug-adapter.js +75 -4
- package/dist/core/lbug/schema.d.ts +8 -4
- package/dist/core/lbug/schema.js +65 -4
- package/dist/core/tree-sitter/parser-loader.js +7 -1
- package/dist/core/wiki/cursor-client.d.ts +31 -0
- package/dist/core/wiki/cursor-client.js +127 -0
- package/dist/core/wiki/generator.d.ts +28 -9
- package/dist/core/wiki/generator.js +115 -18
- package/dist/core/wiki/graph-queries.d.ts +4 -0
- package/dist/core/wiki/graph-queries.js +7 -1
- package/dist/core/wiki/llm-client.d.ts +2 -0
- package/dist/core/wiki/llm-client.js +8 -4
- package/dist/core/wiki/prompts.d.ts +3 -3
- package/dist/core/wiki/prompts.js +6 -0
- package/dist/mcp/core/embedder.js +11 -3
- package/dist/mcp/core/lbug-adapter.d.ts +5 -0
- package/dist/mcp/core/lbug-adapter.js +23 -2
- package/dist/mcp/local/local-backend.d.ts +38 -5
- package/dist/mcp/local/local-backend.js +804 -63
- package/dist/mcp/resources.js +2 -0
- package/dist/mcp/tools.js +73 -4
- package/dist/server/api.d.ts +19 -1
- package/dist/server/api.js +66 -6
- package/dist/storage/git.d.ts +12 -0
- package/dist/storage/git.js +21 -0
- package/dist/storage/repo-manager.d.ts +3 -0
- package/package.json +25 -16
- 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/index.d.ts +0 -18
- package/dist/core/ingestion/resolvers/index.js +0 -13
- 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/type-extractors/index.d.ts +0 -22
- package/dist/core/ingestion/type-extractors/index.js +0 -31
- package/dist/core/ingestion/utils.d.ts +0 -138
- package/dist/core/ingestion/utils.js +0 -1290
- package/scripts/patch-tree-sitter-swift.cjs +0 -74
|
@@ -1,2 +1,7 @@
|
|
|
1
|
+
import type { SyntaxNode } from '../utils/ast-helpers.js';
|
|
1
2
|
import type { LanguageTypeConfig } from './types.js';
|
|
3
|
+
/** Extract the first type name from a template_argument_list child.
|
|
4
|
+
* Unwraps type_descriptor wrappers common in tree-sitter-cpp ASTs.
|
|
5
|
+
* Returns undefined if no template arguments or no type found. */
|
|
6
|
+
export declare const extractFirstTemplateTypeArg: (parentNode: SyntaxNode) => string | undefined;
|
|
2
7
|
export declare const typeConfig: LanguageTypeConfig;
|
|
@@ -2,6 +2,28 @@ import { extractSimpleTypeName, extractVarName, resolveIterableElementType, meth
|
|
|
2
2
|
const DECLARATION_NODE_TYPES = new Set([
|
|
3
3
|
'declaration',
|
|
4
4
|
]);
|
|
5
|
+
/** Smart pointer factory function names that create a typed object. */
|
|
6
|
+
const SMART_PTR_FACTORIES = new Set([
|
|
7
|
+
'make_shared', 'make_unique', 'make_shared_for_overwrite',
|
|
8
|
+
]);
|
|
9
|
+
/** Smart pointer wrapper type names. When the declared type is a smart pointer,
|
|
10
|
+
* the inner template type is extracted for virtual dispatch comparison. */
|
|
11
|
+
const SMART_PTR_WRAPPERS = new Set(['shared_ptr', 'unique_ptr', 'weak_ptr']);
|
|
12
|
+
/** Extract the first type name from a template_argument_list child.
|
|
13
|
+
* Unwraps type_descriptor wrappers common in tree-sitter-cpp ASTs.
|
|
14
|
+
* Returns undefined if no template arguments or no type found. */
|
|
15
|
+
export const extractFirstTemplateTypeArg = (parentNode) => {
|
|
16
|
+
const templateArgs = parentNode.children.find((c) => c.type === 'template_argument_list');
|
|
17
|
+
if (!templateArgs?.firstNamedChild)
|
|
18
|
+
return undefined;
|
|
19
|
+
let argNode = templateArgs.firstNamedChild;
|
|
20
|
+
if (argNode.type === 'type_descriptor') {
|
|
21
|
+
const inner = argNode.childForFieldName('type');
|
|
22
|
+
if (inner)
|
|
23
|
+
argNode = inner;
|
|
24
|
+
}
|
|
25
|
+
return extractSimpleTypeName(argNode) ?? undefined;
|
|
26
|
+
};
|
|
5
27
|
/** C++: Type x = ...; Type* x; Type& x; */
|
|
6
28
|
const extractDeclaration = (node, env) => {
|
|
7
29
|
const typeNode = node.childForFieldName('type');
|
|
@@ -89,6 +111,29 @@ const extractInitializer = (node, env, classNames) => {
|
|
|
89
111
|
if (text && classNames.has(text))
|
|
90
112
|
env.set(varName, text);
|
|
91
113
|
}
|
|
114
|
+
else {
|
|
115
|
+
// auto x = std::make_shared<Dog>() — smart pointer factory via template_function.
|
|
116
|
+
// AST: call_expression > function: qualified_identifier > template_function
|
|
117
|
+
// or: call_expression > function: template_function (unqualified)
|
|
118
|
+
const templateFunc = func.type === 'template_function'
|
|
119
|
+
? func
|
|
120
|
+
: (func.type === 'qualified_identifier' || func.type === 'scoped_identifier')
|
|
121
|
+
? func.namedChildren.find((c) => c.type === 'template_function') ?? null
|
|
122
|
+
: null;
|
|
123
|
+
if (templateFunc) {
|
|
124
|
+
const nameNode = templateFunc.firstNamedChild;
|
|
125
|
+
if (nameNode) {
|
|
126
|
+
const funcName = (nameNode.type === 'qualified_identifier' || nameNode.type === 'scoped_identifier')
|
|
127
|
+
? nameNode.lastNamedChild?.text ?? ''
|
|
128
|
+
: nameNode.text;
|
|
129
|
+
if (SMART_PTR_FACTORIES.has(funcName)) {
|
|
130
|
+
const typeName = extractFirstTemplateTypeArg(templateFunc);
|
|
131
|
+
if (typeName)
|
|
132
|
+
env.set(varName, typeName);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
92
137
|
return;
|
|
93
138
|
}
|
|
94
139
|
// auto x = User{} — compound_literal_expression (brace initialization)
|
|
@@ -398,6 +443,77 @@ const extractForLoopBinding = (node, { scopeEnv, declarationTypeNodes, scope })
|
|
|
398
443
|
if (elementType)
|
|
399
444
|
scopeEnv.set(varName, elementType);
|
|
400
445
|
};
|
|
446
|
+
/** Infer the type of a literal AST node for C++ overload disambiguation. */
|
|
447
|
+
const inferLiteralType = (node) => {
|
|
448
|
+
switch (node.type) {
|
|
449
|
+
case 'number_literal': {
|
|
450
|
+
const t = node.text;
|
|
451
|
+
// Float suffixes
|
|
452
|
+
if (t.endsWith('f') || t.endsWith('F'))
|
|
453
|
+
return 'float';
|
|
454
|
+
if (t.includes('.') || t.includes('e') || t.includes('E'))
|
|
455
|
+
return 'double';
|
|
456
|
+
// Long suffix
|
|
457
|
+
if (t.endsWith('L') || t.endsWith('l') || t.endsWith('LL') || t.endsWith('ll'))
|
|
458
|
+
return 'long';
|
|
459
|
+
return 'int';
|
|
460
|
+
}
|
|
461
|
+
case 'string_literal':
|
|
462
|
+
case 'raw_string_literal':
|
|
463
|
+
case 'concatenated_string':
|
|
464
|
+
return 'string';
|
|
465
|
+
case 'char_literal':
|
|
466
|
+
return 'char';
|
|
467
|
+
case 'true':
|
|
468
|
+
case 'false':
|
|
469
|
+
return 'bool';
|
|
470
|
+
case 'null':
|
|
471
|
+
case 'nullptr':
|
|
472
|
+
return 'null';
|
|
473
|
+
default:
|
|
474
|
+
return undefined;
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
/** C++: detect constructor type from smart pointer factory calls (make_shared<Dog>()).
|
|
478
|
+
* Extracts the template type argument as the constructor type for virtual dispatch. */
|
|
479
|
+
const detectCppConstructorType = (node, classNames) => {
|
|
480
|
+
// Navigate to the initializer value in the declaration
|
|
481
|
+
const declarator = node.childForFieldName('declarator');
|
|
482
|
+
const initDecl = declarator?.type === 'init_declarator' ? declarator : undefined;
|
|
483
|
+
if (!initDecl)
|
|
484
|
+
return undefined;
|
|
485
|
+
const value = initDecl.childForFieldName('value');
|
|
486
|
+
if (!value || value.type !== 'call_expression')
|
|
487
|
+
return undefined;
|
|
488
|
+
// Check for template_function pattern: make_shared<Dog>()
|
|
489
|
+
const func = value.childForFieldName('function');
|
|
490
|
+
if (!func || func.type !== 'template_function')
|
|
491
|
+
return undefined;
|
|
492
|
+
// Extract function name (possibly qualified: std::make_shared)
|
|
493
|
+
const nameNode = func.firstNamedChild;
|
|
494
|
+
if (!nameNode)
|
|
495
|
+
return undefined;
|
|
496
|
+
let funcName;
|
|
497
|
+
if (nameNode.type === 'qualified_identifier' || nameNode.type === 'scoped_identifier') {
|
|
498
|
+
funcName = nameNode.lastNamedChild?.text ?? '';
|
|
499
|
+
}
|
|
500
|
+
else {
|
|
501
|
+
funcName = nameNode.text;
|
|
502
|
+
}
|
|
503
|
+
if (!SMART_PTR_FACTORIES.has(funcName))
|
|
504
|
+
return undefined;
|
|
505
|
+
// Extract template type argument
|
|
506
|
+
return extractFirstTemplateTypeArg(func);
|
|
507
|
+
};
|
|
508
|
+
/** Unwrap a C++ smart pointer declared type to its inner template type.
|
|
509
|
+
* E.g., shared_ptr<Animal> → Animal. Returns the original name if not a smart pointer. */
|
|
510
|
+
const unwrapCppDeclaredType = (declaredType, typeNode) => {
|
|
511
|
+
if (!SMART_PTR_WRAPPERS.has(declaredType))
|
|
512
|
+
return declaredType;
|
|
513
|
+
if (typeNode.type !== 'template_type')
|
|
514
|
+
return declaredType;
|
|
515
|
+
return extractFirstTemplateTypeArg(typeNode) ?? declaredType;
|
|
516
|
+
};
|
|
401
517
|
export const typeConfig = {
|
|
402
518
|
declarationNodeTypes: DECLARATION_NODE_TYPES,
|
|
403
519
|
forLoopNodeTypes: FOR_LOOP_NODE_TYPES,
|
|
@@ -407,4 +523,7 @@ export const typeConfig = {
|
|
|
407
523
|
scanConstructorBinding,
|
|
408
524
|
extractForLoopBinding,
|
|
409
525
|
extractPendingAssignment,
|
|
526
|
+
inferLiteralType,
|
|
527
|
+
detectConstructorType: detectCppConstructorType,
|
|
528
|
+
unwrapDeclaredType: unwrapCppDeclaredType,
|
|
410
529
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { findChild } from '../utils/ast-helpers.js';
|
|
2
|
+
import { extractSimpleTypeName, extractVarName, unwrapAwait, resolveIterableElementType, methodToTypeArgPosition, extractElementTypeFromString } from './shared.js';
|
|
2
3
|
/** Known container property accessors that operate on the container itself (e.g., dict.Keys, dict.Values) */
|
|
3
4
|
const KNOWN_CONTAINER_PROPS = new Set(['Keys', 'Values']);
|
|
4
5
|
const DECLARATION_NODE_TYPES = new Set([
|
|
@@ -43,8 +44,8 @@ const extractDeclaration = (node, env) => {
|
|
|
43
44
|
// tree-sitter-c-sharp may put object_creation_expression as direct child
|
|
44
45
|
// or inside equals_value_clause depending on grammar version
|
|
45
46
|
if (declarators.length === 1) {
|
|
46
|
-
const initializer =
|
|
47
|
-
??
|
|
47
|
+
const initializer = findChild(declarators[0], 'object_creation_expression')
|
|
48
|
+
?? findChild(declarators[0], 'equals_value_clause')?.firstNamedChild;
|
|
48
49
|
if (initializer?.type === 'object_creation_expression') {
|
|
49
50
|
const ctorType = initializer.childForFieldName('type');
|
|
50
51
|
if (ctorType)
|
|
@@ -159,7 +160,7 @@ const extractCSharpElementTypeFromTypeNode = (typeNode, pos = 'last', depth = 0)
|
|
|
159
160
|
// generic_name: List<User>, IEnumerable<User>, Dictionary<string, User>
|
|
160
161
|
// C# uses generic_name (not generic_type)
|
|
161
162
|
if (typeNode.type === 'generic_name') {
|
|
162
|
-
const argList =
|
|
163
|
+
const argList = findChild(typeNode, 'type_argument_list');
|
|
163
164
|
if (argList && argList.namedChildCount >= 1) {
|
|
164
165
|
if (pos === 'first') {
|
|
165
166
|
const firstArg = argList.namedChild(0);
|
|
@@ -307,21 +308,89 @@ const extractForLoopBinding = (node, { scopeEnv, declarationTypeNodes, scope, re
|
|
|
307
308
|
* declaration_pattern, or when the type/name cannot be extracted.
|
|
308
309
|
* No scopeEnv lookup is needed — the pattern explicitly declares the new variable's type.
|
|
309
310
|
*/
|
|
310
|
-
|
|
311
|
+
/**
|
|
312
|
+
* Find the if-body (consequence) block for a C# null-check.
|
|
313
|
+
* Walks up from the expression to find the enclosing if_statement,
|
|
314
|
+
* then returns its first block child (the truthy branch body).
|
|
315
|
+
*/
|
|
316
|
+
const findCSharpIfConsequenceBlock = (expr) => {
|
|
317
|
+
let current = expr.parent;
|
|
318
|
+
while (current) {
|
|
319
|
+
if (current.type === 'if_statement') {
|
|
320
|
+
// C# if_statement consequence is the 'consequence' field or first block child
|
|
321
|
+
const consequence = current.childForFieldName('consequence');
|
|
322
|
+
if (consequence)
|
|
323
|
+
return consequence;
|
|
324
|
+
for (let i = 0; i < current.childCount; i++) {
|
|
325
|
+
const child = current.child(i);
|
|
326
|
+
if (child?.type === 'block')
|
|
327
|
+
return child;
|
|
328
|
+
}
|
|
329
|
+
return undefined;
|
|
330
|
+
}
|
|
331
|
+
if (current.type === 'block' || current.type === 'method_declaration'
|
|
332
|
+
|| current.type === 'constructor_declaration' || current.type === 'local_function_statement'
|
|
333
|
+
|| current.type === 'lambda_expression')
|
|
334
|
+
return undefined;
|
|
335
|
+
current = current.parent;
|
|
336
|
+
}
|
|
337
|
+
return undefined;
|
|
338
|
+
};
|
|
339
|
+
/** Check if a C# declaration type node represents a nullable type.
|
|
340
|
+
* Checks for nullable_type AST node or '?' in the type text (e.g., User?). */
|
|
341
|
+
const isCSharpNullableDecl = (declTypeNode) => {
|
|
342
|
+
if (declTypeNode.type === 'nullable_type')
|
|
343
|
+
return true;
|
|
344
|
+
return declTypeNode.text.includes('?');
|
|
345
|
+
};
|
|
346
|
+
const extractPatternBinding = (node, scopeEnv, declarationTypeNodes, scope) => {
|
|
311
347
|
// is_pattern_expression: `obj is User user` — has a declaration_pattern child
|
|
348
|
+
// Also handles `x is not null` for null-check narrowing
|
|
312
349
|
if (node.type === 'is_pattern_expression') {
|
|
313
350
|
const pattern = node.childForFieldName('pattern');
|
|
314
|
-
if (pattern
|
|
351
|
+
if (!pattern)
|
|
315
352
|
return undefined;
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
353
|
+
// Standard type pattern: `obj is User user`
|
|
354
|
+
if (pattern.type === 'declaration_pattern' || pattern.type === 'recursive_pattern') {
|
|
355
|
+
const typeNode = pattern.childForFieldName('type');
|
|
356
|
+
const nameNode = pattern.childForFieldName('name');
|
|
357
|
+
if (!typeNode || !nameNode)
|
|
358
|
+
return undefined;
|
|
359
|
+
const typeName = extractSimpleTypeName(typeNode);
|
|
360
|
+
const varName = extractVarName(nameNode);
|
|
361
|
+
if (!typeName || !varName)
|
|
362
|
+
return undefined;
|
|
363
|
+
return { varName, typeName };
|
|
364
|
+
}
|
|
365
|
+
// Null-check: `x is not null` — negated_pattern > constant_pattern > null_literal
|
|
366
|
+
if (pattern.type === 'negated_pattern') {
|
|
367
|
+
const inner = pattern.firstNamedChild;
|
|
368
|
+
if (inner?.type === 'constant_pattern') {
|
|
369
|
+
const literal = inner.firstNamedChild ?? inner.firstChild;
|
|
370
|
+
if (literal?.type === 'null_literal' || literal?.text === 'null') {
|
|
371
|
+
const expr = node.childForFieldName('expression');
|
|
372
|
+
if (!expr || expr.type !== 'identifier')
|
|
373
|
+
return undefined;
|
|
374
|
+
const varName = expr.text;
|
|
375
|
+
const resolvedType = scopeEnv.get(varName);
|
|
376
|
+
if (!resolvedType)
|
|
377
|
+
return undefined;
|
|
378
|
+
// Verify the original declaration was nullable
|
|
379
|
+
const declTypeNode = declarationTypeNodes.get(`${scope}\0${varName}`);
|
|
380
|
+
if (!declTypeNode || !isCSharpNullableDecl(declTypeNode))
|
|
381
|
+
return undefined;
|
|
382
|
+
const ifBody = findCSharpIfConsequenceBlock(node);
|
|
383
|
+
if (!ifBody)
|
|
384
|
+
return undefined;
|
|
385
|
+
return {
|
|
386
|
+
varName,
|
|
387
|
+
typeName: resolvedType,
|
|
388
|
+
narrowingRange: { startIndex: ifBody.startIndex, endIndex: ifBody.endIndex },
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return undefined;
|
|
325
394
|
}
|
|
326
395
|
// declaration_pattern / recursive_pattern: standalone in switch statements and switch expressions
|
|
327
396
|
// `case User u:` or `User u =>` or `User { Name: "Alice" } u =>`
|
|
@@ -337,6 +406,41 @@ const extractPatternBinding = (node) => {
|
|
|
337
406
|
return undefined;
|
|
338
407
|
return { varName, typeName };
|
|
339
408
|
}
|
|
409
|
+
// Null-check: `x != null` — binary_expression with != operator
|
|
410
|
+
if (node.type === 'binary_expression') {
|
|
411
|
+
const op = node.children.find(c => !c.isNamed && c.text === '!=');
|
|
412
|
+
if (!op)
|
|
413
|
+
return undefined;
|
|
414
|
+
const left = node.namedChild(0);
|
|
415
|
+
const right = node.namedChild(1);
|
|
416
|
+
if (!left || !right)
|
|
417
|
+
return undefined;
|
|
418
|
+
let varNode;
|
|
419
|
+
if (left.type === 'identifier' && (right.type === 'null_literal' || right.text === 'null')) {
|
|
420
|
+
varNode = left;
|
|
421
|
+
}
|
|
422
|
+
else if (right.type === 'identifier' && (left.type === 'null_literal' || left.text === 'null')) {
|
|
423
|
+
varNode = right;
|
|
424
|
+
}
|
|
425
|
+
if (!varNode)
|
|
426
|
+
return undefined;
|
|
427
|
+
const varName = varNode.text;
|
|
428
|
+
const resolvedType = scopeEnv.get(varName);
|
|
429
|
+
if (!resolvedType)
|
|
430
|
+
return undefined;
|
|
431
|
+
// Verify the original declaration was nullable
|
|
432
|
+
const declTypeNode = declarationTypeNodes.get(`${scope}\0${varName}`);
|
|
433
|
+
if (!declTypeNode || !isCSharpNullableDecl(declTypeNode))
|
|
434
|
+
return undefined;
|
|
435
|
+
const ifBody = findCSharpIfConsequenceBlock(node);
|
|
436
|
+
if (!ifBody)
|
|
437
|
+
return undefined;
|
|
438
|
+
return {
|
|
439
|
+
varName,
|
|
440
|
+
typeName: resolvedType,
|
|
441
|
+
narrowingRange: { startIndex: ifBody.startIndex, endIndex: ifBody.endIndex },
|
|
442
|
+
};
|
|
443
|
+
}
|
|
340
444
|
return undefined;
|
|
341
445
|
};
|
|
342
446
|
/** C#: var alias = u → variable_declarator with name + equals_value_clause.
|
|
@@ -410,14 +514,43 @@ const extractPendingAssignment = (node, scopeEnv) => {
|
|
|
410
514
|
}
|
|
411
515
|
return undefined;
|
|
412
516
|
};
|
|
517
|
+
/** Infer the type of a literal AST node for C# overload disambiguation. */
|
|
518
|
+
const inferLiteralType = (node) => {
|
|
519
|
+
switch (node.type) {
|
|
520
|
+
case 'integer_literal':
|
|
521
|
+
if (node.text.endsWith('L') || node.text.endsWith('l'))
|
|
522
|
+
return 'long';
|
|
523
|
+
return 'int';
|
|
524
|
+
case 'real_literal':
|
|
525
|
+
if (node.text.endsWith('f') || node.text.endsWith('F'))
|
|
526
|
+
return 'float';
|
|
527
|
+
if (node.text.endsWith('m') || node.text.endsWith('M'))
|
|
528
|
+
return 'decimal';
|
|
529
|
+
return 'double';
|
|
530
|
+
case 'string_literal':
|
|
531
|
+
case 'verbatim_string_literal':
|
|
532
|
+
case 'raw_string_literal':
|
|
533
|
+
case 'interpolated_string_expression':
|
|
534
|
+
return 'string';
|
|
535
|
+
case 'character_literal':
|
|
536
|
+
return 'char';
|
|
537
|
+
case 'boolean_literal':
|
|
538
|
+
return 'bool';
|
|
539
|
+
case 'null_literal':
|
|
540
|
+
return 'null';
|
|
541
|
+
default:
|
|
542
|
+
return undefined;
|
|
543
|
+
}
|
|
544
|
+
};
|
|
413
545
|
export const typeConfig = {
|
|
414
546
|
declarationNodeTypes: DECLARATION_NODE_TYPES,
|
|
415
547
|
forLoopNodeTypes: FOR_LOOP_NODE_TYPES,
|
|
416
|
-
patternBindingNodeTypes: new Set(['is_pattern_expression', 'declaration_pattern', 'recursive_pattern']),
|
|
548
|
+
patternBindingNodeTypes: new Set(['is_pattern_expression', 'declaration_pattern', 'recursive_pattern', 'binary_expression']),
|
|
417
549
|
extractDeclaration,
|
|
418
550
|
extractParameter,
|
|
419
551
|
scanConstructorBinding,
|
|
420
552
|
extractForLoopBinding,
|
|
421
553
|
extractPendingAssignment,
|
|
422
554
|
extractPatternBinding,
|
|
555
|
+
inferLiteralType,
|
|
423
556
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dart type extractor — full implementation following type-resolution-system.md.
|
|
3
|
+
*
|
|
4
|
+
* Tier 0: Explicit type annotations (User user = ...)
|
|
5
|
+
* Tier 0b: For-loop element types (for (var u in users))
|
|
6
|
+
* Tier 1: Constructor/initializer inference (var user = User())
|
|
7
|
+
* Tier 2: Assignment chain propagation (copy, fieldAccess, callResult, methodCallResult)
|
|
8
|
+
*
|
|
9
|
+
* Handles tree-sitter-dart's flat sibling AST structure:
|
|
10
|
+
* identifier + selector + selector (not nested call_expression).
|
|
11
|
+
*
|
|
12
|
+
* Credit: Type resolution approach adapted from @xFlaviews' PR #83.
|
|
13
|
+
*/
|
|
14
|
+
import type { LanguageTypeConfig } from './types.js';
|
|
15
|
+
export declare const typeConfig: LanguageTypeConfig;
|