gitnexus 1.6.5-rc.8 → 1.6.5

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 (335) hide show
  1. package/dist/_shared/scope-resolution/finalize-algorithm.js +10 -2
  2. package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
  3. package/dist/_shared/scope-resolution/method-dispatch-index.d.ts +26 -0
  4. package/dist/_shared/scope-resolution/method-dispatch-index.d.ts.map +1 -1
  5. package/dist/_shared/scope-resolution/method-dispatch-index.js +22 -3
  6. package/dist/_shared/scope-resolution/method-dispatch-index.js.map +1 -1
  7. package/dist/_shared/scope-resolution/registries/lookup-core.js +18 -1
  8. package/dist/_shared/scope-resolution/registries/lookup-core.js.map +1 -1
  9. package/dist/_shared/scope-resolution/symbol-definition.d.ts +2 -0
  10. package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
  11. package/dist/cli/ai-context.d.ts +1 -0
  12. package/dist/cli/ai-context.js +70 -16
  13. package/dist/cli/analyze.d.ts +30 -2
  14. package/dist/cli/analyze.js +45 -5
  15. package/dist/cli/index.js +8 -1
  16. package/dist/cli/setup.js +18 -0
  17. package/dist/cli/wiki.d.ts +2 -0
  18. package/dist/cli/wiki.js +11 -0
  19. package/dist/core/augmentation/engine.js +24 -4
  20. package/dist/core/embeddings/http-client.js +22 -6
  21. package/dist/core/incremental/shadow-candidates.d.ts +44 -0
  22. package/dist/core/incremental/shadow-candidates.js +74 -0
  23. package/dist/core/incremental/subgraph-extract.d.ts +64 -0
  24. package/dist/core/incremental/subgraph-extract.js +111 -0
  25. package/dist/core/ingestion/call-processor.d.ts +12 -1
  26. package/dist/core/ingestion/call-processor.js +183 -47
  27. package/dist/core/ingestion/class-extractors/configs/c-cpp.js +38 -0
  28. package/dist/core/ingestion/class-extractors/generic.js +8 -0
  29. package/dist/core/ingestion/class-types.d.ts +15 -0
  30. package/dist/core/ingestion/community-processor.js +18 -0
  31. package/dist/core/ingestion/import-resolvers/standard.d.ts +5 -0
  32. package/dist/core/ingestion/import-resolvers/standard.js +31 -1
  33. package/dist/core/ingestion/import-resolvers/utils.js +4 -0
  34. package/dist/core/ingestion/languages/c-cpp.js +20 -2
  35. package/dist/core/ingestion/languages/cpp/adl.d.ts +141 -0
  36. package/dist/core/ingestion/languages/cpp/adl.js +478 -0
  37. package/dist/core/ingestion/languages/cpp/arity-metadata.d.ts +18 -0
  38. package/dist/core/ingestion/languages/cpp/arity-metadata.js +170 -0
  39. package/dist/core/ingestion/languages/cpp/arity.d.ts +17 -0
  40. package/dist/core/ingestion/languages/cpp/arity.js +31 -0
  41. package/dist/core/ingestion/languages/cpp/captures.d.ts +2 -0
  42. package/dist/core/ingestion/languages/cpp/captures.js +1131 -0
  43. package/dist/core/ingestion/languages/cpp/conversion-rank.d.ts +31 -0
  44. package/dist/core/ingestion/languages/cpp/conversion-rank.js +47 -0
  45. package/dist/core/ingestion/languages/cpp/file-local-linkage.d.ts +118 -0
  46. package/dist/core/ingestion/languages/cpp/file-local-linkage.js +266 -0
  47. package/dist/core/ingestion/languages/cpp/header-scan.d.ts +8 -0
  48. package/dist/core/ingestion/languages/cpp/header-scan.js +50 -0
  49. package/dist/core/ingestion/languages/cpp/import-decomposer.d.ts +19 -0
  50. package/dist/core/ingestion/languages/cpp/import-decomposer.js +111 -0
  51. package/dist/core/ingestion/languages/cpp/import-target.d.ts +10 -0
  52. package/dist/core/ingestion/languages/cpp/import-target.js +13 -0
  53. package/dist/core/ingestion/languages/cpp/index.d.ts +11 -0
  54. package/dist/core/ingestion/languages/cpp/index.js +11 -0
  55. package/dist/core/ingestion/languages/cpp/inline-namespaces.d.ts +67 -0
  56. package/dist/core/ingestion/languages/cpp/inline-namespaces.js +176 -0
  57. package/dist/core/ingestion/languages/cpp/interpret.d.ts +35 -0
  58. package/dist/core/ingestion/languages/cpp/interpret.js +113 -0
  59. package/dist/core/ingestion/languages/cpp/merge-bindings.d.ts +13 -0
  60. package/dist/core/ingestion/languages/cpp/merge-bindings.js +29 -0
  61. package/dist/core/ingestion/languages/cpp/query.d.ts +3 -0
  62. package/dist/core/ingestion/languages/cpp/query.js +508 -0
  63. package/dist/core/ingestion/languages/cpp/range-bindings.d.ts +20 -0
  64. package/dist/core/ingestion/languages/cpp/range-bindings.js +212 -0
  65. package/dist/core/ingestion/languages/cpp/scope-resolver.d.ts +17 -0
  66. package/dist/core/ingestion/languages/cpp/scope-resolver.js +246 -0
  67. package/dist/core/ingestion/languages/cpp/simple-hooks.d.ts +24 -0
  68. package/dist/core/ingestion/languages/cpp/simple-hooks.js +62 -0
  69. package/dist/core/ingestion/languages/cpp/two-phase-lookup.d.ts +76 -0
  70. package/dist/core/ingestion/languages/cpp/two-phase-lookup.js +195 -0
  71. package/dist/core/ingestion/languages/java/arity-metadata.d.ts +18 -0
  72. package/dist/core/ingestion/languages/java/arity-metadata.js +40 -0
  73. package/dist/core/ingestion/languages/java/arity.d.ts +10 -0
  74. package/dist/core/ingestion/languages/java/arity.js +24 -0
  75. package/dist/core/ingestion/languages/java/cache-stats.d.ts +15 -0
  76. package/dist/core/ingestion/languages/java/cache-stats.js +26 -0
  77. package/dist/core/ingestion/languages/java/captures.d.ts +17 -0
  78. package/dist/core/ingestion/languages/java/captures.js +187 -0
  79. package/dist/core/ingestion/languages/java/import-decomposer.d.ts +18 -0
  80. package/dist/core/ingestion/languages/java/import-decomposer.js +85 -0
  81. package/dist/core/ingestion/languages/java/import-target.d.ts +17 -0
  82. package/dist/core/ingestion/languages/java/import-target.js +100 -0
  83. package/dist/core/ingestion/languages/java/index.d.ts +29 -0
  84. package/dist/core/ingestion/languages/java/index.js +29 -0
  85. package/dist/core/ingestion/languages/java/interpret.d.ts +13 -0
  86. package/dist/core/ingestion/languages/java/interpret.js +131 -0
  87. package/dist/core/ingestion/languages/java/merge-bindings.d.ts +12 -0
  88. package/dist/core/ingestion/languages/java/merge-bindings.js +40 -0
  89. package/dist/core/ingestion/languages/java/query.d.ts +30 -0
  90. package/dist/core/ingestion/languages/java/query.js +192 -0
  91. package/dist/core/ingestion/languages/java/receiver-binding.d.ts +11 -0
  92. package/dist/core/ingestion/languages/java/receiver-binding.js +95 -0
  93. package/dist/core/ingestion/languages/java/scope-resolver.d.ts +50 -0
  94. package/dist/core/ingestion/languages/java/scope-resolver.js +74 -0
  95. package/dist/core/ingestion/languages/java/simple-hooks.d.ts +13 -0
  96. package/dist/core/ingestion/languages/java/simple-hooks.js +34 -0
  97. package/dist/core/ingestion/languages/java.js +11 -0
  98. package/dist/core/ingestion/languages/php/arity-metadata.d.ts +28 -0
  99. package/dist/core/ingestion/languages/php/arity-metadata.js +63 -0
  100. package/dist/core/ingestion/languages/php/arity.d.ts +25 -0
  101. package/dist/core/ingestion/languages/php/arity.js +40 -0
  102. package/dist/core/ingestion/languages/php/cache-stats.d.ts +15 -0
  103. package/dist/core/ingestion/languages/php/cache-stats.js +26 -0
  104. package/dist/core/ingestion/languages/php/captures.d.ts +34 -0
  105. package/dist/core/ingestion/languages/php/captures.js +739 -0
  106. package/dist/core/ingestion/languages/php/import-decomposer.d.ts +28 -0
  107. package/dist/core/ingestion/languages/php/import-decomposer.js +265 -0
  108. package/dist/core/ingestion/languages/php/import-target.d.ts +47 -0
  109. package/dist/core/ingestion/languages/php/import-target.js +100 -0
  110. package/dist/core/ingestion/languages/php/index.d.ts +68 -0
  111. package/dist/core/ingestion/languages/php/index.js +72 -0
  112. package/dist/core/ingestion/languages/php/interpret.d.ts +36 -0
  113. package/dist/core/ingestion/languages/php/interpret.js +241 -0
  114. package/dist/core/ingestion/languages/php/merge-bindings.d.ts +19 -0
  115. package/dist/core/ingestion/languages/php/merge-bindings.js +47 -0
  116. package/dist/core/ingestion/languages/php/namespace-siblings.d.ts +51 -0
  117. package/dist/core/ingestion/languages/php/namespace-siblings.js +288 -0
  118. package/dist/core/ingestion/languages/php/query.d.ts +32 -0
  119. package/dist/core/ingestion/languages/php/query.js +326 -0
  120. package/dist/core/ingestion/languages/php/receiver-binding.d.ts +36 -0
  121. package/dist/core/ingestion/languages/php/receiver-binding.js +128 -0
  122. package/dist/core/ingestion/languages/php/scope-resolver.d.ts +23 -0
  123. package/dist/core/ingestion/languages/php/scope-resolver.js +358 -0
  124. package/dist/core/ingestion/languages/php/simple-hooks.d.ts +42 -0
  125. package/dist/core/ingestion/languages/php/simple-hooks.js +111 -0
  126. package/dist/core/ingestion/languages/php.d.ts +0 -7
  127. package/dist/core/ingestion/languages/php.js +15 -0
  128. package/dist/core/ingestion/markdown-processor.js +6 -1
  129. package/dist/core/ingestion/model/symbol-table.d.ts +1 -0
  130. package/dist/core/ingestion/model/symbol-table.js +3 -0
  131. package/dist/core/ingestion/parsing-processor.d.ts +22 -2
  132. package/dist/core/ingestion/parsing-processor.js +123 -50
  133. package/dist/core/ingestion/pipeline-phases/cross-file-impl.js +54 -2
  134. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +5 -0
  135. package/dist/core/ingestion/pipeline-phases/parse-impl.js +119 -11
  136. package/dist/core/ingestion/pipeline-phases/parse.d.ts +14 -0
  137. package/dist/core/ingestion/pipeline.d.ts +13 -0
  138. package/dist/core/ingestion/registry-primary-flag.js +2 -0
  139. package/dist/core/ingestion/scope-extractor.js +4 -0
  140. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +167 -0
  141. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +3 -0
  142. package/dist/core/ingestion/scope-resolution/graph-bridge/ids.d.ts +1 -0
  143. package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +12 -0
  144. package/dist/core/ingestion/scope-resolution/graph-bridge/method-dispatch.d.ts +1 -1
  145. package/dist/core/ingestion/scope-resolution/graph-bridge/method-dispatch.js +12 -2
  146. package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +16 -0
  147. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +36 -0
  148. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +204 -13
  149. package/dist/core/ingestion/scope-resolution/passes/imported-return-types.js +1 -1
  150. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +55 -4
  151. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +186 -5
  152. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +10 -1
  153. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +207 -9
  154. package/dist/core/ingestion/scope-resolution/pipeline/phase.js +13 -1
  155. package/dist/core/ingestion/scope-resolution/pipeline/registry.js +6 -0
  156. package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +17 -0
  157. package/dist/core/ingestion/scope-resolution/pipeline/run.js +86 -8
  158. package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +30 -0
  159. package/dist/core/ingestion/scope-resolution/scope/walkers.js +90 -8
  160. package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
  161. package/dist/core/ingestion/tree-sitter-queries.js +23 -0
  162. package/dist/core/ingestion/utils/ast-helpers.js +6 -1
  163. package/dist/core/ingestion/utils/template-arguments.d.ts +11 -0
  164. package/dist/core/ingestion/utils/template-arguments.js +65 -0
  165. package/dist/core/ingestion/workers/parse-worker.d.ts +3 -0
  166. package/dist/core/ingestion/workers/parse-worker.js +42 -1
  167. package/dist/core/lbug/lbug-adapter.d.ts +39 -0
  168. package/dist/core/lbug/lbug-adapter.js +348 -48
  169. package/dist/core/run-analyze.d.ts +2 -0
  170. package/dist/core/run-analyze.js +323 -29
  171. package/dist/core/search/hybrid-search.d.ts +3 -0
  172. package/dist/core/search/hybrid-search.js +23 -6
  173. package/dist/core/wiki/generator.js +4 -3
  174. package/dist/core/wiki/html-viewer.js +2 -1
  175. package/dist/core/wiki/llm-client.d.ts +4 -0
  176. package/dist/core/wiki/llm-client.js +3 -3
  177. package/dist/core/wiki/mermaid-sanitizer.d.ts +2 -0
  178. package/dist/core/wiki/mermaid-sanitizer.js +100 -0
  179. package/dist/mcp/local/local-backend.js +20 -7
  180. package/dist/storage/file-hash.d.ts +47 -0
  181. package/dist/storage/file-hash.js +86 -0
  182. package/dist/storage/parse-cache.d.ts +73 -0
  183. package/dist/storage/parse-cache.js +253 -0
  184. package/dist/storage/repo-manager.d.ts +41 -1
  185. package/dist/storage/repo-manager.js +61 -6
  186. package/hooks/claude/gitnexus-hook.cjs +42 -4
  187. package/hooks/claude/hook-db-lock-probe.cjs +238 -0
  188. package/hooks/claude/hook-lock.cjs +119 -0
  189. package/hooks/claude/win-rm-list-json.ps1 +76 -0
  190. package/package.json +1 -1
  191. package/scripts/build.js +6 -2
  192. package/vendor/node_modules/node-addon-api/node_addon_api.target.mk +16 -16
  193. package/vendor/node_modules/node-addon-api/node_addon_api_except.target.mk +16 -16
  194. package/vendor/node_modules/node-addon-api/node_addon_api_except_all.target.mk +16 -16
  195. package/vendor/node_modules/node-addon-api/node_addon_api_maybe.target.mk +16 -16
  196. package/web/assets/{agent-BpHQleHE.js → agent-D2kLt6Dl.js} +91 -91
  197. package/web/assets/architecture-7EHR7CIX-6QZW5X65-BETj2x4g.js +1 -0
  198. package/web/assets/architectureDiagram-UL44E2DR-DvIkEGkp.js +36 -0
  199. package/web/assets/blockDiagram-7IZFK4PR-B4niSLvR.js +132 -0
  200. package/web/assets/{c4Diagram-DFAF54RM-DeJV1rCn.js → c4Diagram-Y2BXMSZH-DIzEXalR.js} +6 -6
  201. package/web/assets/chunk-2T2R6R2M-n6s9JZqv.js +4 -0
  202. package/web/assets/chunk-2UTLFMKG-CMBB1TMN.js +1 -0
  203. package/web/assets/{chunk-7RZVMHOQ-BdIU-RGO.js → chunk-3SSMPTDK-BzGeeheI.js} +1 -1
  204. package/web/assets/chunk-4R4BOZG6-mKhL59ul.js +159 -0
  205. package/web/assets/chunk-5IMINLNL-CnTLsXIV.js +1 -0
  206. package/web/assets/chunk-5VCL7Z4A-w1BCx98Z.js +1 -0
  207. package/web/assets/chunk-6764PJDD-ChwMM2z4.js +1 -0
  208. package/web/assets/chunk-67TQ5CYL-CChC2cAv.js +124 -0
  209. package/web/assets/chunk-7J6CGLKN-DT-b53FT.js +10 -0
  210. package/web/assets/chunk-7W6UQGC5-CgFyfZ6k.js +1 -0
  211. package/web/assets/chunk-AQ6EADP3-CCFje6lL.js +1 -0
  212. package/web/assets/{chunk-KSICW3F5-C2tZmXwv.js → chunk-AZZRMDJM-5E9ARdDQ.js} +1 -1
  213. package/web/assets/chunk-C62D2QBJ-CDAWj26E.js +1 -0
  214. package/web/assets/chunk-CEXFNPSA-D68Tk6ls.js +1 -0
  215. package/web/assets/chunk-INKRHTLW-ELpfuk9h.js +70 -0
  216. package/web/assets/chunk-J5EP6P6S-DxWW0yvu.js +1 -0
  217. package/web/assets/{chunk-AEOMTBSW-D7qjBMHW.js → chunk-JQRUD6KW-Dcq_Qnyy.js} +1 -1
  218. package/web/assets/chunk-KGFNY3KK-W-VR57xb.js +62 -0
  219. package/web/assets/chunk-KGYTTC2M-C6PHeuay.js +1 -0
  220. package/web/assets/chunk-KNLZD3CH-BuZBOcso.js +1 -0
  221. package/web/assets/chunk-KRXBNO2N-DH2NPM7I.js +1 -0
  222. package/web/assets/chunk-LCXTWHL2-CqJ0oo1x.js +231 -0
  223. package/web/assets/chunk-LII3EMHJ-3X33tCpU.js +1 -0
  224. package/web/assets/chunk-QA3QBVWF-D5Ha3GgB.js +2 -0
  225. package/web/assets/chunk-RERM46MO-DQNbXtfw.js +1 -0
  226. package/web/assets/chunk-RG4AUYOV-D0M6vdq9.js +206 -0
  227. package/web/assets/chunk-RKZBBQEN-BmTPLSyv.js +1 -0
  228. package/web/assets/chunk-RLI5ZMPA-DExu2DOK.js +1 -0
  229. package/web/assets/chunk-T2UQINTJ-kGYG7ppP.js +1 -0
  230. package/web/assets/chunk-T5OCTHI4--9wWpVws.js +1 -0
  231. package/web/assets/chunk-UP6H54XL-DsKdC6jC.js +1 -0
  232. package/web/assets/chunk-UXSXWOXI-DR81EqLr.js +1 -0
  233. package/web/assets/chunk-UY5QBCOK-Du-c56gs.js +1 -0
  234. package/web/assets/chunk-W44A43WB-lrCpuupA.js +1 -0
  235. package/web/assets/chunk-ZXARS5L4-CSZRiyOf.js +1 -0
  236. package/web/assets/classDiagram-KGZ6W3CR-BB-saqC1.js +1 -0
  237. package/web/assets/classDiagram-v2-72OJOZXJ-Bp2bAlS5.js +1 -0
  238. package/web/assets/cose-bilkent-UX7MHV2Q-BHv2bbtl.js +1 -0
  239. package/web/assets/dagre-ND4H6XIP-DsIr9MOv.js +4 -0
  240. package/web/assets/diagram-3NCE3AQN-BUxnDPOY.js +43 -0
  241. package/web/assets/diagram-GF46GFSD-BJTyqqvI.js +24 -0
  242. package/web/assets/diagram-HNR7UZ2L-fUWreZzx.js +3 -0
  243. package/web/assets/diagram-QXG6HAR7-DilMHamP.js +24 -0
  244. package/web/assets/diagram-WEQXMOUZ-8KUrarg1.js +10 -0
  245. package/web/assets/erDiagram-L5TCEMPS-Doj9mSiW.js +85 -0
  246. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-B3myHUst.js +1 -0
  247. package/web/assets/{flowDiagram-OTCZ4VVT-aAZw4c_M.js → flowDiagram-H6V6AXG4-BOSR-i3p.js} +12 -12
  248. package/web/assets/ganttDiagram-JCBTUEKG-BHQssTz6.js +292 -0
  249. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DF3rtf4A.js +1 -0
  250. package/web/assets/gitGraphDiagram-S2ZK5IYY-CCwVLT__.js +106 -0
  251. package/web/assets/index-j4-NuleT.js +623 -0
  252. package/web/assets/info-J43DQDTF-KCYPFFUO-R4XV_akJ.js +1 -0
  253. package/web/assets/infoDiagram-3YFTVSEB-Ce_TvtaV.js +2 -0
  254. package/web/assets/{ishikawaDiagram-YMYX4NHK-BF8AtDaj.js → ishikawaDiagram-BNXS4ZKH-4MXIDCSF.js} +6 -6
  255. package/web/assets/journeyDiagram-M6C3CM3L-DNPYCpvq.js +139 -0
  256. package/web/assets/kanban-definition-75IXJCU3-yYdfm8Kk.js +89 -0
  257. package/web/assets/{katex-GD7MH7QM-CJiOjBBJ.js → katex-K3KEBU37-CrVLz8l7.js} +1 -1
  258. package/web/assets/mindmap-definition-2TDM6QVE-DFNEKM77.js +96 -0
  259. package/web/assets/packet-YPE3B663-LP52Z2RK-CgQPdNZa.js +1 -0
  260. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BzWOwc_c.js +1 -0
  261. package/web/assets/pieDiagram-CU6KROY3-iZAqpvhd.js +30 -0
  262. package/web/assets/quadrantDiagram-VICAPDV7-bAm6Hi_5.js +7 -0
  263. package/web/assets/radar-GUYGQ44K-RDLRG3WG-B7KG0FN7.js +1 -0
  264. package/web/assets/requirementDiagram-JXO7QTGE-CtDijhnf.js +84 -0
  265. package/web/assets/sankeyDiagram-URQDO5SZ-LFJz53u5.js +40 -0
  266. package/web/assets/sequenceDiagram-VS2MUI6T-BdjvyCHM.js +162 -0
  267. package/web/assets/stateDiagram-7D4R322I-e5odN9fG.js +1 -0
  268. package/web/assets/stateDiagram-v2-36443NZ5-vPsvjR2D.js +1 -0
  269. package/web/assets/timeline-definition-O6YCAMPW-DPAksNQp.js +120 -0
  270. package/web/assets/treeView-BLDUP644-QA4HXRO3-CRSxEwLO.js +1 -0
  271. package/web/assets/treemap-LRROVOQU-LLAWBHMP-a0PfKoVn.js +1 -0
  272. package/web/assets/vennDiagram-MWXL3ELB-Dtlfdt7J.js +34 -0
  273. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-BKQ6e5mC.js +1 -0
  274. package/web/assets/wardleyDiagram-CUQ6CDDI-B23uRMUC.js +78 -0
  275. package/web/assets/{xychartDiagram-ZHJ5623Y-DZ7fP1_3.js → xychartDiagram-N2JHSOCM-DxwHeksW.js} +6 -6
  276. package/web/index.html +13 -2
  277. package/web/assets/architecture-YZFGNWBL-S5CXDPWN-BUzkWgDl.js +0 -1
  278. package/web/assets/architectureDiagram-EMZXCZ2Q-CXbzok1G.js +0 -36
  279. package/web/assets/blockDiagram-IGV67L2C-DA1QJ4ZB.js +0 -132
  280. package/web/assets/chunk-3GS5O3IE-B8hpnia8.js +0 -231
  281. package/web/assets/chunk-3YCYZ6SJ-B-BVu21C.js +0 -1
  282. package/web/assets/chunk-6NTNNK5N-DW-jYSDr.js +0 -1
  283. package/web/assets/chunk-A34GCYZU-BbZl-IKy.js +0 -1
  284. package/web/assets/chunk-DJ7UZH7F-B5tMfF87.js +0 -1
  285. package/web/assets/chunk-DKKBVRCY-Djm-6K_e.js +0 -4
  286. package/web/assets/chunk-DU5LTGQ6-QPoynYcp.js +0 -1
  287. package/web/assets/chunk-FXACKDTF-jieSmbe2.js +0 -159
  288. package/web/assets/chunk-H3VCZNTA-8EMHZ3SV.js +0 -1
  289. package/web/assets/chunk-HN6EAY2L-CgE_agsD.js +0 -1
  290. package/web/assets/chunk-O5ABG6QK-DEZV1O19.js +0 -1
  291. package/web/assets/chunk-PK6DOVAG-BXv0JnsJ.js +0 -206
  292. package/web/assets/chunk-RNJOYNJ4-BiBkF9dN.js +0 -1
  293. package/web/assets/chunk-RWUO3TPN-DTWzAhQ1.js +0 -1
  294. package/web/assets/chunk-TBF5ZNIQ-BSl6s9lT.js +0 -1
  295. package/web/assets/chunk-TU3PZOEN-DE5Qhc0N.js +0 -1
  296. package/web/assets/chunk-TYMNRAUI-D1NDLIMG.js +0 -1
  297. package/web/assets/chunk-VELTKBKT-C9dVN39o.js +0 -1
  298. package/web/assets/chunk-W7ZLLLMY-Bu-cdLzs.js +0 -1
  299. package/web/assets/chunk-WSB5WSVC-Dor71SOz.js +0 -1
  300. package/web/assets/chunk-XGPFEOL4-CUonLRle.js +0 -1
  301. package/web/assets/classDiagram-PPOCWD7C-Cdd6UdVv.js +0 -1
  302. package/web/assets/classDiagram-v2-23LJLIIU-DNhxY2Ib.js +0 -1
  303. package/web/assets/cose-bilkent-PNC4W37J-DdZq7Qz_.js +0 -1
  304. package/web/assets/dagre-E77IOHMT-Cfj_6e17.js +0 -4
  305. package/web/assets/diagram-H7BISOXX-BNvpsrBv.js +0 -43
  306. package/web/assets/diagram-JC5VWROH-Cn0rtDbJ.js +0 -24
  307. package/web/assets/diagram-LXUTUG65-CHfoVKNm.js +0 -10
  308. package/web/assets/diagram-WEHSV5V5-BLxHksnu.js +0 -24
  309. package/web/assets/erDiagram-GCSMX5X6-DfdN6iqF.js +0 -85
  310. package/web/assets/ganttDiagram-MUNLMDZQ-BEfC_7Or.js +0 -292
  311. package/web/assets/gitGraph-7Q5UKJZL-54BCDZD5-B6ZeRLP0.js +0 -1
  312. package/web/assets/gitGraphDiagram-3HKGZ4G3-CG0kC8Q5.js +0 -106
  313. package/web/assets/index-3NUCUW2s.js +0 -886
  314. package/web/assets/info-OMHHGYJF-BF2H5H6G-BIOsZy0W.js +0 -1
  315. package/web/assets/infoDiagram-MN7RKWGX-DUoMH-pq.js +0 -2
  316. package/web/assets/journeyDiagram-SO5T7YLQ-BW8oKa3N.js +0 -139
  317. package/web/assets/kanban-definition-LJHFXRCJ-DzbOsR-2.js +0 -89
  318. package/web/assets/mindmap-definition-2EUWGEK5-BIXGQALq.js +0 -96
  319. package/web/assets/packet-4T2RLAQJ-EV4IVRXR-Bs7ysNMU.js +0 -1
  320. package/web/assets/pie-ZZUOXDRM-N23DN5KN-Csi8nnbH.js +0 -1
  321. package/web/assets/pieDiagram-3IATQBI2-QY-u7P6a.js +0 -30
  322. package/web/assets/quadrantDiagram-E256RVCF-Di4aNiU8.js +0 -7
  323. package/web/assets/radar-PYXPWWZC-P6TP7ZYP-DJlyXh2-.js +0 -1
  324. package/web/assets/requirementDiagram-M5DCFWZL-CzUUrhQD.js +0 -84
  325. package/web/assets/sankeyDiagram-L3NBLAOT-D2fbMiIU.js +0 -10
  326. package/web/assets/sequenceDiagram-ZOUHS735-BNdkqguh.js +0 -157
  327. package/web/assets/stateDiagram-MLPALWAM-51_Q2w2L.js +0 -1
  328. package/web/assets/stateDiagram-v2-B5LQ5ZB2-8nHs2aNE.js +0 -1
  329. package/web/assets/timeline-definition-5SPVSISX-DkMiGj4Z.js +0 -120
  330. package/web/assets/treeView-SZITEDCU-5DXDK3XO-Cy6P0_CZ.js +0 -1
  331. package/web/assets/treemap-W4RFUUIX-WYLRDWKO-C_pp1R7A.js +0 -1
  332. package/web/assets/vennDiagram-IE5QUKF5-BCxMmf9q.js +0 -34
  333. package/web/assets/wardley-RL74JXVD-BCRCBASE-CMStJhpn.js +0 -1
  334. package/web/assets/wardleyDiagram-XU3VSMPF-ijlLF77s.js +0 -20
  335. /package/web/assets/{context-builder-CqQNhRj1.js → context-builder-_HS0v2ma.js} +0 -0
@@ -0,0 +1,1131 @@
1
+ import { findNodeAtRange, nodeToCapture, syntheticCapture, } from '../../utils/ast-helpers.js';
2
+ import { getCppParser, getCppScopeQuery } from './query.js';
3
+ import { getTreeSitterBufferSize } from '../../constants.js';
4
+ import { parseSourceSafe } from '../../../tree-sitter/safe-parse.js';
5
+ import { splitCppInclude, splitCppUsingDecl } from './import-decomposer.js';
6
+ import { computeCppDeclarationArity, computeCppCallArity } from './arity-metadata.js';
7
+ import { markCppAnonymousNamespaceRange, markFileLocal } from './file-local-linkage.js';
8
+ import { markCppDependentBase } from './two-phase-lookup.js';
9
+ import { markCppAdlSiteArgs, markCppAdlSiteNoAdl } from './adl.js';
10
+ import { markCppInlineNamespaceRange } from './inline-namespaces.js';
11
+ export function emitCppScopeCaptures(sourceText, filePath, cachedTree) {
12
+ let tree = cachedTree;
13
+ if (tree === undefined) {
14
+ tree = parseSourceSafe(getCppParser(), sourceText, undefined, {
15
+ bufferSize: getTreeSitterBufferSize(sourceText),
16
+ });
17
+ }
18
+ const rawMatches = getCppScopeQuery().matches(tree.rootNode);
19
+ const out = [];
20
+ // Track ranges where typedef-struct was captured as @declaration.struct
21
+ // so we can suppress the duplicate @declaration.typedef match.
22
+ const structTypedefRanges = new Set();
23
+ for (const m of rawMatches) {
24
+ const grouped = {};
25
+ for (const c of m.captures) {
26
+ const tag = '@' + c.name;
27
+ if (tag.startsWith('@_'))
28
+ continue;
29
+ grouped[tag] = nodeToCapture(tag, c.node);
30
+ }
31
+ if (Object.keys(grouped).length === 0)
32
+ continue;
33
+ // ── Handle #include statements ──────────────────────────────────
34
+ if (grouped['@import.statement'] !== undefined) {
35
+ const anchor = grouped['@import.statement'];
36
+ const includeNode = findNodeAtRange(tree.rootNode, anchor.range, 'preproc_include');
37
+ if (includeNode !== null) {
38
+ const split = splitCppInclude(includeNode);
39
+ if (split !== null) {
40
+ out.push(split);
41
+ continue;
42
+ }
43
+ }
44
+ }
45
+ // ── Handle using declarations (using namespace / using name) ────
46
+ if (grouped['@import.using-decl'] !== undefined) {
47
+ const anchor = grouped['@import.using-decl'];
48
+ const usingNode = findNodeAtRange(tree.rootNode, anchor.range, 'using_declaration');
49
+ if (usingNode !== null) {
50
+ const split = splitCppUsingDecl(usingNode);
51
+ if (split !== null) {
52
+ out.push(split);
53
+ continue;
54
+ }
55
+ }
56
+ }
57
+ // ── Track typedef-struct ranges ─────────────────────────────────
58
+ const structAnchor = grouped['@declaration.struct'] ?? grouped['@declaration.class'];
59
+ if (structAnchor !== undefined) {
60
+ const r = structAnchor.range;
61
+ structTypedefRanges.add(`${r.startLine}:${r.startCol}:${r.endLine}:${r.endCol}`);
62
+ }
63
+ // Suppress @declaration.typedef if the same range was already captured
64
+ const typedefAnchor = grouped['@declaration.typedef'];
65
+ if (typedefAnchor !== undefined) {
66
+ const r = typedefAnchor.range;
67
+ const key = `${r.startLine}:${r.startCol}:${r.endLine}:${r.endCol}`;
68
+ if (structTypedefRanges.has(key))
69
+ continue;
70
+ }
71
+ // ── Enrich function/method declarations with arity metadata ─────
72
+ const declAnchor = grouped['@declaration.function'] ?? grouped['@declaration.method'];
73
+ if (declAnchor !== undefined) {
74
+ const fnNode = findNodeAtRange(tree.rootNode, declAnchor.range, 'function_definition') ??
75
+ findNodeAtRange(tree.rootNode, declAnchor.range, 'declaration') ??
76
+ findNodeAtRange(tree.rootNode, declAnchor.range, 'field_declaration');
77
+ if (fnNode !== null) {
78
+ const arity = computeCppDeclarationArity(fnNode);
79
+ if (arity.parameterCount !== undefined) {
80
+ grouped['@declaration.parameter-count'] = syntheticCapture('@declaration.parameter-count', fnNode, String(arity.parameterCount));
81
+ }
82
+ if (arity.requiredParameterCount !== undefined) {
83
+ grouped['@declaration.required-parameter-count'] = syntheticCapture('@declaration.required-parameter-count', fnNode, String(arity.requiredParameterCount));
84
+ }
85
+ if (arity.parameterTypes !== undefined) {
86
+ grouped['@declaration.parameter-types'] = syntheticCapture('@declaration.parameter-types', fnNode, JSON.stringify(arity.parameterTypes));
87
+ }
88
+ // Detect static storage class (file-local linkage)
89
+ if (hasStaticStorageClass(fnNode)) {
90
+ const nameText = grouped['@declaration.name']?.text;
91
+ if (nameText !== undefined) {
92
+ markFileLocal(filePath, nameText);
93
+ }
94
+ }
95
+ // Detect anonymous namespace (file-local linkage)
96
+ if (isInsideAnonymousNamespace(fnNode)) {
97
+ const nameText = grouped['@declaration.name']?.text;
98
+ if (nameText !== undefined) {
99
+ markFileLocal(filePath, nameText);
100
+ }
101
+ }
102
+ }
103
+ }
104
+ // ── Detect static variables (file-local linkage) ────────────────
105
+ const varDeclAnchor = grouped['@declaration.variable'];
106
+ if (varDeclAnchor !== undefined) {
107
+ const varNode = findNodeAtRange(tree.rootNode, varDeclAnchor.range, 'declaration');
108
+ if (varNode !== null) {
109
+ if (hasStaticStorageClass(varNode) || isInsideAnonymousNamespace(varNode)) {
110
+ const nameText = grouped['@declaration.name']?.text;
111
+ if (nameText !== undefined) {
112
+ markFileLocal(filePath, nameText);
113
+ }
114
+ }
115
+ }
116
+ }
117
+ // ── Enrich call references with arity ───────────────────────────
118
+ const callAnchor = grouped['@reference.call.free'] ??
119
+ grouped['@reference.call.member'] ??
120
+ grouped['@reference.call.qualified'];
121
+ if (callAnchor !== undefined && grouped['@reference.arity'] === undefined) {
122
+ const callNode = findNodeAtRange(tree.rootNode, callAnchor.range, 'call_expression');
123
+ if (callNode !== null) {
124
+ grouped['@reference.arity'] = syntheticCapture('@reference.arity', callNode, String(computeCppCallArity(callNode)));
125
+ }
126
+ }
127
+ // ── Enrich constructor calls (new Foo()) with arity ─────────────
128
+ const ctorCallAnchor = grouped['@reference.call.constructor'];
129
+ if (ctorCallAnchor !== undefined && grouped['@reference.arity'] === undefined) {
130
+ const newNode = findNodeAtRange(tree.rootNode, ctorCallAnchor.range, 'new_expression');
131
+ if (newNode !== null) {
132
+ grouped['@reference.arity'] = syntheticCapture('@reference.arity', newNode, String(computeCppCallArity(newNode)));
133
+ }
134
+ }
135
+ // ── Synthesize argument types for overload narrowing ────────────
136
+ const anyCallAnchor = callAnchor ?? ctorCallAnchor;
137
+ if (anyCallAnchor !== undefined && grouped['@reference.parameter-types'] === undefined) {
138
+ const cNode = findNodeAtRange(tree.rootNode, anyCallAnchor.range, 'call_expression') ??
139
+ findNodeAtRange(tree.rootNode, anyCallAnchor.range, 'new_expression');
140
+ if (cNode !== null) {
141
+ const argTypes = inferCppCallArgTypes(cNode);
142
+ if (argTypes !== undefined && argTypes.length > 0) {
143
+ grouped['@reference.parameter-types'] = syntheticCapture('@reference.parameter-types', cNode, JSON.stringify(argTypes));
144
+ }
145
+ }
146
+ }
147
+ // ── Inline namespace detection ──────────────────────────────────
148
+ // `inline namespace v1 { ... }` — tree-sitter-cpp exposes the
149
+ // `inline` keyword as a child of `namespace_definition`. Record the
150
+ // namespace's source range so `populateCppInlineNamespaceScopes`
151
+ // (during populateOwners) can match it back to the corresponding
152
+ // Namespace scope.
153
+ // `@declaration.namespace` fires only for NAMED namespaces (the query
154
+ // requires a `name: (namespace_identifier)` child). Use the unconditional
155
+ // `@scope.namespace` capture so the anonymous-namespace branch also runs.
156
+ const namespaceScopeAnchor = grouped['@declaration.namespace'] ?? grouped['@scope.namespace'];
157
+ if (namespaceScopeAnchor !== undefined) {
158
+ const nsNode = findNodeAtRange(tree.rootNode, namespaceScopeAnchor.range, 'namespace_definition');
159
+ if (nsNode !== null) {
160
+ // Range coords stored in the shared Range shape use 1-based
161
+ // line numbers (see `ast-helpers.ts` rangeForNode where
162
+ // `startPosition.row + 1` is applied). Match that convention so
163
+ // the populators can join against `Scope.range`.
164
+ const nsRange = {
165
+ startLine: nsNode.startPosition.row + 1,
166
+ startCol: nsNode.startPosition.column,
167
+ endLine: nsNode.endPosition.row + 1,
168
+ endCol: nsNode.endPosition.column,
169
+ };
170
+ if (isInlineNamespace(nsNode)) {
171
+ markCppInlineNamespaceRange(filePath, nsRange);
172
+ }
173
+ // Anonymous namespace: `namespace_definition` with no `name` field.
174
+ // Recorded so `expandCppWildcardNames` can propagate its members
175
+ // to including TUs even though their names are also `markFileLocal`'d
176
+ // (which blocks the global free-call fallback's cross-file path).
177
+ if ((nsNode.childForFieldName?.('name') ?? null) === null) {
178
+ markCppAnonymousNamespaceRange(filePath, nsRange);
179
+ }
180
+ }
181
+ }
182
+ // ── ADL (Koenig lookup) per-site recording ──────────────────────
183
+ // Only free-call sites (no explicit receiver) participate in ADL —
184
+ // qualified `Ns::f(s)` and member `obj.f(s)` calls bypass the
185
+ // free-call fallback entirely (handled by receiver-bound-calls).
186
+ if (grouped['@reference.call.free'] !== undefined) {
187
+ const freeCallNode = findNodeAtRange(tree.rootNode, grouped['@reference.call.free'].range, 'call_expression');
188
+ if (freeCallNode !== null) {
189
+ const adlAnchorRange = grouped['@reference.call.free'].range;
190
+ if (isParenthesizedFunctionCall(freeCallNode)) {
191
+ markCppAdlSiteNoAdl(filePath, adlAnchorRange.startLine, adlAnchorRange.startCol);
192
+ }
193
+ const adlArgs = inferCppCallAdlArgs(freeCallNode);
194
+ if (adlArgs.length > 0) {
195
+ markCppAdlSiteArgs(filePath, adlAnchorRange.startLine, adlAnchorRange.startCol, adlArgs);
196
+ }
197
+ }
198
+ }
199
+ // ── Post-process @type-binding.assignment for auto declarations ──
200
+ // The wildcard `type: (_)` in the @type-binding.assignment query
201
+ // pattern matches before the more specific @type-binding.alias and
202
+ // @type-binding.member-access patterns. When the type is `auto`
203
+ // (placeholder_type_specifier), we re-inspect the AST to synthesize
204
+ // the correct capture tags so interpret.ts can produce the right
205
+ // rawTypeName for compound-receiver chain resolution.
206
+ if (grouped['@type-binding.assignment'] !== undefined &&
207
+ grouped['@type-binding.type']?.text === 'auto') {
208
+ const anchor = grouped['@type-binding.assignment'];
209
+ const declNode = findNodeAtRange(tree.rootNode, anchor.range, 'declaration');
210
+ if (declNode !== null) {
211
+ const declarator = declNode.childForFieldName('declarator');
212
+ if (declarator?.type === 'init_declarator') {
213
+ const valueNode = declarator.childForFieldName('value');
214
+ if (valueNode !== null) {
215
+ if (valueNode.type === 'identifier') {
216
+ // auto alias = existingVar → promote to @type-binding.alias
217
+ grouped['@type-binding.alias'] = anchor;
218
+ grouped['@type-binding.type'] = nodeToCapture('@type-binding.type', valueNode);
219
+ delete grouped['@type-binding.assignment'];
220
+ }
221
+ else if (valueNode.type === 'field_expression') {
222
+ // auto addr = user.address → promote to @type-binding.member-access
223
+ const argNode = valueNode.childForFieldName('argument');
224
+ const fieldNode = valueNode.childForFieldName('field');
225
+ if (argNode !== null && fieldNode !== null) {
226
+ grouped['@type-binding.member-access'] = anchor;
227
+ grouped['@type-binding.member-access-receiver'] = nodeToCapture('@type-binding.member-access-receiver', argNode);
228
+ grouped['@type-binding.type'] = nodeToCapture('@type-binding.type', fieldNode);
229
+ delete grouped['@type-binding.assignment'];
230
+ }
231
+ }
232
+ else if (valueNode.type === 'call_expression') {
233
+ const fnNode = valueNode.childForFieldName('function');
234
+ if (fnNode?.type === 'field_expression') {
235
+ // auto city = addr.getCity() → promote to @type-binding.alias
236
+ // with dotted rawName "addr.getCity" for compound-receiver
237
+ const argNode = fnNode.childForFieldName('argument');
238
+ const fieldNode = fnNode.childForFieldName('field');
239
+ if (argNode !== null && fieldNode !== null) {
240
+ grouped['@type-binding.member-access'] = anchor;
241
+ grouped['@type-binding.member-access-receiver'] = nodeToCapture('@type-binding.member-access-receiver', argNode);
242
+ grouped['@type-binding.type'] = nodeToCapture('@type-binding.type', fieldNode);
243
+ delete grouped['@type-binding.assignment'];
244
+ }
245
+ }
246
+ }
247
+ }
248
+ }
249
+ }
250
+ }
251
+ out.push(grouped);
252
+ }
253
+ // ── Emit inheritance references for scope-resolution MRO / EXTENDS ──
254
+ // Walk every class/struct base list and synthesize `@reference.inherits`
255
+ // captures consumed by the registry-primary graph bridge. The lookup name
256
+ // is normalized to the bare class name so `Base<T>` / `outer::v1::Base<T>`
257
+ // resolve through V1's simple-name `findClassBindingInScope('Base')`.
258
+ emitCppInheritanceCaptures(tree.rootNode, out);
259
+ // ── Detect dependent-base relationships for two-phase template lookup ──
260
+ // Walk the tree once, finding every `template_declaration` whose
261
+ // child is a class/struct definition with a `base_class_clause` whose
262
+ // base names reference an in-scope template parameter. Record the
263
+ // (className, dependentBaseName) pair so `populateCppDependentBases`
264
+ // (called from the `populateOwners` hook) can resolve names to nodeIds
265
+ // and the resolver can suppress unqualified-call binding to those
266
+ // bases per ISO C++ two-phase lookup.
267
+ detectCppDependentBases(tree.rootNode, filePath);
268
+ return out;
269
+ }
270
+ /**
271
+ * Walk every C++ class/struct base clause and emit `@reference.inherits`
272
+ * captures for each base so scope resolution can resolve them into EXTENDS
273
+ * edges. Lookup names are normalized to bare class names (`Base<T>` → `Base`,
274
+ * `outer::v1::Base<T>` → `Base`) to match the V1 simple-name
275
+ * `findClassBindingInScope` contract. This intentionally preserves the
276
+ * existing scope-chain tradeoff: qualified namespace context is discarded
277
+ * here instead of introducing a C++-only name-resolution lane in shared
278
+ * ingestion infrastructure.
279
+ */
280
+ function emitCppInheritanceCaptures(root, out) {
281
+ const stack = [root];
282
+ while (stack.length > 0) {
283
+ const node = stack.pop();
284
+ if (node.type === 'class_specifier' || node.type === 'struct_specifier') {
285
+ const baseClause = findChildOfType(node, ['base_class_clause']);
286
+ if (baseClause !== null) {
287
+ for (const base of iterBaseClasses(baseClause)) {
288
+ const baseName = extractBaseLookupName(base);
289
+ if (baseName.length === 0)
290
+ continue;
291
+ out.push({
292
+ '@reference.inherits': nodeToCapture('@reference.inherits', base),
293
+ '@reference.name': syntheticCapture('@reference.name', base, baseName),
294
+ });
295
+ }
296
+ }
297
+ }
298
+ for (let i = 0; i < node.childCount; i++) {
299
+ const child = node.child(i);
300
+ if (child !== null)
301
+ stack.push(child);
302
+ }
303
+ }
304
+ }
305
+ /**
306
+ * Walk the AST finding every template_declaration containing a class or
307
+ * struct definition with a dependent base. Records (className, baseName)
308
+ * pairs into the module-level state via `markCppDependentBase`.
309
+ *
310
+ * A base is "dependent" when its name (typically a template_type like
311
+ * `Base<T>`) uses a template parameter of the enclosing template_declaration.
312
+ * Conservative bias: `typename T::U`, `decltype(...)` and template-template
313
+ * parameter shapes are also treated as dependent.
314
+ */
315
+ function detectCppDependentBases(root, filePath) {
316
+ const stack = [root];
317
+ while (stack.length > 0) {
318
+ const node = stack.pop();
319
+ if (node.type === 'template_declaration') {
320
+ // Collect template-parameter names declared by this declaration.
321
+ // Inner template_declarations shadow outer ones — handled by the
322
+ // recursive descent below (each template_declaration creates its
323
+ // own parameter scope).
324
+ const params = collectTemplateParameterNames(node);
325
+ // Find the class/struct definition inside this template_declaration.
326
+ const classNode = findChildOfType(node, ['class_specifier', 'struct_specifier']);
327
+ if (classNode !== null) {
328
+ const className = getTypeIdentifierName(classNode);
329
+ if (className !== '') {
330
+ const baseClause = findChildOfType(classNode, ['base_class_clause']);
331
+ if (baseClause !== null) {
332
+ for (const base of iterBaseClasses(baseClause)) {
333
+ if (isBaseDependent(base, params)) {
334
+ const baseName = extractBaseLookupName(base);
335
+ if (baseName !== '') {
336
+ markCppDependentBase(filePath, className, baseName);
337
+ }
338
+ }
339
+ }
340
+ }
341
+ }
342
+ }
343
+ }
344
+ for (let i = 0; i < node.childCount; i++) {
345
+ const child = node.child(i);
346
+ if (child !== null)
347
+ stack.push(child);
348
+ }
349
+ }
350
+ }
351
+ /** Collect simple template parameter names from a template_declaration. */
352
+ function collectTemplateParameterNames(templateDecl) {
353
+ const names = new Set();
354
+ const paramList = findChildOfType(templateDecl, ['template_parameter_list']);
355
+ if (paramList === null)
356
+ return names;
357
+ for (let i = 0; i < paramList.childCount; i++) {
358
+ const param = paramList.child(i);
359
+ if (param === null)
360
+ continue;
361
+ if (param.type === 'type_parameter_declaration' ||
362
+ param.type === 'optional_type_parameter_declaration' ||
363
+ param.type === 'variadic_type_parameter_declaration') {
364
+ const idNode = findFirstDescendantOfType(param, 'type_identifier');
365
+ if (idNode !== null)
366
+ names.add(idNode.text);
367
+ }
368
+ else if (param.type === 'parameter_declaration' ||
369
+ param.type === 'optional_parameter_declaration' ||
370
+ param.type === 'variadic_parameter_declaration') {
371
+ // Non-type template parameter (e.g. `template<int N>`).
372
+ const idNode = findFirstDescendantOfType(param, 'identifier');
373
+ if (idNode !== null)
374
+ names.add(idNode.text);
375
+ }
376
+ else if (param.type === 'template_template_parameter_declaration') {
377
+ // template-template parameter (e.g. `template<template<class> class TT>`)
378
+ const idNode = findFirstDescendantOfType(param, 'type_identifier');
379
+ if (idNode !== null)
380
+ names.add(idNode.text);
381
+ }
382
+ }
383
+ return names;
384
+ }
385
+ /** Yield each base-class entry from a `base_class_clause`. */
386
+ function* iterBaseClasses(baseClause) {
387
+ for (let i = 0; i < baseClause.childCount; i++) {
388
+ const child = baseClause.child(i);
389
+ if (child === null)
390
+ continue;
391
+ // Skip ':', ',', and access_specifier nodes — the base names are
392
+ // type_identifier, template_type, or qualified_identifier.
393
+ if (child.type === 'type_identifier' ||
394
+ child.type === 'template_type' ||
395
+ child.type === 'qualified_identifier') {
396
+ yield child;
397
+ }
398
+ }
399
+ }
400
+ /**
401
+ * A base is dependent when:
402
+ * - it's a `template_type` and its argument list contains a
403
+ * `type_identifier` matching one of the enclosing template's params
404
+ * (e.g., `Base<T>` where `T` is a template parameter), OR
405
+ * - it contains a `typename`, `decltype`, or `template_template_parameter`
406
+ * shape (conservatively treated as dependent).
407
+ *
408
+ * Non-dependent: `Base<int>`, `ConcreteBase`, `Base<MyConcrete>` where
409
+ * `MyConcrete` is not a template parameter.
410
+ */
411
+ function isBaseDependent(baseNode, templateParams) {
412
+ if (baseNode.type !== 'template_type') {
413
+ // Bare `type_identifier` or `qualified_identifier` bases — not
414
+ // dependent (the base name itself doesn't reference a template
415
+ // parameter at this level).
416
+ return false;
417
+ }
418
+ // Walk all descendants of the template_argument_list looking for any
419
+ // type_identifier matching a template parameter, or any conservative-
420
+ // dependent shape.
421
+ const stack = [baseNode];
422
+ while (stack.length > 0) {
423
+ const node = stack.pop();
424
+ if (node.type === 'type_identifier' && templateParams.has(node.text)) {
425
+ return true;
426
+ }
427
+ if (node.type === 'decltype' ||
428
+ node.type === 'dependent_type' ||
429
+ node.type === 'template_template_parameter_declaration') {
430
+ return true;
431
+ }
432
+ if (node.type === 'qualified_identifier') {
433
+ // `typename T::U` or `T::nested` — if any inner identifier matches
434
+ // a template parameter, dependent.
435
+ for (let i = 0; i < node.childCount; i++) {
436
+ const c = node.child(i);
437
+ if (c !== null)
438
+ stack.push(c);
439
+ }
440
+ continue;
441
+ }
442
+ for (let i = 0; i < node.childCount; i++) {
443
+ const c = node.child(i);
444
+ if (c !== null)
445
+ stack.push(c);
446
+ }
447
+ }
448
+ return false;
449
+ }
450
+ /**
451
+ * Recursively extract the bare lookup name of a base class node.
452
+ * Examples: `Base` → `Base`, `Base<T>` → `Base`,
453
+ * `outer::v1::Base<T>` → `Base`. Namespace qualifiers are intentionally
454
+ * dropped to align with V1 scope-chain lookup everywhere else in the
455
+ * registry-primary pipeline.
456
+ */
457
+ function extractBaseLookupName(baseNode) {
458
+ if (baseNode.type === 'type_identifier' || baseNode.type === 'identifier')
459
+ return baseNode.text;
460
+ if (baseNode.type === 'template_type') {
461
+ const nameNode = baseNode.childForFieldName('name');
462
+ if (nameNode !== null)
463
+ return extractBaseLookupName(nameNode);
464
+ const id = findFirstDescendantOfType(baseNode, 'type_identifier') ??
465
+ findFirstDescendantOfType(baseNode, 'identifier');
466
+ if (id !== null)
467
+ return id.text;
468
+ }
469
+ if (baseNode.type === 'qualified_identifier') {
470
+ const nameNode = baseNode.childForFieldName('name');
471
+ if (nameNode !== null) {
472
+ const nested = extractBaseLookupName(nameNode);
473
+ if (nested.length > 0)
474
+ return nested;
475
+ }
476
+ for (let i = baseNode.childCount - 1; i >= 0; i--) {
477
+ const child = baseNode.child(i);
478
+ if (child === null)
479
+ continue;
480
+ const nested = extractBaseLookupName(child);
481
+ if (nested.length > 0)
482
+ return nested;
483
+ }
484
+ }
485
+ return '';
486
+ }
487
+ /** Find the first direct child matching one of the given types. */
488
+ function findChildOfType(node, types) {
489
+ for (let i = 0; i < node.childCount; i++) {
490
+ const c = node.child(i);
491
+ if (c !== null && types.includes(c.type))
492
+ return c;
493
+ }
494
+ return null;
495
+ }
496
+ /** Recursive search for the first descendant of a given type. */
497
+ function findFirstDescendantOfType(node, type) {
498
+ if (node.type === type)
499
+ return node;
500
+ for (let i = 0; i < node.childCount; i++) {
501
+ const c = node.child(i);
502
+ if (c === null)
503
+ continue;
504
+ const hit = findFirstDescendantOfType(c, type);
505
+ if (hit !== null)
506
+ return hit;
507
+ }
508
+ return null;
509
+ }
510
+ /** Get the name of a class/struct/template_type node via its `name` field. */
511
+ function getTypeIdentifierName(node) {
512
+ const nameNode = node.childForFieldName('name');
513
+ if (nameNode !== null)
514
+ return nameNode.text;
515
+ const id = findFirstDescendantOfType(node, 'type_identifier');
516
+ return id !== null ? id.text : '';
517
+ }
518
+ /**
519
+ * Infer argument types from a call_expression or new_expression node.
520
+ * Used for overload disambiguation by parameter types.
521
+ *
522
+ * Only literal types are inferred — identifiers and complex expressions
523
+ * return empty string (unknown) so narrowOverloadCandidates treats them
524
+ * as any-match.
525
+ */
526
+ function inferCppCallArgTypes(node) {
527
+ const argList = node.childForFieldName('arguments');
528
+ if (argList === null)
529
+ return undefined;
530
+ const types = [];
531
+ for (let i = 0; i < argList.childCount; i++) {
532
+ const child = argList.child(i);
533
+ if (child === null)
534
+ continue;
535
+ if (child.type === ',' || child.type === '(' || child.type === ')')
536
+ continue;
537
+ const litType = inferCppLiteralType(child);
538
+ if (litType !== '') {
539
+ types.push(litType);
540
+ }
541
+ else if (child.type === 'identifier') {
542
+ // Variable reference — look up declared type in enclosing scope
543
+ types.push(lookupDeclaredTypeForIdentifier(child));
544
+ }
545
+ else {
546
+ types.push('');
547
+ }
548
+ }
549
+ return types.length > 0 ? types : undefined;
550
+ }
551
+ /**
552
+ * Infer the canonical type name of a C++ literal AST node.
553
+ * Returns empty string for non-literal / unknown nodes.
554
+ */
555
+ function inferCppLiteralType(node) {
556
+ switch (node.type) {
557
+ case 'number_literal': {
558
+ const text = node.text;
559
+ // Floating-point literals contain '.', 'e', 'E', or end with 'f'/'F'
560
+ if (text.includes('.') ||
561
+ text.includes('e') ||
562
+ text.includes('E') ||
563
+ text.endsWith('f') ||
564
+ text.endsWith('F')) {
565
+ return 'double';
566
+ }
567
+ return 'int';
568
+ }
569
+ case 'string_literal':
570
+ case 'raw_string_literal':
571
+ case 'concatenated_string':
572
+ return 'string';
573
+ case 'char_literal':
574
+ return 'char';
575
+ case 'true':
576
+ case 'false':
577
+ return 'bool';
578
+ case 'null':
579
+ case 'nullptr':
580
+ return 'null';
581
+ default:
582
+ return '';
583
+ }
584
+ }
585
+ /**
586
+ * Look up the declared type of a variable by scanning sibling declarations
587
+ * in the enclosing compound_statement (function body). Handles:
588
+ * - `std::string result = ...` → 'string'
589
+ * - `int n = ...` → 'int'
590
+ * - `const int n = ...` → 'int'
591
+ * Returns empty string if no declaration found or type is auto/placeholder.
592
+ */
593
+ function lookupDeclaredTypeForIdentifier(identNode) {
594
+ const varName = identNode.text;
595
+ // Walk up to the enclosing compound_statement (function body)
596
+ let scope = identNode.parent;
597
+ while (scope !== null &&
598
+ scope.type !== 'compound_statement' &&
599
+ scope.type !== 'translation_unit') {
600
+ scope = scope.parent;
601
+ }
602
+ if (scope === null)
603
+ return '';
604
+ // Scan declarations in the scope for a matching variable name
605
+ for (let i = 0; i < scope.childCount; i++) {
606
+ const stmt = scope.child(i);
607
+ if (stmt === null || stmt.type !== 'declaration')
608
+ continue;
609
+ const typeNode = stmt.childForFieldName('type');
610
+ if (typeNode === null)
611
+ continue;
612
+ // Skip auto/placeholder types — those need chain-follow, not literal
613
+ if (typeNode.type === 'placeholder_type_specifier')
614
+ continue;
615
+ // Check init_declarator children for the variable name
616
+ const declarator = stmt.childForFieldName('declarator');
617
+ if (declarator === null)
618
+ continue;
619
+ if (declarator.type === 'init_declarator') {
620
+ const nameChild = declarator.childForFieldName('declarator');
621
+ if (nameChild !== null && nameChild.text === varName) {
622
+ return normalizeCppTypeText(typeNode.text);
623
+ }
624
+ }
625
+ else if (declarator.text === varName) {
626
+ return normalizeCppTypeText(typeNode.text);
627
+ }
628
+ }
629
+ return '';
630
+ }
631
+ /** Normalize a type-specifier text for argument type matching.
632
+ * Strips qualifiers (const, volatile), namespace prefixes (std::),
633
+ * and pointer/reference markers. */
634
+ function normalizeCppTypeText(text) {
635
+ let t = text.trim();
636
+ t = t.replace(/\b(const|volatile|static|extern|mutable)\b/g, '').trim();
637
+ t = t.replace(/^.*::/, ''); // strip namespace prefix
638
+ t = t.replace(/[*&]/g, '').trim();
639
+ return t;
640
+ }
641
+ /**
642
+ * Detect whether a `namespace_definition` AST node is inline.
643
+ * Tree-sitter-cpp exposes the `inline` keyword as an anonymous child
644
+ * node — we scan direct children for that keyword.
645
+ */
646
+ function isInlineNamespace(nsNode) {
647
+ for (let i = 0; i < nsNode.childCount; i++) {
648
+ const c = nsNode.child(i);
649
+ if (c === null)
650
+ continue;
651
+ if (c.type === 'inline')
652
+ return true;
653
+ // Some grammar variants surface keywords by their text rather than
654
+ // by a dedicated node type; check both for resilience.
655
+ if (c.text === 'inline' && (c.type === 'storage_class_specifier' || c.type === 'inline')) {
656
+ return true;
657
+ }
658
+ }
659
+ return false;
660
+ }
661
+ /**
662
+ * Detect `(f)(args)` shape — the call-expression's `function` field is a
663
+ * `parenthesized_expression`. ISO C++ specifies that this form suppresses
664
+ * ADL (`[basic.lookup.argdep]/3.1`): the parenthesized name is treated as
665
+ * an ordinary unqualified-lookup-only callee.
666
+ */
667
+ function isParenthesizedFunctionCall(callNode) {
668
+ const fn = callNode.childForFieldName('function');
669
+ return fn !== null && fn.type === 'parenthesized_expression';
670
+ }
671
+ /**
672
+ * Per-argument ADL classification: walk each argument of a free call and
673
+ * classify its declared type for associated-namespace lookup.
674
+ *
675
+ * Value/pointer/reference class-typed args and template specializations
676
+ * with explicit type arguments contribute; function pointers, primitives,
677
+ * literals, and other unsupported shapes produce an empty result.
678
+ *
679
+ * Class-typed values/pointers/references (`N::S`, `N::S*`, `N::S&`) all
680
+ * preserve the class name for associated-namespace lookup.
681
+ * Function pointers remain excluded even when their return type names a
682
+ * class, because the associated entity is the pointed-to function type,
683
+ * not the return type.
684
+ */
685
+ function inferCppCallAdlArgs(callNode) {
686
+ const argList = callNode.childForFieldName('arguments');
687
+ if (argList === null)
688
+ return [];
689
+ const out = [];
690
+ for (let i = 0; i < argList.childCount; i++) {
691
+ const child = argList.child(i);
692
+ if (child === null)
693
+ continue;
694
+ if (child.type === ',' || child.type === '(' || child.type === ')')
695
+ continue;
696
+ out.push(classifyAdlArg(child));
697
+ }
698
+ return out;
699
+ }
700
+ const ADL_TEMPLATE_RECURSION_MAX_DEPTH = 8;
701
+ const EMPTY_ADL_ARG = {
702
+ simpleClassName: '',
703
+ templateSimpleClassName: '',
704
+ templateNamespace: '',
705
+ templateArgClassNames: [],
706
+ templateArgNamespaces: [],
707
+ };
708
+ function classifyAdlArg(argNode) {
709
+ // Literals and primitive-shaped expressions never have associated namespaces.
710
+ if (argNode.type === 'number_literal' ||
711
+ argNode.type === 'string_literal' ||
712
+ argNode.type === 'raw_string_literal' ||
713
+ argNode.type === 'char_literal' ||
714
+ argNode.type === 'true' ||
715
+ argNode.type === 'false' ||
716
+ argNode.type === 'null' ||
717
+ argNode.type === 'nullptr') {
718
+ return EMPTY_ADL_ARG;
719
+ }
720
+ // Qualified expression (a::b) — may be a function, variable, enum value,
721
+ // or static member. Record as a potential function reference; resolution
722
+ // time verifies via workspace lookup that a Function/Method with this simple
723
+ // name exists in the extracted namespace before contributing to the set.
724
+ if (argNode.type === 'qualified_identifier') {
725
+ return {
726
+ simpleClassName: '',
727
+ templateSimpleClassName: '',
728
+ templateNamespace: '',
729
+ templateArgClassNames: [],
730
+ templateArgNamespaces: [],
731
+ functionRefText: argNode.text,
732
+ };
733
+ }
734
+ // Variable reference — look up its declared type (preserving pointer /
735
+ // reference / qualified-name shape; the existing arity-narrowing helper
736
+ // strips this info).
737
+ if (argNode.type === 'identifier') {
738
+ const result = lookupAdlIdentifierType(argNode);
739
+ if (result === null) {
740
+ // Not found in the local compound_statement scope — could be a
741
+ // free-function reference (unqualified name, namespace scope).
742
+ return {
743
+ simpleClassName: '',
744
+ templateSimpleClassName: '',
745
+ templateNamespace: '',
746
+ templateArgClassNames: [],
747
+ templateArgNamespaces: [],
748
+ functionRefText: argNode.text,
749
+ };
750
+ }
751
+ return result;
752
+ }
753
+ // Other shapes (calls, member access, operators) — V1 unsupported.
754
+ return EMPTY_ADL_ARG;
755
+ }
756
+ /**
757
+ * Returns `true` when `varName` appears as a parameter name in the nearest
758
+ * enclosing `function_definition` or `function_declarator` that contains
759
+ * `identNode`. Parameters live in `parameter_list` (a sibling of the
760
+ * `compound_statement`), so the `compound_statement`-local declaration scan
761
+ * in `lookupAdlIdentifierType` would not find them — causing them to be
762
+ * mistakenly classified as potential free-function references.
763
+ *
764
+ * In tree-sitter-cpp a `function_definition` does NOT expose `parameters`
765
+ * as a direct named field; parameters live inside the nested
766
+ * `function_declarator`. For `function_declarator` nodes the `parameters`
767
+ * field IS direct. Both cases are handled below.
768
+ */
769
+ function isIdentifierAFunctionParameter(identNode, varName) {
770
+ let node = identNode.parent;
771
+ let safety = 64;
772
+ while (node !== null && safety-- > 0) {
773
+ let params = null;
774
+ if (node.type === 'function_declarator') {
775
+ // parameters is a direct field on function_declarator.
776
+ params = node.childForFieldName('parameters');
777
+ }
778
+ else if (node.type === 'function_definition') {
779
+ // function_definition carries parameters inside its `declarator` field
780
+ // (which is a function_declarator). Walk through it.
781
+ const decl = node.childForFieldName('declarator');
782
+ if (decl !== null && decl.type === 'function_declarator') {
783
+ params = decl.childForFieldName('parameters');
784
+ }
785
+ }
786
+ if (params !== null) {
787
+ for (let i = 0; i < params.namedChildCount; i++) {
788
+ const param = params.namedChild(i);
789
+ if (param === null)
790
+ continue;
791
+ const declNode = param.childForFieldName('declarator');
792
+ if (declNode === null)
793
+ continue;
794
+ const leafName = extractDeclaratorLeafName(declNode);
795
+ if (leafName === varName)
796
+ return true;
797
+ }
798
+ // Only check the immediately enclosing function — do not climb further.
799
+ break;
800
+ }
801
+ if (node.type === 'translation_unit')
802
+ break;
803
+ node = node.parent;
804
+ }
805
+ return false;
806
+ }
807
+ function lookupAdlIdentifierType(identNode) {
808
+ const varName = identNode.text;
809
+ let scope = identNode.parent;
810
+ while (scope !== null &&
811
+ scope.type !== 'compound_statement' &&
812
+ scope.type !== 'translation_unit') {
813
+ scope = scope.parent;
814
+ }
815
+ if (scope === null)
816
+ return null;
817
+ // Function parameters live in the enclosing function's `parameter_list`,
818
+ // NOT inside the `compound_statement`, so the declaration scan below would
819
+ // never find them and would return `null` — incorrectly triggering the
820
+ // free-function-reference path. Check the parameter_list first.
821
+ if (isIdentifierAFunctionParameter(identNode, varName)) {
822
+ return EMPTY_ADL_ARG;
823
+ }
824
+ let foundAsLocalFunctionPointer = false;
825
+ for (let i = 0; i < scope.childCount; i++) {
826
+ const stmt = scope.child(i);
827
+ if (stmt === null || stmt.type !== 'declaration')
828
+ continue;
829
+ const typeNode = stmt.childForFieldName('type');
830
+ if (typeNode === null)
831
+ continue;
832
+ if (typeNode.type === 'placeholder_type_specifier')
833
+ continue;
834
+ const declarator = stmt.childForFieldName('declarator');
835
+ if (declarator === null)
836
+ continue;
837
+ // Unwrap declarator chain to find pointer/reference markers and the
838
+ // variable name. `init_declarator > pointer_declarator > identifier`
839
+ // means pointer-typed; repeated pointer wrappers still count as pointer
840
+ // typed; `init_declarator > reference_declarator > ...` (or
841
+ // `rvalue_reference_declarator`) means reference-typed; bare
842
+ // `init_declarator > identifier` is value.
843
+ // Function-pointer wrappers (`pointer_declarator > function_declarator`)
844
+ // must not contribute ADL associated namespaces.
845
+ let isFunctionPointer = false;
846
+ let inner = declarator;
847
+ let nameText = null;
848
+ let safety = 16; // bound walk depth defensively
849
+ while (safety-- > 0) {
850
+ if (inner.type === 'pointer_declarator') {
851
+ if (findFirstDescendantOfType(inner, 'function_declarator') !== null) {
852
+ isFunctionPointer = true;
853
+ // Extract the name from within the function-pointer declarator chain
854
+ // so `foundAsLocalFunctionPointer` can detect a matching declaration.
855
+ nameText = extractDeclaratorLeafName(inner);
856
+ break;
857
+ }
858
+ const next = inner.childForFieldName('declarator');
859
+ if (next === null)
860
+ break;
861
+ inner = next;
862
+ continue;
863
+ }
864
+ if (inner.type === 'reference_declarator' || inner.type === 'rvalue_reference_declarator') {
865
+ // reference_declarator has a single child (the inner declarator).
866
+ let next = null;
867
+ for (let j = 0; j < inner.namedChildCount; j++) {
868
+ const c = inner.namedChild(j);
869
+ if (c !== null) {
870
+ next = c;
871
+ break;
872
+ }
873
+ }
874
+ if (next === null)
875
+ break;
876
+ inner = next;
877
+ continue;
878
+ }
879
+ if (inner.type === 'init_declarator') {
880
+ const next = inner.childForFieldName('declarator');
881
+ if (next === null)
882
+ break;
883
+ inner = next;
884
+ continue;
885
+ }
886
+ if (inner.type === 'function_declarator') {
887
+ isFunctionPointer = true;
888
+ // Extract the name from the inner declarator (e.g. `(*g)` in `void (*g)()`).
889
+ const innerDecl = inner.childForFieldName('declarator');
890
+ if (innerDecl !== null)
891
+ nameText = extractDeclaratorLeafName(innerDecl);
892
+ break;
893
+ }
894
+ // Reached the leaf — usually `identifier`. Take its text.
895
+ nameText = inner.text;
896
+ break;
897
+ }
898
+ if (nameText === varName && isFunctionPointer) {
899
+ // Explicitly declared as a function-pointer variable — must not be
900
+ // treated as a free-function reference by the caller.
901
+ foundAsLocalFunctionPointer = true;
902
+ continue;
903
+ }
904
+ if (isFunctionPointer || nameText !== varName)
905
+ continue;
906
+ const simpleClassName = extractAdlSimpleTypeName(typeNode);
907
+ const { templateSimpleClassName, templateNamespace, templateArgClassNames, templateArgNamespaces, } = extractAdlTemplateInfo(typeNode);
908
+ return {
909
+ simpleClassName,
910
+ templateSimpleClassName,
911
+ templateNamespace,
912
+ templateArgClassNames,
913
+ templateArgNamespaces,
914
+ };
915
+ }
916
+ // If the identifier was found in local scope as a function-pointer variable,
917
+ // return EMPTY_ADL_ARG so the caller does NOT treat it as a free-function
918
+ // reference. Otherwise return null to indicate "not in local scope".
919
+ //
920
+ // Known limitation (Finding 4): variables whose type is a typedef/using alias
921
+ // for a function-pointer type are NOT detected here. For example:
922
+ // using Callback = void (*)();
923
+ // Callback g;
924
+ // foo(g); // `g`'s declarator is `identifier` with type `Callback`
925
+ // The declarator has no `pointer_declarator` wrapper, so `isFunctionPointer`
926
+ // stays false and `extractAdlSimpleTypeName` returns `"Callback"`. ADL then
927
+ // looks for a class named `Callback`; if none exists, this degrades to
928
+ // EMPTY_ADL_ARG (class not found → no namespace contributed). If a class
929
+ // named `Callback` does exist, a spurious namespace contribution could occur.
930
+ // Risk is low in practice; a future fix should resolve the typedef/alias chain.
931
+ return foundAsLocalFunctionPointer ? EMPTY_ADL_ARG : null;
932
+ }
933
+ /** Extract the simple class-like type name from a `type:` field node.
934
+ * Returns '' for primitives and any other
935
+ * unsupported type-only shape. Function pointers are filtered at the
936
+ * declarator level in `lookupAdlIdentifierType`. */
937
+ function extractAdlSimpleTypeName(typeNode) {
938
+ if (typeNode.type === 'type_descriptor') {
939
+ const innerType = typeNode.childForFieldName('type');
940
+ if (innerType !== null)
941
+ return extractAdlSimpleTypeName(innerType);
942
+ for (let i = 0; i < typeNode.childCount; i++) {
943
+ const child = typeNode.child(i);
944
+ if (child === null)
945
+ continue;
946
+ if (child.type === 'type_identifier' ||
947
+ child.type === 'qualified_identifier' ||
948
+ child.type === 'template_type') {
949
+ return extractAdlSimpleTypeName(child);
950
+ }
951
+ }
952
+ return '';
953
+ }
954
+ if (typeNode.type === 'primitive_type')
955
+ return '';
956
+ if (typeNode.type === 'sized_type_specifier')
957
+ return '';
958
+ if (typeNode.type === 'type_identifier')
959
+ return typeNode.text;
960
+ if (typeNode.type === 'template_type') {
961
+ const nameNode = typeNode.childForFieldName('name');
962
+ if (nameNode !== null)
963
+ return extractAdlSimpleTypeName(nameNode);
964
+ const id = findFirstDescendantOfType(typeNode, 'type_identifier');
965
+ return id !== null ? id.text : '';
966
+ }
967
+ if (typeNode.type === 'qualified_identifier') {
968
+ const nameNode = typeNode.childForFieldName('name');
969
+ if (nameNode !== null)
970
+ return extractAdlSimpleTypeName(nameNode);
971
+ const id = findFirstDescendantOfType(typeNode, 'type_identifier');
972
+ return id !== null ? id.text : '';
973
+ }
974
+ // Function pointers, decltype, etc — unsupported for ADL participation.
975
+ return '';
976
+ }
977
+ function extractAdlTypeNamespace(typeNode) {
978
+ if (typeNode.type === 'type_descriptor') {
979
+ const innerType = typeNode.childForFieldName('type');
980
+ if (innerType !== null)
981
+ return extractAdlTypeNamespace(innerType);
982
+ for (let i = 0; i < typeNode.childCount; i++) {
983
+ const child = typeNode.child(i);
984
+ if (child === null)
985
+ continue;
986
+ if (child.type === 'qualified_identifier' ||
987
+ child.type === 'template_type' ||
988
+ child.type === 'type_identifier') {
989
+ return extractAdlTypeNamespace(child);
990
+ }
991
+ }
992
+ return '';
993
+ }
994
+ if (typeNode.type === 'template_type') {
995
+ const nameNode = typeNode.childForFieldName('name');
996
+ return nameNode !== null ? extractAdlTypeNamespace(nameNode) : '';
997
+ }
998
+ if (typeNode.type === 'qualified_identifier') {
999
+ const scope = typeNode.childForFieldName('scope');
1000
+ if (scope !== null)
1001
+ return normalizeCppNamespaceQName(scope.text);
1002
+ return extractNamespaceFromQualifiedText(typeNode.text);
1003
+ }
1004
+ return '';
1005
+ }
1006
+ function extractAdlTemplateInfo(typeNode) {
1007
+ const templateTypeNode = findTemplateTypeNode(typeNode);
1008
+ if (templateTypeNode === null) {
1009
+ return {
1010
+ templateSimpleClassName: '',
1011
+ templateNamespace: '',
1012
+ templateArgClassNames: [],
1013
+ templateArgNamespaces: [],
1014
+ };
1015
+ }
1016
+ const templateArgClassNames = [];
1017
+ const templateArgNamespaces = [];
1018
+ collectAdlTemplateArgs(templateTypeNode, 0, templateArgClassNames, templateArgNamespaces);
1019
+ return {
1020
+ templateSimpleClassName: extractAdlSimpleTypeName(templateTypeNode),
1021
+ templateNamespace: extractAdlTypeNamespace(typeNode),
1022
+ templateArgClassNames,
1023
+ templateArgNamespaces,
1024
+ };
1025
+ }
1026
+ function collectAdlTemplateArgs(templateTypeNode, depth, outClassNames, outNamespaces) {
1027
+ if (depth >= ADL_TEMPLATE_RECURSION_MAX_DEPTH)
1028
+ return;
1029
+ if (templateTypeNode.type !== 'template_type')
1030
+ return;
1031
+ const argList = templateTypeNode.childForFieldName('arguments') ??
1032
+ findChildOfType(templateTypeNode, ['template_argument_list']);
1033
+ if (argList === null)
1034
+ return;
1035
+ for (let i = 0; i < argList.namedChildCount; i++) {
1036
+ const arg = argList.namedChild(i);
1037
+ if (arg === null || arg.type !== 'type_descriptor')
1038
+ continue;
1039
+ const simpleClassName = extractAdlSimpleTypeName(arg);
1040
+ if (simpleClassName.length > 0)
1041
+ outClassNames.push(simpleClassName);
1042
+ const ns = extractAdlTypeNamespace(arg);
1043
+ if (ns.length > 0)
1044
+ outNamespaces.push(ns);
1045
+ const nestedType = arg.childForFieldName('type');
1046
+ const nestedTemplate = nestedType !== null ? findTemplateTypeNode(nestedType) : null;
1047
+ if (nestedTemplate !== null) {
1048
+ collectAdlTemplateArgs(nestedTemplate, depth + 1, outClassNames, outNamespaces);
1049
+ }
1050
+ }
1051
+ }
1052
+ function findTemplateTypeNode(typeNode) {
1053
+ if (typeNode.type === 'template_type')
1054
+ return typeNode;
1055
+ if (typeNode.type === 'type_descriptor') {
1056
+ const innerType = typeNode.childForFieldName('type');
1057
+ if (innerType !== null)
1058
+ return findTemplateTypeNode(innerType);
1059
+ return null;
1060
+ }
1061
+ if (typeNode.type === 'qualified_identifier') {
1062
+ const nameNode = typeNode.childForFieldName('name');
1063
+ if (nameNode !== null)
1064
+ return findTemplateTypeNode(nameNode);
1065
+ return null;
1066
+ }
1067
+ return null;
1068
+ }
1069
+ function normalizeCppNamespaceQName(text) {
1070
+ const normalized = text.replace(/^::/, '').replace(/::$/, '').replace(/::/g, '.');
1071
+ return normalized;
1072
+ }
1073
+ function extractNamespaceFromQualifiedText(text) {
1074
+ const cleaned = text.replace(/\s+/g, '');
1075
+ const idx = cleaned.lastIndexOf('::');
1076
+ if (idx <= 0)
1077
+ return '';
1078
+ return normalizeCppNamespaceQName(cleaned.slice(0, idx));
1079
+ }
1080
+ /**
1081
+ * Walk a declarator node chain, unwrapping pointer/reference/function/
1082
+ * parenthesized wrappers, and return the text of the innermost identifier.
1083
+ * Returns `null` when no identifier is found within `safety` steps.
1084
+ * Used by `lookupAdlIdentifierType` to extract the variable name from
1085
+ * function-pointer declarator trees such as `(*g)()` in `void (*g)()`.
1086
+ */
1087
+ function extractDeclaratorLeafName(node) {
1088
+ let cur = node;
1089
+ let safety = 16;
1090
+ while (safety-- > 0) {
1091
+ if (cur.type === 'identifier' || cur.type === 'type_identifier')
1092
+ return cur.text;
1093
+ // Common wrapper nodes — follow the 'declarator' field when present.
1094
+ const next = cur.childForFieldName('declarator') ??
1095
+ // parenthesized_declarator: single named child
1096
+ (cur.type === 'parenthesized_declarator' ? cur.namedChild(0) : null);
1097
+ if (next === null)
1098
+ return null;
1099
+ cur = next;
1100
+ }
1101
+ return null;
1102
+ }
1103
+ /**
1104
+ * Check if a C++ function_definition or declaration has `static` storage class.
1105
+ */
1106
+ function hasStaticStorageClass(node) {
1107
+ for (let i = 0; i < node.childCount; i++) {
1108
+ const child = node.child(i);
1109
+ if (child !== null && child.type === 'storage_class_specifier' && child.text === 'static') {
1110
+ return true;
1111
+ }
1112
+ }
1113
+ return false;
1114
+ }
1115
+ /**
1116
+ * Check if a node is inside an anonymous namespace (file-local linkage in C++).
1117
+ * Anonymous namespaces have no `name` field in tree-sitter-cpp.
1118
+ */
1119
+ function isInsideAnonymousNamespace(node) {
1120
+ let ancestor = node.parent ?? null;
1121
+ while (ancestor !== null) {
1122
+ if (ancestor.type === 'namespace_definition') {
1123
+ // Anonymous namespace: has declaration_list but no name child
1124
+ const nameChild = ancestor.childForFieldName?.('name') ?? null;
1125
+ if (nameChild === null)
1126
+ return true;
1127
+ }
1128
+ ancestor = ancestor.parent;
1129
+ }
1130
+ return false;
1131
+ }