@colbymchenry/codegraph-darwin-x64 0.9.4 → 0.9.6

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 (199) hide show
  1. package/lib/dist/bin/codegraph.js +12 -0
  2. package/lib/dist/bin/codegraph.js.map +1 -1
  3. package/lib/dist/db/queries.d.ts +1 -0
  4. package/lib/dist/db/queries.d.ts.map +1 -1
  5. package/lib/dist/db/queries.js +31 -3
  6. package/lib/dist/db/queries.js.map +1 -1
  7. package/lib/dist/extraction/grammars.d.ts +1 -1
  8. package/lib/dist/extraction/grammars.d.ts.map +1 -1
  9. package/lib/dist/extraction/grammars.js +29 -1
  10. package/lib/dist/extraction/grammars.js.map +1 -1
  11. package/lib/dist/extraction/index.d.ts +15 -2
  12. package/lib/dist/extraction/index.d.ts.map +1 -1
  13. package/lib/dist/extraction/index.js +170 -78
  14. package/lib/dist/extraction/index.js.map +1 -1
  15. package/lib/dist/extraction/languages/c-cpp.d.ts.map +1 -1
  16. package/lib/dist/extraction/languages/c-cpp.js +45 -0
  17. package/lib/dist/extraction/languages/c-cpp.js.map +1 -1
  18. package/lib/dist/extraction/languages/csharp.d.ts.map +1 -1
  19. package/lib/dist/extraction/languages/csharp.js +2 -1
  20. package/lib/dist/extraction/languages/csharp.js.map +1 -1
  21. package/lib/dist/extraction/languages/go.d.ts.map +1 -1
  22. package/lib/dist/extraction/languages/go.js +12 -0
  23. package/lib/dist/extraction/languages/go.js.map +1 -1
  24. package/lib/dist/extraction/languages/index.d.ts.map +1 -1
  25. package/lib/dist/extraction/languages/index.js +2 -0
  26. package/lib/dist/extraction/languages/index.js.map +1 -1
  27. package/lib/dist/extraction/languages/objc.d.ts +3 -0
  28. package/lib/dist/extraction/languages/objc.d.ts.map +1 -0
  29. package/lib/dist/extraction/languages/objc.js +133 -0
  30. package/lib/dist/extraction/languages/objc.js.map +1 -0
  31. package/lib/dist/extraction/mybatis-extractor.d.ts +48 -0
  32. package/lib/dist/extraction/mybatis-extractor.d.ts.map +1 -0
  33. package/lib/dist/extraction/mybatis-extractor.js +198 -0
  34. package/lib/dist/extraction/mybatis-extractor.js.map +1 -0
  35. package/lib/dist/extraction/tree-sitter-types.d.ts +4 -0
  36. package/lib/dist/extraction/tree-sitter-types.d.ts.map +1 -1
  37. package/lib/dist/extraction/tree-sitter.d.ts +33 -0
  38. package/lib/dist/extraction/tree-sitter.d.ts.map +1 -1
  39. package/lib/dist/extraction/tree-sitter.js +351 -14
  40. package/lib/dist/extraction/tree-sitter.js.map +1 -1
  41. package/lib/dist/index.d.ts +21 -2
  42. package/lib/dist/index.d.ts.map +1 -1
  43. package/lib/dist/index.js +53 -1
  44. package/lib/dist/index.js.map +1 -1
  45. package/lib/dist/installer/index.d.ts +1 -1
  46. package/lib/dist/installer/index.js +3 -3
  47. package/lib/dist/installer/index.js.map +1 -1
  48. package/lib/dist/installer/instructions-template.d.ts +2 -2
  49. package/lib/dist/installer/instructions-template.d.ts.map +1 -1
  50. package/lib/dist/installer/instructions-template.js +1 -1
  51. package/lib/dist/installer/targets/antigravity.d.ts +57 -0
  52. package/lib/dist/installer/targets/antigravity.d.ts.map +1 -0
  53. package/lib/dist/installer/targets/antigravity.js +307 -0
  54. package/lib/dist/installer/targets/antigravity.js.map +1 -0
  55. package/lib/dist/installer/targets/gemini.d.ts +26 -0
  56. package/lib/dist/installer/targets/gemini.d.ts.map +1 -0
  57. package/lib/dist/installer/targets/gemini.js +165 -0
  58. package/lib/dist/installer/targets/gemini.js.map +1 -0
  59. package/lib/dist/installer/targets/hermes.d.ts.map +1 -1
  60. package/lib/dist/installer/targets/hermes.js +57 -3
  61. package/lib/dist/installer/targets/hermes.js.map +1 -1
  62. package/lib/dist/installer/targets/kiro.d.ts +27 -0
  63. package/lib/dist/installer/targets/kiro.d.ts.map +1 -0
  64. package/lib/dist/installer/targets/kiro.js +196 -0
  65. package/lib/dist/installer/targets/kiro.js.map +1 -0
  66. package/lib/dist/installer/targets/registry.d.ts.map +1 -1
  67. package/lib/dist/installer/targets/registry.js +6 -0
  68. package/lib/dist/installer/targets/registry.js.map +1 -1
  69. package/lib/dist/installer/targets/types.d.ts +1 -1
  70. package/lib/dist/installer/targets/types.d.ts.map +1 -1
  71. package/lib/dist/mcp/daemon-paths.d.ts +46 -0
  72. package/lib/dist/mcp/daemon-paths.d.ts.map +1 -0
  73. package/lib/dist/mcp/daemon-paths.js +125 -0
  74. package/lib/dist/mcp/daemon-paths.js.map +1 -0
  75. package/lib/dist/mcp/daemon.d.ts +161 -0
  76. package/lib/dist/mcp/daemon.d.ts.map +1 -0
  77. package/lib/dist/mcp/daemon.js +403 -0
  78. package/lib/dist/mcp/daemon.js.map +1 -0
  79. package/lib/dist/mcp/engine.d.ts +100 -0
  80. package/lib/dist/mcp/engine.d.ts.map +1 -0
  81. package/lib/dist/mcp/engine.js +291 -0
  82. package/lib/dist/mcp/engine.js.map +1 -0
  83. package/lib/dist/mcp/index.d.ts +64 -53
  84. package/lib/dist/mcp/index.d.ts.map +1 -1
  85. package/lib/dist/mcp/index.js +307 -387
  86. package/lib/dist/mcp/index.js.map +1 -1
  87. package/lib/dist/mcp/proxy.d.ts +46 -0
  88. package/lib/dist/mcp/proxy.d.ts.map +1 -0
  89. package/lib/dist/mcp/proxy.js +276 -0
  90. package/lib/dist/mcp/proxy.js.map +1 -0
  91. package/lib/dist/mcp/server-instructions.d.ts +1 -1
  92. package/lib/dist/mcp/server-instructions.d.ts.map +1 -1
  93. package/lib/dist/mcp/server-instructions.js +1 -1
  94. package/lib/dist/mcp/session.d.ts +67 -0
  95. package/lib/dist/mcp/session.d.ts.map +1 -0
  96. package/lib/dist/mcp/session.js +276 -0
  97. package/lib/dist/mcp/session.js.map +1 -0
  98. package/lib/dist/mcp/tools.d.ts +49 -0
  99. package/lib/dist/mcp/tools.d.ts.map +1 -1
  100. package/lib/dist/mcp/tools.js +253 -17
  101. package/lib/dist/mcp/tools.js.map +1 -1
  102. package/lib/dist/mcp/transport.d.ts +111 -29
  103. package/lib/dist/mcp/transport.d.ts.map +1 -1
  104. package/lib/dist/mcp/transport.js +181 -71
  105. package/lib/dist/mcp/transport.js.map +1 -1
  106. package/lib/dist/mcp/version.d.ts +19 -0
  107. package/lib/dist/mcp/version.d.ts.map +1 -0
  108. package/lib/dist/mcp/version.js +71 -0
  109. package/lib/dist/mcp/version.js.map +1 -0
  110. package/lib/dist/resolution/callback-synthesizer.d.ts +3 -2
  111. package/lib/dist/resolution/callback-synthesizer.d.ts.map +1 -1
  112. package/lib/dist/resolution/callback-synthesizer.js +351 -3
  113. package/lib/dist/resolution/callback-synthesizer.js.map +1 -1
  114. package/lib/dist/resolution/frameworks/expo-modules.d.ts +3 -0
  115. package/lib/dist/resolution/frameworks/expo-modules.d.ts.map +1 -0
  116. package/lib/dist/resolution/frameworks/expo-modules.js +143 -0
  117. package/lib/dist/resolution/frameworks/expo-modules.js.map +1 -0
  118. package/lib/dist/resolution/frameworks/fabric.d.ts +3 -0
  119. package/lib/dist/resolution/frameworks/fabric.d.ts.map +1 -0
  120. package/lib/dist/resolution/frameworks/fabric.js +354 -0
  121. package/lib/dist/resolution/frameworks/fabric.js.map +1 -0
  122. package/lib/dist/resolution/frameworks/index.d.ts +4 -0
  123. package/lib/dist/resolution/frameworks/index.d.ts.map +1 -1
  124. package/lib/dist/resolution/frameworks/index.js +21 -1
  125. package/lib/dist/resolution/frameworks/index.js.map +1 -1
  126. package/lib/dist/resolution/frameworks/java.d.ts.map +1 -1
  127. package/lib/dist/resolution/frameworks/java.js +270 -1
  128. package/lib/dist/resolution/frameworks/java.js.map +1 -1
  129. package/lib/dist/resolution/frameworks/nestjs.d.ts.map +1 -1
  130. package/lib/dist/resolution/frameworks/nestjs.js +324 -0
  131. package/lib/dist/resolution/frameworks/nestjs.js.map +1 -1
  132. package/lib/dist/resolution/frameworks/react-native.d.ts +3 -0
  133. package/lib/dist/resolution/frameworks/react-native.d.ts.map +1 -0
  134. package/lib/dist/resolution/frameworks/react-native.js +360 -0
  135. package/lib/dist/resolution/frameworks/react-native.js.map +1 -0
  136. package/lib/dist/resolution/frameworks/swift-objc.d.ts +37 -0
  137. package/lib/dist/resolution/frameworks/swift-objc.d.ts.map +1 -0
  138. package/lib/dist/resolution/frameworks/swift-objc.js +252 -0
  139. package/lib/dist/resolution/frameworks/swift-objc.js.map +1 -0
  140. package/lib/dist/resolution/go-module.d.ts +26 -0
  141. package/lib/dist/resolution/go-module.d.ts.map +1 -0
  142. package/lib/dist/resolution/go-module.js +78 -0
  143. package/lib/dist/resolution/go-module.js.map +1 -0
  144. package/lib/dist/resolution/import-resolver.d.ts +18 -0
  145. package/lib/dist/resolution/import-resolver.d.ts.map +1 -1
  146. package/lib/dist/resolution/import-resolver.js +538 -4
  147. package/lib/dist/resolution/import-resolver.js.map +1 -1
  148. package/lib/dist/resolution/index.d.ts +10 -0
  149. package/lib/dist/resolution/index.d.ts.map +1 -1
  150. package/lib/dist/resolution/index.js +102 -0
  151. package/lib/dist/resolution/index.js.map +1 -1
  152. package/lib/dist/resolution/name-matcher.d.ts.map +1 -1
  153. package/lib/dist/resolution/name-matcher.js +212 -0
  154. package/lib/dist/resolution/name-matcher.js.map +1 -1
  155. package/lib/dist/resolution/swift-objc-bridge.d.ts +134 -0
  156. package/lib/dist/resolution/swift-objc-bridge.d.ts.map +1 -0
  157. package/lib/dist/resolution/swift-objc-bridge.js +256 -0
  158. package/lib/dist/resolution/swift-objc-bridge.js.map +1 -0
  159. package/lib/dist/resolution/types.d.ts +29 -0
  160. package/lib/dist/resolution/types.d.ts.map +1 -1
  161. package/lib/dist/sync/index.d.ts +3 -1
  162. package/lib/dist/sync/index.d.ts.map +1 -1
  163. package/lib/dist/sync/index.js +8 -1
  164. package/lib/dist/sync/index.js.map +1 -1
  165. package/lib/dist/sync/watcher.d.ts +119 -7
  166. package/lib/dist/sync/watcher.d.ts.map +1 -1
  167. package/lib/dist/sync/watcher.js +243 -37
  168. package/lib/dist/sync/watcher.js.map +1 -1
  169. package/lib/dist/sync/worktree.d.ts +54 -0
  170. package/lib/dist/sync/worktree.d.ts.map +1 -0
  171. package/lib/dist/sync/worktree.js +136 -0
  172. package/lib/dist/sync/worktree.js.map +1 -0
  173. package/lib/dist/types.d.ts +1 -1
  174. package/lib/dist/types.d.ts.map +1 -1
  175. package/lib/dist/types.js +3 -0
  176. package/lib/dist/types.js.map +1 -1
  177. package/lib/node_modules/.package-lock.json +29 -1
  178. package/lib/node_modules/chokidar/LICENSE +21 -0
  179. package/lib/node_modules/chokidar/README.md +305 -0
  180. package/lib/node_modules/chokidar/esm/handler.d.ts +90 -0
  181. package/lib/node_modules/chokidar/esm/handler.js +629 -0
  182. package/lib/node_modules/chokidar/esm/index.d.ts +215 -0
  183. package/lib/node_modules/chokidar/esm/index.js +798 -0
  184. package/lib/node_modules/chokidar/esm/package.json +1 -0
  185. package/lib/node_modules/chokidar/handler.d.ts +90 -0
  186. package/lib/node_modules/chokidar/handler.js +635 -0
  187. package/lib/node_modules/chokidar/index.d.ts +215 -0
  188. package/lib/node_modules/chokidar/index.js +804 -0
  189. package/lib/node_modules/chokidar/package.json +69 -0
  190. package/lib/node_modules/readdirp/LICENSE +21 -0
  191. package/lib/node_modules/readdirp/README.md +120 -0
  192. package/lib/node_modules/readdirp/esm/index.d.ts +108 -0
  193. package/lib/node_modules/readdirp/esm/index.js +257 -0
  194. package/lib/node_modules/readdirp/esm/package.json +1 -0
  195. package/lib/node_modules/readdirp/index.d.ts +108 -0
  196. package/lib/node_modules/readdirp/index.js +263 -0
  197. package/lib/node_modules/readdirp/package.json +70 -0
  198. package/lib/package.json +2 -1
  199. package/package.json +1 -1
@@ -48,6 +48,7 @@ const liquid_extractor_1 = require("./liquid-extractor");
48
48
  const svelte_extractor_1 = require("./svelte-extractor");
49
49
  const dfm_extractor_1 = require("./dfm-extractor");
50
50
  const vue_extractor_1 = require("./vue-extractor");
51
+ const mybatis_extractor_1 = require("./mybatis-extractor");
51
52
  const frameworks_1 = require("../resolution/frameworks");
52
53
  // Re-export for backward compatibility
53
54
  var tree_sitter_helpers_2 = require("./tree-sitter-helpers");
@@ -56,6 +57,9 @@ Object.defineProperty(exports, "generateNodeId", { enumerable: true, get: functi
56
57
  * Extract the name from a node based on language
57
58
  */
58
59
  function extractName(node, source, extractor) {
60
+ const hookName = extractor.resolveName?.(node, source);
61
+ if (hookName)
62
+ return hookName;
59
63
  // Try field name first
60
64
  const nameNode = (0, tree_sitter_helpers_1.getChildByField)(node, extractor.nameField);
61
65
  if (nameNode) {
@@ -392,6 +396,20 @@ class TreeSitterExtractor {
392
396
  else if (nodeType === 'impl_item') {
393
397
  this.extractRustImplItem(node);
394
398
  }
399
+ // TypeScript interface members: property_signature (`foo: T`, `foo?: T`)
400
+ // and method_signature (`foo(arg: A): R`) both carry type annotations the
401
+ // interface walker would otherwise drop. Extract them as `references`
402
+ // edges from the interface so resolvers can wire callers/impact for
403
+ // types that only appear in interface members.
404
+ else if ((nodeType === 'property_signature' || nodeType === 'method_signature') &&
405
+ this.isInsideClassLikeNode() &&
406
+ this.TYPE_ANNOTATION_LANGUAGES.has(this.language)) {
407
+ const parentId = this.nodeStack[this.nodeStack.length - 1];
408
+ if (parentId) {
409
+ this.extractTypeAnnotations(node, parentId);
410
+ }
411
+ // don't skipChildren — nested signatures still need traversal
412
+ }
395
413
  // Visit children (unless the extract method already visited them)
396
414
  if (!skipChildren) {
397
415
  for (let i = 0; i < node.namedChildCount; i++) {
@@ -648,6 +666,11 @@ class TreeSitterExtractor {
648
666
  // in inline objects). These are ephemeral and create noise (e.g., Svelte context
649
667
  // objects: `ctx.set({ get view() { ... } })`).
650
668
  if (node.parent?.type === 'object' || node.parent?.type === 'object_expression') {
669
+ const body = this.extractor.resolveBody?.(node, this.extractor.bodyField)
670
+ ?? (0, tree_sitter_helpers_1.getChildByField)(node, this.extractor.bodyField);
671
+ if (body) {
672
+ this.visitFunctionBody(body, '');
673
+ }
651
674
  return;
652
675
  }
653
676
  // Not inside a class-like node and no receiver type, treat as function
@@ -849,12 +872,13 @@ class TreeSitterExtractor {
849
872
  const docstring = (0, tree_sitter_helpers_1.getPrecedingDocstring)(node, this.source);
850
873
  const visibility = this.extractor.getVisibility?.(node);
851
874
  const isStatic = this.extractor.isStatic?.(node) ?? false;
852
- // Property name is a direct identifier child
853
- const nameNode = (0, tree_sitter_helpers_1.getChildByField)(node, 'name')
854
- || node.namedChildren.find(c => c.type === 'identifier');
855
- if (!nameNode)
875
+ const hookName = this.extractor.extractPropertyName?.(node, this.source);
876
+ const nameNode = hookName
877
+ ? null
878
+ : (0, tree_sitter_helpers_1.getChildByField)(node, 'name') || node.namedChildren.find(c => c.type === 'identifier');
879
+ const name = hookName ?? (nameNode ? (0, tree_sitter_helpers_1.getNodeText)(nameNode, this.source) : null);
880
+ if (!name)
856
881
  return;
857
- const name = (0, tree_sitter_helpers_1.getNodeText)(nameNode, this.source);
858
882
  // Get property type from the type child (first named child that isn't modifier or identifier)
859
883
  const typeNode = node.namedChildren.find(c => c.type !== 'modifier' && c.type !== 'modifiers'
860
884
  && c.type !== 'identifier' && c.type !== 'accessor_list'
@@ -871,6 +895,10 @@ class TreeSitterExtractor {
871
895
  // decorator->target relationship for class properties too.
872
896
  if (propNode) {
873
897
  this.extractDecoratorsFor(node, propNode.id);
898
+ // Emit `references` edges from the property to types named in its
899
+ // type annotation (#381). The generic walker handles TS-style
900
+ // `type_annotation` children; the C# branch walks the `type` field.
901
+ this.extractTypeAnnotations(node, propNode.id);
874
902
  }
875
903
  }
876
904
  /**
@@ -943,8 +971,15 @@ class TreeSitterExtractor {
943
971
  });
944
972
  // Java/Kotlin annotations / TS field decorators sit on the
945
973
  // outer field_declaration, not on the individual declarator.
946
- if (fieldNode)
974
+ if (fieldNode) {
947
975
  this.extractDecoratorsFor(node, fieldNode.id);
976
+ // Same as properties: emit `references` to the field's annotated
977
+ // type. The outer `field_declaration` is the right scope to
978
+ // search from — C# carries the `type` inside `variable_declaration`
979
+ // and the language-aware path in `extractTypeAnnotations` descends
980
+ // into that wrapper (#381).
981
+ this.extractTypeAnnotations(node, fieldNode.id);
982
+ }
948
983
  }
949
984
  }
950
985
  else {
@@ -1012,6 +1047,11 @@ class TreeSitterExtractor {
1012
1047
  if (varNode) {
1013
1048
  this.extractVariableTypeAnnotation(child, varNode.id);
1014
1049
  }
1050
+ if (valueNode &&
1051
+ valueNode.type !== 'object' &&
1052
+ valueNode.type !== 'object_expression') {
1053
+ this.visitFunctionBody(valueNode, '');
1054
+ }
1015
1055
  // Exported const object-of-functions: `export const actions =
1016
1056
  // { default: async () => {} }` (SvelteKit form actions / handler maps
1017
1057
  // / route tables). Extract each function-valued property as a function
@@ -1217,8 +1257,87 @@ class TreeSitterExtractor {
1217
1257
  const value = (0, tree_sitter_helpers_1.getChildByField)(node, 'value');
1218
1258
  if (value) {
1219
1259
  this.extractTypeRefsFromSubtree(value, typeAliasNode.id);
1260
+ // `type X = { foo: T; bar(): T }` — make the members first-class
1261
+ // property/method nodes under the type alias so `recorder.stop()`
1262
+ // can attach the call edge to `RecorderHandle.stop` instead of
1263
+ // an unrelated class method picked by path-proximity (#359).
1264
+ if (this.language === 'typescript' || this.language === 'tsx') {
1265
+ this.extractTsTypeAliasMembers(value, typeAliasNode);
1266
+ }
1267
+ }
1268
+ }
1269
+ return false;
1270
+ }
1271
+ /**
1272
+ * Surface the members of a TypeScript `type X = { ... }` (or intersection
1273
+ * thereof) as `property` / `method` nodes under the type-alias node. Only
1274
+ * walks the immediate object_type / intersection operands so anonymous
1275
+ * nested object types inside generic arguments (`Promise<{ ok: true }>`)
1276
+ * don't produce phantom members.
1277
+ */
1278
+ extractTsTypeAliasMembers(value, typeAliasNode) {
1279
+ const objectTypes = [];
1280
+ if (value.type === 'object_type') {
1281
+ objectTypes.push(value);
1282
+ }
1283
+ else if (value.type === 'intersection_type') {
1284
+ for (let i = 0; i < value.namedChildCount; i++) {
1285
+ const op = value.namedChild(i);
1286
+ if (op && op.type === 'object_type')
1287
+ objectTypes.push(op);
1288
+ }
1289
+ }
1290
+ else {
1291
+ return;
1292
+ }
1293
+ this.nodeStack.push(typeAliasNode.id);
1294
+ for (const objType of objectTypes) {
1295
+ for (let i = 0; i < objType.namedChildCount; i++) {
1296
+ const child = objType.namedChild(i);
1297
+ if (!child)
1298
+ continue;
1299
+ if (child.type !== 'property_signature' && child.type !== 'method_signature')
1300
+ continue;
1301
+ const nameNode = (0, tree_sitter_helpers_1.getChildByField)(child, 'name');
1302
+ const memberName = nameNode ? (0, tree_sitter_helpers_1.getNodeText)(nameNode, this.source) : '';
1303
+ if (!memberName)
1304
+ continue;
1305
+ // `foo: () => T` and `foo(): T` are functionally a method on the
1306
+ // type contract. Treat the property_signature with a function-typed
1307
+ // annotation as a method too so call sites can resolve to it.
1308
+ const memberKind = child.type === 'method_signature'
1309
+ ? 'method'
1310
+ : this.isTsFunctionTypedProperty(child) ? 'method' : 'property';
1311
+ const docstring = (0, tree_sitter_helpers_1.getPrecedingDocstring)(child, this.source);
1312
+ const signature = (0, tree_sitter_helpers_1.getNodeText)(child, this.source);
1313
+ this.createNode(memberKind, memberName, child, {
1314
+ docstring,
1315
+ signature,
1316
+ qualifiedName: `${typeAliasNode.name}::${memberName}`,
1317
+ });
1318
+ // Emit `references` edges from the type alias to types named in the
1319
+ // member's signature, matching the interface-member behavior added in
1320
+ // #432. We attach refs to the type-alias parent (consistent with
1321
+ // interface property_signature treatment).
1322
+ this.extractTypeAnnotations(child, typeAliasNode.id);
1220
1323
  }
1221
1324
  }
1325
+ this.nodeStack.pop();
1326
+ }
1327
+ /**
1328
+ * `foo: () => T` → property_signature whose type_annotation contains a
1329
+ * `function_type`. Treat that as a method-shaped contract member, since
1330
+ * the call site `obj.foo()` has identical semantics to `bar(): T`.
1331
+ */
1332
+ isTsFunctionTypedProperty(propertySignature) {
1333
+ const typeAnno = (0, tree_sitter_helpers_1.getChildByField)(propertySignature, 'type');
1334
+ if (!typeAnno)
1335
+ return false;
1336
+ for (let i = 0; i < typeAnno.namedChildCount; i++) {
1337
+ const inner = typeAnno.namedChild(i);
1338
+ if (inner && inner.type === 'function_type')
1339
+ return true;
1340
+ }
1222
1341
  return false;
1223
1342
  }
1224
1343
  // extractExportedVariables removed — the walker now descends into
@@ -1369,7 +1488,25 @@ class TreeSitterExtractor {
1369
1488
  if (nameField && objectField && (node.type === 'method_invocation' || node.type === 'member_call_expression' || node.type === 'scoped_call_expression')) {
1370
1489
  // Method call with explicit receiver: receiver.method() / $receiver->method() / ClassName::method()
1371
1490
  const methodName = (0, tree_sitter_helpers_1.getNodeText)(nameField, this.source);
1372
- let receiverName = (0, tree_sitter_helpers_1.getNodeText)(objectField, this.source);
1491
+ // Java `this.userbo.toLogin2()` parses as method_invocation(object=field_access(this, userbo)).
1492
+ // Without unwrapping, receiverName is `this.userbo` and the name-matcher's
1493
+ // single-dot receiver regex fails. Pull out the immediate field after `this.`
1494
+ // so the receiver is the field name (`userbo`), which the resolver can then
1495
+ // look up in the enclosing class's field declarations.
1496
+ let receiverName;
1497
+ if (objectField.type === 'field_access') {
1498
+ const inner = (0, tree_sitter_helpers_1.getChildByField)(objectField, 'object');
1499
+ const fld = (0, tree_sitter_helpers_1.getChildByField)(objectField, 'field');
1500
+ if (inner && fld && (inner.type === 'this' || inner.type === 'this_expression')) {
1501
+ receiverName = (0, tree_sitter_helpers_1.getNodeText)(fld, this.source);
1502
+ }
1503
+ else {
1504
+ receiverName = (0, tree_sitter_helpers_1.getNodeText)(objectField, this.source);
1505
+ }
1506
+ }
1507
+ else {
1508
+ receiverName = (0, tree_sitter_helpers_1.getNodeText)(objectField, this.source);
1509
+ }
1373
1510
  // Strip PHP $ prefix from variable names
1374
1511
  receiverName = receiverName.replace(/^\$/, '');
1375
1512
  if (methodName) {
@@ -1383,13 +1520,51 @@ class TreeSitterExtractor {
1383
1520
  }
1384
1521
  }
1385
1522
  }
1523
+ else if (node.type === 'message_expression') {
1524
+ // ObjC message expressions emit one `method` field child per selector
1525
+ // keyword: `[obj a:1 b:2 c:3]` has three `method=identifier` siblings.
1526
+ // Joining them with `:` reconstructs the full selector and matches the
1527
+ // multi-part selector names produced by the ObjC method_definition
1528
+ // extractor (`extractObjcMethodName` in languages/objc.ts). Without this
1529
+ // join, multi-keyword call sites only emitted the first keyword and never
1530
+ // resolved to their target methods (e.g. `GET:parameters:headers:...` had
1531
+ // zero callers despite obviously being called).
1532
+ const methodKeywords = [];
1533
+ for (let i = 0; i < node.namedChildCount; i++) {
1534
+ if (node.fieldNameForNamedChild(i) === 'method') {
1535
+ const kw = node.namedChild(i);
1536
+ if (kw)
1537
+ methodKeywords.push((0, tree_sitter_helpers_1.getNodeText)(kw, this.source));
1538
+ }
1539
+ }
1540
+ if (methodKeywords.length > 0) {
1541
+ const methodName = methodKeywords.length === 1
1542
+ ? methodKeywords[0]
1543
+ : methodKeywords.map((k) => `${k}:`).join('');
1544
+ const receiverField = (0, tree_sitter_helpers_1.getChildByField)(node, 'receiver');
1545
+ const SKIP_RECEIVERS = new Set(['self', 'super']);
1546
+ if (receiverField && receiverField.type !== 'message_expression') {
1547
+ const receiverName = (0, tree_sitter_helpers_1.getNodeText)(receiverField, this.source);
1548
+ if (receiverName && !SKIP_RECEIVERS.has(receiverName)) {
1549
+ calleeName = `${receiverName}.${methodName}`;
1550
+ }
1551
+ else {
1552
+ calleeName = methodName;
1553
+ }
1554
+ }
1555
+ else {
1556
+ calleeName = methodName;
1557
+ }
1558
+ }
1559
+ }
1386
1560
  else {
1387
1561
  const func = (0, tree_sitter_helpers_1.getChildByField)(node, 'function') || node.namedChild(0);
1388
1562
  if (func) {
1389
- if (func.type === 'member_expression' || func.type === 'attribute' || func.type === 'selector_expression' || func.type === 'navigation_expression') {
1563
+ if (func.type === 'member_expression' || func.type === 'attribute' || func.type === 'selector_expression' || func.type === 'navigation_expression' || func.type === 'field_expression') {
1390
1564
  // Method call: obj.method() or obj.field.method()
1391
1565
  // Go uses selector_expression with 'field', JS/TS uses member_expression with 'property'
1392
1566
  // Kotlin uses navigation_expression with navigation_suffix > simple_identifier
1567
+ // C/C++ use field_expression for both `obj.method()` and `ptr->method()`
1393
1568
  let property = (0, tree_sitter_helpers_1.getChildByField)(func, 'property') || (0, tree_sitter_helpers_1.getChildByField)(func, 'field');
1394
1569
  if (!property) {
1395
1570
  const child1 = func.namedChild(1);
@@ -1407,9 +1582,12 @@ class TreeSitterExtractor {
1407
1582
  // This helps the resolver distinguish method calls from bare function calls
1408
1583
  // (e.g., Python's console.print() vs builtin print())
1409
1584
  // Skip self/this/cls as they don't aid resolution
1410
- const receiver = (0, tree_sitter_helpers_1.getChildByField)(func, 'object') || (0, tree_sitter_helpers_1.getChildByField)(func, 'operand') || func.namedChild(0);
1585
+ const receiver = (0, tree_sitter_helpers_1.getChildByField)(func, 'object') ||
1586
+ (0, tree_sitter_helpers_1.getChildByField)(func, 'operand') ||
1587
+ (0, tree_sitter_helpers_1.getChildByField)(func, 'argument') ||
1588
+ func.namedChild(0);
1411
1589
  const SKIP_RECEIVERS = new Set(['self', 'this', 'cls', 'super']);
1412
- if (receiver && (receiver.type === 'identifier' || receiver.type === 'simple_identifier')) {
1590
+ if (receiver && (receiver.type === 'identifier' || receiver.type === 'simple_identifier' || receiver.type === 'field_identifier')) {
1413
1591
  const receiverName = (0, tree_sitter_helpers_1.getNodeText)(receiver, this.source);
1414
1592
  if (!SKIP_RECEIVERS.has(receiverName)) {
1415
1593
  calleeName = `${receiverName}.${methodName}`;
@@ -1691,6 +1869,42 @@ class TreeSitterExtractor {
1691
1869
  * Extract inheritance relationships
1692
1870
  */
1693
1871
  extractInheritance(node, classId) {
1872
+ // Objective-C @interface MyClass : NSObject <ProtoA, ProtoB>
1873
+ if (node.type === 'class_interface') {
1874
+ const superclass = (0, tree_sitter_helpers_1.getChildByField)(node, 'superclass');
1875
+ if (superclass) {
1876
+ const name = (0, tree_sitter_helpers_1.getNodeText)(superclass, this.source);
1877
+ this.unresolvedReferences.push({
1878
+ fromNodeId: classId,
1879
+ referenceName: name,
1880
+ referenceKind: 'extends',
1881
+ line: superclass.startPosition.row + 1,
1882
+ column: superclass.startPosition.column,
1883
+ });
1884
+ }
1885
+ for (let j = 0; j < node.namedChildCount; j++) {
1886
+ const argList = node.namedChild(j);
1887
+ if (argList?.type !== 'parameterized_arguments')
1888
+ continue;
1889
+ for (let k = 0; k < argList.namedChildCount; k++) {
1890
+ const typeName = argList.namedChild(k);
1891
+ if (!typeName)
1892
+ continue;
1893
+ const typeId = typeName.namedChildren.find((c) => c.type === 'type_identifier' || c.type === 'identifier');
1894
+ if (!typeId)
1895
+ continue;
1896
+ const protocolName = (0, tree_sitter_helpers_1.getNodeText)(typeId, this.source);
1897
+ this.unresolvedReferences.push({
1898
+ fromNodeId: classId,
1899
+ referenceName: protocolName,
1900
+ referenceKind: 'implements',
1901
+ line: typeId.startPosition.row + 1,
1902
+ column: typeId.startPosition.column,
1903
+ });
1904
+ }
1905
+ }
1906
+ return;
1907
+ }
1694
1908
  // Look for extends/implements clauses
1695
1909
  for (let i = 0; i < node.namedChildCount; i++) {
1696
1910
  const child = node.namedChild(i);
@@ -2006,6 +2220,16 @@ class TreeSitterExtractor {
2006
2220
  return;
2007
2221
  if (!this.TYPE_ANNOTATION_LANGUAGES.has(this.language))
2008
2222
  return;
2223
+ // C# tree-sitter doesn't produce `type_identifier` leaves — it uses
2224
+ // `identifier`, `predefined_type`, `qualified_name`, `generic_name`,
2225
+ // etc. — so the generic walker below emits zero references for it.
2226
+ // Dispatch to a C#-aware path that only walks type-position subtrees
2227
+ // (the `type` field of a parameter/method/property/field), so
2228
+ // parameter NAMES never accidentally surface as type refs (#381).
2229
+ if (this.language === 'csharp') {
2230
+ this.extractCsharpTypeRefs(node, nodeId);
2231
+ return;
2232
+ }
2009
2233
  // Extract parameter type annotations
2010
2234
  const params = (0, tree_sitter_helpers_1.getChildByField)(node, this.extractor.paramsField || 'parameters');
2011
2235
  if (params) {
@@ -2022,6 +2246,112 @@ class TreeSitterExtractor {
2022
2246
  this.extractTypeRefsFromSubtree(typeAnnotation, nodeId);
2023
2247
  }
2024
2248
  }
2249
+ /**
2250
+ * Extract C# type references from a node that owns a type position —
2251
+ * a method/constructor declaration, a property declaration, or a
2252
+ * field declaration (which wraps `variable_declaration → type`).
2253
+ *
2254
+ * Walks ONLY into known type fields, so parameter names like
2255
+ * `request` in `Build(UserDto request)` are never mis-emitted as
2256
+ * type references. Once inside a type subtree, `walkCsharpTypePosition`
2257
+ * recognizes C#'s actual type-leaf node kinds (`identifier`,
2258
+ * `qualified_name`, `generic_name`, `array_type`, `nullable_type`,
2259
+ * `tuple_type`, …) — none of which are `type_identifier`. Closes #381.
2260
+ */
2261
+ extractCsharpTypeRefs(node, nodeId) {
2262
+ // Return type / property type — the field is named `type`.
2263
+ const directType = (0, tree_sitter_helpers_1.getChildByField)(node, 'type');
2264
+ if (directType)
2265
+ this.walkCsharpTypePosition(directType, nodeId);
2266
+ // Field declarations wrap declarators in a `variable_declaration`
2267
+ // whose `type` field carries the type. The outer `field_declaration`
2268
+ // has no `type` field of its own, so the call above is a no-op here
2269
+ // and we descend one level.
2270
+ const varDecl = node.namedChildren.find((c) => c.type === 'variable_declaration');
2271
+ if (varDecl) {
2272
+ const vdType = (0, tree_sitter_helpers_1.getChildByField)(varDecl, 'type');
2273
+ if (vdType)
2274
+ this.walkCsharpTypePosition(vdType, nodeId);
2275
+ }
2276
+ // Method / constructor parameters. The field name on
2277
+ // `method_declaration` is `parameters`; it points at a
2278
+ // `parameter_list` whose `parameter` children each have their own
2279
+ // `type` field. Walking ONLY the type field skips parameter NAMES,
2280
+ // which would otherwise mis-emit as type references.
2281
+ const params = (0, tree_sitter_helpers_1.getChildByField)(node, 'parameters');
2282
+ if (params) {
2283
+ for (let i = 0; i < params.namedChildCount; i++) {
2284
+ const child = params.namedChild(i);
2285
+ if (!child || child.type !== 'parameter')
2286
+ continue;
2287
+ const paramType = (0, tree_sitter_helpers_1.getChildByField)(child, 'type');
2288
+ if (paramType)
2289
+ this.walkCsharpTypePosition(paramType, nodeId);
2290
+ }
2291
+ }
2292
+ }
2293
+ /**
2294
+ * Walk a C# subtree that is KNOWN to be in a type position
2295
+ * (return type, parameter type, property type, field type, generic
2296
+ * argument). Identifiers here are type names, not parameter names.
2297
+ */
2298
+ walkCsharpTypePosition(node, fromNodeId) {
2299
+ // `predefined_type` is int/string/bool/etc. — never a project ref.
2300
+ if (node.type === 'predefined_type')
2301
+ return;
2302
+ // Bare type name: `Foo` in `Foo bar`, or the `Foo` inside `List<Foo>`.
2303
+ if (node.type === 'identifier') {
2304
+ const name = (0, tree_sitter_helpers_1.getNodeText)(node, this.source);
2305
+ if (name && !this.BUILTIN_TYPES.has(name)) {
2306
+ this.unresolvedReferences.push({
2307
+ fromNodeId,
2308
+ referenceName: name,
2309
+ referenceKind: 'references',
2310
+ line: node.startPosition.row + 1,
2311
+ column: node.startPosition.column,
2312
+ });
2313
+ }
2314
+ return;
2315
+ }
2316
+ // `Namespace.Foo` → the rightmost identifier is the type. Emit the
2317
+ // full qualified name as the reference; the resolver can still match
2318
+ // on the trailing simple name when needed.
2319
+ if (node.type === 'qualified_name') {
2320
+ const text = (0, tree_sitter_helpers_1.getNodeText)(node, this.source);
2321
+ const last = text.split('.').pop() ?? text;
2322
+ if (last && !this.BUILTIN_TYPES.has(last)) {
2323
+ this.unresolvedReferences.push({
2324
+ fromNodeId,
2325
+ referenceName: last,
2326
+ referenceKind: 'references',
2327
+ line: node.startPosition.row + 1,
2328
+ column: node.startPosition.column,
2329
+ });
2330
+ }
2331
+ return;
2332
+ }
2333
+ // `(int Code, Foo Payload)` — tuple element has BOTH a `type` and a
2334
+ // `name` field; descending into all named children would mis-emit
2335
+ // the element name (`Code`, `Payload`) as a type ref. Walk only the
2336
+ // type field.
2337
+ if (node.type === 'tuple_element') {
2338
+ const t = (0, tree_sitter_helpers_1.getChildByField)(node, 'type');
2339
+ if (t)
2340
+ this.walkCsharpTypePosition(t, fromNodeId);
2341
+ return;
2342
+ }
2343
+ // Composite type nodes — recurse into named children. Covers
2344
+ // `generic_name` (head identifier + `type_argument_list`),
2345
+ // `nullable_type`, `array_type`, `pointer_type`, `tuple_type`,
2346
+ // `ref_type`, and any newer wrapping shapes the grammar adds.
2347
+ // Identifiers reached here are all type-positional (parameter/field
2348
+ // names are gated out before we descend).
2349
+ for (let i = 0; i < node.namedChildCount; i++) {
2350
+ const child = node.namedChild(i);
2351
+ if (child)
2352
+ this.walkCsharpTypePosition(child, fromNodeId);
2353
+ }
2354
+ }
2025
2355
  /**
2026
2356
  * Extract type references from a variable's type annotation.
2027
2357
  */
@@ -2458,10 +2788,17 @@ function extractFromSource(filePath, source, language, frameworkNames) {
2458
2788
  const extractor = new liquid_extractor_1.LiquidExtractor(filePath, source);
2459
2789
  result = extractor.extract();
2460
2790
  }
2461
- else if (detectedLanguage === 'yaml' || detectedLanguage === 'twig') {
2462
- // No symbol extraction file is tracked at the file-record level only.
2463
- // Framework extractors (e.g. Drupal routing resolver) run below and may
2464
- // add route nodes / references for yaml files such as *.routing.yml.
2791
+ else if (detectedLanguage === 'xml') {
2792
+ // Custom extractor for MyBatis mapper XML. Non-mapper XML returns just a
2793
+ // file node so the watcher tracks it without emitting symbols.
2794
+ const extractor = new mybatis_extractor_1.MyBatisExtractor(filePath, source);
2795
+ result = extractor.extract();
2796
+ }
2797
+ else if (detectedLanguage === 'yaml' || detectedLanguage === 'twig' || detectedLanguage === 'properties') {
2798
+ // No symbol extraction at this stage — files are tracked at the file-record
2799
+ // level only. Framework extractors (Drupal routing yml, Spring `@Value`
2800
+ // resolution against application.yml/application.properties) run later and
2801
+ // add per-file nodes/references when they apply.
2465
2802
  result = { nodes: [], edges: [], unresolvedReferences: [], errors: [], durationMs: 0 };
2466
2803
  }
2467
2804
  else if (detectedLanguage === 'pascal' &&