gitnexus 1.6.4-rc.2 → 1.6.4-rc.21

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 (243) hide show
  1. package/README.md +35 -0
  2. package/dist/_shared/index.d.ts +1 -1
  3. package/dist/_shared/index.d.ts.map +1 -1
  4. package/dist/_shared/index.js +1 -1
  5. package/dist/_shared/index.js.map +1 -1
  6. package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +22 -14
  7. package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -1
  8. package/dist/_shared/scope-resolution/finalize-algorithm.js +298 -37
  9. package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
  10. package/dist/_shared/scope-resolution/scope-tree.d.ts +23 -1
  11. package/dist/_shared/scope-resolution/scope-tree.d.ts.map +1 -1
  12. package/dist/_shared/scope-resolution/scope-tree.js +36 -2
  13. package/dist/_shared/scope-resolution/scope-tree.js.map +1 -1
  14. package/dist/_shared/scope-resolution/types.d.ts +47 -3
  15. package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
  16. package/dist/_shared/scope-resolution/types.js +10 -2
  17. package/dist/_shared/scope-resolution/types.js.map +1 -1
  18. package/dist/cli/analyze.d.ts +6 -0
  19. package/dist/cli/analyze.js +35 -0
  20. package/dist/cli/doctor.d.ts +1 -0
  21. package/dist/cli/doctor.js +31 -0
  22. package/dist/cli/index.js +13 -0
  23. package/dist/cli/setup.js +2 -2
  24. package/dist/core/embeddings/config.d.ts +2 -0
  25. package/dist/core/embeddings/config.js +36 -0
  26. package/dist/core/embeddings/embedder.js +11 -6
  27. package/dist/core/embeddings/embedding-pipeline.d.ts +7 -1
  28. package/dist/core/embeddings/embedding-pipeline.js +93 -29
  29. package/dist/core/embeddings/exact-search.d.ts +15 -0
  30. package/dist/core/embeddings/exact-search.js +27 -0
  31. package/dist/core/embeddings/types.d.ts +4 -0
  32. package/dist/core/embeddings/types.js +2 -0
  33. package/dist/core/group/config-parser.js +2 -0
  34. package/dist/core/group/matching.d.ts +3 -3
  35. package/dist/core/group/matching.js +46 -6
  36. package/dist/core/group/storage.js +2 -0
  37. package/dist/core/group/sync.js +1 -1
  38. package/dist/core/group/types.d.ts +18 -0
  39. package/dist/core/ingestion/call-processor.d.ts +3 -3
  40. package/dist/core/ingestion/call-processor.js +58 -65
  41. package/dist/core/ingestion/constants.d.ts +4 -3
  42. package/dist/core/ingestion/constants.js +8 -3
  43. package/dist/core/ingestion/finalize-orchestrator.js +6 -3
  44. package/dist/core/ingestion/heritage-processor.js +2 -2
  45. package/dist/core/ingestion/import-processor.js +1 -1
  46. package/dist/core/ingestion/language-provider.d.ts +8 -0
  47. package/dist/core/ingestion/languages/csharp/captures.js +4 -1
  48. package/dist/core/ingestion/languages/csharp/namespace-siblings.d.ts +14 -13
  49. package/dist/core/ingestion/languages/csharp/namespace-siblings.js +62 -50
  50. package/dist/core/ingestion/languages/python/captures.js +9 -1
  51. package/dist/core/ingestion/languages/python/index.d.ts +1 -1
  52. package/dist/core/ingestion/languages/python/index.js +1 -1
  53. package/dist/core/ingestion/languages/python/simple-hooks.d.ts +3 -1
  54. package/dist/core/ingestion/languages/python/simple-hooks.js +8 -0
  55. package/dist/core/ingestion/languages/python.js +28 -1
  56. package/dist/core/ingestion/languages/swift.js +14 -0
  57. package/dist/core/ingestion/languages/typescript/arity-metadata.d.ts +59 -0
  58. package/dist/core/ingestion/languages/typescript/arity-metadata.js +103 -0
  59. package/dist/core/ingestion/languages/typescript/arity.d.ts +37 -0
  60. package/dist/core/ingestion/languages/typescript/arity.js +54 -0
  61. package/dist/core/ingestion/languages/typescript/cache-stats.d.ts +17 -0
  62. package/dist/core/ingestion/languages/typescript/cache-stats.js +28 -0
  63. package/dist/core/ingestion/languages/typescript/captures.d.ts +28 -0
  64. package/dist/core/ingestion/languages/typescript/captures.js +451 -0
  65. package/dist/core/ingestion/languages/typescript/import-decomposer.d.ts +49 -0
  66. package/dist/core/ingestion/languages/typescript/import-decomposer.js +371 -0
  67. package/dist/core/ingestion/languages/typescript/import-target.d.ts +50 -0
  68. package/dist/core/ingestion/languages/typescript/import-target.js +61 -0
  69. package/dist/core/ingestion/languages/typescript/index.d.ts +94 -0
  70. package/dist/core/ingestion/languages/typescript/index.js +94 -0
  71. package/dist/core/ingestion/languages/typescript/interpret.d.ts +35 -0
  72. package/dist/core/ingestion/languages/typescript/interpret.js +317 -0
  73. package/dist/core/ingestion/languages/typescript/merge-bindings.d.ts +62 -0
  74. package/dist/core/ingestion/languages/typescript/merge-bindings.js +158 -0
  75. package/dist/core/ingestion/languages/typescript/query.d.ts +77 -0
  76. package/dist/core/ingestion/languages/typescript/query.js +778 -0
  77. package/dist/core/ingestion/languages/typescript/receiver-binding.d.ts +59 -0
  78. package/dist/core/ingestion/languages/typescript/receiver-binding.js +171 -0
  79. package/dist/core/ingestion/languages/typescript/scope-resolver.d.ts +16 -0
  80. package/dist/core/ingestion/languages/typescript/scope-resolver.js +113 -0
  81. package/dist/core/ingestion/languages/typescript/simple-hooks.d.ts +71 -0
  82. package/dist/core/ingestion/languages/typescript/simple-hooks.js +131 -0
  83. package/dist/core/ingestion/languages/typescript.js +19 -0
  84. package/dist/core/ingestion/method-extractors/configs/swift.js +3 -4
  85. package/dist/core/ingestion/model/scope-resolution-indexes.d.ts +14 -1
  86. package/dist/core/ingestion/parsing-processor.js +20 -9
  87. package/dist/core/ingestion/pipeline-phases/processes.js +9 -4
  88. package/dist/core/ingestion/pipeline-phases/tools.d.ts +1 -0
  89. package/dist/core/ingestion/pipeline-phases/tools.js +10 -4
  90. package/dist/core/ingestion/registry-primary-flag.d.ts +3 -1
  91. package/dist/core/ingestion/registry-primary-flag.js +4 -1
  92. package/dist/core/ingestion/scope-extractor-bridge.d.ts +5 -2
  93. package/dist/core/ingestion/scope-extractor-bridge.js +7 -2
  94. package/dist/core/ingestion/scope-extractor.js +19 -18
  95. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +73 -11
  96. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +48 -10
  97. package/dist/core/ingestion/scope-resolution/passes/compound-receiver.js +283 -14
  98. package/dist/core/ingestion/scope-resolution/passes/imported-return-types.d.ts +23 -2
  99. package/dist/core/ingestion/scope-resolution/passes/imported-return-types.js +109 -37
  100. package/dist/core/ingestion/scope-resolution/passes/mro.js +3 -1
  101. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +13 -5
  102. package/dist/core/ingestion/scope-resolution/pipeline/phase.js +11 -2
  103. package/dist/core/ingestion/scope-resolution/pipeline/registry.js +2 -0
  104. package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +8 -0
  105. package/dist/core/ingestion/scope-resolution/pipeline/run.js +21 -5
  106. package/dist/core/ingestion/scope-resolution/pipeline/validate-bindings-immutability.d.ts +39 -0
  107. package/dist/core/ingestion/scope-resolution/pipeline/validate-bindings-immutability.js +65 -0
  108. package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +54 -11
  109. package/dist/core/ingestion/scope-resolution/scope/walkers.js +105 -30
  110. package/dist/core/ingestion/type-extractors/swift.js +7 -4
  111. package/dist/core/ingestion/utils/ast-helpers.d.ts +2 -0
  112. package/dist/core/ingestion/utils/ast-helpers.js +12 -0
  113. package/dist/core/ingestion/utils/env.d.ts +10 -0
  114. package/dist/core/ingestion/utils/env.js +14 -0
  115. package/dist/core/ingestion/workers/parse-worker.d.ts +1 -0
  116. package/dist/core/ingestion/workers/parse-worker.js +15 -9
  117. package/dist/core/ingestion/workers/worker-pool.d.ts +11 -4
  118. package/dist/core/ingestion/workers/worker-pool.js +244 -48
  119. package/dist/core/lbug/extension-loader.d.ts +86 -0
  120. package/dist/core/lbug/extension-loader.js +184 -0
  121. package/dist/core/lbug/lbug-adapter.d.ts +18 -17
  122. package/dist/core/lbug/lbug-adapter.js +45 -73
  123. package/dist/core/lbug/pool-adapter.js +10 -28
  124. package/dist/core/platform/capabilities.d.ts +24 -0
  125. package/dist/core/platform/capabilities.js +54 -0
  126. package/dist/core/run-analyze.js +36 -9
  127. package/dist/core/search/bm25-index.d.ts +0 -17
  128. package/dist/core/search/bm25-index.js +10 -118
  129. package/dist/core/search/fts-indexes.d.ts +1 -0
  130. package/dist/core/search/fts-indexes.js +7 -0
  131. package/dist/core/search/fts-schema.d.ts +6 -0
  132. package/dist/core/search/fts-schema.js +7 -0
  133. package/dist/mcp/core/embedder.js +11 -4
  134. package/dist/mcp/local/local-backend.js +50 -15
  135. package/dist/server/api.d.ts +5 -0
  136. package/dist/server/api.js +113 -0
  137. package/hooks/claude/gitnexus-hook.cjs +11 -1
  138. package/package.json +6 -5
  139. package/scripts/build-tree-sitter-dart.cjs +42 -0
  140. package/scripts/build-tree-sitter-proto.cjs +1 -1
  141. package/scripts/build.js +22 -2
  142. package/scripts/install-duckdb-extension.mjs +37 -0
  143. package/vendor/tree-sitter-dart/README.md +18 -0
  144. package/vendor/tree-sitter-dart/binding.gyp +31 -0
  145. package/vendor/tree-sitter-dart/bindings/node/binding.cc +20 -0
  146. package/vendor/tree-sitter-dart/bindings/node/index.d.ts +28 -0
  147. package/vendor/tree-sitter-dart/bindings/node/index.js +7 -0
  148. package/vendor/tree-sitter-dart/grammar.js +2895 -0
  149. package/vendor/tree-sitter-dart/package.json +18 -0
  150. package/vendor/tree-sitter-dart/queries/highlights.scm +246 -0
  151. package/vendor/tree-sitter-dart/queries/tags.scm +92 -0
  152. package/vendor/tree-sitter-dart/queries/test.scm +1 -0
  153. package/vendor/tree-sitter-dart/src/grammar.json +12459 -0
  154. package/vendor/tree-sitter-dart/src/node-types.json +15055 -0
  155. package/vendor/tree-sitter-dart/src/parser.c +196127 -0
  156. package/vendor/tree-sitter-dart/src/scanner.c +130 -0
  157. package/vendor/tree-sitter-dart/src/tree_sitter/alloc.h +54 -0
  158. package/vendor/tree-sitter-dart/src/tree_sitter/array.h +290 -0
  159. package/vendor/tree-sitter-dart/src/tree_sitter/parser.h +265 -0
  160. package/vendor/tree-sitter-swift/LICENSE +21 -0
  161. package/vendor/tree-sitter-swift/README.md +139 -0
  162. package/vendor/tree-sitter-swift/bindings/node/index.d.ts +28 -0
  163. package/vendor/tree-sitter-swift/bindings/node/index.js +7 -0
  164. package/vendor/tree-sitter-swift/package.json +28 -0
  165. package/vendor/tree-sitter-swift/prebuilds/darwin-arm64/tree-sitter-swift.node +0 -0
  166. package/vendor/tree-sitter-swift/prebuilds/darwin-x64/tree-sitter-swift.node +0 -0
  167. package/vendor/tree-sitter-swift/prebuilds/linux-arm64/tree-sitter-swift.node +0 -0
  168. package/vendor/tree-sitter-swift/prebuilds/linux-x64/tree-sitter-swift.node +0 -0
  169. package/vendor/tree-sitter-swift/prebuilds/win32-arm64/tree-sitter-swift.node +0 -0
  170. package/vendor/tree-sitter-swift/prebuilds/win32-x64/tree-sitter-swift.node +0 -0
  171. package/vendor/tree-sitter-swift/src/node-types.json +30694 -0
  172. package/web/assets/agent-DaprsFSX.js +597 -0
  173. package/web/assets/architecture-YZFGNWBL-S5CXDPWN-DEdGaPg2.js +1 -0
  174. package/web/assets/architectureDiagram-EMZXCZ2Q-Domyk_gO.js +36 -0
  175. package/web/assets/blockDiagram-IGV67L2C-B_2kD7tM.js +132 -0
  176. package/web/assets/c4Diagram-DFAF54RM-BhJJW8Gg.js +10 -0
  177. package/web/assets/chunk-3GS5O3IE-jlWIjPsl.js +231 -0
  178. package/web/assets/chunk-3YCYZ6SJ-Blq_IzZs.js +1 -0
  179. package/web/assets/chunk-6NTNNK5N-DyPc58pp.js +1 -0
  180. package/web/assets/chunk-7RZVMHOQ-BdIU-RGO.js +321 -0
  181. package/web/assets/chunk-A34GCYZU-BI2i_LdU.js +1 -0
  182. package/web/assets/chunk-AEOMTBSW-D7qjBMHW.js +1 -0
  183. package/web/assets/chunk-CilyBKbf.js +1 -0
  184. package/web/assets/chunk-DJ7UZH7F-i11ywiBl.js +1 -0
  185. package/web/assets/chunk-DKKBVRCY-1SffGI1N.js +4 -0
  186. package/web/assets/chunk-DU5LTGQ6-DaPeiwD5.js +1 -0
  187. package/web/assets/chunk-FXACKDTF-uhhi2PC2.js +159 -0
  188. package/web/assets/chunk-H3VCZNTA-IchcISDt.js +1 -0
  189. package/web/assets/chunk-HN6EAY2L-D7ZFMNrB.js +1 -0
  190. package/web/assets/chunk-KSICW3F5-C2tZmXwv.js +15 -0
  191. package/web/assets/chunk-O5ABG6QK-Bt-Km84H.js +1 -0
  192. package/web/assets/chunk-PK6DOVAG-ChlWY0BQ.js +206 -0
  193. package/web/assets/chunk-RNJOYNJ4-B724K7cW.js +1 -0
  194. package/web/assets/chunk-RWUO3TPN-DYn1XriD.js +1 -0
  195. package/web/assets/chunk-TBF5ZNIQ-DKtDz6ae.js +1 -0
  196. package/web/assets/chunk-TU3PZOEN-DE5Qhc0N.js +1 -0
  197. package/web/assets/chunk-TYMNRAUI-g1h33cq-.js +1 -0
  198. package/web/assets/chunk-VELTKBKT-C9dVN39o.js +1 -0
  199. package/web/assets/chunk-W7ZLLLMY-Du-Hb9yb.js +1 -0
  200. package/web/assets/chunk-WSB5WSVC-B123clsZ.js +1 -0
  201. package/web/assets/chunk-XGPFEOL4-BR7Eue38.js +1 -0
  202. package/web/assets/classDiagram-PPOCWD7C-BglfKSs_.js +1 -0
  203. package/web/assets/classDiagram-v2-23LJLIIU-BSzTM28O.js +1 -0
  204. package/web/assets/context-builder-CqQNhRj1.js +15 -0
  205. package/web/assets/cose-bilkent-PNC4W37J-DCfErU-A.js +1 -0
  206. package/web/assets/dagre-E77IOHMT-tDRRhDoN.js +4 -0
  207. package/web/assets/diagram-H7BISOXX-CUVHlmAh.js +43 -0
  208. package/web/assets/diagram-JC5VWROH-BoyOxulB.js +24 -0
  209. package/web/assets/diagram-LXUTUG65-osr9hb7N.js +10 -0
  210. package/web/assets/diagram-WEHSV5V5-d8nUqS39.js +24 -0
  211. package/web/assets/erDiagram-GCSMX5X6-b-IwOhPS.js +85 -0
  212. package/web/assets/flowDiagram-OTCZ4VVT-Ott2Q0AP.js +162 -0
  213. package/web/assets/ganttDiagram-MUNLMDZQ-BYtgN_5s.js +292 -0
  214. package/web/assets/gitGraph-7Q5UKJZL-54BCDZD5-CFyBIGZq.js +1 -0
  215. package/web/assets/gitGraphDiagram-3HKGZ4G3-CsVD2gn4.js +106 -0
  216. package/web/assets/index-BleGLU8S.css +2 -0
  217. package/web/assets/index-C_xK08EW.js +885 -0
  218. package/web/assets/info-OMHHGYJF-BF2H5H6G-yjAxKEzh.js +1 -0
  219. package/web/assets/infoDiagram-MN7RKWGX-DXK0Unn5.js +2 -0
  220. package/web/assets/ishikawaDiagram-YMYX4NHK-CXsnC2FA.js +70 -0
  221. package/web/assets/journeyDiagram-SO5T7YLQ-BzZ07B-X.js +139 -0
  222. package/web/assets/kanban-definition-LJHFXRCJ-C6_EpAd9.js +89 -0
  223. package/web/assets/katex-GD7MH7QM-CJiOjBBJ.js +261 -0
  224. package/web/assets/mindmap-definition-2EUWGEK5-CCYGWZ1m.js +96 -0
  225. package/web/assets/packet-4T2RLAQJ-EV4IVRXR-B8k4E3IT.js +1 -0
  226. package/web/assets/pie-ZZUOXDRM-N23DN5KN-DdvfY118.js +1 -0
  227. package/web/assets/pieDiagram-3IATQBI2-RyvRlQb4.js +30 -0
  228. package/web/assets/quadrantDiagram-E256RVCF-Bfb6sxCx.js +7 -0
  229. package/web/assets/radar-PYXPWWZC-P6TP7ZYP-1EEDC_yU.js +1 -0
  230. package/web/assets/requirementDiagram-M5DCFWZL-DjvHDyvN.js +84 -0
  231. package/web/assets/sankeyDiagram-L3NBLAOT-CBCbbl8s.js +10 -0
  232. package/web/assets/sequenceDiagram-ZOUHS735-BscU8TUR.js +157 -0
  233. package/web/assets/stateDiagram-MLPALWAM-CJusEK2D.js +1 -0
  234. package/web/assets/stateDiagram-v2-B5LQ5ZB2-DImJ3PXD.js +1 -0
  235. package/web/assets/timeline-definition-5SPVSISX-DigPA1X8.js +120 -0
  236. package/web/assets/treeView-SZITEDCU-5DXDK3XO-CzPDt3aG.js +1 -0
  237. package/web/assets/treemap-W4RFUUIX-WYLRDWKO-B9Iqiorr.js +1 -0
  238. package/web/assets/vennDiagram-IE5QUKF5-C91UkZIf.js +34 -0
  239. package/web/assets/wardley-RL74JXVD-BCRCBASE-x42Qw7hp.js +1 -0
  240. package/web/assets/wardleyDiagram-XU3VSMPF-DloBhI0U.js +20 -0
  241. package/web/assets/xychartDiagram-ZHJ5623Y-BGWJvgwI.js +7 -0
  242. package/web/index.html +21 -0
  243. package/scripts/patch-tree-sitter-swift.cjs +0 -78
@@ -1,3 +1,4 @@
1
+ import { Buffer } from 'node:buffer';
1
2
  /**
2
3
  * Default minimum buffer size for tree-sitter parsing (512 KB).
3
4
  * tree-sitter requires bufferSize >= file size in bytes.
@@ -10,7 +11,11 @@ export const TREE_SITTER_BUFFER_SIZE = 512 * 1024;
10
11
  export const TREE_SITTER_MAX_BUFFER = 32 * 1024 * 1024;
11
12
  /**
12
13
  * Compute adaptive buffer size for tree-sitter parsing.
13
- * Uses file size, clamped between 512 KB and 32 MB.
14
- * Previous 256 KB fixed limit silently skipped files > ~200 KB (e.g., imgui.h at 411 KB).
14
+ * Uses 2x UTF-8 byte size, clamped between 512 KB and 32 MB.
15
+ * Keeps tree-sitter's byte-sized buffer above large ASCII and multibyte sources.
15
16
  */
16
- export const getTreeSitterBufferSize = (contentLength) => Math.min(Math.max(contentLength * 2, TREE_SITTER_BUFFER_SIZE), TREE_SITTER_MAX_BUFFER);
17
+ export const getTreeSitterContentByteLength = (sourceText) => Buffer.byteLength(sourceText, 'utf8');
18
+ export const getTreeSitterBufferSize = (sourceText) => {
19
+ const byteLength = getTreeSitterContentByteLength(sourceText);
20
+ return Math.min(Math.max(byteLength * 2, TREE_SITTER_BUFFER_SIZE), TREE_SITTER_MAX_BUFFER);
21
+ };
@@ -58,7 +58,7 @@ export function finalizeScopeModel(parsedFiles, options = {}) {
58
58
  const allScopes = [];
59
59
  const allDefs = [];
60
60
  const moduleEntries = [];
61
- const allReferenceSites = [];
61
+ const allReferenceSites = collectReferenceSites(parsedFiles);
62
62
  for (const file of parsedFiles) {
63
63
  for (const s of file.scopes)
64
64
  allScopes.push(s);
@@ -66,8 +66,6 @@ export function finalizeScopeModel(parsedFiles, options = {}) {
66
66
  allDefs.push(d);
67
67
  moduleEntries.push({ filePath: file.filePath, moduleScopeId: file.moduleScope });
68
68
  }
69
- // References kept out of the loop above to centralize list-init.
70
- allReferenceSites.push(...collectReferenceSites(parsedFiles));
71
69
  const scopeTree = buildScopeTree(allScopes);
72
70
  const defs = buildDefIndex(allDefs);
73
71
  const qualifiedNames = buildQualifiedNameIndex(allDefs);
@@ -91,6 +89,11 @@ export function finalizeScopeModel(parsedFiles, options = {}) {
91
89
  methodDispatch,
92
90
  imports: finalizeOut.imports,
93
91
  bindings: finalizeOut.bindings,
92
+ // Empty post-finalize augmentation channel. Populated (if at all)
93
+ // by language hooks like `populateCsharpNamespaceSiblings` running
94
+ // AFTER `finalizeScopeModel` returns, before `resolveReferenceSites`
95
+ // consumes the bundle. Most languages leave it empty.
96
+ bindingAugmentations: new Map(),
94
97
  referenceSites: Object.freeze([...allReferenceSites]),
95
98
  sccs: finalizeOut.sccs,
96
99
  stats: finalizeOut.stats,
@@ -148,7 +148,7 @@ export const processHeritage = async (graph, files, astCache, ctx, onProgress) =
148
148
  // Use larger bufferSize for files > 32KB
149
149
  try {
150
150
  tree = parser.parse(file.content, undefined, {
151
- bufferSize: getTreeSitterBufferSize(file.content.length),
151
+ bufferSize: getTreeSitterBufferSize(file.content),
152
152
  });
153
153
  }
154
154
  catch (parseError) {
@@ -295,7 +295,7 @@ export async function extractExtractedHeritageFromFiles(files, astCache) {
295
295
  if (!tree) {
296
296
  try {
297
297
  tree = parser.parse(file.content, undefined, {
298
- bufferSize: getTreeSitterBufferSize(file.content.length),
298
+ bufferSize: getTreeSitterBufferSize(file.content),
299
299
  });
300
300
  }
301
301
  catch {
@@ -242,7 +242,7 @@ export const processImports = async (graph, files, astCache, ctx, onProgress, re
242
242
  if (!tree) {
243
243
  try {
244
244
  tree = parser.parse(file.content, undefined, {
245
- bufferSize: getTreeSitterBufferSize(file.content.length),
245
+ bufferSize: getTreeSitterBufferSize(file.content),
246
246
  });
247
247
  }
248
248
  catch (parseError) {
@@ -382,6 +382,14 @@ interface LanguageProviderConfig {
382
382
  * else treats as `'free'`).
383
383
  */
384
384
  readonly classifyCallForm?: (captures: CaptureMatch, enclosingScope: Scope) => 'free' | 'member' | 'constructor' | 'index';
385
+ /** Order same-name type candidates when a language can index multiple
386
+ * definitions for one logical type. Return null to keep shared ambiguity
387
+ * handling. */
388
+ readonly orderSameNameTypeCandidates?: (params: {
389
+ readonly typeName: string;
390
+ readonly callSiteFilePath: string;
391
+ readonly candidates: readonly SymbolDefinition[];
392
+ }) => readonly SymbolDefinition[] | null;
385
393
  /**
386
394
  * Is this callable definition compatible with the given call-site arity?
387
395
  * Language-specific rules: Python `*args`/`**kwargs`/defaults, JS default
@@ -21,6 +21,7 @@ import { computeCsharpArityMetadata } from './arity-metadata.js';
21
21
  import { synthesizeCsharpReceiverBinding } from './receiver-binding.js';
22
22
  import { getCsharpParser, getCsharpScopeQuery } from './query.js';
23
23
  import { recordCacheHit, recordCacheMiss } from './cache-stats.js';
24
+ import { getTreeSitterBufferSize } from '../../constants.js';
24
25
  /** Declaration anchors that carry function-like arity metadata. */
25
26
  const FUNCTION_DECL_TAGS = [
26
27
  '@declaration.method',
@@ -43,7 +44,9 @@ export function emitCsharpScopeCaptures(sourceText, _filePath, cachedTree) {
43
44
  // the LanguageProvider contract layer; cast here at the use site.
44
45
  let tree = cachedTree;
45
46
  if (tree === undefined) {
46
- tree = getCsharpParser().parse(sourceText);
47
+ tree = getCsharpParser().parse(sourceText, undefined, {
48
+ bufferSize: getTreeSitterBufferSize(sourceText),
49
+ });
47
50
  recordCacheMiss();
48
51
  }
49
52
  else {
@@ -11,17 +11,18 @@
11
11
  * field-chain resolution fails at `findClassBindingInScope('User')`
12
12
  * in the Service.cs scope chain.
13
13
  *
14
- * Implementation: after the finalize pass populates `indexes.bindings`
15
- * (from explicit `using` directives), walk each file's tree-sitter
16
- * AST for `namespace_declaration` / `file_scoped_namespace_declaration`
17
- * and `using_directive` nodes. The orchestrator hands us its
18
- * `treeCache` so files already parsed by `extractParsedFile` are
19
- * re-used instead of re-parsed — `ParsedFile`'s underlying tree is
20
- * the single source of truth. Group classes by namespace, and inject
21
- * cross-file sibling classes into each Namespace scope's finalized
22
- * bindings with `origin: 'namespace'` — a tier below `local` so a
23
- * local declaration still shadows a cross-file sibling with the same
24
- * name.
14
+ * Implementation: after the finalize pass populates immutable
15
+ * `indexes.bindings` (from explicit `using` directives), walk each
16
+ * file's tree-sitter AST for `namespace_declaration` /
17
+ * `file_scoped_namespace_declaration` and `using_directive` nodes.
18
+ * The orchestrator hands us its `treeCache` so files already parsed
19
+ * by `extractParsedFile` are re-used instead of re-parsed —
20
+ * `ParsedFile`'s underlying tree is the single source of truth.
21
+ * Group classes by namespace, and append cross-file sibling classes
22
+ * into each Namespace scope's `bindingAugmentations` bucket with
23
+ * `origin: 'namespace'`. Finalized bindings remain first in
24
+ * `lookupBindingsAt`, and local lexical `Scope.bindings` remains the
25
+ * first-tier shadowing channel.
25
26
  *
26
27
  * The tree-sitter walk is authoritative: it sees `global using static`,
27
28
  * aliased `using static X = Y.Z;`, attributed namespace declarations,
@@ -42,8 +43,8 @@ export interface CsharpSiblingInputs {
42
43
  };
43
44
  }
44
45
  /**
45
- * Mutate `indexes.bindings` in-place, adding cross-file sibling class
46
- * defs to each Namespace scope. Class-like defs (Class / Interface /
46
+ * Append cross-file sibling class defs to each Namespace scope's
47
+ * `bindingAugmentations` bucket. Class-like defs (Class / Interface /
47
48
  * Struct / Record / Enum) are visible cross-file; method / field
48
49
  * members are not.
49
50
  */
@@ -11,17 +11,18 @@
11
11
  * field-chain resolution fails at `findClassBindingInScope('User')`
12
12
  * in the Service.cs scope chain.
13
13
  *
14
- * Implementation: after the finalize pass populates `indexes.bindings`
15
- * (from explicit `using` directives), walk each file's tree-sitter
16
- * AST for `namespace_declaration` / `file_scoped_namespace_declaration`
17
- * and `using_directive` nodes. The orchestrator hands us its
18
- * `treeCache` so files already parsed by `extractParsedFile` are
19
- * re-used instead of re-parsed — `ParsedFile`'s underlying tree is
20
- * the single source of truth. Group classes by namespace, and inject
21
- * cross-file sibling classes into each Namespace scope's finalized
22
- * bindings with `origin: 'namespace'` — a tier below `local` so a
23
- * local declaration still shadows a cross-file sibling with the same
24
- * name.
14
+ * Implementation: after the finalize pass populates immutable
15
+ * `indexes.bindings` (from explicit `using` directives), walk each
16
+ * file's tree-sitter AST for `namespace_declaration` /
17
+ * `file_scoped_namespace_declaration` and `using_directive` nodes.
18
+ * The orchestrator hands us its `treeCache` so files already parsed
19
+ * by `extractParsedFile` are re-used instead of re-parsed —
20
+ * `ParsedFile`'s underlying tree is the single source of truth.
21
+ * Group classes by namespace, and append cross-file sibling classes
22
+ * into each Namespace scope's `bindingAugmentations` bucket with
23
+ * `origin: 'namespace'`. Finalized bindings remain first in
24
+ * `lookupBindingsAt`, and local lexical `Scope.bindings` remains the
25
+ * first-tier shadowing channel.
25
26
  *
26
27
  * The tree-sitter walk is authoritative: it sees `global using static`,
27
28
  * aliased `using static X = Y.Z;`, attributed namespace declarations,
@@ -30,13 +31,17 @@
30
31
  * coincidences).
31
32
  */
32
33
  import { getCsharpParser } from './query.js';
34
+ import { getTreeSitterBufferSize } from '../../constants.js';
33
35
  /** Build a structural view of a C# file by walking the tree-sitter
34
36
  * AST. Prefers `cachedTree` (handed in via `treeCache`) so we don't
35
37
  * re-parse files the orchestrator already parsed for `extractParsedFile`;
36
38
  * falls back to a fresh parse on cache miss. Parser singleton is
37
39
  * shared across calls. */
38
40
  function extractFileStructure(content, cachedTree) {
39
- const tree = cachedTree ?? getCsharpParser().parse(content);
41
+ const tree = cachedTree ??
42
+ getCsharpParser().parse(content, undefined, {
43
+ bufferSize: getTreeSitterBufferSize(content),
44
+ });
40
45
  const namespaces = [];
41
46
  const usingStaticPaths = [];
42
47
  const visit = (node) => {
@@ -81,8 +86,8 @@ function extractFileStructure(content, cachedTree) {
81
86
  return { namespaces, usingStaticPaths };
82
87
  }
83
88
  /**
84
- * Mutate `indexes.bindings` in-place, adding cross-file sibling class
85
- * defs to each Namespace scope. Class-like defs (Class / Interface /
89
+ * Append cross-file sibling class defs to each Namespace scope's
90
+ * `bindingAugmentations` bucket. Class-like defs (Class / Interface /
86
91
  * Struct / Record / Enum) are visible cross-file; method / field
87
92
  * members are not.
88
93
  */
@@ -161,12 +166,15 @@ export function populateCsharpNamespaceSiblings(parsedFiles, indexes, inputs) {
161
166
  }
162
167
  }
163
168
  }
164
- // Inject cross-file siblings into each namespace scope's finalized
165
- // bindings. `indexes.bindings` is typed `ReadonlyMap<ScopeId, ...>`
166
- // but is a plain Map at runtime; mutating here is the established
167
- // pattern (see `propagateImportedReturnTypes` which does the same
168
- // for module-scope typeBindings).
169
- const finalized = indexes.bindings;
169
+ // Inject cross-file siblings into each namespace scope's
170
+ // post-finalize augmentation channel (per I8). The
171
+ // `indexes.bindingAugmentations` map is the dedicated mutable
172
+ // append-only buffer for post-finalize hooks: inner `BindingRef[]`
173
+ // arrays here are NEVER frozen (unlike `indexes.bindings`, which
174
+ // `materializeBindings` freezes). Walkers consult both channels
175
+ // via `lookupBindingsAt`; we never need to consult or mutate
176
+ // `indexes.bindings`.
177
+ const augmentations = indexes.bindingAugmentations;
170
178
  // Cross-namespace type-binding propagation: for each file, mirror
171
179
  // method return-type bindings from same-namespace sibling files and
172
180
  // from files in namespaces the importer `using`s, into the
@@ -268,18 +276,14 @@ export function populateCsharpNamespaceSiblings(parsedFiles, indexes, inputs) {
268
276
  const simpleName = mq.includes('.') ? mq.slice(mq.lastIndexOf('.') + 1) : mq;
269
277
  if (simpleName === '')
270
278
  continue;
271
- // Add to `indexes.bindings[moduleScope]` so
272
- // `findCallableBindingInScope` picks it up.
273
- let scopeBindings = finalized.get(moduleScope.id);
274
- if (scopeBindings === undefined) {
275
- scopeBindings = new Map();
276
- finalized.set(moduleScope.id, scopeBindings);
277
- }
278
- const existing = scopeBindings.get(simpleName) ?? [];
279
- if (existing.some((b) => b.def.nodeId === memberDef.nodeId))
279
+ // Append to the augmentation bucket for the importer's module
280
+ // scope. `findCallableBindingInScope` reads via
281
+ // `lookupBindingsAt`, which fans out across `bindings` +
282
+ // `bindingAugmentations`.
283
+ const bucketArr = getAugmentationBucket(augmentations, moduleScope.id, simpleName);
284
+ if (bucketArr.some((b) => b.def.nodeId === memberDef.nodeId))
280
285
  continue;
281
- existing.push({ def: memberDef, origin: 'import' });
282
- scopeBindings.set(simpleName, existing);
286
+ bucketArr.push({ def: memberDef, origin: 'import' });
283
287
  }
284
288
  }
285
289
  }
@@ -310,16 +314,10 @@ export function populateCsharpNamespaceSiblings(parsedFiles, indexes, inputs) {
310
314
  const simpleName = q.includes('.') ? q.slice(q.lastIndexOf('.') + 1) : q;
311
315
  if (simpleName === '')
312
316
  continue;
313
- let scopeBindings = finalized.get(moduleScope.id);
314
- if (scopeBindings === undefined) {
315
- scopeBindings = new Map();
316
- finalized.set(moduleScope.id, scopeBindings);
317
- }
318
- const existing = scopeBindings.get(simpleName) ?? [];
319
- if (existing.some((b) => b.def.nodeId === def.nodeId))
317
+ const bucketArr = getAugmentationBucket(augmentations, moduleScope.id, simpleName);
318
+ if (bucketArr.some((b) => b.def.nodeId === def.nodeId))
320
319
  continue;
321
- existing.push({ def, origin: 'namespace' });
322
- scopeBindings.set(simpleName, existing);
320
+ bucketArr.push({ def, origin: 'namespace' });
323
321
  }
324
322
  }
325
323
  }
@@ -339,11 +337,6 @@ export function populateCsharpNamespaceSiblings(parsedFiles, indexes, inputs) {
339
337
  defsByName.set(key, arr);
340
338
  }
341
339
  for (const { scopeId, filePath } of bucket.scopes) {
342
- let scopeBindings = finalized.get(scopeId);
343
- if (scopeBindings === undefined) {
344
- scopeBindings = new Map();
345
- finalized.set(scopeId, scopeBindings);
346
- }
347
340
  for (const [name, defs] of defsByName) {
348
341
  // Skip names already present locally — `origin: 'local'` in
349
342
  // scope.bindings would naturally shadow the cross-file
@@ -351,20 +344,39 @@ export function populateCsharpNamespaceSiblings(parsedFiles, indexes, inputs) {
351
344
  const local = bucket.scopes.find((s) => s.filePath === filePath)?.scope.bindings.get(name);
352
345
  if (local !== undefined && local.some((b) => b.origin === 'local'))
353
346
  continue;
354
- const existing = scopeBindings.get(name) ?? [];
347
+ let bucketArr = null;
355
348
  for (const def of defs) {
356
349
  if (def.filePath === filePath)
357
350
  continue; // don't self-reference
358
- if (existing.some((b) => b.def.nodeId === def.nodeId))
351
+ if (bucketArr === null)
352
+ bucketArr = getAugmentationBucket(augmentations, scopeId, name);
353
+ if (bucketArr.some((b) => b.def.nodeId === def.nodeId))
359
354
  continue;
360
- existing.push({ def, origin: 'namespace' });
355
+ bucketArr.push({ def, origin: 'namespace' });
361
356
  }
362
- if (existing.length > 0)
363
- scopeBindings.set(name, existing);
364
357
  }
365
358
  }
366
359
  }
367
360
  }
361
+ /** Get-or-create a mutable inner bucket inside the `bindingAugmentations`
362
+ * channel. The inner arrays here are mutable by contract (see
363
+ * `ScopeResolutionIndexes.bindingAugmentations` doc + scope-resolver I8);
364
+ * callers may `push` directly. Allocating the outer/inner Maps lazily
365
+ * keeps the augmentation footprint zero for files with no cross-file
366
+ * fanout. */
367
+ function getAugmentationBucket(augmentations, scopeId, name) {
368
+ let scopeBindings = augmentations.get(scopeId);
369
+ if (scopeBindings === undefined) {
370
+ scopeBindings = new Map();
371
+ augmentations.set(scopeId, scopeBindings);
372
+ }
373
+ let bucketArr = scopeBindings.get(name);
374
+ if (bucketArr === undefined) {
375
+ bucketArr = [];
376
+ scopeBindings.set(name, bucketArr);
377
+ }
378
+ return bucketArr;
379
+ }
368
380
  function isTypeDef(def) {
369
381
  return (def.type === 'Class' ||
370
382
  def.type === 'Interface' ||
@@ -21,6 +21,8 @@ import { getPythonParser, getPythonScopeQuery } from './query.js';
21
21
  import { synthesizeReceiverTypeBinding } from './receiver-binding.js';
22
22
  import { computePythonArityMetadata } from './arity-metadata.js';
23
23
  import { recordCacheHit, recordCacheMiss } from './cache-stats.js';
24
+ import { getTreeSitterBufferSize } from '../../constants.js';
25
+ import { pythonFunctionDefinitionLabel } from './simple-hooks.js';
24
26
  export function emitPythonScopeCaptures(sourceText, _filePath, cachedTree) {
25
27
  // Skip the parse when the caller (parse phase's ASTCache) already
26
28
  // produced a Tree for this source. Cache miss = re-parse, same as
@@ -29,7 +31,9 @@ export function emitPythonScopeCaptures(sourceText, _filePath, cachedTree) {
29
31
  // here at the use site.
30
32
  let tree = cachedTree;
31
33
  if (tree === undefined) {
32
- tree = getPythonParser().parse(sourceText);
34
+ tree = getPythonParser().parse(sourceText, undefined, {
35
+ bufferSize: getTreeSitterBufferSize(sourceText),
36
+ });
33
37
  recordCacheMiss();
34
38
  }
35
39
  else {
@@ -83,6 +87,10 @@ export function emitPythonScopeCaptures(sourceText, _filePath, cachedTree) {
83
87
  const anchorCap = grouped['@declaration.function'];
84
88
  const fnNode = findNodeAtRange(tree.rootNode, anchorCap.range, 'function_definition');
85
89
  if (fnNode !== null) {
90
+ if (pythonFunctionDefinitionLabel(fnNode, 'Function') === 'Method') {
91
+ delete grouped['@declaration.function'];
92
+ grouped['@declaration.method'] = { ...anchorCap, name: '@declaration.method' };
93
+ }
86
94
  const arity = computePythonArityMetadata(fnNode);
87
95
  if (arity.parameterCount !== undefined) {
88
96
  grouped['@declaration.parameter-count'] = syntheticCapture('@declaration.parameter-count', fnNode, String(arity.parameterCount));
@@ -77,4 +77,4 @@ export { interpretPythonImport, interpretPythonTypeBinding } from './interpret.j
77
77
  export { pythonMergeBindings } from './merge-bindings.js';
78
78
  export { pythonArityCompatibility } from './arity.js';
79
79
  export { resolvePythonImportTarget, type PythonResolveContext } from './import-target.js';
80
- export { pythonBindingScopeFor, pythonImportOwningScope, pythonReceiverBinding, } from './simple-hooks.js';
80
+ export { pythonBindingScopeFor, pythonFunctionDefinitionLabel, pythonImportOwningScope, pythonReceiverBinding, } from './simple-hooks.js';
@@ -77,4 +77,4 @@ export { interpretPythonImport, interpretPythonTypeBinding } from './interpret.j
77
77
  export { pythonMergeBindings } from './merge-bindings.js';
78
78
  export { pythonArityCompatibility } from './arity.js';
79
79
  export { resolvePythonImportTarget } from './import-target.js';
80
- export { pythonBindingScopeFor, pythonImportOwningScope, pythonReceiverBinding, } from './simple-hooks.js';
80
+ export { pythonBindingScopeFor, pythonFunctionDefinitionLabel, pythonImportOwningScope, pythonReceiverBinding, } from './simple-hooks.js';
@@ -5,7 +5,9 @@
5
5
  * "absence == default") so reviewers don't have to re-derive the
6
6
  * analysis.
7
7
  */
8
- import type { CaptureMatch, ParsedImport, Scope, ScopeId, ScopeTree, TypeRef } from '../../../../_shared/index.js';
8
+ import type { CaptureMatch, NodeLabel, ParsedImport, Scope, ScopeId, ScopeTree, TypeRef } from '../../../../_shared/index.js';
9
+ import type { SyntaxNode } from 'tree-sitter';
10
+ export declare function pythonFunctionDefinitionLabel(functionNode: SyntaxNode, defaultLabel: NodeLabel): NodeLabel;
9
11
  /** Python has no block scope, so the central extractor's "innermost
10
12
  * enclosing scope" default is already correct: `for x in …` creates
11
13
  * `x` in the enclosing function/module scope (because we never emit a
@@ -5,6 +5,14 @@
5
5
  * "absence == default") so reviewers don't have to re-derive the
6
6
  * analysis.
7
7
  */
8
+ import { findAncestorBeforeBoundary, FUNCTION_NODE_TYPES } from '../../utils/ast-helpers.js';
9
+ const PYTHON_METHOD_CONTAINER_TYPES = new Set(['class_definition']);
10
+ export function pythonFunctionDefinitionLabel(functionNode, defaultLabel) {
11
+ if (defaultLabel !== 'Function')
12
+ return defaultLabel;
13
+ const ancestor = findAncestorBeforeBoundary(functionNode, PYTHON_METHOD_CONTAINER_TYPES, FUNCTION_NODE_TYPES);
14
+ return ancestor === null ? 'Function' : 'Method';
15
+ }
8
16
  // ─── bindingScopeFor ──────────────────────────────────────────────────────
9
17
  /** Python has no block scope, so the central extractor's "innermost
10
18
  * enclosing scope" default is already correct: `for x in …` creates
@@ -28,7 +28,7 @@ import { pythonVariableConfig } from '../variable-extractors/configs/python.js';
28
28
  import { createCallExtractor } from '../call-extractors/generic.js';
29
29
  import { pythonCallConfig } from '../call-extractors/configs/python.js';
30
30
  import { createHeritageExtractor } from '../heritage-extractors/generic.js';
31
- import { emitPythonScopeCaptures, interpretPythonImport, interpretPythonTypeBinding, pythonArityCompatibility, pythonBindingScopeFor, pythonImportOwningScope, pythonMergeBindings, pythonReceiverBinding, resolvePythonImportTarget, } from './python/index.js';
31
+ import { emitPythonScopeCaptures, pythonFunctionDefinitionLabel, interpretPythonImport, interpretPythonTypeBinding, pythonArityCompatibility, pythonBindingScopeFor, pythonImportOwningScope, pythonMergeBindings, pythonReceiverBinding, resolvePythonImportTarget, } from './python/index.js';
32
32
  const BUILT_INS = new Set([
33
33
  'print',
34
34
  'len',
@@ -58,6 +58,31 @@ const BUILT_INS = new Set([
58
58
  'sum',
59
59
  'abs',
60
60
  ]);
61
+ function pythonDescriptionExtractor(nodeLabel, _nodeName, captureMap) {
62
+ if (nodeLabel !== 'Function' && nodeLabel !== 'Method')
63
+ return undefined;
64
+ const functionNode = captureMap['definition.function'] ?? captureMap['definition.method'];
65
+ if (functionNode === undefined)
66
+ return undefined;
67
+ return extractPythonDocstring(functionNode);
68
+ }
69
+ function extractPythonDocstring(functionNode) {
70
+ const body = functionNode.childForFieldName('body');
71
+ const firstStatement = body?.namedChild(0);
72
+ if (firstStatement?.type !== 'expression_statement')
73
+ return undefined;
74
+ const literal = firstStatement.namedChild(0);
75
+ if (literal?.type !== 'string')
76
+ return undefined;
77
+ return normalizePythonStringLiteral(literal.text);
78
+ }
79
+ function normalizePythonStringLiteral(text) {
80
+ const match = text.match(/^[rRuUbBfF]*("""|'''|"|')([\s\S]*)\1$/);
81
+ const raw = match?.[2]?.trim();
82
+ if (!raw)
83
+ return undefined;
84
+ return raw.replace(/\s+/g, ' ');
85
+ }
61
86
  export const pythonProvider = defineLanguage({
62
87
  id: SupportedLanguages.Python,
63
88
  extensions: ['.py'],
@@ -74,7 +99,9 @@ export const pythonProvider = defineLanguage({
74
99
  variableExtractor: createVariableExtractor(pythonVariableConfig),
75
100
  classExtractor: createClassExtractor(pythonClassConfig),
76
101
  heritageExtractor: createHeritageExtractor(SupportedLanguages.Python),
102
+ descriptionExtractor: pythonDescriptionExtractor,
77
103
  builtInNames: BUILT_INS,
104
+ labelOverride: pythonFunctionDefinitionLabel,
78
105
  // ── RFC #909 Ring 3: scope-based resolution hooks (RFC §5) ──────────
79
106
  // Python is the first migration. See ./python/index.ts for the
80
107
  // full per-hook rationale and the canonical capture vocabulary in
@@ -112,6 +112,19 @@ const swiftExtractFunctionName = (node) => {
112
112
  return { funcName: 'deinit', label: 'Constructor' };
113
113
  return null; // fall through to generic
114
114
  };
115
+ const orderSwiftSameNameTypeCandidates = ({ callSiteFilePath, candidates, }) => {
116
+ if (!callSiteFilePath.endsWith('.swift'))
117
+ return null;
118
+ if (candidates.length <= 1)
119
+ return null;
120
+ if (!candidates.every((c) => c.type === candidates[0].type))
121
+ return null;
122
+ if (candidates[0].type !== 'Class' && candidates[0].type !== 'Struct')
123
+ return null;
124
+ if (!candidates.every((c) => c.filePath.endsWith('.swift')))
125
+ return null;
126
+ return [...candidates].sort((a, b) => a.filePath.length - b.filePath.length || a.filePath.localeCompare(b.filePath));
127
+ };
115
128
  const BUILT_INS = new Set([
116
129
  'print',
117
130
  'debugPrint',
@@ -240,5 +253,6 @@ export const swiftProvider = defineLanguage({
240
253
  classExtractor: createClassExtractor(swiftClassConfig),
241
254
  heritageExtractor: createHeritageExtractor(SupportedLanguages.Swift),
242
255
  implicitImportWirer: wireSwiftImplicitImports,
256
+ orderSameNameTypeCandidates: orderSwiftSameNameTypeCandidates,
243
257
  builtInNames: BUILT_INS,
244
258
  });
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Extract TypeScript arity metadata from a method-like tree-sitter node —
3
+ * `method_definition`, `method_signature`, `abstract_method_signature`,
4
+ * `function_declaration`, `generator_function_declaration`, or
5
+ * `function_signature` (overload signature).
6
+ *
7
+ * Reuses `typescriptMethodConfig.extractParameters` so scope-extracted defs
8
+ * carry the same arity semantics as the legacy parse-worker path:
9
+ * - Rest parameters (`...args: T[]`) collapse `parameterCount` to
10
+ * `undefined`, which `typescriptArityCompatibility` treats as
11
+ * "max unknown" — the candidate stays eligible at
12
+ * `argCount >= required` (mirrors Python `*args` / C# `params`).
13
+ * - Optional (`p?: T`) and defaulted (`p: T = …`) parameters both
14
+ * contribute to `optionalCount`;
15
+ * `requiredParameterCount = total − optionalCount`.
16
+ * - `parameterTypes` collects declared type-annotation text for
17
+ * overload narrowing; TypeScript supports function overloading
18
+ * (`function f(x: string); function f(x: number); function f(x) {}`),
19
+ * so populated types let the registry disambiguate same-arity
20
+ * siblings by declared types.
21
+ * - A literal `'params'` marker is appended for variadic methods so
22
+ * `typescriptArityCompatibility` can detect rest params without
23
+ * re-reading the AST.
24
+ *
25
+ * ## Generics stripping
26
+ *
27
+ * TypeScript parameter types frequently contain generic instantiations
28
+ * (`User<string>`, `Array<User>`, `Promise<User[]>`). For overload
29
+ * narrowing by declared type, we want the "head" name — `User`,
30
+ * `Array`, `Promise` — so `arity-metadata` applies a light strip to
31
+ * each `parameterTypes[i]`:
32
+ *
33
+ * - `Foo<Bar>` → `Foo`
34
+ * - `Foo<Bar, Baz>` → `Foo`
35
+ * - `Foo[]` → `Foo`
36
+ * - `Foo<Bar>[]` → `Foo`
37
+ * - `Foo<Bar<Baz>>` → `Foo` (greedy — strip the outermost once)
38
+ * - plain `Foo` → `Foo`
39
+ *
40
+ * We do NOT strip unions / intersections at this layer — those stay
41
+ * intact because the registry's overload narrowing is a string
42
+ * equality check; union types shouldn't match anything and we prefer
43
+ * "unknown" to "accidental match". `undefined` / `null` in unions
44
+ * (TS strict mode) is handled by `interpret.ts`'s `stripNullableUnion`
45
+ * when the name would be consumed as a receiver type — that path is
46
+ * separate from this arity-metadata path.
47
+ *
48
+ * Generic type parameters on the function itself (`function f<T>(x: T)`)
49
+ * do NOT enter here — the method extractor reads the `parameters`
50
+ * field only, which contains value parameters, not type parameters.
51
+ */
52
+ import type { SyntaxNode } from '../../utils/ast-helpers.js';
53
+ interface TsArityMetadata {
54
+ readonly parameterCount: number | undefined;
55
+ readonly requiredParameterCount: number | undefined;
56
+ readonly parameterTypes: readonly string[] | undefined;
57
+ }
58
+ export declare function computeTsArityMetadata(fnNode: SyntaxNode): TsArityMetadata;
59
+ export {};