gitnexus 1.5.3 → 1.6.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 +10 -0
- package/dist/_shared/graph/types.d.ts +1 -1
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/index.d.ts +1 -0
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/language-detection.d.ts.map +1 -1
- package/dist/_shared/language-detection.js +2 -0
- package/dist/_shared/language-detection.js.map +1 -1
- package/dist/_shared/languages.d.ts +1 -0
- package/dist/_shared/languages.d.ts.map +1 -1
- package/dist/_shared/languages.js +1 -0
- package/dist/_shared/languages.js.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +3 -1
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/mro-strategy.d.ts +19 -0
- package/dist/_shared/mro-strategy.d.ts.map +1 -0
- package/dist/_shared/mro-strategy.js +2 -0
- package/dist/_shared/mro-strategy.js.map +1 -0
- package/dist/cli/ai-context.d.ts +1 -0
- package/dist/cli/ai-context.js +28 -4
- package/dist/cli/analyze.d.ts +2 -0
- package/dist/cli/analyze.js +2 -1
- package/dist/cli/group.d.ts +2 -0
- package/dist/cli/group.js +233 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/serve.js +4 -1
- package/dist/cli/setup.js +34 -3
- package/dist/config/ignore-service.js +8 -3
- package/dist/core/augmentation/engine.js +1 -1
- package/dist/core/git-staleness.d.ts +13 -0
- package/dist/core/git-staleness.js +29 -0
- package/dist/core/group/bridge-db.d.ts +82 -0
- package/dist/core/group/bridge-db.js +460 -0
- package/dist/core/group/bridge-schema.d.ts +27 -0
- package/dist/core/group/bridge-schema.js +55 -0
- package/dist/core/group/config-parser.d.ts +3 -0
- package/dist/core/group/config-parser.js +83 -0
- package/dist/core/group/contract-extractor.d.ts +7 -0
- package/dist/core/group/contract-extractor.js +1 -0
- package/dist/core/group/extractors/grpc-extractor.d.ts +16 -0
- package/dist/core/group/extractors/grpc-extractor.js +264 -0
- package/dist/core/group/extractors/http-route-extractor.d.ts +24 -0
- package/dist/core/group/extractors/http-route-extractor.js +428 -0
- package/dist/core/group/extractors/topic-extractor.d.ts +9 -0
- package/dist/core/group/extractors/topic-extractor.js +234 -0
- package/dist/core/group/matching.d.ts +13 -0
- package/dist/core/group/matching.js +198 -0
- package/dist/core/group/normalization.d.ts +3 -0
- package/dist/core/group/normalization.js +115 -0
- package/dist/core/group/service-boundary-detector.d.ts +8 -0
- package/dist/core/group/service-boundary-detector.js +155 -0
- package/dist/core/group/service.d.ts +46 -0
- package/dist/core/group/service.js +160 -0
- package/dist/core/group/storage.d.ts +9 -0
- package/dist/core/group/storage.js +91 -0
- package/dist/core/group/sync.d.ts +21 -0
- package/dist/core/group/sync.js +148 -0
- package/dist/core/group/types.d.ts +130 -0
- package/dist/core/group/types.js +1 -0
- package/dist/core/ingestion/binding-accumulator.d.ts +207 -0
- package/dist/core/ingestion/binding-accumulator.js +332 -0
- package/dist/core/ingestion/call-processor.d.ts +155 -24
- package/dist/core/ingestion/call-processor.js +1129 -247
- package/dist/core/ingestion/class-extractors/generic.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/generic.js +135 -0
- package/dist/core/ingestion/class-types.d.ts +34 -0
- package/dist/core/ingestion/class-types.js +1 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +1 -0
- package/dist/core/ingestion/entry-point-scoring.js +1 -0
- package/dist/core/ingestion/field-types.d.ts +2 -2
- package/dist/core/ingestion/filesystem-walker.js +8 -0
- package/dist/core/ingestion/framework-detection.d.ts +1 -0
- package/dist/core/ingestion/framework-detection.js +1 -0
- package/dist/core/ingestion/heritage-processor.d.ts +8 -15
- package/dist/core/ingestion/heritage-processor.js +15 -28
- package/dist/core/ingestion/import-processor.d.ts +1 -11
- package/dist/core/ingestion/import-processor.js +0 -12
- package/dist/core/ingestion/import-resolvers/utils.js +1 -0
- package/dist/core/ingestion/import-resolvers/vue.d.ts +8 -0
- package/dist/core/ingestion/import-resolvers/vue.js +9 -0
- package/dist/core/ingestion/language-provider.d.ts +6 -3
- package/dist/core/ingestion/languages/c-cpp.js +168 -1
- package/dist/core/ingestion/languages/csharp.js +20 -0
- package/dist/core/ingestion/languages/dart.js +26 -4
- package/dist/core/ingestion/languages/go.js +22 -0
- package/dist/core/ingestion/languages/index.d.ts +1 -0
- package/dist/core/ingestion/languages/index.js +2 -0
- package/dist/core/ingestion/languages/java.js +17 -0
- package/dist/core/ingestion/languages/kotlin.js +24 -1
- package/dist/core/ingestion/languages/php.js +23 -11
- package/dist/core/ingestion/languages/python.js +9 -0
- package/dist/core/ingestion/languages/ruby.js +28 -0
- package/dist/core/ingestion/languages/rust.js +38 -0
- package/dist/core/ingestion/languages/swift.js +31 -0
- package/dist/core/ingestion/languages/typescript.d.ts +1 -0
- package/dist/core/ingestion/languages/typescript.js +52 -3
- package/dist/core/ingestion/languages/vue.d.ts +13 -0
- package/dist/core/ingestion/languages/vue.js +81 -0
- package/dist/core/ingestion/method-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
- package/dist/core/ingestion/method-extractors/configs/csharp.js +5 -1
- package/dist/core/ingestion/method-extractors/configs/dart.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/dart.js +376 -0
- package/dist/core/ingestion/method-extractors/configs/go.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/go.js +176 -0
- package/dist/core/ingestion/method-extractors/configs/jvm.js +13 -4
- package/dist/core/ingestion/method-extractors/configs/php.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/php.js +304 -0
- package/dist/core/ingestion/method-extractors/configs/python.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/python.js +309 -0
- package/dist/core/ingestion/method-extractors/configs/ruby.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/ruby.js +285 -0
- package/dist/core/ingestion/method-extractors/configs/rust.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/rust.js +195 -0
- package/dist/core/ingestion/method-extractors/configs/swift.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/swift.js +277 -0
- package/dist/core/ingestion/method-extractors/configs/typescript-javascript.js +85 -8
- package/dist/core/ingestion/method-extractors/generic.js +38 -15
- package/dist/core/ingestion/method-types.d.ts +25 -0
- package/dist/core/ingestion/model/field-registry.d.ts +18 -0
- package/dist/core/ingestion/model/field-registry.js +22 -0
- package/dist/core/ingestion/model/heritage-map.d.ts +70 -0
- package/dist/core/ingestion/model/heritage-map.js +159 -0
- package/dist/core/ingestion/model/index.d.ts +20 -0
- package/dist/core/ingestion/model/index.js +41 -0
- package/dist/core/ingestion/model/method-registry.d.ts +62 -0
- package/dist/core/ingestion/model/method-registry.js +130 -0
- package/dist/core/ingestion/model/registration-table.d.ts +139 -0
- package/dist/core/ingestion/model/registration-table.js +224 -0
- package/dist/core/ingestion/model/resolution-context.d.ts +93 -0
- package/dist/core/ingestion/model/resolution-context.js +337 -0
- package/dist/core/ingestion/model/resolve.d.ts +56 -0
- package/dist/core/ingestion/model/resolve.js +242 -0
- package/dist/core/ingestion/model/semantic-model.d.ts +86 -0
- package/dist/core/ingestion/model/semantic-model.js +120 -0
- package/dist/core/ingestion/model/symbol-table.d.ts +222 -0
- package/dist/core/ingestion/model/symbol-table.js +206 -0
- package/dist/core/ingestion/model/type-registry.d.ts +39 -0
- package/dist/core/ingestion/model/type-registry.js +62 -0
- package/dist/core/ingestion/mro-processor.d.ts +4 -3
- package/dist/core/ingestion/mro-processor.js +310 -106
- package/dist/core/ingestion/parsing-processor.d.ts +5 -4
- package/dist/core/ingestion/parsing-processor.js +210 -85
- package/dist/core/ingestion/pipeline.d.ts +2 -0
- package/dist/core/ingestion/pipeline.js +192 -68
- package/dist/core/ingestion/tree-sitter-queries.d.ts +5 -5
- package/dist/core/ingestion/tree-sitter-queries.js +21 -0
- package/dist/core/ingestion/type-env.d.ts +15 -2
- package/dist/core/ingestion/type-env.js +163 -102
- package/dist/core/ingestion/type-extractors/csharp.js +17 -0
- package/dist/core/ingestion/type-extractors/jvm.js +11 -0
- package/dist/core/ingestion/type-extractors/php.js +0 -55
- package/dist/core/ingestion/type-extractors/ruby.js +0 -32
- package/dist/core/ingestion/type-extractors/swift.js +13 -0
- package/dist/core/ingestion/type-extractors/types.d.ts +8 -8
- package/dist/core/ingestion/type-extractors/typescript.js +66 -69
- package/dist/core/ingestion/utils/ast-helpers.d.ts +33 -43
- package/dist/core/ingestion/utils/ast-helpers.js +129 -572
- package/dist/core/ingestion/utils/method-props.d.ts +32 -0
- package/dist/core/ingestion/utils/method-props.js +147 -0
- package/dist/core/ingestion/vue-sfc-extractor.d.ts +44 -0
- package/dist/core/ingestion/vue-sfc-extractor.js +94 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +31 -19
- package/dist/core/ingestion/workers/parse-worker.js +463 -198
- package/dist/core/lbug/lbug-adapter.d.ts +6 -0
- package/dist/core/lbug/lbug-adapter.js +68 -3
- package/dist/core/lbug/pool-adapter.d.ts +76 -0
- package/dist/core/lbug/pool-adapter.js +522 -0
- package/dist/core/run-analyze.d.ts +2 -0
- package/dist/core/run-analyze.js +1 -1
- package/dist/core/search/bm25-index.js +1 -1
- package/dist/core/tree-sitter/parser-loader.js +1 -0
- package/dist/core/wiki/graph-queries.js +1 -1
- package/dist/mcp/core/embedder.js +6 -5
- package/dist/mcp/core/lbug-adapter.d.ts +3 -63
- package/dist/mcp/core/lbug-adapter.js +3 -484
- package/dist/mcp/local/local-backend.d.ts +31 -2
- package/dist/mcp/local/local-backend.js +255 -46
- package/dist/mcp/resources.js +5 -4
- package/dist/mcp/staleness.d.ts +3 -13
- package/dist/mcp/staleness.js +2 -31
- package/dist/mcp/tools.js +80 -4
- package/dist/server/analyze-job.d.ts +2 -0
- package/dist/server/analyze-job.js +4 -0
- package/dist/server/api.d.ts +20 -1
- package/dist/server/api.js +306 -71
- package/dist/server/git-clone.d.ts +2 -1
- package/dist/server/git-clone.js +98 -5
- package/dist/storage/git.d.ts +13 -0
- package/dist/storage/git.js +25 -0
- package/dist/storage/repo-manager.js +1 -1
- package/package.json +8 -2
- package/scripts/patch-tree-sitter-swift.cjs +78 -0
- package/dist/core/ingestion/named-binding-processor.d.ts +0 -18
- package/dist/core/ingestion/named-binding-processor.js +0 -42
- package/dist/core/ingestion/resolution-context.d.ts +0 -58
- package/dist/core/ingestion/resolution-context.js +0 -135
- package/dist/core/ingestion/symbol-table.d.ts +0 -79
- package/dist/core/ingestion/symbol-table.js +0 -115
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/method-extractors/configs/dart.ts
|
|
2
|
+
// Verified against tree-sitter-dart 1.0.0 (80e23c07)
|
|
3
|
+
import { SupportedLanguages } from '../../../../_shared/index.js';
|
|
4
|
+
import { extractSimpleTypeName } from '../../type-extractors/shared.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Dart helpers
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
/** Type node types that represent a return type in function/getter/setter signatures. */
|
|
9
|
+
const TYPE_NODE_TYPES = new Set([
|
|
10
|
+
'type_identifier',
|
|
11
|
+
'generic_type',
|
|
12
|
+
'function_type',
|
|
13
|
+
'nullable_type',
|
|
14
|
+
'void_type',
|
|
15
|
+
'record_type',
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Dart method_signature is a WRAPPER node containing one inner signature:
|
|
19
|
+
* function_signature, constructor_signature, getter_signature, setter_signature,
|
|
20
|
+
* operator_signature, or factory_constructor_signature.
|
|
21
|
+
*
|
|
22
|
+
* Name, parameters, and return type live on the INNER signature, not on
|
|
23
|
+
* method_signature itself.
|
|
24
|
+
*/
|
|
25
|
+
function getInnerSignature(node) {
|
|
26
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
27
|
+
const child = node.namedChild(i);
|
|
28
|
+
if (child &&
|
|
29
|
+
(child.type === 'function_signature' ||
|
|
30
|
+
child.type === 'constructor_signature' ||
|
|
31
|
+
child.type === 'getter_signature' ||
|
|
32
|
+
child.type === 'setter_signature' ||
|
|
33
|
+
child.type === 'operator_signature' ||
|
|
34
|
+
child.type === 'factory_constructor_signature')) {
|
|
35
|
+
return child;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// `declaration` nodes (abstract methods) also wrap function_signature as a
|
|
39
|
+
// named child — handled by the loop above.
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Extract the method name from a method_signature node.
|
|
44
|
+
*
|
|
45
|
+
* Descends into the inner signature to find the name field/identifier.
|
|
46
|
+
*/
|
|
47
|
+
function extractDartName(node) {
|
|
48
|
+
const inner = getInnerSignature(node);
|
|
49
|
+
if (!inner)
|
|
50
|
+
return undefined;
|
|
51
|
+
// constructor_signature name field may include "ClassName.namedCtor" via multiple children.
|
|
52
|
+
// getter_signature, setter_signature, function_signature all have a 'name' field.
|
|
53
|
+
if (inner.type === 'operator_signature') {
|
|
54
|
+
// operator_signature has no 'name' field; name is 'operator' + the operator symbol
|
|
55
|
+
for (let i = 0; i < inner.namedChildCount; i++) {
|
|
56
|
+
const child = inner.namedChild(i);
|
|
57
|
+
if (child?.type === 'binary_operator') {
|
|
58
|
+
return `operator ${child.text.trim()}`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Check for unnamed operator tokens like []= or ~
|
|
62
|
+
for (let i = 0; i < inner.childCount; i++) {
|
|
63
|
+
const child = inner.child(i);
|
|
64
|
+
if (child && !child.isNamed && child.text.trim() !== 'operator') {
|
|
65
|
+
const text = child.text.trim();
|
|
66
|
+
if (text && !TYPE_NODE_TYPES.has(child.type)) {
|
|
67
|
+
return `operator ${text}`;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
if (inner.type === 'getter_signature') {
|
|
74
|
+
const nameNode = inner.childForFieldName('name');
|
|
75
|
+
return nameNode?.text;
|
|
76
|
+
}
|
|
77
|
+
if (inner.type === 'setter_signature') {
|
|
78
|
+
const nameNode = inner.childForFieldName('name');
|
|
79
|
+
return nameNode ? `set ${nameNode.text}` : undefined;
|
|
80
|
+
}
|
|
81
|
+
if (inner.type === 'factory_constructor_signature') {
|
|
82
|
+
// Collect all identifier children to form "ClassName" or "ClassName.named"
|
|
83
|
+
const parts = [];
|
|
84
|
+
for (let i = 0; i < inner.childCount; i++) {
|
|
85
|
+
const child = inner.child(i);
|
|
86
|
+
if (child?.isNamed && child.type === 'identifier') {
|
|
87
|
+
parts.push(child.text);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return parts.length > 0 ? parts.join('.') : undefined;
|
|
91
|
+
}
|
|
92
|
+
// function_signature and constructor_signature both have a 'name' field
|
|
93
|
+
const nameNode = inner.childForFieldName('name');
|
|
94
|
+
if (nameNode) {
|
|
95
|
+
// constructor_signature: name field may be multiple identifiers joined by '.'
|
|
96
|
+
return nameNode.text;
|
|
97
|
+
}
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Extract the return type from the inner signature.
|
|
102
|
+
*
|
|
103
|
+
* function_signature children include type nodes before the name.
|
|
104
|
+
* getter_signature children include type nodes before 'get' keyword.
|
|
105
|
+
* constructor/setter signatures have no return type.
|
|
106
|
+
*/
|
|
107
|
+
function extractDartReturnType(node) {
|
|
108
|
+
const inner = getInnerSignature(node);
|
|
109
|
+
if (!inner)
|
|
110
|
+
return undefined;
|
|
111
|
+
// Constructors and setters have no return type
|
|
112
|
+
if (inner.type === 'constructor_signature' ||
|
|
113
|
+
inner.type === 'setter_signature' ||
|
|
114
|
+
inner.type === 'factory_constructor_signature') {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
// For function_signature, getter_signature, operator_signature:
|
|
118
|
+
// The type node is a named child before the name/operator
|
|
119
|
+
for (let i = 0; i < inner.namedChildCount; i++) {
|
|
120
|
+
const child = inner.namedChild(i);
|
|
121
|
+
if (child && TYPE_NODE_TYPES.has(child.type)) {
|
|
122
|
+
return child.text?.trim();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Extract parameters from the inner signature's formal_parameter_list.
|
|
129
|
+
*
|
|
130
|
+
* Dart parameters can be:
|
|
131
|
+
* - Positional required: `int x`
|
|
132
|
+
* - Optional positional: `[int? x]` — wrapped in optional_formal_parameters with '['
|
|
133
|
+
* - Optional named: `{int? x}` or `{required int x}` — wrapped in optional_formal_parameters with '{'
|
|
134
|
+
*/
|
|
135
|
+
function extractDartParameters(node) {
|
|
136
|
+
const inner = getInnerSignature(node);
|
|
137
|
+
if (!inner)
|
|
138
|
+
return [];
|
|
139
|
+
// getter_signature has no parameters
|
|
140
|
+
if (inner.type === 'getter_signature')
|
|
141
|
+
return [];
|
|
142
|
+
// Find formal_parameter_list — it's a child, not a field in function_signature
|
|
143
|
+
let paramList = null;
|
|
144
|
+
if (inner.type === 'constructor_signature' || inner.type === 'factory_constructor_signature') {
|
|
145
|
+
paramList = inner.childForFieldName('parameters');
|
|
146
|
+
}
|
|
147
|
+
if (!paramList) {
|
|
148
|
+
for (let i = 0; i < inner.namedChildCount; i++) {
|
|
149
|
+
const child = inner.namedChild(i);
|
|
150
|
+
if (child?.type === 'formal_parameter_list') {
|
|
151
|
+
paramList = child;
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (!paramList)
|
|
157
|
+
return [];
|
|
158
|
+
return extractParamsFromList(paramList, false);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Extract ParameterInfo entries from a formal_parameter_list or optional_formal_parameters node.
|
|
162
|
+
*/
|
|
163
|
+
function extractParamsFromList(listNode, isOptionalBlock) {
|
|
164
|
+
const params = [];
|
|
165
|
+
for (let i = 0; i < listNode.namedChildCount; i++) {
|
|
166
|
+
const child = listNode.namedChild(i);
|
|
167
|
+
if (!child)
|
|
168
|
+
continue;
|
|
169
|
+
if (child.type === 'formal_parameter') {
|
|
170
|
+
params.push(extractSingleParam(child, isOptionalBlock));
|
|
171
|
+
}
|
|
172
|
+
else if (child.type === 'optional_formal_parameters') {
|
|
173
|
+
// Determine if these are named ({}) or positional ([]) optional params
|
|
174
|
+
// by checking the surrounding delimiters
|
|
175
|
+
params.push(...extractParamsFromList(child, true));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return params;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Extract a single ParameterInfo from a formal_parameter node.
|
|
182
|
+
*/
|
|
183
|
+
function extractSingleParam(param, isOptionalBlock) {
|
|
184
|
+
const nameNode = param.childForFieldName('name');
|
|
185
|
+
const name = nameNode?.text ?? '<unknown>';
|
|
186
|
+
// Find the type node
|
|
187
|
+
let typeName = null;
|
|
188
|
+
let rawTypeName = null;
|
|
189
|
+
for (let i = 0; i < param.namedChildCount; i++) {
|
|
190
|
+
const child = param.namedChild(i);
|
|
191
|
+
if (child && TYPE_NODE_TYPES.has(child.type)) {
|
|
192
|
+
rawTypeName = child.text?.trim() ?? null;
|
|
193
|
+
typeName = extractSimpleTypeName(child) ?? rawTypeName;
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
// Also check type_identifier
|
|
197
|
+
if (child?.type === 'type_identifier') {
|
|
198
|
+
rawTypeName = child.text?.trim() ?? null;
|
|
199
|
+
typeName = rawTypeName;
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Check for 'required' keyword:
|
|
204
|
+
// 1. Among children of the param node itself
|
|
205
|
+
let hasRequired = false;
|
|
206
|
+
for (let i = 0; i < param.childCount; i++) {
|
|
207
|
+
const child = param.child(i);
|
|
208
|
+
if (child && child.text.trim() === 'required') {
|
|
209
|
+
hasRequired = true;
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// 2. In tree-sitter-dart, `required` may be an anonymous sibling token
|
|
214
|
+
// immediately preceding the formal_parameter inside optional_formal_parameters.
|
|
215
|
+
if (!hasRequired) {
|
|
216
|
+
let prev = param.previousSibling;
|
|
217
|
+
// Skip comma separators
|
|
218
|
+
while (prev && !prev.isNamed && prev.text.trim() === ',') {
|
|
219
|
+
prev = prev.previousSibling;
|
|
220
|
+
}
|
|
221
|
+
if (prev && !prev.isNamed && prev.text.trim() === 'required') {
|
|
222
|
+
hasRequired = true;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// A parameter is optional if it's inside an optional_formal_parameters block
|
|
226
|
+
// and does NOT have the 'required' keyword
|
|
227
|
+
const isOptional = isOptionalBlock && !hasRequired;
|
|
228
|
+
return {
|
|
229
|
+
name,
|
|
230
|
+
type: typeName,
|
|
231
|
+
rawType: rawTypeName,
|
|
232
|
+
isOptional,
|
|
233
|
+
isVariadic: false, // Dart has no variadic params
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Dart visibility: underscore prefix = private, else public.
|
|
238
|
+
*
|
|
239
|
+
* We resolve the name by descending into the inner signature.
|
|
240
|
+
*/
|
|
241
|
+
function extractDartVisibility(node) {
|
|
242
|
+
const name = extractDartName(node);
|
|
243
|
+
if (!name)
|
|
244
|
+
return 'public';
|
|
245
|
+
// Strip 'set ' or 'operator ' prefix to get the raw name
|
|
246
|
+
const rawName = name.startsWith('set ')
|
|
247
|
+
? name.slice(4)
|
|
248
|
+
: name.startsWith('operator ')
|
|
249
|
+
? name.slice(9)
|
|
250
|
+
: name;
|
|
251
|
+
return rawName.startsWith('_') ? 'private' : 'public';
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* In tree-sitter-dart, `static` is an anonymous child token of
|
|
255
|
+
* `method_signature` (or `declaration`), not a previous sibling.
|
|
256
|
+
*
|
|
257
|
+
* We check children first, then fall back to previous siblings for
|
|
258
|
+
* grammar variants.
|
|
259
|
+
*/
|
|
260
|
+
function isDartStatic(node) {
|
|
261
|
+
// In tree-sitter-dart, `static` is an anonymous child token of method_signature
|
|
262
|
+
// (or declaration), not a previous sibling.
|
|
263
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
264
|
+
const child = node.child(i);
|
|
265
|
+
if (child && !child.isNamed && child.text.trim() === 'static')
|
|
266
|
+
return true;
|
|
267
|
+
// Stop once we hit the inner signature — static always precedes it
|
|
268
|
+
if (child?.isNamed)
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
// Also check previous siblings (fallback for grammar variants)
|
|
272
|
+
let sibling = node.previousSibling;
|
|
273
|
+
while (sibling) {
|
|
274
|
+
if (sibling.isNamed && sibling.type !== 'annotation')
|
|
275
|
+
break;
|
|
276
|
+
if (!sibling.isNamed && sibling.text.trim() === 'static')
|
|
277
|
+
return true;
|
|
278
|
+
sibling = sibling.previousSibling;
|
|
279
|
+
}
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* A Dart method is abstract if it has no function_body sibling following it.
|
|
284
|
+
* In the tree-sitter grammar, function_body is a sibling of method_signature
|
|
285
|
+
* in class_body.
|
|
286
|
+
*/
|
|
287
|
+
function isDartAbstract(node, _ownerNode) {
|
|
288
|
+
// `declaration` nodes in class_body represent abstract methods (no body, followed by ';').
|
|
289
|
+
// Note: extension bodies cannot have abstract members in Dart, but `declaration` nodes
|
|
290
|
+
// do not appear in extension_body in practice since extensions must provide implementations.
|
|
291
|
+
if (node.type === 'declaration')
|
|
292
|
+
return true;
|
|
293
|
+
// For method_signature nodes, check if the next named sibling is a function_body
|
|
294
|
+
const next = node.nextNamedSibling;
|
|
295
|
+
return !next || next.type !== 'function_body';
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Check for `async`, `async*`, or `sync*` keyword in the function_body sibling.
|
|
299
|
+
* The keyword appears as an unnamed child of function_body, or
|
|
300
|
+
* as a sibling keyword before function_body.
|
|
301
|
+
*
|
|
302
|
+
* Dart has three async-like forms: `async` (Future), `async*` (Stream), `sync*` (Iterable).
|
|
303
|
+
* All three are treated as async for graph purposes.
|
|
304
|
+
*/
|
|
305
|
+
function isDartAsync(node) {
|
|
306
|
+
let sibling = node.nextSibling;
|
|
307
|
+
let limit = 3;
|
|
308
|
+
while (sibling && limit > 0) {
|
|
309
|
+
if (!sibling.isNamed) {
|
|
310
|
+
const text = sibling.text.trim();
|
|
311
|
+
if (text === 'async' || text === 'async*' || text === 'sync*')
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
if (sibling.isNamed && sibling.type === 'function_body') {
|
|
315
|
+
// Check first child of function_body for async/async*/sync*
|
|
316
|
+
for (let i = 0; i < sibling.childCount; i++) {
|
|
317
|
+
const child = sibling.child(i);
|
|
318
|
+
if (child) {
|
|
319
|
+
const text = child.text.trim();
|
|
320
|
+
if (text === 'async' || text === 'async*' || text === 'sync*')
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
// Stop at first substantial child
|
|
324
|
+
if (child?.isNamed)
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
sibling = sibling.nextSibling;
|
|
330
|
+
limit--;
|
|
331
|
+
}
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Extract annotations that appear as sibling nodes before the method_signature
|
|
336
|
+
* in class_body. Each annotation node is prefixed with '@'.
|
|
337
|
+
*/
|
|
338
|
+
function extractDartAnnotations(node) {
|
|
339
|
+
const annotations = [];
|
|
340
|
+
let sibling = node.previousNamedSibling;
|
|
341
|
+
while (sibling && sibling.type === 'annotation') {
|
|
342
|
+
// annotation node text already includes '@', e.g. "@override"
|
|
343
|
+
const text = sibling.text?.trim();
|
|
344
|
+
if (text) {
|
|
345
|
+
// Normalize: strip arguments from annotation if present, keep just the name
|
|
346
|
+
// e.g. "@deprecated" -> "@deprecated", "@JsonKey(name: 'id')" -> "@JsonKey"
|
|
347
|
+
const match = text.match(/^@(\w+)/);
|
|
348
|
+
if (match) {
|
|
349
|
+
annotations.unshift('@' + match[1]);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
annotations.unshift(text);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
sibling = sibling.previousNamedSibling;
|
|
356
|
+
}
|
|
357
|
+
return annotations;
|
|
358
|
+
}
|
|
359
|
+
// ---------------------------------------------------------------------------
|
|
360
|
+
// Dart config
|
|
361
|
+
// ---------------------------------------------------------------------------
|
|
362
|
+
export const dartMethodConfig = {
|
|
363
|
+
language: SupportedLanguages.Dart,
|
|
364
|
+
typeDeclarationNodes: ['class_definition', 'mixin_declaration', 'extension_declaration'],
|
|
365
|
+
methodNodeTypes: ['method_signature', 'declaration'],
|
|
366
|
+
bodyNodeTypes: ['class_body', 'extension_body'],
|
|
367
|
+
extractName: extractDartName,
|
|
368
|
+
extractReturnType: extractDartReturnType,
|
|
369
|
+
extractParameters: extractDartParameters,
|
|
370
|
+
extractVisibility: extractDartVisibility,
|
|
371
|
+
isStatic: isDartStatic,
|
|
372
|
+
isAbstract: isDartAbstract,
|
|
373
|
+
isFinal: () => false, // Dart methods cannot be 'final'
|
|
374
|
+
isAsync: isDartAsync,
|
|
375
|
+
extractAnnotations: extractDartAnnotations,
|
|
376
|
+
};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/method-extractors/configs/go.ts
|
|
2
|
+
// Verified against tree-sitter-go 0.23.4
|
|
3
|
+
import { SupportedLanguages } from '../../../../_shared/index.js';
|
|
4
|
+
import { extractSimpleTypeName } from '../../type-extractors/shared.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Go helpers
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
/**
|
|
9
|
+
* Extract the method/function name.
|
|
10
|
+
* - method_declaration: name is a `field_identifier`
|
|
11
|
+
* - function_declaration: name is an `identifier`
|
|
12
|
+
*/
|
|
13
|
+
function extractGoName(node) {
|
|
14
|
+
const nameNode = node.childForFieldName('name');
|
|
15
|
+
return nameNode?.text;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Extract return type from the `result` field.
|
|
19
|
+
*
|
|
20
|
+
* Go supports single return (`int`) and multi-return (`(User, error)`).
|
|
21
|
+
* Multi-return appears as a `parameter_list` — extract the first type.
|
|
22
|
+
*/
|
|
23
|
+
function extractGoReturnType(node) {
|
|
24
|
+
const result = node.childForFieldName('result');
|
|
25
|
+
if (!result)
|
|
26
|
+
return undefined;
|
|
27
|
+
// Single return type (type_identifier, pointer_type, etc.)
|
|
28
|
+
if (result.type !== 'parameter_list') {
|
|
29
|
+
return result.text?.trim();
|
|
30
|
+
}
|
|
31
|
+
// Multi-return: (Type, error) — extract first parameter's type
|
|
32
|
+
for (let i = 0; i < result.namedChildCount; i++) {
|
|
33
|
+
const param = result.namedChild(i);
|
|
34
|
+
if (param?.type === 'parameter_declaration') {
|
|
35
|
+
const typeNode = param.childForFieldName('type');
|
|
36
|
+
if (typeNode)
|
|
37
|
+
return typeNode.text?.trim();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Extract parameters from the `parameters` field.
|
|
44
|
+
*
|
|
45
|
+
* Go parameter_list contains parameter_declaration nodes with optional
|
|
46
|
+
* `name` and required `type` fields. Go allows multiple names for one type:
|
|
47
|
+
* `func(a, b int)` — each name shares the type.
|
|
48
|
+
*
|
|
49
|
+
* Handles variadic_parameter_declaration (`...string`).
|
|
50
|
+
*/
|
|
51
|
+
function extractGoParameters(node) {
|
|
52
|
+
const paramList = node.childForFieldName('parameters');
|
|
53
|
+
if (!paramList)
|
|
54
|
+
return [];
|
|
55
|
+
const params = [];
|
|
56
|
+
for (let i = 0; i < paramList.namedChildCount; i++) {
|
|
57
|
+
const param = paramList.namedChild(i);
|
|
58
|
+
if (!param)
|
|
59
|
+
continue;
|
|
60
|
+
if (param.type === 'parameter_declaration') {
|
|
61
|
+
const typeNode = param.childForFieldName('type');
|
|
62
|
+
const typeName = typeNode
|
|
63
|
+
? (extractSimpleTypeName(typeNode) ?? typeNode.text?.trim() ?? null)
|
|
64
|
+
: null;
|
|
65
|
+
// Go allows multiple names for one type: func(a, b int)
|
|
66
|
+
const names = [];
|
|
67
|
+
for (let j = 0; j < param.namedChildCount; j++) {
|
|
68
|
+
const child = param.namedChild(j);
|
|
69
|
+
if (child?.type === 'identifier') {
|
|
70
|
+
names.push(child.text);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const rawType = typeNode?.text?.trim() ?? null;
|
|
74
|
+
if (names.length === 0) {
|
|
75
|
+
// Unnamed parameter: func(int, string)
|
|
76
|
+
params.push({
|
|
77
|
+
name: `_${i}`,
|
|
78
|
+
type: typeName,
|
|
79
|
+
rawType,
|
|
80
|
+
isOptional: false,
|
|
81
|
+
isVariadic: false,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
for (const name of names) {
|
|
86
|
+
params.push({ name, type: typeName, rawType, isOptional: false, isVariadic: false });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else if (param.type === 'variadic_parameter_declaration') {
|
|
91
|
+
const nameNode = param.childForFieldName('name');
|
|
92
|
+
const typeNode = param.childForFieldName('type');
|
|
93
|
+
const typeName = typeNode
|
|
94
|
+
? (extractSimpleTypeName(typeNode) ?? typeNode.text?.trim() ?? null)
|
|
95
|
+
: null;
|
|
96
|
+
params.push({
|
|
97
|
+
name: nameNode?.text ?? `_${i}`,
|
|
98
|
+
type: typeName,
|
|
99
|
+
rawType: typeNode?.text?.trim() ?? null,
|
|
100
|
+
isOptional: false,
|
|
101
|
+
isVariadic: true,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return params;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Go visibility: uppercase first character = exported (public), lowercase = unexported (private).
|
|
109
|
+
*/
|
|
110
|
+
function extractGoVisibility(node) {
|
|
111
|
+
const name = extractGoName(node);
|
|
112
|
+
if (!name || name.length === 0)
|
|
113
|
+
return 'private';
|
|
114
|
+
const first = name[0];
|
|
115
|
+
return first === first.toUpperCase() && first !== first.toLowerCase() ? 'public' : 'private';
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Extract receiver type from the `receiver` field.
|
|
119
|
+
*
|
|
120
|
+
* The receiver is a parameter_list with one parameter_declaration:
|
|
121
|
+
* (r *Repo) → pointer_type → type_identifier "Repo"
|
|
122
|
+
* (r Repo) → type_identifier "Repo"
|
|
123
|
+
*/
|
|
124
|
+
function extractGoReceiverType(node) {
|
|
125
|
+
const receiver = node.childForFieldName('receiver');
|
|
126
|
+
if (!receiver)
|
|
127
|
+
return undefined;
|
|
128
|
+
for (let i = 0; i < receiver.namedChildCount; i++) {
|
|
129
|
+
const param = receiver.namedChild(i);
|
|
130
|
+
if (param?.type === 'parameter_declaration') {
|
|
131
|
+
const typeNode = param.childForFieldName('type');
|
|
132
|
+
if (!typeNode)
|
|
133
|
+
continue;
|
|
134
|
+
// Unwrap pointer_type: *User → User
|
|
135
|
+
const inner = typeNode.type === 'pointer_type' ? typeNode.firstNamedChild : typeNode;
|
|
136
|
+
return inner?.text;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Resolve owner name from the receiver type.
|
|
143
|
+
* For function_declaration (no receiver), returns undefined.
|
|
144
|
+
*/
|
|
145
|
+
function extractGoOwnerName(node) {
|
|
146
|
+
return extractGoReceiverType(node);
|
|
147
|
+
}
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
// Config
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
export const goMethodConfig = {
|
|
152
|
+
language: SupportedLanguages.Go,
|
|
153
|
+
// Each method_declaration/function_declaration is treated as its own "container"
|
|
154
|
+
// for extractFromNode() — not used with extract() in the traditional sense.
|
|
155
|
+
// method_elem covers interface method signatures (abstract methods).
|
|
156
|
+
typeDeclarationNodes: ['method_declaration', 'function_declaration', 'method_elem'],
|
|
157
|
+
methodNodeTypes: ['method_declaration', 'function_declaration', 'method_elem'],
|
|
158
|
+
bodyNodeTypes: [],
|
|
159
|
+
extractName: extractGoName,
|
|
160
|
+
extractReturnType: extractGoReturnType,
|
|
161
|
+
extractParameters: extractGoParameters,
|
|
162
|
+
extractVisibility: extractGoVisibility,
|
|
163
|
+
extractReceiverType: extractGoReceiverType,
|
|
164
|
+
extractOwnerName: extractGoOwnerName,
|
|
165
|
+
isStatic(node) {
|
|
166
|
+
// Go functions (no receiver) are effectively static
|
|
167
|
+
return node.type === 'function_declaration';
|
|
168
|
+
},
|
|
169
|
+
isAbstract(node, _ownerNode) {
|
|
170
|
+
// Go interface method signatures (method_elem) are abstract — no body
|
|
171
|
+
return node.type === 'method_elem';
|
|
172
|
+
},
|
|
173
|
+
isFinal(_node) {
|
|
174
|
+
return false; // Go has no final methods
|
|
175
|
+
},
|
|
176
|
+
};
|
|
@@ -10,7 +10,9 @@ function extractReturnTypeFromField(node) {
|
|
|
10
10
|
const typeNode = node.childForFieldName('type');
|
|
11
11
|
if (!typeNode)
|
|
12
12
|
return undefined;
|
|
13
|
-
|
|
13
|
+
// Use .text to preserve full generic types (e.g. List<User>, Stream<T>)
|
|
14
|
+
// needed by the call resolver for return-type inference.
|
|
15
|
+
return typeNode.text?.trim();
|
|
14
16
|
}
|
|
15
17
|
function extractAnnotations(node, modifierType) {
|
|
16
18
|
const annotations = [];
|
|
@@ -56,6 +58,7 @@ function extractJavaParameters(node) {
|
|
|
56
58
|
params.push({
|
|
57
59
|
name: nameNode.text,
|
|
58
60
|
type: typeNode ? (extractSimpleTypeName(typeNode) ?? typeNode.text?.trim()) : null,
|
|
61
|
+
rawType: typeNode?.text?.trim() ?? null,
|
|
59
62
|
isOptional: false,
|
|
60
63
|
isVariadic: false,
|
|
61
64
|
});
|
|
@@ -65,6 +68,7 @@ function extractJavaParameters(node) {
|
|
|
65
68
|
// Varargs: type_identifier + "..." + variable_declarator
|
|
66
69
|
let paramName;
|
|
67
70
|
let paramType = null;
|
|
71
|
+
let paramRawType = null;
|
|
68
72
|
for (let j = 0; j < param.namedChildCount; j++) {
|
|
69
73
|
const c = param.namedChild(j);
|
|
70
74
|
if (!c)
|
|
@@ -79,13 +83,15 @@ function extractJavaParameters(node) {
|
|
|
79
83
|
c.type === 'integral_type' ||
|
|
80
84
|
c.type === 'floating_point_type' ||
|
|
81
85
|
c.type === 'boolean_type') {
|
|
82
|
-
|
|
86
|
+
paramRawType = c.text?.trim() ?? null;
|
|
87
|
+
paramType = extractSimpleTypeName(c) ?? paramRawType;
|
|
83
88
|
}
|
|
84
89
|
}
|
|
85
90
|
if (paramName) {
|
|
86
91
|
params.push({
|
|
87
92
|
name: paramName,
|
|
88
93
|
type: paramType,
|
|
94
|
+
rawType: paramRawType,
|
|
89
95
|
isOptional: false,
|
|
90
96
|
isVariadic: true,
|
|
91
97
|
});
|
|
@@ -173,6 +179,7 @@ function extractKotlinParameters(node) {
|
|
|
173
179
|
continue;
|
|
174
180
|
let paramName;
|
|
175
181
|
let paramType = null;
|
|
182
|
+
let paramRawType = null;
|
|
176
183
|
let hasDefault = false;
|
|
177
184
|
const isVariadic = nextIsVariadic;
|
|
178
185
|
nextIsVariadic = false;
|
|
@@ -186,7 +193,8 @@ function extractKotlinParameters(node) {
|
|
|
186
193
|
else if (part.type === 'user_type' ||
|
|
187
194
|
part.type === 'nullable_type' ||
|
|
188
195
|
part.type === 'function_type') {
|
|
189
|
-
|
|
196
|
+
paramRawType = part.text?.trim() ?? null;
|
|
197
|
+
paramType = extractSimpleTypeName(part) ?? paramRawType;
|
|
190
198
|
}
|
|
191
199
|
}
|
|
192
200
|
// Check for default value: `= expr`
|
|
@@ -201,6 +209,7 @@ function extractKotlinParameters(node) {
|
|
|
201
209
|
params.push({
|
|
202
210
|
name: paramName,
|
|
203
211
|
type: paramType,
|
|
212
|
+
rawType: paramRawType,
|
|
204
213
|
isOptional: hasDefault,
|
|
205
214
|
isVariadic: isVariadic,
|
|
206
215
|
});
|
|
@@ -227,7 +236,7 @@ function extractKotlinReturnType(node) {
|
|
|
227
236
|
(child.type === 'user_type' ||
|
|
228
237
|
child.type === 'nullable_type' ||
|
|
229
238
|
child.type === 'function_type')) {
|
|
230
|
-
return
|
|
239
|
+
return child.text?.trim();
|
|
231
240
|
}
|
|
232
241
|
if (child.type === 'function_body')
|
|
233
242
|
break;
|