gitnexus 1.5.2 → 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.
Files changed (207) hide show
  1. package/README.md +10 -0
  2. package/dist/_shared/graph/types.d.ts +1 -1
  3. package/dist/_shared/graph/types.d.ts.map +1 -1
  4. package/dist/_shared/index.d.ts +1 -0
  5. package/dist/_shared/index.d.ts.map +1 -1
  6. package/dist/_shared/language-detection.d.ts.map +1 -1
  7. package/dist/_shared/language-detection.js +2 -0
  8. package/dist/_shared/language-detection.js.map +1 -1
  9. package/dist/_shared/languages.d.ts +1 -0
  10. package/dist/_shared/languages.d.ts.map +1 -1
  11. package/dist/_shared/languages.js +1 -0
  12. package/dist/_shared/languages.js.map +1 -1
  13. package/dist/_shared/lbug/schema-constants.d.ts +1 -1
  14. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  15. package/dist/_shared/lbug/schema-constants.js +3 -1
  16. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  17. package/dist/_shared/mro-strategy.d.ts +19 -0
  18. package/dist/_shared/mro-strategy.d.ts.map +1 -0
  19. package/dist/_shared/mro-strategy.js +2 -0
  20. package/dist/_shared/mro-strategy.js.map +1 -0
  21. package/dist/cli/ai-context.d.ts +1 -0
  22. package/dist/cli/ai-context.js +28 -4
  23. package/dist/cli/analyze.d.ts +2 -0
  24. package/dist/cli/analyze.js +2 -1
  25. package/dist/cli/group.d.ts +2 -0
  26. package/dist/cli/group.js +233 -0
  27. package/dist/cli/index.js +3 -0
  28. package/dist/cli/serve.js +4 -1
  29. package/dist/cli/setup.js +34 -3
  30. package/dist/cli/wiki.js +15 -44
  31. package/dist/config/ignore-service.js +8 -3
  32. package/dist/core/augmentation/engine.js +1 -1
  33. package/dist/core/git-staleness.d.ts +13 -0
  34. package/dist/core/git-staleness.js +29 -0
  35. package/dist/core/group/bridge-db.d.ts +82 -0
  36. package/dist/core/group/bridge-db.js +460 -0
  37. package/dist/core/group/bridge-schema.d.ts +27 -0
  38. package/dist/core/group/bridge-schema.js +55 -0
  39. package/dist/core/group/config-parser.d.ts +3 -0
  40. package/dist/core/group/config-parser.js +83 -0
  41. package/dist/core/group/contract-extractor.d.ts +7 -0
  42. package/dist/core/group/contract-extractor.js +1 -0
  43. package/dist/core/group/extractors/grpc-extractor.d.ts +16 -0
  44. package/dist/core/group/extractors/grpc-extractor.js +264 -0
  45. package/dist/core/group/extractors/http-route-extractor.d.ts +24 -0
  46. package/dist/core/group/extractors/http-route-extractor.js +428 -0
  47. package/dist/core/group/extractors/topic-extractor.d.ts +9 -0
  48. package/dist/core/group/extractors/topic-extractor.js +234 -0
  49. package/dist/core/group/matching.d.ts +13 -0
  50. package/dist/core/group/matching.js +198 -0
  51. package/dist/core/group/normalization.d.ts +3 -0
  52. package/dist/core/group/normalization.js +115 -0
  53. package/dist/core/group/service-boundary-detector.d.ts +8 -0
  54. package/dist/core/group/service-boundary-detector.js +155 -0
  55. package/dist/core/group/service.d.ts +46 -0
  56. package/dist/core/group/service.js +160 -0
  57. package/dist/core/group/storage.d.ts +9 -0
  58. package/dist/core/group/storage.js +91 -0
  59. package/dist/core/group/sync.d.ts +21 -0
  60. package/dist/core/group/sync.js +148 -0
  61. package/dist/core/group/types.d.ts +130 -0
  62. package/dist/core/group/types.js +1 -0
  63. package/dist/core/ingestion/binding-accumulator.d.ts +207 -0
  64. package/dist/core/ingestion/binding-accumulator.js +332 -0
  65. package/dist/core/ingestion/call-processor.d.ts +155 -24
  66. package/dist/core/ingestion/call-processor.js +1129 -247
  67. package/dist/core/ingestion/class-extractors/generic.d.ts +2 -0
  68. package/dist/core/ingestion/class-extractors/generic.js +135 -0
  69. package/dist/core/ingestion/class-types.d.ts +34 -0
  70. package/dist/core/ingestion/class-types.js +1 -0
  71. package/dist/core/ingestion/entry-point-scoring.d.ts +1 -0
  72. package/dist/core/ingestion/entry-point-scoring.js +1 -0
  73. package/dist/core/ingestion/field-extractors/configs/helpers.d.ts +5 -1
  74. package/dist/core/ingestion/field-extractors/configs/helpers.js +13 -3
  75. package/dist/core/ingestion/field-types.d.ts +2 -2
  76. package/dist/core/ingestion/filesystem-walker.js +8 -0
  77. package/dist/core/ingestion/framework-detection.d.ts +1 -0
  78. package/dist/core/ingestion/framework-detection.js +1 -0
  79. package/dist/core/ingestion/heritage-processor.d.ts +8 -15
  80. package/dist/core/ingestion/heritage-processor.js +15 -28
  81. package/dist/core/ingestion/import-processor.d.ts +1 -11
  82. package/dist/core/ingestion/import-processor.js +0 -12
  83. package/dist/core/ingestion/import-resolvers/utils.js +1 -0
  84. package/dist/core/ingestion/import-resolvers/vue.d.ts +8 -0
  85. package/dist/core/ingestion/import-resolvers/vue.js +9 -0
  86. package/dist/core/ingestion/language-provider.d.ts +6 -3
  87. package/dist/core/ingestion/languages/c-cpp.js +168 -1
  88. package/dist/core/ingestion/languages/csharp.js +20 -0
  89. package/dist/core/ingestion/languages/dart.js +26 -4
  90. package/dist/core/ingestion/languages/go.js +22 -0
  91. package/dist/core/ingestion/languages/index.d.ts +1 -0
  92. package/dist/core/ingestion/languages/index.js +2 -0
  93. package/dist/core/ingestion/languages/java.js +17 -0
  94. package/dist/core/ingestion/languages/kotlin.js +24 -1
  95. package/dist/core/ingestion/languages/php.js +23 -11
  96. package/dist/core/ingestion/languages/python.js +9 -0
  97. package/dist/core/ingestion/languages/ruby.js +28 -0
  98. package/dist/core/ingestion/languages/rust.js +38 -0
  99. package/dist/core/ingestion/languages/swift.js +31 -0
  100. package/dist/core/ingestion/languages/typescript.d.ts +1 -0
  101. package/dist/core/ingestion/languages/typescript.js +54 -1
  102. package/dist/core/ingestion/languages/vue.d.ts +13 -0
  103. package/dist/core/ingestion/languages/vue.js +81 -0
  104. package/dist/core/ingestion/method-extractors/configs/c-cpp.d.ts +3 -0
  105. package/dist/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
  106. package/dist/core/ingestion/method-extractors/configs/csharp.js +5 -1
  107. package/dist/core/ingestion/method-extractors/configs/dart.d.ts +2 -0
  108. package/dist/core/ingestion/method-extractors/configs/dart.js +376 -0
  109. package/dist/core/ingestion/method-extractors/configs/go.d.ts +2 -0
  110. package/dist/core/ingestion/method-extractors/configs/go.js +176 -0
  111. package/dist/core/ingestion/method-extractors/configs/jvm.js +13 -4
  112. package/dist/core/ingestion/method-extractors/configs/php.d.ts +2 -0
  113. package/dist/core/ingestion/method-extractors/configs/php.js +304 -0
  114. package/dist/core/ingestion/method-extractors/configs/python.d.ts +2 -0
  115. package/dist/core/ingestion/method-extractors/configs/python.js +309 -0
  116. package/dist/core/ingestion/method-extractors/configs/ruby.d.ts +2 -0
  117. package/dist/core/ingestion/method-extractors/configs/ruby.js +285 -0
  118. package/dist/core/ingestion/method-extractors/configs/rust.d.ts +2 -0
  119. package/dist/core/ingestion/method-extractors/configs/rust.js +195 -0
  120. package/dist/core/ingestion/method-extractors/configs/swift.d.ts +2 -0
  121. package/dist/core/ingestion/method-extractors/configs/swift.js +277 -0
  122. package/dist/core/ingestion/method-extractors/configs/typescript-javascript.d.ts +3 -0
  123. package/dist/core/ingestion/method-extractors/configs/typescript-javascript.js +338 -0
  124. package/dist/core/ingestion/method-extractors/generic.js +38 -15
  125. package/dist/core/ingestion/method-types.d.ts +25 -0
  126. package/dist/core/ingestion/model/field-registry.d.ts +18 -0
  127. package/dist/core/ingestion/model/field-registry.js +22 -0
  128. package/dist/core/ingestion/model/heritage-map.d.ts +70 -0
  129. package/dist/core/ingestion/model/heritage-map.js +159 -0
  130. package/dist/core/ingestion/model/index.d.ts +20 -0
  131. package/dist/core/ingestion/model/index.js +41 -0
  132. package/dist/core/ingestion/model/method-registry.d.ts +62 -0
  133. package/dist/core/ingestion/model/method-registry.js +130 -0
  134. package/dist/core/ingestion/model/registration-table.d.ts +139 -0
  135. package/dist/core/ingestion/model/registration-table.js +224 -0
  136. package/dist/core/ingestion/model/resolution-context.d.ts +93 -0
  137. package/dist/core/ingestion/model/resolution-context.js +337 -0
  138. package/dist/core/ingestion/model/resolve.d.ts +56 -0
  139. package/dist/core/ingestion/model/resolve.js +242 -0
  140. package/dist/core/ingestion/model/semantic-model.d.ts +86 -0
  141. package/dist/core/ingestion/model/semantic-model.js +120 -0
  142. package/dist/core/ingestion/model/symbol-table.d.ts +222 -0
  143. package/dist/core/ingestion/model/symbol-table.js +206 -0
  144. package/dist/core/ingestion/model/type-registry.d.ts +39 -0
  145. package/dist/core/ingestion/model/type-registry.js +62 -0
  146. package/dist/core/ingestion/mro-processor.d.ts +4 -3
  147. package/dist/core/ingestion/mro-processor.js +310 -106
  148. package/dist/core/ingestion/parsing-processor.d.ts +5 -4
  149. package/dist/core/ingestion/parsing-processor.js +210 -85
  150. package/dist/core/ingestion/pipeline.d.ts +2 -0
  151. package/dist/core/ingestion/pipeline.js +192 -68
  152. package/dist/core/ingestion/tree-sitter-queries.d.ts +6 -6
  153. package/dist/core/ingestion/tree-sitter-queries.js +37 -0
  154. package/dist/core/ingestion/type-env.d.ts +15 -2
  155. package/dist/core/ingestion/type-env.js +163 -102
  156. package/dist/core/ingestion/type-extractors/csharp.js +17 -0
  157. package/dist/core/ingestion/type-extractors/jvm.js +11 -0
  158. package/dist/core/ingestion/type-extractors/php.js +0 -55
  159. package/dist/core/ingestion/type-extractors/ruby.js +0 -32
  160. package/dist/core/ingestion/type-extractors/swift.js +13 -0
  161. package/dist/core/ingestion/type-extractors/types.d.ts +8 -8
  162. package/dist/core/ingestion/type-extractors/typescript.js +66 -69
  163. package/dist/core/ingestion/utils/ast-helpers.d.ts +33 -43
  164. package/dist/core/ingestion/utils/ast-helpers.js +129 -565
  165. package/dist/core/ingestion/utils/method-props.d.ts +32 -0
  166. package/dist/core/ingestion/utils/method-props.js +147 -0
  167. package/dist/core/ingestion/vue-sfc-extractor.d.ts +44 -0
  168. package/dist/core/ingestion/vue-sfc-extractor.js +94 -0
  169. package/dist/core/ingestion/workers/parse-worker.d.ts +31 -19
  170. package/dist/core/ingestion/workers/parse-worker.js +463 -198
  171. package/dist/core/lbug/lbug-adapter.d.ts +6 -0
  172. package/dist/core/lbug/lbug-adapter.js +68 -3
  173. package/dist/core/lbug/pool-adapter.d.ts +76 -0
  174. package/dist/core/lbug/pool-adapter.js +522 -0
  175. package/dist/core/run-analyze.d.ts +2 -0
  176. package/dist/core/run-analyze.js +1 -1
  177. package/dist/core/search/bm25-index.js +1 -1
  178. package/dist/core/tree-sitter/parser-loader.js +1 -0
  179. package/dist/core/wiki/graph-queries.js +1 -1
  180. package/dist/core/wiki/html-viewer.js +6 -4
  181. package/dist/core/wiki/llm-client.js +4 -6
  182. package/dist/mcp/core/embedder.js +6 -5
  183. package/dist/mcp/core/lbug-adapter.d.ts +3 -63
  184. package/dist/mcp/core/lbug-adapter.js +3 -484
  185. package/dist/mcp/local/local-backend.d.ts +31 -2
  186. package/dist/mcp/local/local-backend.js +255 -46
  187. package/dist/mcp/resources.js +5 -4
  188. package/dist/mcp/staleness.d.ts +3 -13
  189. package/dist/mcp/staleness.js +2 -31
  190. package/dist/mcp/tools.js +80 -4
  191. package/dist/server/analyze-job.d.ts +2 -0
  192. package/dist/server/analyze-job.js +4 -0
  193. package/dist/server/api.d.ts +20 -1
  194. package/dist/server/api.js +306 -71
  195. package/dist/server/git-clone.d.ts +2 -1
  196. package/dist/server/git-clone.js +98 -5
  197. package/dist/storage/git.d.ts +13 -0
  198. package/dist/storage/git.js +25 -0
  199. package/dist/storage/repo-manager.js +1 -1
  200. package/package.json +8 -2
  201. package/scripts/patch-tree-sitter-swift.cjs +78 -0
  202. package/dist/core/ingestion/named-binding-processor.d.ts +0 -18
  203. package/dist/core/ingestion/named-binding-processor.js +0 -42
  204. package/dist/core/ingestion/resolution-context.d.ts +0 -58
  205. package/dist/core/ingestion/resolution-context.js +0 -135
  206. package/dist/core/ingestion/symbol-table.d.ts +0 -79
  207. package/dist/core/ingestion/symbol-table.js +0 -115
@@ -3,6 +3,10 @@ import type { SyntaxNode } from '../utils/ast-helpers.js';
3
3
  export type TypeBindingExtractor = (node: SyntaxNode, env: Map<string, string>) => void;
4
4
  /** Extracts type bindings from a parameter node into the env map */
5
5
  export type ParameterExtractor = (node: SyntaxNode, env: Map<string, string>) => void;
6
+ /** Optionally locates the type-annotation AST node for a declaration node.
7
+ * Used by buildTypeEnv to populate declarationTypeNodes and constructorTypeMap.
8
+ * If absent, buildTypeEnv falls back to generic heuristics (childForFieldName('type'), etc). */
9
+ export type DeclarationTypeNodeLocator = (node: SyntaxNode) => SyntaxNode | null;
6
10
  /** Minimal interface for checking whether a name is a known class/struct.
7
11
  * Narrower than ReadonlySet — only `.has()` is used by extractors. */
8
12
  export type ClassNameLookup = {
@@ -19,10 +23,6 @@ export type ConstructorBindingScanner = (node: SyntaxNode) => {
19
23
  calleeName: string;
20
24
  receiverClassName?: string;
21
25
  } | undefined;
22
- /** Extracts a return type string from a method/function definition node.
23
- * Used for languages where return types are expressed in comments (e.g. YARD @return [Type])
24
- * rather than in AST fields. Returns undefined if no return type can be determined. */
25
- export type ReturnTypeExtractor = (node: SyntaxNode) => string | undefined;
26
26
  /** Infer the type name of a literal AST node for overload disambiguation.
27
27
  * Returns the canonical type name (e.g. 'int', 'String', 'boolean') or undefined
28
28
  * for non-literal nodes. Only used when resolveCallTarget has multiple candidates
@@ -38,7 +38,7 @@ export type ConstructorTypeDetector = (node: SyntaxNode, classNames: ClassNameLo
38
38
  * E.g., C++ shared_ptr<Animal> → Animal. Returns undefined if no unwrapping applies. */
39
39
  export type DeclaredTypeUnwrapper = (declaredType: string, typeNode: SyntaxNode) => string | undefined;
40
40
  /** Narrow lookup interface for resolving a callee name → return type name.
41
- * Backed by SymbolTable.lookupFuzzyCallable; passed via ForLoopExtractorContext.
41
+ * Backed by SymbolTable.lookupCallableByName; passed via ForLoopExtractorContext.
42
42
  * Conservative: returns undefined when the callee is ambiguous (0 or 2+ matches). */
43
43
  export interface ReturnTypeLookup {
44
44
  /** Processed type name after stripping wrappers (e.g., 'User' from 'Promise<User>').
@@ -130,6 +130,9 @@ export interface LanguageTypeConfig {
130
130
  readonly allowPatternBindingOverwrite?: boolean;
131
131
  /** Node types that represent typed declarations for this language */
132
132
  declarationNodeTypes: ReadonlySet<string>;
133
+ /** Optional: language-specific way to find a declaration's type-annotation node.
134
+ * Prefer providing this for grammars where the type is wrapped (e.g., C#, Kotlin, Swift). */
135
+ getDeclarationTypeNode?: DeclarationTypeNodeLocator;
133
136
  /** AST node types for for-each/for-in statements with explicit element types. */
134
137
  forLoopNodeTypes?: ReadonlySet<string>;
135
138
  /** Optional allowlist of AST node types on which extractPatternBinding should run.
@@ -150,9 +153,6 @@ export interface LanguageTypeConfig {
150
153
  * Called on every AST node during buildTypeEnv walk; returns undefined for non-matches.
151
154
  * The callee binding is unverified — the caller must confirm against the SymbolTable. */
152
155
  scanConstructorBinding?: ConstructorBindingScanner;
153
- /** Extract return type from comment-based annotations (e.g. YARD @return [Type]).
154
- * Called as fallback when extractMethodSignature finds no AST-based return type. */
155
- extractReturnType?: ReturnTypeExtractor;
156
156
  /** Extract loop variable → type binding from a for-each AST node. */
157
157
  extractForLoopBinding?: ForLoopExtractor;
158
158
  /** Extract pending assignment for Tier 2 propagation.
@@ -179,48 +179,6 @@ const scanConstructorBinding = (node) => {
179
179
  return undefined;
180
180
  return { varName: nameNode.text, calleeName };
181
181
  };
182
- /** Regex to extract @returns or @return from JSDoc comments: `@returns {Type}` */
183
- const JSDOC_RETURN_RE = /@returns?\s*\{([^}]+)\}/;
184
- /**
185
- * Minimal sanitization for JSDoc return types — preserves generic wrappers
186
- * (e.g. `Promise<User>`) so that extractReturnTypeName in call-processor
187
- * can apply WRAPPER_GENERICS unwrapping. Unlike normalizeJsDocType (which
188
- * strips generics), this only strips JSDoc-specific syntax markers.
189
- */
190
- const sanitizeReturnType = (raw) => {
191
- let type = raw.trim();
192
- // Strip JSDoc nullable/non-nullable prefixes: ?User → User, !User → User
193
- if (type.startsWith('?') || type.startsWith('!'))
194
- type = type.slice(1);
195
- // Strip module: prefix — module:models.User → models.User
196
- if (type.startsWith('module:'))
197
- type = type.slice(7);
198
- // Reject unions (ambiguous)
199
- if (type.includes('|'))
200
- return undefined;
201
- if (!type)
202
- return undefined;
203
- return type;
204
- };
205
- /**
206
- * Extract return type from JSDoc `@returns {Type}` or `@return {Type}` annotation
207
- * preceding a function/method definition. Walks backwards through preceding siblings
208
- * looking for comment nodes containing the annotation.
209
- */
210
- const extractReturnType = (node) => {
211
- let sibling = node.previousSibling;
212
- while (sibling) {
213
- if (sibling.type === 'comment') {
214
- const match = JSDOC_RETURN_RE.exec(sibling.text);
215
- if (match)
216
- return sanitizeReturnType(match[1]);
217
- }
218
- else if (sibling.isNamed && sibling.type !== 'decorator')
219
- break;
220
- sibling = sibling.previousSibling;
221
- }
222
- return undefined;
223
- };
224
182
  const FOR_LOOP_NODE_TYPES = new Set(['for_in_statement']);
225
183
  /** TS function/method node types that carry a parameters list. */
226
184
  const TS_FUNCTION_NODE_TYPES = new Set([
@@ -448,8 +406,37 @@ const extractForLoopBinding = (node, { scopeEnv, declarationTypeNodes, scope, re
448
406
  if (loopVarName)
449
407
  scopeEnv.set(loopVarName, elementType);
450
408
  };
409
+ /** Collect fieldAccess items from an object_pattern's destructured properties. */
410
+ const collectDestructuredFields = (nameNode, receiver, scopeEnv) => {
411
+ const items = [];
412
+ for (let j = 0; j < nameNode.namedChildCount; j++) {
413
+ const prop = nameNode.namedChild(j);
414
+ if (!prop)
415
+ continue;
416
+ if (prop.type === 'shorthand_property_identifier_pattern') {
417
+ // `const { name } = obj` → shorthand: varName = fieldName
418
+ const varName = prop.text;
419
+ if (!scopeEnv.has(varName)) {
420
+ items.push({ kind: 'fieldAccess', lhs: varName, receiver, field: varName });
421
+ }
422
+ }
423
+ else if (prop.type === 'pair_pattern') {
424
+ // `const { address: addr } = obj` → pair_pattern: key=field, value=varName
425
+ const keyNode = prop.childForFieldName('key');
426
+ const valNode = prop.childForFieldName('value');
427
+ if (keyNode && valNode) {
428
+ const fieldName = keyNode.text;
429
+ const varName = valNode.text;
430
+ if (!scopeEnv.has(varName)) {
431
+ items.push({ kind: 'fieldAccess', lhs: varName, receiver, field: fieldName });
432
+ }
433
+ }
434
+ }
435
+ }
436
+ return items;
437
+ };
451
438
  /** TS/JS: const alias = u → variable_declarator with name/value fields.
452
- * Also handles destructuring: `const { a, b } = obj` → N fieldAccess items. */
439
+ * Also handles destructuring: `const { a, b } = obj` and `const { a } = fn()` → N fieldAccess items. */
453
440
  const extractPendingAssignment = (node, scopeEnv) => {
454
441
  for (let i = 0; i < node.namedChildCount; i++) {
455
442
  const child = node.namedChild(i);
@@ -459,37 +446,48 @@ const extractPendingAssignment = (node, scopeEnv) => {
459
446
  const valueNode = child.childForFieldName('value');
460
447
  if (!nameNode || !valueNode)
461
448
  continue;
462
- // Object destructuring: `const { address, name } = user`
463
- // Emits N fieldAccess items — one per destructured binding.
449
+ // Object destructuring from identifier: `const { address, name } = user`
464
450
  if (nameNode.type === 'object_pattern' && valueNode.type === 'identifier') {
465
- const receiver = valueNode.text;
466
- const items = [];
467
- for (let j = 0; j < nameNode.namedChildCount; j++) {
468
- const prop = nameNode.namedChild(j);
469
- if (!prop)
470
- continue;
471
- if (prop.type === 'shorthand_property_identifier_pattern') {
472
- // `const { name } = user` → shorthand: varName = fieldName
473
- const varName = prop.text;
474
- if (!scopeEnv.has(varName)) {
475
- items.push({ kind: 'fieldAccess', lhs: varName, receiver, field: varName });
451
+ const items = collectDestructuredFields(nameNode, valueNode.text, scopeEnv);
452
+ if (items.length > 0)
453
+ return items;
454
+ continue;
455
+ }
456
+ // Object destructuring from call/await: `const { x } = fn()` or `const { x } = await fn()`
457
+ // Emits a synthetic callResult + N fieldAccess items resolved via fixpoint iteration.
458
+ if (nameNode.type === 'object_pattern') {
459
+ const callNode = unwrapAwait(valueNode);
460
+ if (callNode?.type === 'call_expression') {
461
+ const funcNode = callNode.childForFieldName('function');
462
+ if (funcNode) {
463
+ let syntheticVar;
464
+ let leadItem;
465
+ if (funcNode.type === 'identifier') {
466
+ syntheticVar = `__destr_${funcNode.text}_${callNode.startIndex}`;
467
+ leadItem = { kind: 'callResult', lhs: syntheticVar, callee: funcNode.text };
476
468
  }
477
- }
478
- else if (prop.type === 'pair_pattern') {
479
- // `const { address: addr } = user` → pair_pattern: key=field, value=varName
480
- const keyNode = prop.childForFieldName('key');
481
- const valNode = prop.childForFieldName('value');
482
- if (keyNode && valNode) {
483
- const fieldName = keyNode.text;
484
- const varName = valNode.text;
485
- if (!scopeEnv.has(varName)) {
486
- items.push({ kind: 'fieldAccess', lhs: varName, receiver, field: fieldName });
469
+ else if (funcNode.type === 'member_expression') {
470
+ const obj = funcNode.childForFieldName('object');
471
+ const prop = funcNode.childForFieldName('property');
472
+ if (obj &&
473
+ prop?.type === 'property_identifier' &&
474
+ (obj.type === 'identifier' || obj.type === 'this')) {
475
+ syntheticVar = `__destr_${prop.text}_${callNode.startIndex}`;
476
+ leadItem = {
477
+ kind: 'methodCallResult',
478
+ lhs: syntheticVar,
479
+ receiver: obj.text,
480
+ method: prop.text,
481
+ };
487
482
  }
488
483
  }
484
+ if (syntheticVar && leadItem) {
485
+ const fieldItems = collectDestructuredFields(nameNode, syntheticVar, scopeEnv);
486
+ if (fieldItems.length > 0)
487
+ return [leadItem, ...fieldItems];
488
+ }
489
489
  }
490
490
  }
491
- if (items.length > 0)
492
- return items;
493
491
  continue;
494
492
  }
495
493
  const lhs = nameNode.text;
@@ -656,7 +654,6 @@ export const typeConfig = {
656
654
  extractParameter,
657
655
  extractInitializer,
658
656
  scanConstructorBinding,
659
- extractReturnType,
660
657
  extractForLoopBinding,
661
658
  extractPendingAssignment,
662
659
  extractPatternBinding,
@@ -12,23 +12,25 @@ export declare const DEFINITION_CAPTURE_KEYS: readonly ["definition.function", "
12
12
  export declare const getDefinitionNodeFromCaptures: (captureMap: Record<string, SyntaxNode>) => SyntaxNode | null;
13
13
  /**
14
14
  * Node types that represent function/method definitions across languages.
15
- * Used to find the enclosing function for a call site.
15
+ * Used by parent-walk in call-processor, parse-worker, and type-env to detect
16
+ * enclosing function scope boundaries.
17
+ *
18
+ * INVARIANT: This set MUST be a superset of every language's
19
+ * MethodExtractionConfig.methodNodeTypes. When adding a new node type to a
20
+ * MethodExtractor config, add it here too — otherwise enclosing-function
21
+ * resolution will silently miss that node type during parent-walks.
16
22
  */
17
23
  export declare const FUNCTION_NODE_TYPES: Set<string>;
18
24
  /**
19
- * Node types for standard function declarations that need C/C++ declarator handling.
20
- * Used by extractFunctionName to determine how to extract the function name.
25
+ * AST node types that represent a class-like container (for HAS_METHOD edge extraction).
26
+ *
27
+ * INVARIANT: When a language config adds a new node type to `typeDeclarationNodes`,
28
+ * that type must also be added here AND to `CONTAINER_TYPE_TO_LABEL` below,
29
+ * otherwise `findEnclosingClassNode` won't recognize it and methods may get
30
+ * orphaned HAS_METHOD edges or incorrect labels.
21
31
  */
22
- export declare const FUNCTION_DECLARATION_TYPES: Set<string>;
23
- /** AST node types that represent a class-like container (for HAS_METHOD edge extraction) */
24
32
  export declare const CLASS_CONTAINER_TYPES: Set<string>;
25
33
  export declare const CONTAINER_TYPE_TO_LABEL: Record<string, string>;
26
- /** Check if a Kotlin function_declaration capture is inside a class_body (i.e., a method).
27
- * Kotlin grammar uses function_declaration for both top-level functions and class methods.
28
- * Returns true when the captured definition node has a class_body ancestor. */
29
- export declare function isKotlinClassMethod(captureNode: {
30
- parent?: SyntaxNode | null;
31
- } | null | undefined): boolean;
32
34
  /**
33
35
  * Determine the graph node label from a tree-sitter capture map.
34
36
  * Handles language-specific reclassification via the provider's labelOverride hook
@@ -36,48 +38,36 @@ export declare function isKotlinClassMethod(captureNode: {
36
38
  * Returns null if the capture should be skipped (import, call, C/C++ duplicate, missing name).
37
39
  */
38
40
  export declare function getLabelFromCaptures(captureMap: Record<string, SyntaxNode>, provider: LanguageProvider): NodeLabel | null;
39
- /** Walk up AST to find enclosing class/struct/interface/impl, return its generateId or null.
41
+ /** Enclosing class info: both the generated node ID and the bare class name. */
42
+ export interface EnclosingClassInfo {
43
+ classId: string;
44
+ className: string;
45
+ }
46
+ /** Walk up AST to find enclosing class/struct/interface/impl, return its ID and name.
40
47
  * For Go method_declaration nodes, extracts receiver type (e.g. `func (u *User) Save()` → User struct). */
48
+ export declare const findEnclosingClassInfo: (node: SyntaxNode, filePath: string) => EnclosingClassInfo | null;
49
+ /** Convenience wrapper: returns just the class ID string (backward compat). */
41
50
  export declare const findEnclosingClassId: (node: SyntaxNode, filePath: string) => string | null;
42
51
  /**
43
52
  * Find a child of `childType` within a sibling node of `siblingType`.
44
53
  * Used for Kotlin AST traversal where visibility_modifier lives inside a modifiers sibling.
45
54
  */
46
55
  export declare const findSiblingChild: (parent: SyntaxNode, siblingType: string, childType: string) => SyntaxNode | null;
47
- /**
48
- * Extract function name and label from a function_definition or similar AST node.
49
- * Handles C/C++ qualified_identifier (ClassName::MethodName) and other language patterns.
50
- */
51
- export declare const extractFunctionName: (node: SyntaxNode) => {
52
- funcName: string | null;
53
- label: NodeLabel;
54
- };
55
- export interface MethodSignature {
56
- parameterCount: number | undefined;
57
- /** Number of required (non-optional, non-default) parameters.
58
- * Only set when fewer than parameterCount — enables range-based arity filtering.
59
- * undefined means all parameters are required (or metadata unavailable). */
60
- requiredParameterCount: number | undefined;
61
- /** Per-parameter type names extracted via extractSimpleTypeName.
62
- * Only populated for languages with method overloading (Java, Kotlin, C#, C++).
63
- * undefined (not []) when no types are extractable — avoids empty array allocations. */
64
- parameterTypes: string[] | undefined;
65
- returnType: string | undefined;
66
- }
67
- /** Argument list node types shared between extractMethodSignature and countCallArguments. */
56
+ /** Generic name extraction from a function-like AST node.
57
+ * Tries `node.childForFieldName('name')?.text`, then scans children for
58
+ * `identifier` / `property_identifier` / `simple_identifier`. */
59
+ export declare const genericFuncName: (node: SyntaxNode) => string | null;
60
+ /** AST node types that represent a method definition (for `inferFunctionLabel`). */
61
+ export declare const METHOD_LABEL_NODE_TYPES: Set<string>;
62
+ /** AST node types that represent a constructor definition (for `inferFunctionLabel`). */
63
+ export declare const CONSTRUCTOR_LABEL_NODE_TYPES: Set<string>;
64
+ /** Infer node label from AST node type for function-like nodes without a provider hook. */
65
+ export declare const inferFunctionLabel: (nodeType: string) => NodeLabel;
66
+ /** Argument list node types shared between countCallArguments and call-resolution helpers. */
68
67
  export declare const CALL_ARGUMENT_LIST_TYPES: Set<string>;
69
- /**
70
- * Extract parameter count and return type text from an AST method/function node.
71
- * Works across languages by looking for common AST patterns.
72
- */
73
- export declare const extractMethodSignature: (node: SyntaxNode | null | undefined) => MethodSignature;
74
68
  /** Walk an AST node depth-first, returning the first descendant with the given type. */
75
- export declare function findDescendant(node: SyntaxNode, type: string): SyntaxNode | null;
69
+ export declare function findDescendant(root: SyntaxNode, type: string): SyntaxNode | null;
76
70
  /** Extract the text content from a string or encapsed_string AST node. */
77
71
  export declare function extractStringContent(node: SyntaxNode | null | undefined): string | null;
78
- /** Check if a C/C++ function_definition is inside a class or struct body.
79
- * Used by the C/C++ labelOverride to skip duplicate function captures
80
- * that are already covered by definition.method queries. */
81
- export declare function isCppInsideClassOrStruct(functionNode: SyntaxNode): boolean;
82
72
  /** Find the first direct named child of a tree-sitter node matching the given type. */
83
73
  export declare function findChild(node: SyntaxNode, type: string): SyntaxNode | null;