cgraphx 2.0.1 → 2.0.3

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 (701) hide show
  1. package/dist/.claude-template/FLOW-MAP.md +7 -5
  2. package/dist/.claude-template/commands/end.md +1 -1
  3. package/dist/.claude-template/skills/cgraphx-guide/SKILL.md +2 -1
  4. package/dist/.claude-template/skills/cgraphx-guide/how-to-use.html +4 -2
  5. package/dist/.claude-template/skills/cgraphx-guide/how-to-use.md +5 -2
  6. package/dist/.claude-template/skills/iboc-check/SKILL.md +116 -0
  7. package/dist/.claude-template/skills/iboc-check/filler-prompt.md +75 -0
  8. package/dist/.claude-template/skills/implementation/SKILL.md +7 -0
  9. package/dist/.claude-template/skills/init-project-guides/SKILL.md +1 -1
  10. package/dist/.claude-template/skills/run-api-test/references/db-verification.md +2 -2
  11. package/dist/.claude-template/skills/subagent-implement/SKILL.md +3 -2
  12. package/dist/.claude-template/skills/write-api/assets/template-request.bru +3 -3
  13. package/dist/.claude-template/skills/write-api/references/bru-format.md +6 -6
  14. package/dist/.claude-template/skills/write-delivery-guide/SKILL.md +97 -0
  15. package/dist/.claude-template/skills/write-delivery-guide/template-change-type.md +120 -0
  16. package/dist/.claude-template/skills/write-delivery-guide/template-multi-role-flow.md +148 -0
  17. package/dist/.claude-template/skills/write-unit-test-code/SKILL.md +23 -6
  18. package/dist/core/code/engine/cli/analyze-config.js +320 -0
  19. package/dist/core/code/engine/cli/analyze.js +1086 -0
  20. package/dist/core/code/engine/cli/cli-message.js +83 -0
  21. package/dist/core/code/engine/cli/detect-changes-format.js +58 -0
  22. package/dist/core/code/engine/cli/embedding-dims.js +43 -0
  23. package/dist/core/code/engine/cli/format-elapsed.js +12 -0
  24. package/dist/core/code/engine/cli/help-i18n.js +144 -0
  25. package/dist/core/code/engine/cli/i18n/en.js +110 -0
  26. package/dist/core/code/engine/cli/i18n/index.js +47 -0
  27. package/dist/core/code/engine/cli/i18n/resources.js +9 -0
  28. package/dist/core/code/engine/cli/i18n/zh-CN.js +110 -0
  29. package/dist/core/code/engine/cli/lazy-action.js +67 -0
  30. package/dist/core/code/engine/cli/optional-grammars.js +136 -0
  31. package/dist/core/code/engine/cli/resolve-invocation.js +76 -0
  32. package/dist/core/code/engine/cli/status.js +156 -0
  33. package/dist/core/code/engine/cli/tool.js +384 -0
  34. package/dist/core/code/engine/config/ignore-service.js +511 -0
  35. package/dist/core/code/engine/config/supported-languages.js +17 -0
  36. package/dist/core/code/engine/core/analysis-features.js +64 -0
  37. package/dist/core/code/engine/core/analyzer-identity.js +2171 -0
  38. package/dist/core/code/engine/core/git-staleness.js +180 -0
  39. package/dist/core/code/engine/core/graph/graph.js +180 -0
  40. package/dist/core/code/engine/core/graph/import-cycles.js +106 -0
  41. package/dist/core/code/engine/core/graph/types.js +2 -0
  42. package/dist/core/code/engine/core/index-freshness.js +12 -0
  43. package/dist/core/code/engine/core/ingestion/binding-accumulator.js +341 -0
  44. package/dist/core/code/engine/core/ingestion/call-extractors/configs/c-cpp.js +168 -0
  45. package/dist/core/code/engine/core/ingestion/call-extractors/configs/csharp.js +9 -0
  46. package/dist/core/code/engine/core/ingestion/call-extractors/configs/dart.js +8 -0
  47. package/dist/core/code/engine/core/ingestion/call-extractors/configs/go.js +8 -0
  48. package/dist/core/code/engine/core/ingestion/call-extractors/configs/jvm.js +54 -0
  49. package/dist/core/code/engine/core/ingestion/call-extractors/configs/php.js +8 -0
  50. package/dist/core/code/engine/core/ingestion/call-extractors/configs/python.js +8 -0
  51. package/dist/core/code/engine/core/ingestion/call-extractors/configs/ruby.js +8 -0
  52. package/dist/core/code/engine/core/ingestion/call-extractors/configs/rust.js +8 -0
  53. package/dist/core/code/engine/core/ingestion/call-extractors/configs/swift.js +8 -0
  54. package/dist/core/code/engine/core/ingestion/call-extractors/configs/typescript-javascript.js +11 -0
  55. package/dist/core/code/engine/core/ingestion/call-extractors/generic.js +62 -0
  56. package/dist/core/code/engine/core/ingestion/call-processor.js +503 -0
  57. package/dist/core/code/engine/core/ingestion/call-routing.js +98 -0
  58. package/dist/core/code/engine/core/ingestion/call-types.js +3 -0
  59. package/dist/core/code/engine/core/ingestion/cfg/callee-cell-format.js +45 -0
  60. package/dist/core/code/engine/core/ingestion/cfg/cfg-builder.js +202 -0
  61. package/dist/core/code/engine/core/ingestion/cfg/collect.js +81 -0
  62. package/dist/core/code/engine/core/ingestion/cfg/control-dependence.js +185 -0
  63. package/dist/core/code/engine/core/ingestion/cfg/control-flow-context.js +130 -0
  64. package/dist/core/code/engine/core/ingestion/cfg/emit.js +646 -0
  65. package/dist/core/code/engine/core/ingestion/cfg/post-dominators.js +182 -0
  66. package/dist/core/code/engine/core/ingestion/cfg/reaching-def-reason-codec.js +139 -0
  67. package/dist/core/code/engine/core/ingestion/cfg/reaching-defs-graph.js +322 -0
  68. package/dist/core/code/engine/core/ingestion/cfg/reaching-defs.js +792 -0
  69. package/dist/core/code/engine/core/ingestion/cfg/synthetic-escape.js +305 -0
  70. package/dist/core/code/engine/core/ingestion/cfg/traversal-result.js +6 -0
  71. package/dist/core/code/engine/core/ingestion/cfg/types.js +14 -0
  72. package/dist/core/code/engine/core/ingestion/cfg/visitors/c-cpp-harvest.js +545 -0
  73. package/dist/core/code/engine/core/ingestion/cfg/visitors/c-cpp.js +590 -0
  74. package/dist/core/code/engine/core/ingestion/cfg/visitors/call-site-harvest.js +356 -0
  75. package/dist/core/code/engine/core/ingestion/cfg/visitors/csharp-harvest.js +593 -0
  76. package/dist/core/code/engine/core/ingestion/cfg/visitors/csharp.js +871 -0
  77. package/dist/core/code/engine/core/ingestion/cfg/visitors/dart-harvest.js +874 -0
  78. package/dist/core/code/engine/core/ingestion/cfg/visitors/dart.js +840 -0
  79. package/dist/core/code/engine/core/ingestion/cfg/visitors/go-harvest.js +625 -0
  80. package/dist/core/code/engine/core/ingestion/cfg/visitors/go.js +642 -0
  81. package/dist/core/code/engine/core/ingestion/cfg/visitors/java-harvest.js +517 -0
  82. package/dist/core/code/engine/core/ingestion/cfg/visitors/java.js +816 -0
  83. package/dist/core/code/engine/core/ingestion/cfg/visitors/kotlin-harvest.js +723 -0
  84. package/dist/core/code/engine/core/ingestion/cfg/visitors/kotlin.js +813 -0
  85. package/dist/core/code/engine/core/ingestion/cfg/visitors/php-harvest.js +630 -0
  86. package/dist/core/code/engine/core/ingestion/cfg/visitors/php.js +725 -0
  87. package/dist/core/code/engine/core/ingestion/cfg/visitors/python-harvest.js +776 -0
  88. package/dist/core/code/engine/core/ingestion/cfg/visitors/python.js +562 -0
  89. package/dist/core/code/engine/core/ingestion/cfg/visitors/ruby-harvest.js +591 -0
  90. package/dist/core/code/engine/core/ingestion/cfg/visitors/ruby.js +760 -0
  91. package/dist/core/code/engine/core/ingestion/cfg/visitors/rust-harvest.js +877 -0
  92. package/dist/core/code/engine/core/ingestion/cfg/visitors/rust.js +562 -0
  93. package/dist/core/code/engine/core/ingestion/cfg/visitors/scope-tree-harvest.js +120 -0
  94. package/dist/core/code/engine/core/ingestion/cfg/visitors/swift-harvest.js +683 -0
  95. package/dist/core/code/engine/core/ingestion/cfg/visitors/swift.js +791 -0
  96. package/dist/core/code/engine/core/ingestion/cfg/visitors/typescript-harvest.js +1060 -0
  97. package/dist/core/code/engine/core/ingestion/cfg/visitors/typescript.js +587 -0
  98. package/dist/core/code/engine/core/ingestion/class-extractors/configs/c-cpp.js +77 -0
  99. package/dist/core/code/engine/core/ingestion/class-extractors/configs/csharp.js +24 -0
  100. package/dist/core/code/engine/core/ingestion/class-extractors/configs/dart.js +10 -0
  101. package/dist/core/code/engine/core/ingestion/class-extractors/configs/go.js +28 -0
  102. package/dist/core/code/engine/core/ingestion/class-extractors/configs/jvm.js +67 -0
  103. package/dist/core/code/engine/core/ingestion/class-extractors/configs/php.js +10 -0
  104. package/dist/core/code/engine/core/ingestion/class-extractors/configs/python.js +10 -0
  105. package/dist/core/code/engine/core/ingestion/class-extractors/configs/ruby.js +13 -0
  106. package/dist/core/code/engine/core/ingestion/class-extractors/configs/rust.js +10 -0
  107. package/dist/core/code/engine/core/ingestion/class-extractors/configs/swift.js +21 -0
  108. package/dist/core/code/engine/core/ingestion/class-extractors/configs/typescript-javascript.js +31 -0
  109. package/dist/core/code/engine/core/ingestion/class-extractors/generic.js +144 -0
  110. package/dist/core/code/engine/core/ingestion/class-types.js +2 -0
  111. package/dist/core/code/engine/core/ingestion/cluster-enricher.js +174 -0
  112. package/dist/core/code/engine/core/ingestion/community-processor.js +604 -0
  113. package/dist/core/code/engine/core/ingestion/constants.js +26 -0
  114. package/dist/core/code/engine/core/ingestion/cpp-ue-preprocessor.js +263 -0
  115. package/dist/core/code/engine/core/ingestion/csharp-namespace-gate.js +133 -0
  116. package/dist/core/code/engine/core/ingestion/di-extractors/index.js +38 -0
  117. package/dist/core/code/engine/core/ingestion/di-extractors/spring.js +310 -0
  118. package/dist/core/code/engine/core/ingestion/emit-references.js +244 -0
  119. package/dist/core/code/engine/core/ingestion/entry-point-scoring.js +201 -0
  120. package/dist/core/code/engine/core/ingestion/export-detection.js +244 -0
  121. package/dist/core/code/engine/core/ingestion/field-extractor.js +29 -0
  122. package/dist/core/code/engine/core/ingestion/field-extractors/configs/c-cpp.js +107 -0
  123. package/dist/core/code/engine/core/ingestion/field-extractors/configs/csharp.js +124 -0
  124. package/dist/core/code/engine/core/ingestion/field-extractors/configs/dart.js +99 -0
  125. package/dist/core/code/engine/core/ingestion/field-extractors/configs/go.js +102 -0
  126. package/dist/core/code/engine/core/ingestion/field-extractors/configs/helpers.js +198 -0
  127. package/dist/core/code/engine/core/ingestion/field-extractors/configs/jvm.js +172 -0
  128. package/dist/core/code/engine/core/ingestion/field-extractors/configs/php.js +67 -0
  129. package/dist/core/code/engine/core/ingestion/field-extractors/configs/python.js +94 -0
  130. package/dist/core/code/engine/core/ingestion/field-extractors/configs/ruby.js +79 -0
  131. package/dist/core/code/engine/core/ingestion/field-extractors/configs/rust.js +55 -0
  132. package/dist/core/code/engine/core/ingestion/field-extractors/configs/swift.js +93 -0
  133. package/dist/core/code/engine/core/ingestion/field-extractors/configs/typescript-javascript.js +59 -0
  134. package/dist/core/code/engine/core/ingestion/field-extractors/generic.js +147 -0
  135. package/dist/core/code/engine/core/ingestion/field-extractors/typescript.js +266 -0
  136. package/dist/core/code/engine/core/ingestion/field-types.js +3 -0
  137. package/dist/core/code/engine/core/ingestion/filesystem-walker.js +136 -0
  138. package/dist/core/code/engine/core/ingestion/finalize-orchestrator.js +159 -0
  139. package/dist/core/code/engine/core/ingestion/framework-detection.js +432 -0
  140. package/dist/core/code/engine/core/ingestion/frameworks/spring/analysis-features.js +38 -0
  141. package/dist/core/code/engine/core/ingestion/frameworks/spring/annotation-arguments.js +234 -0
  142. package/dist/core/code/engine/core/ingestion/frameworks/spring/aop-candidates.js +88 -0
  143. package/dist/core/code/engine/core/ingestion/frameworks/spring/aop.js +487 -0
  144. package/dist/core/code/engine/core/ingestion/frameworks/spring/auto-configuration.js +21 -0
  145. package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-candidates.js +189 -0
  146. package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-catalog.js +32 -0
  147. package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-factories.js +73 -0
  148. package/dist/core/code/engine/core/ingestion/frameworks/spring/conditionals.js +323 -0
  149. package/dist/core/code/engine/core/ingestion/frameworks/spring/config-bindings.js +119 -0
  150. package/dist/core/code/engine/core/ingestion/frameworks/spring/di-metadata.js +385 -0
  151. package/dist/core/code/engine/core/ingestion/frameworks/spring/resource-injection.js +96 -0
  152. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/c-cpp.js +17 -0
  153. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/csharp.js +46 -0
  154. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/dart.js +59 -0
  155. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/go.js +30 -0
  156. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/jvm.js +73 -0
  157. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/php.js +19 -0
  158. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/python.js +45 -0
  159. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/ruby.js +20 -0
  160. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/rust.js +58 -0
  161. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/swift.js +94 -0
  162. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/typescript-javascript.js +26 -0
  163. package/dist/core/code/engine/core/ingestion/import-resolvers/csharp.js +128 -0
  164. package/dist/core/code/engine/core/ingestion/import-resolvers/go.js +50 -0
  165. package/dist/core/code/engine/core/ingestion/import-resolvers/jvm.js +112 -0
  166. package/dist/core/code/engine/core/ingestion/import-resolvers/php.js +80 -0
  167. package/dist/core/code/engine/core/ingestion/import-resolvers/python.js +75 -0
  168. package/dist/core/code/engine/core/ingestion/import-resolvers/resolver-factory.js +36 -0
  169. package/dist/core/code/engine/core/ingestion/import-resolvers/ruby.js +20 -0
  170. package/dist/core/code/engine/core/ingestion/import-resolvers/rust.js +79 -0
  171. package/dist/core/code/engine/core/ingestion/import-resolvers/standard.js +180 -0
  172. package/dist/core/code/engine/core/ingestion/import-resolvers/types.js +7 -0
  173. package/dist/core/code/engine/core/ingestion/import-resolvers/utils.js +153 -0
  174. package/dist/core/code/engine/core/ingestion/import-target-adapter.js +99 -0
  175. package/dist/core/code/engine/core/ingestion/language-config.js +391 -0
  176. package/dist/core/code/engine/core/ingestion/language-provider.js +25 -0
  177. package/dist/core/code/engine/core/ingestion/languages/c/arity-metadata.js +98 -0
  178. package/dist/core/code/engine/core/ingestion/languages/c/arity.js +21 -0
  179. package/dist/core/code/engine/core/ingestion/languages/c/capture-side-channel.js +69 -0
  180. package/dist/core/code/engine/core/ingestion/languages/c/captures.js +189 -0
  181. package/dist/core/code/engine/core/ingestion/languages/c/header-scan.js +58 -0
  182. package/dist/core/code/engine/core/ingestion/languages/c/import-decomposer.js +68 -0
  183. package/dist/core/code/engine/core/ingestion/languages/c/import-target.js +103 -0
  184. package/dist/core/code/engine/core/ingestion/languages/c/index.js +33 -0
  185. package/dist/core/code/engine/core/ingestion/languages/c/interpret.js +53 -0
  186. package/dist/core/code/engine/core/ingestion/languages/c/merge-bindings.js +26 -0
  187. package/dist/core/code/engine/core/ingestion/languages/c/query.js +210 -0
  188. package/dist/core/code/engine/core/ingestion/languages/c/scope-resolver.js +112 -0
  189. package/dist/core/code/engine/core/ingestion/languages/c/simple-hooks.js +24 -0
  190. package/dist/core/code/engine/core/ingestion/languages/c/static-linkage.js +109 -0
  191. package/dist/core/code/engine/core/ingestion/languages/c-cpp.js +506 -0
  192. package/dist/core/code/engine/core/ingestion/languages/cpp/adl.js +804 -0
  193. package/dist/core/code/engine/core/ingestion/languages/cpp/arity-metadata.js +258 -0
  194. package/dist/core/code/engine/core/ingestion/languages/cpp/arity.js +37 -0
  195. package/dist/core/code/engine/core/ingestion/languages/cpp/capture-side-channel.js +89 -0
  196. package/dist/core/code/engine/core/ingestion/languages/cpp/captures.js +1975 -0
  197. package/dist/core/code/engine/core/ingestion/languages/cpp/constraint-extractor.js +311 -0
  198. package/dist/core/code/engine/core/ingestion/languages/cpp/constraint-filter.js +210 -0
  199. package/dist/core/code/engine/core/ingestion/languages/cpp/conversion-rank.js +163 -0
  200. package/dist/core/code/engine/core/ingestion/languages/cpp/file-local-linkage.js +327 -0
  201. package/dist/core/code/engine/core/ingestion/languages/cpp/header-scan.js +53 -0
  202. package/dist/core/code/engine/core/ingestion/languages/cpp/import-decomposer.js +134 -0
  203. package/dist/core/code/engine/core/ingestion/languages/cpp/import-target.js +16 -0
  204. package/dist/core/code/engine/core/ingestion/languages/cpp/index.js +33 -0
  205. package/dist/core/code/engine/core/ingestion/languages/cpp/inline-namespaces.js +379 -0
  206. package/dist/core/code/engine/core/ingestion/languages/cpp/interpret.js +239 -0
  207. package/dist/core/code/engine/core/ingestion/languages/cpp/member-lookup.js +470 -0
  208. package/dist/core/code/engine/core/ingestion/languages/cpp/merge-bindings.js +32 -0
  209. package/dist/core/code/engine/core/ingestion/languages/cpp/query.js +763 -0
  210. package/dist/core/code/engine/core/ingestion/languages/cpp/range-bindings.js +230 -0
  211. package/dist/core/code/engine/core/ingestion/languages/cpp/scope-resolver.js +354 -0
  212. package/dist/core/code/engine/core/ingestion/languages/cpp/simple-hooks.js +67 -0
  213. package/dist/core/code/engine/core/ingestion/languages/cpp/two-phase-lookup.js +348 -0
  214. package/dist/core/code/engine/core/ingestion/languages/cpp/type-classifier.js +56 -0
  215. package/dist/core/code/engine/core/ingestion/languages/cpp/user-defined-conversions.js +128 -0
  216. package/dist/core/code/engine/core/ingestion/languages/csharp/accessor-unwrap.js +67 -0
  217. package/dist/core/code/engine/core/ingestion/languages/csharp/arity-metadata.js +49 -0
  218. package/dist/core/code/engine/core/ingestion/languages/csharp/arity.js +40 -0
  219. package/dist/core/code/engine/core/ingestion/languages/csharp/cache-stats.js +32 -0
  220. package/dist/core/code/engine/core/ingestion/languages/csharp/captures.js +557 -0
  221. package/dist/core/code/engine/core/ingestion/languages/csharp/import-decomposer.js +96 -0
  222. package/dist/core/code/engine/core/ingestion/languages/csharp/import-target.js +176 -0
  223. package/dist/core/code/engine/core/ingestion/languages/csharp/index.js +95 -0
  224. package/dist/core/code/engine/core/ingestion/languages/csharp/interpret.js +150 -0
  225. package/dist/core/code/engine/core/ingestion/languages/csharp/merge-bindings.js +58 -0
  226. package/dist/core/code/engine/core/ingestion/languages/csharp/namespace-siblings.js +708 -0
  227. package/dist/core/code/engine/core/ingestion/languages/csharp/qualified-type-names.js +62 -0
  228. package/dist/core/code/engine/core/ingestion/languages/csharp/query.js +578 -0
  229. package/dist/core/code/engine/core/ingestion/languages/csharp/receiver-binding.js +142 -0
  230. package/dist/core/code/engine/core/ingestion/languages/csharp/resolution-config.js +18 -0
  231. package/dist/core/code/engine/core/ingestion/languages/csharp/scope-resolver.js +84 -0
  232. package/dist/core/code/engine/core/ingestion/languages/csharp/simple-hooks.js +81 -0
  233. package/dist/core/code/engine/core/ingestion/languages/csharp.js +204 -0
  234. package/dist/core/code/engine/core/ingestion/languages/dart/arity-metadata.js +38 -0
  235. package/dist/core/code/engine/core/ingestion/languages/dart/arity.js +34 -0
  236. package/dist/core/code/engine/core/ingestion/languages/dart/built-ins.js +37 -0
  237. package/dist/core/code/engine/core/ingestion/languages/dart/cache-stats.js +30 -0
  238. package/dist/core/code/engine/core/ingestion/languages/dart/captures.js +1096 -0
  239. package/dist/core/code/engine/core/ingestion/languages/dart/expand-wildcards.js +34 -0
  240. package/dist/core/code/engine/core/ingestion/languages/dart/extension-type-preprocess.js +33 -0
  241. package/dist/core/code/engine/core/ingestion/languages/dart/import-target.js +68 -0
  242. package/dist/core/code/engine/core/ingestion/languages/dart/index.js +45 -0
  243. package/dist/core/code/engine/core/ingestion/languages/dart/interpret.js +101 -0
  244. package/dist/core/code/engine/core/ingestion/languages/dart/merge-bindings.js +42 -0
  245. package/dist/core/code/engine/core/ingestion/languages/dart/query.js +246 -0
  246. package/dist/core/code/engine/core/ingestion/languages/dart/receiver-binding.js +90 -0
  247. package/dist/core/code/engine/core/ingestion/languages/dart/scope-resolver.js +197 -0
  248. package/dist/core/code/engine/core/ingestion/languages/dart/signature-bindings.js +54 -0
  249. package/dist/core/code/engine/core/ingestion/languages/dart/simple-hooks.js +61 -0
  250. package/dist/core/code/engine/core/ingestion/languages/dart.js +138 -0
  251. package/dist/core/code/engine/core/ingestion/languages/go/arity-metadata.js +71 -0
  252. package/dist/core/code/engine/core/ingestion/languages/go/arity.js +17 -0
  253. package/dist/core/code/engine/core/ingestion/languages/go/cache-stats.js +21 -0
  254. package/dist/core/code/engine/core/ingestion/languages/go/captures.js +492 -0
  255. package/dist/core/code/engine/core/ingestion/languages/go/expand-wildcards.js +97 -0
  256. package/dist/core/code/engine/core/ingestion/languages/go/generic-type-parameters.js +146 -0
  257. package/dist/core/code/engine/core/ingestion/languages/go/import-decomposer.js +47 -0
  258. package/dist/core/code/engine/core/ingestion/languages/go/import-target.js +70 -0
  259. package/dist/core/code/engine/core/ingestion/languages/go/index.js +39 -0
  260. package/dist/core/code/engine/core/ingestion/languages/go/interface-impls.js +955 -0
  261. package/dist/core/code/engine/core/ingestion/languages/go/interpret.js +177 -0
  262. package/dist/core/code/engine/core/ingestion/languages/go/merge-bindings.js +21 -0
  263. package/dist/core/code/engine/core/ingestion/languages/go/method-owners.js +131 -0
  264. package/dist/core/code/engine/core/ingestion/languages/go/namespace-mirror.js +56 -0
  265. package/dist/core/code/engine/core/ingestion/languages/go/package-clause.js +79 -0
  266. package/dist/core/code/engine/core/ingestion/languages/go/package-siblings.js +83 -0
  267. package/dist/core/code/engine/core/ingestion/languages/go/query.js +298 -0
  268. package/dist/core/code/engine/core/ingestion/languages/go/range-binding.js +127 -0
  269. package/dist/core/code/engine/core/ingestion/languages/go/receiver-binding.js +24 -0
  270. package/dist/core/code/engine/core/ingestion/languages/go/scope-resolver.js +75 -0
  271. package/dist/core/code/engine/core/ingestion/languages/go/simple-hooks.js +31 -0
  272. package/dist/core/code/engine/core/ingestion/languages/go/type-binding.js +279 -0
  273. package/dist/core/code/engine/core/ingestion/languages/go.js +160 -0
  274. package/dist/core/code/engine/core/ingestion/languages/index.js +66 -0
  275. package/dist/core/code/engine/core/ingestion/languages/java/analysis-features.js +16 -0
  276. package/dist/core/code/engine/core/ingestion/languages/java/arity-metadata.js +43 -0
  277. package/dist/core/code/engine/core/ingestion/languages/java/arity.js +27 -0
  278. package/dist/core/code/engine/core/ingestion/languages/java/cache-stats.js +32 -0
  279. package/dist/core/code/engine/core/ingestion/languages/java/capture-side-channel.js +123 -0
  280. package/dist/core/code/engine/core/ingestion/languages/java/captures.js +791 -0
  281. package/dist/core/code/engine/core/ingestion/languages/java/import-decomposer.js +88 -0
  282. package/dist/core/code/engine/core/ingestion/languages/java/import-target.js +103 -0
  283. package/dist/core/code/engine/core/ingestion/languages/java/index.js +43 -0
  284. package/dist/core/code/engine/core/ingestion/languages/java/interpret.js +146 -0
  285. package/dist/core/code/engine/core/ingestion/languages/java/merge-bindings.js +43 -0
  286. package/dist/core/code/engine/core/ingestion/languages/java/package-facts.js +16 -0
  287. package/dist/core/code/engine/core/ingestion/languages/java/package-siblings.js +11 -0
  288. package/dist/core/code/engine/core/ingestion/languages/java/query.js +319 -0
  289. package/dist/core/code/engine/core/ingestion/languages/java/receiver-binding.js +98 -0
  290. package/dist/core/code/engine/core/ingestion/languages/java/scope-resolver.js +213 -0
  291. package/dist/core/code/engine/core/ingestion/languages/java/simple-hooks.js +39 -0
  292. package/dist/core/code/engine/core/ingestion/languages/java/spring-aop.js +53 -0
  293. package/dist/core/code/engine/core/ingestion/languages/java/spring-bean-metadata.js +11 -0
  294. package/dist/core/code/engine/core/ingestion/languages/java/spring-conditionals.js +52 -0
  295. package/dist/core/code/engine/core/ingestion/languages/java/spring-config-bindings.js +222 -0
  296. package/dist/core/code/engine/core/ingestion/languages/java/spring-di.js +165 -0
  297. package/dist/core/code/engine/core/ingestion/languages/java.js +192 -0
  298. package/dist/core/code/engine/core/ingestion/languages/javascript/arity.js +15 -0
  299. package/dist/core/code/engine/core/ingestion/languages/javascript/captures.js +1122 -0
  300. package/dist/core/code/engine/core/ingestion/languages/javascript/import-target.js +56 -0
  301. package/dist/core/code/engine/core/ingestion/languages/javascript/index.js +109 -0
  302. package/dist/core/code/engine/core/ingestion/languages/javascript/interpret.js +45 -0
  303. package/dist/core/code/engine/core/ingestion/languages/javascript/merge-bindings.js +21 -0
  304. package/dist/core/code/engine/core/ingestion/languages/javascript/query.js +659 -0
  305. package/dist/core/code/engine/core/ingestion/languages/javascript/scope-resolver.js +78 -0
  306. package/dist/core/code/engine/core/ingestion/languages/javascript/simple-hooks.js +44 -0
  307. package/dist/core/code/engine/core/ingestion/languages/jvm/package-facts.js +46 -0
  308. package/dist/core/code/engine/core/ingestion/languages/jvm/package-siblings.js +200 -0
  309. package/dist/core/code/engine/core/ingestion/languages/kotlin/arity-metadata.js +23 -0
  310. package/dist/core/code/engine/core/ingestion/languages/kotlin/arity.js +18 -0
  311. package/dist/core/code/engine/core/ingestion/languages/kotlin/cache-stats.js +21 -0
  312. package/dist/core/code/engine/core/ingestion/languages/kotlin/capture-side-channel.js +160 -0
  313. package/dist/core/code/engine/core/ingestion/languages/kotlin/captures.js +1262 -0
  314. package/dist/core/code/engine/core/ingestion/languages/kotlin/companion-scopes.js +72 -0
  315. package/dist/core/code/engine/core/ingestion/languages/kotlin/import-decomposer.js +40 -0
  316. package/dist/core/code/engine/core/ingestion/languages/kotlin/import-target.js +135 -0
  317. package/dist/core/code/engine/core/ingestion/languages/kotlin/index.js +26 -0
  318. package/dist/core/code/engine/core/ingestion/languages/kotlin/interpret.js +75 -0
  319. package/dist/core/code/engine/core/ingestion/languages/kotlin/merge-bindings.js +28 -0
  320. package/dist/core/code/engine/core/ingestion/languages/kotlin/owners.js +134 -0
  321. package/dist/core/code/engine/core/ingestion/languages/kotlin/package-facts.js +16 -0
  322. package/dist/core/code/engine/core/ingestion/languages/kotlin/package-siblings.js +11 -0
  323. package/dist/core/code/engine/core/ingestion/languages/kotlin/query.js +243 -0
  324. package/dist/core/code/engine/core/ingestion/languages/kotlin/receiver-binding.js +103 -0
  325. package/dist/core/code/engine/core/ingestion/languages/kotlin/scope-resolver.js +207 -0
  326. package/dist/core/code/engine/core/ingestion/languages/kotlin/simple-hooks.js +42 -0
  327. package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-aop.js +68 -0
  328. package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-bean-metadata.js +11 -0
  329. package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-conditionals.js +53 -0
  330. package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-di.js +304 -0
  331. package/dist/core/code/engine/core/ingestion/languages/kotlin.js +189 -0
  332. package/dist/core/code/engine/core/ingestion/languages/php/arity-metadata.js +66 -0
  333. package/dist/core/code/engine/core/ingestion/languages/php/arity.js +43 -0
  334. package/dist/core/code/engine/core/ingestion/languages/php/cache-stats.js +32 -0
  335. package/dist/core/code/engine/core/ingestion/languages/php/captures.js +1166 -0
  336. package/dist/core/code/engine/core/ingestion/languages/php/import-decomposer.js +238 -0
  337. package/dist/core/code/engine/core/ingestion/languages/php/import-target.js +213 -0
  338. package/dist/core/code/engine/core/ingestion/languages/php/index.js +85 -0
  339. package/dist/core/code/engine/core/ingestion/languages/php/interpret.js +256 -0
  340. package/dist/core/code/engine/core/ingestion/languages/php/merge-bindings.js +50 -0
  341. package/dist/core/code/engine/core/ingestion/languages/php/namespace-siblings.js +353 -0
  342. package/dist/core/code/engine/core/ingestion/languages/php/query.js +391 -0
  343. package/dist/core/code/engine/core/ingestion/languages/php/receiver-binding.js +135 -0
  344. package/dist/core/code/engine/core/ingestion/languages/php/scope-resolver.js +361 -0
  345. package/dist/core/code/engine/core/ingestion/languages/php/simple-hooks.js +116 -0
  346. package/dist/core/code/engine/core/ingestion/languages/php.js +302 -0
  347. package/dist/core/code/engine/core/ingestion/languages/python/arity-metadata.js +49 -0
  348. package/dist/core/code/engine/core/ingestion/languages/python/arity.js +41 -0
  349. package/dist/core/code/engine/core/ingestion/languages/python/cache-stats.js +34 -0
  350. package/dist/core/code/engine/core/ingestion/languages/python/captures.js +299 -0
  351. package/dist/core/code/engine/core/ingestion/languages/python/depends-references.js +68 -0
  352. package/dist/core/code/engine/core/ingestion/languages/python/import-decomposer.js +115 -0
  353. package/dist/core/code/engine/core/ingestion/languages/python/import-target.js +440 -0
  354. package/dist/core/code/engine/core/ingestion/languages/python/index-stats.js +30 -0
  355. package/dist/core/code/engine/core/ingestion/languages/python/index.js +96 -0
  356. package/dist/core/code/engine/core/ingestion/languages/python/interpret.js +430 -0
  357. package/dist/core/code/engine/core/ingestion/languages/python/merge-bindings.js +47 -0
  358. package/dist/core/code/engine/core/ingestion/languages/python/query.js +323 -0
  359. package/dist/core/code/engine/core/ingestion/languages/python/receiver-binding.js +310 -0
  360. package/dist/core/code/engine/core/ingestion/languages/python/scope-resolver.js +80 -0
  361. package/dist/core/code/engine/core/ingestion/languages/python/simple-hooks.js +53 -0
  362. package/dist/core/code/engine/core/ingestion/languages/python.js +140 -0
  363. package/dist/core/code/engine/core/ingestion/languages/ruby/arity.js +41 -0
  364. package/dist/core/code/engine/core/ingestion/languages/ruby/cache-stats.js +21 -0
  365. package/dist/core/code/engine/core/ingestion/languages/ruby/captures.js +864 -0
  366. package/dist/core/code/engine/core/ingestion/languages/ruby/import-target.js +88 -0
  367. package/dist/core/code/engine/core/ingestion/languages/ruby/index.js +29 -0
  368. package/dist/core/code/engine/core/ingestion/languages/ruby/interpret.js +115 -0
  369. package/dist/core/code/engine/core/ingestion/languages/ruby/merge-bindings.js +21 -0
  370. package/dist/core/code/engine/core/ingestion/languages/ruby/query.js +349 -0
  371. package/dist/core/code/engine/core/ingestion/languages/ruby/receiver-binding.js +70 -0
  372. package/dist/core/code/engine/core/ingestion/languages/ruby/scope-resolver.js +263 -0
  373. package/dist/core/code/engine/core/ingestion/languages/ruby/simple-hooks.js +68 -0
  374. package/dist/core/code/engine/core/ingestion/languages/ruby.js +215 -0
  375. package/dist/core/code/engine/core/ingestion/languages/rust/arity.js +16 -0
  376. package/dist/core/code/engine/core/ingestion/languages/rust/cache-stats.js +21 -0
  377. package/dist/core/code/engine/core/ingestion/languages/rust/captures.js +304 -0
  378. package/dist/core/code/engine/core/ingestion/languages/rust/import-decomposer.js +167 -0
  379. package/dist/core/code/engine/core/ingestion/languages/rust/import-target.js +108 -0
  380. package/dist/core/code/engine/core/ingestion/languages/rust/index.js +29 -0
  381. package/dist/core/code/engine/core/ingestion/languages/rust/interpret.js +201 -0
  382. package/dist/core/code/engine/core/ingestion/languages/rust/merge-bindings.js +21 -0
  383. package/dist/core/code/engine/core/ingestion/languages/rust/method-owners.js +76 -0
  384. package/dist/core/code/engine/core/ingestion/languages/rust/module-path.js +222 -0
  385. package/dist/core/code/engine/core/ingestion/languages/rust/qualified-call.js +482 -0
  386. package/dist/core/code/engine/core/ingestion/languages/rust/query.js +280 -0
  387. package/dist/core/code/engine/core/ingestion/languages/rust/range-binding.js +687 -0
  388. package/dist/core/code/engine/core/ingestion/languages/rust/receiver-binding.js +148 -0
  389. package/dist/core/code/engine/core/ingestion/languages/rust/scope-resolver.js +151 -0
  390. package/dist/core/code/engine/core/ingestion/languages/rust/simple-hooks.js +32 -0
  391. package/dist/core/code/engine/core/ingestion/languages/rust.js +183 -0
  392. package/dist/core/code/engine/core/ingestion/languages/swift/arity-metadata.js +44 -0
  393. package/dist/core/code/engine/core/ingestion/languages/swift/arity.js +45 -0
  394. package/dist/core/code/engine/core/ingestion/languages/swift/base-type.js +30 -0
  395. package/dist/core/code/engine/core/ingestion/languages/swift/cache-stats.js +32 -0
  396. package/dist/core/code/engine/core/ingestion/languages/swift/captures.js +594 -0
  397. package/dist/core/code/engine/core/ingestion/languages/swift/conditional-directive-preprocess.js +256 -0
  398. package/dist/core/code/engine/core/ingestion/languages/swift/implicit-imports.js +60 -0
  399. package/dist/core/code/engine/core/ingestion/languages/swift/import-decomposer.js +87 -0
  400. package/dist/core/code/engine/core/ingestion/languages/swift/import-target.js +84 -0
  401. package/dist/core/code/engine/core/ingestion/languages/swift/index.js +56 -0
  402. package/dist/core/code/engine/core/ingestion/languages/swift/interpret.js +93 -0
  403. package/dist/core/code/engine/core/ingestion/languages/swift/merge-bindings.js +51 -0
  404. package/dist/core/code/engine/core/ingestion/languages/swift/query.js +226 -0
  405. package/dist/core/code/engine/core/ingestion/languages/swift/receiver-binding.js +169 -0
  406. package/dist/core/code/engine/core/ingestion/languages/swift/scope-resolver.js +192 -0
  407. package/dist/core/code/engine/core/ingestion/languages/swift/sibling-type-bindings.js +68 -0
  408. package/dist/core/code/engine/core/ingestion/languages/swift/signature-bindings.js +69 -0
  409. package/dist/core/code/engine/core/ingestion/languages/swift/simple-hooks.js +65 -0
  410. package/dist/core/code/engine/core/ingestion/languages/swift/target-grouping.js +97 -0
  411. package/dist/core/code/engine/core/ingestion/languages/swift/target-siblings.js +74 -0
  412. package/dist/core/code/engine/core/ingestion/languages/swift.js +246 -0
  413. package/dist/core/code/engine/core/ingestion/languages/typescript/arity-metadata.js +106 -0
  414. package/dist/core/code/engine/core/ingestion/languages/typescript/arity.js +57 -0
  415. package/dist/core/code/engine/core/ingestion/languages/typescript/array-callback.js +58 -0
  416. package/dist/core/code/engine/core/ingestion/languages/typescript/cache-stats.js +34 -0
  417. package/dist/core/code/engine/core/ingestion/languages/typescript/captures.js +956 -0
  418. package/dist/core/code/engine/core/ingestion/languages/typescript/cjs-export-assignment.js +535 -0
  419. package/dist/core/code/engine/core/ingestion/languages/typescript/cjs-module-exports.js +196 -0
  420. package/dist/core/code/engine/core/ingestion/languages/typescript/import-decomposer.js +374 -0
  421. package/dist/core/code/engine/core/ingestion/languages/typescript/import-target.js +65 -0
  422. package/dist/core/code/engine/core/ingestion/languages/typescript/index.js +108 -0
  423. package/dist/core/code/engine/core/ingestion/languages/typescript/interpret.js +344 -0
  424. package/dist/core/code/engine/core/ingestion/languages/typescript/merge-bindings.js +161 -0
  425. package/dist/core/code/engine/core/ingestion/languages/typescript/nuxt-auto-imports.js +325 -0
  426. package/dist/core/code/engine/core/ingestion/languages/typescript/query.js +1328 -0
  427. package/dist/core/code/engine/core/ingestion/languages/typescript/receiver-binding.js +201 -0
  428. package/dist/core/code/engine/core/ingestion/languages/typescript/scope-resolver.js +293 -0
  429. package/dist/core/code/engine/core/ingestion/languages/typescript/simple-hooks.js +139 -0
  430. package/dist/core/code/engine/core/ingestion/languages/typescript.js +455 -0
  431. package/dist/core/code/engine/core/ingestion/languages/vue/captures.js +70 -0
  432. package/dist/core/code/engine/core/ingestion/languages/vue/import-target.js +61 -0
  433. package/dist/core/code/engine/core/ingestion/languages/vue/index.js +55 -0
  434. package/dist/core/code/engine/core/ingestion/languages/vue/scope-resolver.js +295 -0
  435. package/dist/core/code/engine/core/ingestion/languages/vue.js +96 -0
  436. package/dist/core/code/engine/core/ingestion/local-symbol-pruner.js +68 -0
  437. package/dist/core/code/engine/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
  438. package/dist/core/code/engine/core/ingestion/method-extractors/configs/csharp.js +290 -0
  439. package/dist/core/code/engine/core/ingestion/method-extractors/configs/dart.js +392 -0
  440. package/dist/core/code/engine/core/ingestion/method-extractors/configs/go.js +179 -0
  441. package/dist/core/code/engine/core/ingestion/method-extractors/configs/jvm.js +350 -0
  442. package/dist/core/code/engine/core/ingestion/method-extractors/configs/php.js +306 -0
  443. package/dist/core/code/engine/core/ingestion/method-extractors/configs/python.js +312 -0
  444. package/dist/core/code/engine/core/ingestion/method-extractors/configs/ruby.js +289 -0
  445. package/dist/core/code/engine/core/ingestion/method-extractors/configs/rust.js +198 -0
  446. package/dist/core/code/engine/core/ingestion/method-extractors/configs/swift.js +286 -0
  447. package/dist/core/code/engine/core/ingestion/method-extractors/configs/typescript-javascript.js +341 -0
  448. package/dist/core/code/engine/core/ingestion/method-extractors/generic.js +209 -0
  449. package/dist/core/code/engine/core/ingestion/method-types.js +3 -0
  450. package/dist/core/code/engine/core/ingestion/model/field-registry.js +41 -0
  451. package/dist/core/code/engine/core/ingestion/model/index.js +52 -0
  452. package/dist/core/code/engine/core/ingestion/model/method-registry.js +138 -0
  453. package/dist/core/code/engine/core/ingestion/model/owned-members-lookup.js +46 -0
  454. package/dist/core/code/engine/core/ingestion/model/registration-table.js +234 -0
  455. package/dist/core/code/engine/core/ingestion/model/resolve.js +183 -0
  456. package/dist/core/code/engine/core/ingestion/model/scope-resolution-indexes.js +43 -0
  457. package/dist/core/code/engine/core/ingestion/model/semantic-model.js +179 -0
  458. package/dist/core/code/engine/core/ingestion/model/symbol-table.js +216 -0
  459. package/dist/core/code/engine/core/ingestion/model/type-registry.js +84 -0
  460. package/dist/core/code/engine/core/ingestion/mro-processor.js +709 -0
  461. package/dist/core/code/engine/core/ingestion/parsing-processor.js +312 -0
  462. package/dist/core/code/engine/core/ingestion/pipeline-phases/communities.js +69 -0
  463. package/dist/core/code/engine/core/ingestion/pipeline-phases/cross-file.js +71 -0
  464. package/dist/core/code/engine/core/ingestion/pipeline-phases/di.js +338 -0
  465. package/dist/core/code/engine/core/ingestion/pipeline-phases/http-api-calls.js +312 -0
  466. package/dist/core/code/engine/core/ingestion/pipeline-phases/index.js +54 -0
  467. package/dist/core/code/engine/core/ingestion/pipeline-phases/mro.js +40 -0
  468. package/dist/core/code/engine/core/ingestion/pipeline-phases/orm.js +78 -0
  469. package/dist/core/code/engine/core/ingestion/pipeline-phases/parse-impl.js +1286 -0
  470. package/dist/core/code/engine/core/ingestion/pipeline-phases/parse.js +41 -0
  471. package/dist/core/code/engine/core/ingestion/pipeline-phases/processes.js +193 -0
  472. package/dist/core/code/engine/core/ingestion/pipeline-phases/prune-local-symbols.js +29 -0
  473. package/dist/core/code/engine/core/ingestion/pipeline-phases/registry.js +52 -0
  474. package/dist/core/code/engine/core/ingestion/pipeline-phases/routes.js +409 -0
  475. package/dist/core/code/engine/core/ingestion/pipeline-phases/rpc-edges.js +301 -0
  476. package/dist/core/code/engine/core/ingestion/pipeline-phases/runner.js +207 -0
  477. package/dist/core/code/engine/core/ingestion/pipeline-phases/scan.js +49 -0
  478. package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-aop.js +442 -0
  479. package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-auto-configuration.js +264 -0
  480. package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-config.js +440 -0
  481. package/dist/core/code/engine/core/ingestion/pipeline-phases/structure.js +38 -0
  482. package/dist/core/code/engine/core/ingestion/pipeline-phases/tools.js +89 -0
  483. package/dist/core/code/engine/core/ingestion/pipeline-phases/types.js +40 -0
  484. package/dist/core/code/engine/core/ingestion/pipeline.js +152 -0
  485. package/dist/core/code/engine/core/ingestion/process-processor.js +325 -0
  486. package/dist/core/code/engine/core/ingestion/resolve-references.js +205 -0
  487. package/dist/core/code/engine/core/ingestion/route-extractors/constant-resolver.js +135 -0
  488. package/dist/core/code/engine/core/ingestion/route-extractors/django-root-discovery.js +221 -0
  489. package/dist/core/code/engine/core/ingestion/route-extractors/django.js +428 -0
  490. package/dist/core/code/engine/core/ingestion/route-extractors/expo.js +39 -0
  491. package/dist/core/code/engine/core/ingestion/route-extractors/fastapi-router-bindings.js +264 -0
  492. package/dist/core/code/engine/core/ingestion/route-extractors/laravel.js +501 -0
  493. package/dist/core/code/engine/core/ingestion/route-extractors/middleware.js +175 -0
  494. package/dist/core/code/engine/core/ingestion/route-extractors/nextjs.js +81 -0
  495. package/dist/core/code/engine/core/ingestion/route-extractors/php.js +25 -0
  496. package/dist/core/code/engine/core/ingestion/route-extractors/python-const-resolver.js +307 -0
  497. package/dist/core/code/engine/core/ingestion/route-extractors/response-shapes.js +299 -0
  498. package/dist/core/code/engine/core/ingestion/route-extractors/route-path.js +71 -0
  499. package/dist/core/code/engine/core/ingestion/route-extractors/spring-shared.js +310 -0
  500. package/dist/core/code/engine/core/ingestion/route-extractors/spring.js +441 -0
  501. package/dist/core/code/engine/core/ingestion/scope-extractor-bridge.js +60 -0
  502. package/dist/core/code/engine/core/ingestion/scope-extractor.js +1373 -0
  503. package/dist/core/code/engine/core/ingestion/scope-resolution/contract/scope-resolver.js +282 -0
  504. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +72 -0
  505. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/edges.js +194 -0
  506. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/ids.js +472 -0
  507. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/imports-to-edges.js +49 -0
  508. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/method-dispatch.js +43 -0
  509. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +274 -0
  510. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +93 -0
  511. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/callable-value-flow.js +1240 -0
  512. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/compound-receiver.js +1174 -0
  513. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/free-call-fallback.js +873 -0
  514. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/imported-return-types.js +226 -0
  515. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/mro.js +107 -0
  516. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/overload-narrowing.js +441 -0
  517. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/property-dispatch.js +122 -0
  518. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +1720 -0
  519. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/phase.js +395 -0
  520. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +208 -0
  521. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/registry.js +49 -0
  522. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/run.js +632 -0
  523. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/validate-bindings-immutability.js +112 -0
  524. package/dist/core/code/engine/core/ingestion/scope-resolution/resolution-outcome.js +41 -0
  525. package/dist/core/code/engine/core/ingestion/scope-resolution/scope/namespace-targets.js +81 -0
  526. package/dist/core/code/engine/core/ingestion/scope-resolution/scope/walkers.js +1835 -0
  527. package/dist/core/code/engine/core/ingestion/scope-resolution/unresolved-receivers.js +242 -0
  528. package/dist/core/code/engine/core/ingestion/scope-resolution/utils/definition-id.js +22 -0
  529. package/dist/core/code/engine/core/ingestion/scope-resolution/workspace-index.js +151 -0
  530. package/dist/core/code/engine/core/ingestion/structure-processor.js +40 -0
  531. package/dist/core/code/engine/core/ingestion/tree-sitter-queries.js +2244 -0
  532. package/dist/core/code/engine/core/ingestion/ts-js-hoc-utils.js +115 -0
  533. package/dist/core/code/engine/core/ingestion/type-env.js +1136 -0
  534. package/dist/core/code/engine/core/ingestion/type-extractors/c-cpp.js +555 -0
  535. package/dist/core/code/engine/core/ingestion/type-extractors/csharp.js +570 -0
  536. package/dist/core/code/engine/core/ingestion/type-extractors/dart.js +372 -0
  537. package/dist/core/code/engine/core/ingestion/type-extractors/go.js +508 -0
  538. package/dist/core/code/engine/core/ingestion/type-extractors/jvm.js +875 -0
  539. package/dist/core/code/engine/core/ingestion/type-extractors/php.js +537 -0
  540. package/dist/core/code/engine/core/ingestion/type-extractors/python.js +477 -0
  541. package/dist/core/code/engine/core/ingestion/type-extractors/ruby.js +380 -0
  542. package/dist/core/code/engine/core/ingestion/type-extractors/rust.js +502 -0
  543. package/dist/core/code/engine/core/ingestion/type-extractors/shared.js +843 -0
  544. package/dist/core/code/engine/core/ingestion/type-extractors/swift.js +490 -0
  545. package/dist/core/code/engine/core/ingestion/type-extractors/types.js +2 -0
  546. package/dist/core/code/engine/core/ingestion/type-extractors/typescript.js +690 -0
  547. package/dist/core/code/engine/core/ingestion/utils/ast-helpers.js +1693 -0
  548. package/dist/core/code/engine/core/ingestion/utils/call-analysis.js +779 -0
  549. package/dist/core/code/engine/core/ingestion/utils/callable-flow-captures.js +932 -0
  550. package/dist/core/code/engine/core/ingestion/utils/callable-labels.js +49 -0
  551. package/dist/core/code/engine/core/ingestion/utils/deferred-resolution-profile.js +151 -0
  552. package/dist/core/code/engine/core/ingestion/utils/effective-ram.js +67 -0
  553. package/dist/core/code/engine/core/ingestion/utils/env.js +60 -0
  554. package/dist/core/code/engine/core/ingestion/utils/event-loop.js +9 -0
  555. package/dist/core/code/engine/core/ingestion/utils/graph-sort.js +103 -0
  556. package/dist/core/code/engine/core/ingestion/utils/heap-probe.js +45 -0
  557. package/dist/core/code/engine/core/ingestion/utils/heritage-marker.js +47 -0
  558. package/dist/core/code/engine/core/ingestion/utils/line-base.js +24 -0
  559. package/dist/core/code/engine/core/ingestion/utils/max-file-size.js +59 -0
  560. package/dist/core/code/engine/core/ingestion/utils/method-props.js +198 -0
  561. package/dist/core/code/engine/core/ingestion/utils/qualified-name.js +73 -0
  562. package/dist/core/code/engine/core/ingestion/utils/receiver-chain-captures.js +60 -0
  563. package/dist/core/code/engine/core/ingestion/utils/receiver-chain-codec.js +188 -0
  564. package/dist/core/code/engine/core/ingestion/utils/scope-tree-walk.js +36 -0
  565. package/dist/core/code/engine/core/ingestion/utils/symbol-labels.js +48 -0
  566. package/dist/core/code/engine/core/ingestion/utils/template-arguments.js +187 -0
  567. package/dist/core/code/engine/core/ingestion/utils/type-parameters.js +209 -0
  568. package/dist/core/code/engine/core/ingestion/utils/verbose.js +6 -0
  569. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/c-cpp.js +133 -0
  570. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/csharp.js +66 -0
  571. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/dart.js +111 -0
  572. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/go.js +153 -0
  573. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/jvm.js +145 -0
  574. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/php.js +61 -0
  575. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/python.js +104 -0
  576. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/ruby.js +55 -0
  577. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/rust.js +79 -0
  578. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/swift.js +91 -0
  579. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/typescript-javascript.js +86 -0
  580. package/dist/core/code/engine/core/ingestion/variable-extractors/generic.js +111 -0
  581. package/dist/core/code/engine/core/ingestion/variable-types.js +3 -0
  582. package/dist/core/code/engine/core/ingestion/vue-sfc-extractor.js +544 -0
  583. package/dist/core/code/engine/core/ingestion/workers/callable-id.js +122 -0
  584. package/dist/core/code/engine/core/ingestion/workers/clone-safety.js +470 -0
  585. package/dist/core/code/engine/core/ingestion/workers/parse-worker.js +2456 -0
  586. package/dist/core/code/engine/core/ingestion/workers/post-result.js +90 -0
  587. package/dist/core/code/engine/core/ingestion/workers/quarantine.js +41 -0
  588. package/dist/core/code/engine/core/ingestion/workers/result-merge.js +59 -0
  589. package/dist/core/code/engine/core/ingestion/workers/worker-pool.js +1725 -0
  590. package/dist/core/code/engine/core/ingestion/workspace-config.js +139 -0
  591. package/dist/core/code/engine/core/lbug/conn-lock.js +72 -0
  592. package/dist/core/code/engine/core/lbug/csv-generator.js +710 -0
  593. package/dist/core/code/engine/core/lbug/cypher-escape.js +24 -0
  594. package/dist/core/code/engine/core/lbug/extension-load-error.js +339 -0
  595. package/dist/core/code/engine/core/lbug/extension-loader.js +261 -0
  596. package/dist/core/code/engine/core/lbug/graph-emit-sink.js +584 -0
  597. package/dist/core/code/engine/core/lbug/lbug-adapter.js +2703 -0
  598. package/dist/core/code/engine/core/lbug/lbug-config.js +1029 -0
  599. package/dist/core/code/engine/core/lbug/native-check.js +435 -0
  600. package/dist/core/code/engine/core/lbug/pool-adapter.js +973 -0
  601. package/dist/core/code/engine/core/lbug/query-params.js +25 -0
  602. package/dist/core/code/engine/core/lbug/query-result-utils.js +31 -0
  603. package/dist/core/code/engine/core/lbug/rel-pair-routing.js +373 -0
  604. package/dist/core/code/engine/core/lbug/schema.js +771 -0
  605. package/dist/core/code/engine/core/lbug/shutdown-helpers.js +40 -0
  606. package/dist/core/code/engine/core/lbug/sidecar-recovery.js +716 -0
  607. package/dist/core/code/engine/core/lbug/stdio-capture.js +49 -0
  608. package/dist/core/code/engine/core/lbug/sync-csv-writer.js +115 -0
  609. package/dist/core/code/engine/core/lbug/wal-checkpoint-driver.js +215 -0
  610. package/dist/core/code/engine/core/lbug/wal-driver-state.js +28 -0
  611. package/dist/core/code/engine/core/logger.js +339 -0
  612. package/dist/core/code/engine/core/platform/capabilities.js +91 -0
  613. package/dist/core/code/engine/core/run-analyze.js +1098 -0
  614. package/dist/core/code/engine/core/tree-sitter/parser-loader.js +281 -0
  615. package/dist/core/code/engine/core/tree-sitter/safe-parse.js +258 -0
  616. package/dist/core/code/engine/core/tree-sitter/vendored-grammars.js +64 -0
  617. package/dist/core/code/engine/lib/utils.js +121 -0
  618. package/dist/core/code/engine/mcp/core/lbug-adapter.js +27 -0
  619. package/dist/core/code/engine/mcp/local/aop-metadata.js +230 -0
  620. package/dist/core/code/engine/mcp/local/bean-metadata.js +49 -0
  621. package/dist/core/code/engine/mcp/local/limits.js +15 -0
  622. package/dist/core/code/engine/mcp/local/line-display.js +6 -0
  623. package/dist/core/code/engine/mcp/local/local-backend.js +4142 -0
  624. package/dist/core/code/engine/storage/branch-index.js +72 -0
  625. package/dist/core/code/engine/storage/file-hash.js +95 -0
  626. package/dist/core/code/engine/storage/fs-atomic.js +34 -0
  627. package/dist/core/code/engine/storage/git.js +555 -0
  628. package/dist/core/code/engine/storage/index-lock.js +664 -0
  629. package/dist/core/code/engine/storage/parse-cache.js +650 -0
  630. package/dist/core/code/engine/storage/parsedfile-store.js +620 -0
  631. package/dist/core/code/engine/storage/repo-manager.js +1061 -0
  632. package/dist/core/code/engine/storage/scope-index-store.js +247 -0
  633. package/dist/core/code/engine/types/pipeline.js +2 -0
  634. package/dist/core/code/scripts/install-duckdb-extension.mjs +125 -0
  635. package/dist/core/code/scripts/resolve-analyze-cmd.cjs +346 -0
  636. package/dist/core/code/shared/graph/types.js +8 -0
  637. package/dist/core/code/shared/index.js +105 -0
  638. package/dist/core/code/shared/integrations/circuit-breaker.js +242 -0
  639. package/dist/core/code/shared/integrations/resilient-fetch.js +224 -0
  640. package/dist/core/code/shared/integrations/retry.js +70 -0
  641. package/dist/core/code/shared/integrations/understand-quickly.js +145 -0
  642. package/dist/core/code/shared/language-detection.js +162 -0
  643. package/dist/core/code/shared/languages.js +27 -0
  644. package/dist/core/code/shared/lbug/schema-constants.js +98 -0
  645. package/dist/core/code/shared/mro-strategy.js +2 -0
  646. package/dist/core/code/shared/pipeline.js +5 -0
  647. package/dist/core/code/shared/scope-resolution/callable-flow-site.js +11 -0
  648. package/dist/core/code/shared/scope-resolution/def-index.js +53 -0
  649. package/dist/core/code/shared/scope-resolution/evidence-weights.js +87 -0
  650. package/dist/core/code/shared/scope-resolution/finalize-algorithm.js +807 -0
  651. package/dist/core/code/shared/scope-resolution/language-classification.js +46 -0
  652. package/dist/core/code/shared/scope-resolution/method-dispatch-index.js +100 -0
  653. package/dist/core/code/shared/scope-resolution/module-scope-index.js +59 -0
  654. package/dist/core/code/shared/scope-resolution/origin-priority.js +23 -0
  655. package/dist/core/code/shared/scope-resolution/parsed-file.js +54 -0
  656. package/dist/core/code/shared/scope-resolution/position-index.js +136 -0
  657. package/dist/core/code/shared/scope-resolution/qualified-name-index.js +77 -0
  658. package/dist/core/code/shared/scope-resolution/reference-site.js +24 -0
  659. package/dist/core/code/shared/scope-resolution/registries/class-registry.js +32 -0
  660. package/dist/core/code/shared/scope-resolution/registries/context.js +52 -0
  661. package/dist/core/code/shared/scope-resolution/registries/evidence.js +152 -0
  662. package/dist/core/code/shared/scope-resolution/registries/field-registry.js +33 -0
  663. package/dist/core/code/shared/scope-resolution/registries/lookup-core.js +392 -0
  664. package/dist/core/code/shared/scope-resolution/registries/lookup-qualified.js +58 -0
  665. package/dist/core/code/shared/scope-resolution/registries/macro-registry.js +34 -0
  666. package/dist/core/code/shared/scope-resolution/registries/method-registry.js +34 -0
  667. package/dist/core/code/shared/scope-resolution/registries/tie-breaks.js +63 -0
  668. package/dist/core/code/shared/scope-resolution/resolve-type-ref.js +128 -0
  669. package/dist/core/code/shared/scope-resolution/scope-id.js +49 -0
  670. package/dist/core/code/shared/scope-resolution/scope-tree.js +225 -0
  671. package/dist/core/code/shared/scope-resolution/symbol-definition.js +12 -0
  672. package/dist/core/code/shared/scope-resolution/types.js +25 -0
  673. package/dist/core/code/shared/test-helpers.js +17 -0
  674. package/dist/core/code/vendor/leiden/index.cjs +355 -0
  675. package/dist/core/code/vendor/leiden/utils.cjs +419 -0
  676. package/dist/core/features/scanner.d.ts +2 -0
  677. package/dist/core/features/scanner.d.ts.map +1 -1
  678. package/dist/core/features/scanner.js +27 -6
  679. package/dist/core/features/scanner.js.map +1 -1
  680. package/dist/core/timeline/cli.d.ts.map +1 -1
  681. package/dist/core/timeline/cli.js +13 -6
  682. package/dist/core/timeline/cli.js.map +1 -1
  683. package/dist/core/timeline/debris.d.ts +20 -0
  684. package/dist/core/timeline/debris.d.ts.map +1 -0
  685. package/dist/core/timeline/debris.js +124 -0
  686. package/dist/core/timeline/debris.js.map +1 -0
  687. package/dist/core/timeline/hook-runner.d.ts.map +1 -1
  688. package/dist/core/timeline/hook-runner.js +3 -1
  689. package/dist/core/timeline/hook-runner.js.map +1 -1
  690. package/dist/core/timeline/hooks.d.ts.map +1 -1
  691. package/dist/core/timeline/hooks.js +13 -5
  692. package/dist/core/timeline/hooks.js.map +1 -1
  693. package/dist/core/timeline/installer.d.ts +2 -0
  694. package/dist/core/timeline/installer.d.ts.map +1 -1
  695. package/dist/core/timeline/installer.js +12 -0
  696. package/dist/core/timeline/installer.js.map +1 -1
  697. package/dist/core/timeline/project-root.d.ts +21 -0
  698. package/dist/core/timeline/project-root.d.ts.map +1 -0
  699. package/dist/core/timeline/project-root.js +83 -0
  700. package/dist/core/timeline/project-root.js.map +1 -0
  701. package/package.json +1 -1
@@ -0,0 +1,1975 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.emitCppScopeCaptures = emitCppScopeCaptures;
4
+ const ast_helpers_js_1 = require("../../utils/ast-helpers.js");
5
+ const query_js_1 = require("./query.js");
6
+ const constants_js_1 = require("../../constants.js");
7
+ const safe_parse_js_1 = require("../../../tree-sitter/safe-parse.js");
8
+ const cpp_ue_preprocessor_js_1 = require("../../cpp-ue-preprocessor.js");
9
+ const qualified_name_js_1 = require("../../utils/qualified-name.js");
10
+ const import_decomposer_js_1 = require("./import-decomposer.js");
11
+ const arity_metadata_js_1 = require("./arity-metadata.js");
12
+ const file_local_linkage_js_1 = require("./file-local-linkage.js");
13
+ const two_phase_lookup_js_1 = require("./two-phase-lookup.js");
14
+ const adl_js_1 = require("./adl.js");
15
+ const inline_namespaces_js_1 = require("./inline-namespaces.js");
16
+ const constraint_extractor_js_1 = require("./constraint-extractor.js");
17
+ const member_lookup_js_1 = require("./member-lookup.js");
18
+ const conversion_rank_js_1 = require("./conversion-rank.js");
19
+ const logger_js_1 = require("../../../logger.js");
20
+ const receiver_chain_captures_js_1 = require("../../utils/receiver-chain-captures.js");
21
+ const callable_flow_captures_js_1 = require("../../utils/callable-flow-captures.js");
22
+ const CPP_CALLABLE_CAPTURE_OPTIONS = {
23
+ functionNodeTypes: new Set(['function_definition', 'lambda_expression']),
24
+ callNodeTypes: new Set(['call_expression']),
25
+ parameterListNodeTypes: new Set(['parameter_list', 'argument_list']),
26
+ parameterNodeTypes: new Set(['parameter_declaration', 'optional_parameter_declaration']),
27
+ bindingNodeTypes: new Set(['init_declarator']),
28
+ assignmentNodeTypes: new Set(['assignment_expression']),
29
+ identifierNodeTypes: new Set([
30
+ 'identifier',
31
+ 'field_identifier',
32
+ 'type_identifier',
33
+ 'namespace_identifier',
34
+ ]),
35
+ callableSignatureDeclarationNodeTypes: new Set([
36
+ 'declaration',
37
+ 'field_declaration',
38
+ 'parameter_declaration',
39
+ 'optional_parameter_declaration',
40
+ ]),
41
+ callableReferenceNodeTypes: new Set(['qualified_identifier']),
42
+ emitCanonicalInvokeReference: true,
43
+ memberPointerOperators: new Set(['.*', '->*']),
44
+ memberPointerParts: (node) => cppRecoveredMemberPointerParts(node),
45
+ parameterPassingMode: (parameter) => cppOutermostPassingMode(parameter),
46
+ isTrueReferenceBinding: (_container, destination) => cppContainsNodeType(destination, 'reference_declarator'),
47
+ expectedSignature: (container, destination) => cppFunctionDeclaratorSignature(destination) ?? cppFunctionDeclaratorSignature(container),
48
+ normalizeQualifiedName: (raw) => raw.replaceAll('::', '.'),
49
+ };
50
+ /**
51
+ * Passing mode from the parameter's OUTERMOST declarator chain only. A deep
52
+ * subtree scan inverted copy vs alias: `void reg(void (*cb)(int& out))` has a
53
+ * `reference_declarator` inside the nested parameter list, but `cb` itself is
54
+ * a by-value pointer copy — classifying it 'reference' made the solver
55
+ * back-propagate formal targets into every caller's argument cell (#2522
56
+ * review, M5). The chain walk never descends into nested parameter lists.
57
+ */
58
+ function cppOutermostPassingMode(parameter) {
59
+ let sawReference = false;
60
+ let sawPointer = false;
61
+ let node = parameter.childForFieldName('declarator') ?? null;
62
+ const visited = new Set();
63
+ while (node !== null && !visited.has(node.id)) {
64
+ visited.add(node.id);
65
+ if (node.type === 'reference_declarator' || node.type === 'abstract_reference_declarator') {
66
+ // A reference ANYWHERE on the chain aliases the caller's storage —
67
+ // `void (*&cb)(int)` is a reference to pointer, i.e. an alias.
68
+ sawReference = true;
69
+ }
70
+ else if (node.type === 'pointer_declarator' || node.type === 'abstract_pointer_declarator') {
71
+ sawPointer = true;
72
+ }
73
+ const next = node.childForFieldName('declarator');
74
+ if (next !== null) {
75
+ node = next;
76
+ continue;
77
+ }
78
+ if (node.type === 'parenthesized_declarator') {
79
+ node =
80
+ node.namedChildren.find((child) => child !== null && child.type.includes('declarator')) ?? null;
81
+ continue;
82
+ }
83
+ break;
84
+ }
85
+ return sawReference ? 'reference' : sawPointer ? 'pointer' : 'value';
86
+ }
87
+ function cppRecoveredMemberPointerParts(node) {
88
+ if (!node.type.includes('parenthesized'))
89
+ return undefined;
90
+ const recovered = node.namedChildren.find((child) => child !== null && child.type === 'ERROR');
91
+ if (recovered === undefined)
92
+ return undefined;
93
+ const operator = recovered.children.find((child) => child !== null && child.text === '->*');
94
+ const sibling = node.namedChildren.find((child) => child !== null && child.id !== recovered.id);
95
+ const errIdentifier = recovered.namedChildren.find((child) => child !== null);
96
+ if (operator === undefined || sibling === undefined || errIdentifier === undefined) {
97
+ return undefined;
98
+ }
99
+ // tree-sitter's error recovery groups `(obj->*ptr)` two ways depending on
100
+ // recovery cost (identifier lengths!): either `[identifier, ERROR "->*m"]`
101
+ // or `[ERROR "obj->*", identifier]`. Disambiguate by token order INSIDE the
102
+ // ERROR: an identifier BEFORE `->*` is the receiver (the sibling is the
103
+ // pointer/member); an identifier AFTER `->*` is the member (the sibling is
104
+ // the receiver). Assuming one fixed grouping swapped the roles and silently
105
+ // dropped the call site (#2522 review, H2).
106
+ if (errIdentifier.startIndex < operator.startIndex) {
107
+ return { receiver: errIdentifier, member: sibling, operator: operator.text };
108
+ }
109
+ return { receiver: sibling, member: errIdentifier, operator: operator.text };
110
+ }
111
+ /**
112
+ * Per-file wall-clock budget for the capture-emit loop (#2432). A worker
113
+ * thread stuck in this loop cannot be terminated safely (terminating a
114
+ * thread mid-N-API call aborts the whole process with Napi::Error), so the
115
+ * loop must bound itself: on breach we return the captures accumulated so
116
+ * far with a warning — degraded coverage for one file, never a crash or a
117
+ * thrown error (a throw here would make the language-group catch drop every
118
+ * remaining file in the batch).
119
+ *
120
+ * `CGRAPH_CPP_CAPTURE_BUDGET_MS`: unset/invalid/negative → 20000; explicit
121
+ * 0 → expires immediately (deterministic test hook).
122
+ */
123
+ const CPP_CAPTURE_BUDGET_DEFAULT_MS = 20_000;
124
+ function cppCaptureBudgetMs() {
125
+ const raw = process.env.CGRAPH_CPP_CAPTURE_BUDGET_MS;
126
+ if (raw === undefined || raw === '')
127
+ return CPP_CAPTURE_BUDGET_DEFAULT_MS;
128
+ const parsed = Number(raw);
129
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : CPP_CAPTURE_BUDGET_DEFAULT_MS;
130
+ }
131
+ function emitCppScopeCaptures(sourceText, filePath, cachedTree) {
132
+ let tree = cachedTree;
133
+ if (tree === undefined) {
134
+ // Idempotent re-application: `extractParsedFile` already preprocesses, but
135
+ // direct emitter callers (benchmarks, capture goldens) must see the same
136
+ // program the pipeline does.
137
+ const parseText = (0, cpp_ue_preprocessor_js_1.stripUeMacros)(sourceText);
138
+ tree = (0, safe_parse_js_1.parseSourceSafe)((0, query_js_1.getCppParser)(), parseText, undefined, {
139
+ bufferSize: (0, constants_js_1.getTreeSitterBufferSize)(parseText),
140
+ });
141
+ }
142
+ const rawMatches = (0, query_js_1.getCppScopeQuery)().matches(tree.rootNode);
143
+ const out = [];
144
+ // #2432: reset the per-file lookup index. The identifier-argument type
145
+ // lookups below used to re-walk the AST per identifier (full-tree DFS in
146
+ // isKnownEnumName, per-scope declaration scans) — O(calls × args × treeSize)
147
+ // per file, 151s on a 194KB file that parses in 46ms. The index makes each
148
+ // lookup O(1) after a single lazily-built pass.
149
+ resetCppFileLookupIndex();
150
+ // Track ranges where typedef-struct/enum was captured as its concrete type
151
+ // so we can suppress the duplicate @declaration.typedef match.
152
+ const concreteTypedefRanges = new Set();
153
+ // #2432: per-file deadline for the loop below (see cppCaptureBudgetMs).
154
+ // Checked every 64 matches — post-index a single iteration is microseconds,
155
+ // so the check granularity costs nothing and bounds the drift past the
156
+ // deadline to well under a second.
157
+ const budgetMs = cppCaptureBudgetMs();
158
+ const deadline = Date.now() + budgetMs;
159
+ let matchIndex = 0;
160
+ for (const m of rawMatches) {
161
+ if ((matchIndex++ & 63) === 0 && Date.now() >= deadline) {
162
+ logger_js_1.logger.warn({ filePath, budgetMs, processedMatches: matchIndex - 1, totalMatches: rawMatches.length }, `C++ capture extraction exceeded its ${budgetMs}ms budget for ${filePath}; returning partial captures for this file (#2432).`);
163
+ break;
164
+ }
165
+ const grouped = {};
166
+ // Parallel tag -> captured SyntaxNode map. The tree-sitter query already
167
+ // hands us each matched node as `c.node`, so anchors resolve via a
168
+ // type-guarded lookup (`nodeIfType`) instead of re-deriving them with
169
+ // `findNodeAtRange(tree.rootNode, ...)` per match — the
170
+ // O(matches × rootChildren) root-walk fixed for go #1848 / python #1918 /
171
+ // rust/csharp #1915 / java, mirrored here for C++ (#1951). Each C++
172
+ // scope-query anchor used below captures directly ON the node the old
173
+ // root-walk re-derived (verified against CPP_SCOPE_QUERY in query.ts and a
174
+ // real-parse AST probe), so the type check is exact.
175
+ const nodeMap = {};
176
+ for (const c of m.captures) {
177
+ const tag = '@' + c.name;
178
+ if (tag.startsWith('@_'))
179
+ continue;
180
+ grouped[tag] = (0, ast_helpers_js_1.nodeToCapture)(tag, c.node);
181
+ nodeMap[tag] = c.node;
182
+ }
183
+ if (Object.keys(grouped).length === 0)
184
+ continue;
185
+ // ── Handle #include statements ──────────────────────────────────
186
+ // `@import.statement` is captured directly on the `preproc_include` node.
187
+ if (grouped['@import.statement'] !== undefined) {
188
+ const includeNode = (0, ast_helpers_js_1.nodeIfType)(nodeMap['@import.statement'], 'preproc_include');
189
+ if (includeNode !== null) {
190
+ const split = (0, import_decomposer_js_1.splitCppInclude)(includeNode);
191
+ if (split !== null) {
192
+ out.push(split);
193
+ continue;
194
+ }
195
+ }
196
+ }
197
+ // ── Handle using declarations (using namespace / using name) ────
198
+ // `@import.using-decl` is captured directly on the `using_declaration` node.
199
+ if (grouped['@import.using-decl'] !== undefined) {
200
+ const usingNode = (0, ast_helpers_js_1.nodeIfType)(nodeMap['@import.using-decl'], 'using_declaration');
201
+ if (usingNode !== null) {
202
+ const split = (0, import_decomposer_js_1.splitCppUsingDecl)(usingNode);
203
+ if (split !== null) {
204
+ out.push(split);
205
+ continue;
206
+ }
207
+ }
208
+ }
209
+ // ── Track concrete typedef ranges ───────────────────────────────
210
+ const concreteTypeAnchor = grouped['@declaration.struct'] ??
211
+ grouped['@declaration.class'] ??
212
+ grouped['@declaration.enum'];
213
+ if (concreteTypeAnchor !== undefined) {
214
+ const r = concreteTypeAnchor.range;
215
+ concreteTypedefRanges.add(`${r.startLine}:${r.startCol}:${r.endLine}:${r.endCol}`);
216
+ }
217
+ // Suppress @declaration.typedef if the same range was already captured
218
+ const typedefAnchor = grouped['@declaration.typedef'];
219
+ if (typedefAnchor !== undefined) {
220
+ const r = typedefAnchor.range;
221
+ const key = `${r.startLine}:${r.startCol}:${r.endLine}:${r.endCol}`;
222
+ if (concreteTypedefRanges.has(key))
223
+ continue;
224
+ }
225
+ // ── Enrich function/method declarations with arity metadata ─────
226
+ // `@declaration.function` / `@declaration.method` capture directly on the
227
+ // `function_definition` (definitions/templates), `declaration` (free/
228
+ // constructor prototypes), or `field_declaration` (class-body method
229
+ // prototypes) node — the node the old findNodeAtRange re-derived.
230
+ const declAnchorNode = nodeMap['@declaration.function'] ?? nodeMap['@declaration.method'];
231
+ if (declAnchorNode !== undefined) {
232
+ const fnNode = (0, ast_helpers_js_1.nodeIfType)(declAnchorNode, 'function_definition', 'declaration', 'field_declaration');
233
+ if (fnNode !== null) {
234
+ const arity = (0, arity_metadata_js_1.computeCppDeclarationArity)(fnNode);
235
+ if (arity.parameterCount !== undefined) {
236
+ grouped['@declaration.parameter-count'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-count', fnNode, String(arity.parameterCount));
237
+ }
238
+ if (arity.requiredParameterCount !== undefined) {
239
+ grouped['@declaration.required-parameter-count'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.required-parameter-count', fnNode, String(arity.requiredParameterCount));
240
+ }
241
+ if (arity.parameterTypes !== undefined) {
242
+ grouped['@declaration.parameter-types'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-types', fnNode, JSON.stringify(arity.parameterTypes));
243
+ }
244
+ if (arity.parameterTypeClasses !== undefined) {
245
+ grouped['@declaration.parameter-type-classes'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-type-classes', fnNode, JSON.stringify(arity.parameterTypeClasses));
246
+ }
247
+ const returnType = extractCppDeclarationReturnType(fnNode);
248
+ if (returnType !== undefined) {
249
+ grouped['@declaration.return-type'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.return-type', fnNode, returnType);
250
+ }
251
+ if (hasExplicitSpecifier(fnNode)) {
252
+ grouped['@declaration.is-explicit'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.is-explicit', fnNode, 'true');
253
+ }
254
+ if (hasDeletedMethodClause(fnNode, grouped['@declaration.name']?.text)) {
255
+ grouped['@declaration.is-deleted'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.is-deleted', fnNode, 'true');
256
+ }
257
+ // Detect static storage class (file-local linkage)
258
+ if (hasStaticStorageClass(fnNode)) {
259
+ const nameText = grouped['@declaration.name']?.text;
260
+ if (nameText !== undefined) {
261
+ (0, file_local_linkage_js_1.markFileLocal)(filePath, nameText);
262
+ }
263
+ }
264
+ // Detect anonymous namespace (file-local linkage)
265
+ if (isInsideAnonymousNamespace(fnNode)) {
266
+ const nameText = grouped['@declaration.name']?.text;
267
+ if (nameText !== undefined) {
268
+ (0, file_local_linkage_js_1.markFileLocal)(filePath, nameText);
269
+ }
270
+ }
271
+ // SFINAE / `requires`-clause aware constraints for overload
272
+ // narrowing (issue #1579). Walk from the enclosing
273
+ // `template_declaration` — not the inner `function_definition` —
274
+ // so inline method templates (`template<...> class C { template<...> void f(); }`)
275
+ // pick up the correct outer constraint scope.
276
+ const templateDecl = findEnclosingTemplateDeclaration(fnNode);
277
+ if (templateDecl !== null) {
278
+ const funcDeclarator = findFunctionDeclarator(fnNode);
279
+ const constraints = (0, constraint_extractor_js_1.extractCppTemplateConstraints)(templateDecl, funcDeclarator);
280
+ if (constraints !== undefined) {
281
+ grouped['@declaration.template-constraints'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.template-constraints', fnNode, JSON.stringify(constraints));
282
+ }
283
+ }
284
+ }
285
+ }
286
+ // ── Detect static variables (file-local linkage) ────────────────
287
+ // `@declaration.variable` is captured directly on the `declaration` node.
288
+ if (grouped['@declaration.variable'] !== undefined) {
289
+ const varNode = (0, ast_helpers_js_1.nodeIfType)(nodeMap['@declaration.variable'], 'declaration');
290
+ if (varNode !== null) {
291
+ if (hasStaticStorageClass(varNode) || isInsideAnonymousNamespace(varNode)) {
292
+ const nameText = grouped['@declaration.name']?.text;
293
+ if (nameText !== undefined) {
294
+ (0, file_local_linkage_js_1.markFileLocal)(filePath, nameText);
295
+ }
296
+ }
297
+ }
298
+ }
299
+ // ── Enrich call references with arity ───────────────────────────
300
+ // `@reference.call.free` / `.member` capture on the `call_expression` (plain
301
+ // / member / template calls) or on the `binary_expression` (the operator-call
302
+ // patterns: `a + b`, `lhs << rhs`); `@reference.call.qualified` always on the
303
+ // `call_expression`. The captured node IS the node the old findNodeAtRange
304
+ // re-derived (verified against CPP_SCOPE_QUERY + a real-parse probe).
305
+ const callAnchor = grouped['@reference.call.free'] ??
306
+ grouped['@reference.call.member'] ??
307
+ grouped['@reference.call.qualified'];
308
+ const callAnchorNode = nodeMap['@reference.call.free'] ??
309
+ nodeMap['@reference.call.member'] ??
310
+ nodeMap['@reference.call.qualified'];
311
+ const operatorAnchor = grouped['@reference.operator'];
312
+ if (operatorAnchor !== undefined) {
313
+ // When `@reference.operator` fires, the co-captured call anchor is the
314
+ // enclosing `binary_expression` itself, so a type guard reproduces the
315
+ // old findNodeAtRange(callAnchor.range, 'binary_expression').
316
+ const operatorNode = callAnchorNode !== undefined ? (0, ast_helpers_js_1.nodeIfType)(callAnchorNode, 'binary_expression') : null;
317
+ if (operatorNode !== null && isPrimitiveOnlyBinaryOperator(operatorNode))
318
+ continue;
319
+ }
320
+ if (callAnchorNode !== undefined && grouped['@reference.arity'] === undefined) {
321
+ const callNode = (0, ast_helpers_js_1.nodeIfType)(callAnchorNode, 'call_expression', 'binary_expression');
322
+ if (callNode?.type === 'call_expression') {
323
+ grouped['@reference.arity'] = (0, ast_helpers_js_1.syntheticCapture)('@reference.arity', callNode, String((0, arity_metadata_js_1.computeCppCallArity)(callNode)));
324
+ }
325
+ else if (callNode?.type === 'binary_expression') {
326
+ grouped['@reference.arity'] = (0, ast_helpers_js_1.syntheticCapture)('@reference.arity', callNode, grouped['@reference.call.member'] !== undefined ? '1' : '2');
327
+ }
328
+ }
329
+ if (operatorAnchor !== undefined && grouped['@reference.name'] === undefined) {
330
+ // The old code did `findNodeAtRange(tree.rootNode, operatorAnchor.range,
331
+ // operatorAnchor.text)`, searching for a node of type `+` / `<<` at the
332
+ // operator-token range. That token is an UNNAMED grammar node, and
333
+ // findNodeAtRange only descends `namedChild`ren, so the search NEVER hit
334
+ // and ALWAYS fell back to `tree.rootNode`. Use `tree.rootNode` directly to
335
+ // preserve the exact synthetic-capture range while dropping the root-walk.
336
+ grouped['@reference.name'] = (0, ast_helpers_js_1.syntheticCapture)('@reference.name', tree.rootNode, `operator${operatorAnchor.text}`);
337
+ }
338
+ // ── Enrich constructor calls (new Foo()) with arity ─────────────
339
+ // `@reference.call.constructor` is captured directly on the `new_expression`.
340
+ const ctorCallAnchor = grouped['@reference.call.constructor'];
341
+ const ctorCallAnchorNode = nodeMap['@reference.call.constructor'];
342
+ if (ctorCallAnchor !== undefined && grouped['@reference.arity'] === undefined) {
343
+ const newNode = (0, ast_helpers_js_1.nodeIfType)(ctorCallAnchorNode, 'new_expression');
344
+ if (newNode !== null) {
345
+ grouped['@reference.arity'] = (0, ast_helpers_js_1.syntheticCapture)('@reference.arity', newNode, String((0, arity_metadata_js_1.computeCppCallArity)(newNode)));
346
+ }
347
+ }
348
+ // ── Synthesize argument types for overload narrowing ────────────
349
+ // The any-call anchor is either the call/operator anchor (`call_expression`
350
+ // / `binary_expression`) or the constructor anchor (`new_expression`); the
351
+ // captured node IS what the old findNodeAtRange re-derived.
352
+ const anyCallAnchor = callAnchor ?? ctorCallAnchor;
353
+ const anyCallAnchorNode = callAnchorNode ?? ctorCallAnchorNode;
354
+ if (anyCallAnchor !== undefined && grouped['@reference.parameter-types'] === undefined) {
355
+ const cNode = (0, ast_helpers_js_1.nodeIfType)(anyCallAnchorNode, 'call_expression', 'new_expression', 'binary_expression');
356
+ if (cNode !== null) {
357
+ const argTypes = cNode.type === 'binary_expression'
358
+ ? inferCppBinaryOperatorArgTypes(cNode, grouped['@reference.call.free'] !== undefined)
359
+ : inferCppCallArgTypes(cNode);
360
+ if (argTypes !== undefined && argTypes.length > 0) {
361
+ grouped['@reference.parameter-types'] = (0, ast_helpers_js_1.syntheticCapture)('@reference.parameter-types', cNode, JSON.stringify(argTypes));
362
+ }
363
+ const argTypeClasses = cNode.type === 'binary_expression'
364
+ ? inferCppBinaryOperatorArgTypeClasses(cNode, grouped['@reference.call.free'] !== undefined)
365
+ : inferCppCallArgTypeClasses(cNode);
366
+ if (argTypeClasses !== undefined && argTypeClasses.length > 0) {
367
+ grouped['@reference.parameter-type-classes'] = (0, ast_helpers_js_1.syntheticCapture)('@reference.parameter-type-classes', cNode, JSON.stringify(argTypeClasses));
368
+ }
369
+ }
370
+ }
371
+ // ── Inline namespace detection ──────────────────────────────────
372
+ // `inline namespace v1 { ... }` — tree-sitter-cpp exposes the
373
+ // `inline` keyword as a child of `namespace_definition`. Record the
374
+ // namespace's source range so `populateCppInlineNamespaceScopes`
375
+ // (during populateOwners) can match it back to the corresponding
376
+ // Namespace scope.
377
+ // `@declaration.namespace` fires only for NAMED namespaces (the query
378
+ // requires a `name: (namespace_identifier)` child). Use the unconditional
379
+ // `@scope.namespace` capture so the anonymous-namespace branch also runs.
380
+ // `@declaration.namespace` and `@scope.namespace` both capture directly on
381
+ // the `namespace_definition` node.
382
+ const namespaceScopeAnchorNode = nodeMap['@declaration.namespace'] ?? nodeMap['@scope.namespace'];
383
+ if (namespaceScopeAnchorNode !== undefined) {
384
+ const nsNode = (0, ast_helpers_js_1.nodeIfType)(namespaceScopeAnchorNode, 'namespace_definition');
385
+ if (nsNode !== null) {
386
+ // Range coords stored in the shared Range shape use 1-based
387
+ // line numbers (see `ast-helpers.ts` rangeForNode where
388
+ // `startPosition.row + 1` is applied). Match that convention so
389
+ // the populators can join against `Scope.range`.
390
+ const nsRange = {
391
+ startLine: nsNode.startPosition.row + 1,
392
+ startCol: nsNode.startPosition.column,
393
+ endLine: nsNode.endPosition.row + 1,
394
+ endCol: nsNode.endPosition.column,
395
+ };
396
+ if (isInlineNamespace(nsNode)) {
397
+ (0, inline_namespaces_js_1.markCppInlineNamespaceRange)(filePath, nsRange);
398
+ }
399
+ // Anonymous namespace: `namespace_definition` with no `name` field.
400
+ // Recorded so `expandCppWildcardNames` can propagate its members
401
+ // to including TUs even though their names are also `markFileLocal`'d
402
+ // (which blocks the global free-call fallback's cross-file path).
403
+ if ((nsNode.childForFieldName?.('name') ?? null) === null) {
404
+ (0, file_local_linkage_js_1.markCppAnonymousNamespaceRange)(filePath, nsRange);
405
+ }
406
+ }
407
+ }
408
+ // ── ADL (Koenig lookup) per-site recording ──────────────────────
409
+ // Only free-call sites (no explicit receiver) participate in ADL —
410
+ // qualified `Ns::f(s)` and member `obj.f(s)` calls bypass the
411
+ // free-call fallback entirely (handled by receiver-bound-calls).
412
+ if (grouped['@reference.call.free'] !== undefined) {
413
+ // `@reference.call.free` captures on a `call_expression` (plain/template
414
+ // free call) or a `binary_expression` (the `lhs << rhs` operator-call
415
+ // pattern). The old findNodeAtRange filtered to `call_expression`, so the
416
+ // `binary_expression` case yields null here — `nodeIfType` matches exactly.
417
+ const freeCallNode = (0, ast_helpers_js_1.nodeIfType)(nodeMap['@reference.call.free'], 'call_expression');
418
+ if (freeCallNode !== null) {
419
+ const adlAnchorRange = grouped['@reference.call.free'].range;
420
+ if (isParenthesizedFunctionCall(freeCallNode)) {
421
+ (0, adl_js_1.markCppAdlSiteNoAdl)(filePath, adlAnchorRange.startLine, adlAnchorRange.startCol);
422
+ }
423
+ const adlArgs = inferCppCallAdlArgs(freeCallNode);
424
+ if (adlArgs.length > 0) {
425
+ (0, adl_js_1.markCppAdlSiteArgs)(filePath, adlAnchorRange.startLine, adlAnchorRange.startCol, adlArgs);
426
+ }
427
+ }
428
+ }
429
+ // ── Post-process @type-binding.assignment for auto declarations ──
430
+ // The wildcard `type: (_)` in the @type-binding.assignment query
431
+ // pattern matches before the more specific @type-binding.alias and
432
+ // @type-binding.member-access patterns. When the type is `auto`
433
+ // (placeholder_type_specifier), we re-inspect the AST to synthesize
434
+ // the correct capture tags so interpret.ts can produce the right
435
+ // rawTypeName for compound-receiver chain resolution.
436
+ if (grouped['@type-binding.assignment'] !== undefined &&
437
+ grouped['@type-binding.type']?.text === 'auto') {
438
+ const anchor = grouped['@type-binding.assignment'];
439
+ // `@type-binding.assignment` is captured directly on the `declaration` node.
440
+ const declNode = (0, ast_helpers_js_1.nodeIfType)(nodeMap['@type-binding.assignment'], 'declaration');
441
+ if (declNode !== null) {
442
+ const declarator = declNode.childForFieldName('declarator');
443
+ if (declarator?.type === 'init_declarator') {
444
+ const valueNode = declarator.childForFieldName('value');
445
+ if (valueNode !== null) {
446
+ if (valueNode.type === 'identifier') {
447
+ // auto alias = existingVar → promote to @type-binding.alias
448
+ grouped['@type-binding.alias'] = anchor;
449
+ grouped['@type-binding.type'] = (0, ast_helpers_js_1.nodeToCapture)('@type-binding.type', valueNode);
450
+ delete grouped['@type-binding.assignment'];
451
+ }
452
+ else if (valueNode.type === 'field_expression') {
453
+ // auto addr = user.address → promote to @type-binding.member-access
454
+ const argNode = valueNode.childForFieldName('argument');
455
+ const fieldNode = valueNode.childForFieldName('field');
456
+ if (argNode !== null && fieldNode !== null) {
457
+ grouped['@type-binding.member-access'] = anchor;
458
+ grouped['@type-binding.member-access-receiver'] = (0, ast_helpers_js_1.nodeToCapture)('@type-binding.member-access-receiver', argNode);
459
+ grouped['@type-binding.type'] = (0, ast_helpers_js_1.nodeToCapture)('@type-binding.type', fieldNode);
460
+ delete grouped['@type-binding.assignment'];
461
+ }
462
+ }
463
+ else if (valueNode.type === 'call_expression') {
464
+ const fnNode = valueNode.childForFieldName('function');
465
+ if (fnNode?.type === 'field_expression') {
466
+ // auto city = addr.getCity() → promote to @type-binding.alias
467
+ // with dotted rawName "addr.getCity" for compound-receiver
468
+ const argNode = fnNode.childForFieldName('argument');
469
+ const fieldNode = fnNode.childForFieldName('field');
470
+ if (argNode !== null && fieldNode !== null) {
471
+ grouped['@type-binding.member-access'] = anchor;
472
+ grouped['@type-binding.member-access-receiver'] = (0, ast_helpers_js_1.nodeToCapture)('@type-binding.member-access-receiver', argNode);
473
+ grouped['@type-binding.type'] = (0, ast_helpers_js_1.nodeToCapture)('@type-binding.type', fieldNode);
474
+ delete grouped['@type-binding.assignment'];
475
+ }
476
+ }
477
+ }
478
+ }
479
+ }
480
+ }
481
+ }
482
+ // Structural receiver chain for a call whose receiver is itself an
483
+ // expression, so resolution can type it by folding over structure
484
+ // instead of re-parsing the receiver's source text. Self-gating: a
485
+ // non-call match, an absent receiver, or a chain with no nameable base
486
+ // all leave `grouped` untouched.
487
+ (0, receiver_chain_captures_js_1.synthesizeReceiverChainCapture)(grouped, nodeMap['@reference.receiver']);
488
+ out.push(grouped);
489
+ }
490
+ // ── Emit inheritance references for scope-resolution MRO / EXTENDS ──
491
+ // Walk every class/struct base list and synthesize `@reference.inherits`
492
+ // captures consumed by the registry-primary graph bridge. The lookup name
493
+ // is normalized to the bare class name so `Base<T>` / `outer::v1::Base<T>`
494
+ // resolve through V1's simple-name `findClassBindingInScope('Base')`.
495
+ emitCppInheritanceCaptures(tree.rootNode, out, filePath);
496
+ // ── Detect dependent-base relationships for two-phase template lookup ──
497
+ // Walk the tree once, finding every `template_declaration` whose
498
+ // child is a class/struct definition with a `base_class_clause` whose
499
+ // base names reference an in-scope template parameter. Record the
500
+ // (className, dependentBaseName) pair so `populateCppDependentBases`
501
+ // (called from the `populateOwners` hook) can resolve names to nodeIds
502
+ // and the resolver can suppress unqualified-call binding to those
503
+ // bases per ISO C++ two-phase lookup.
504
+ detectCppDependentBases(tree.rootNode, filePath);
505
+ (0, member_lookup_js_1.captureCppMemberLookupFacts)(tree.rootNode, filePath);
506
+ out.push(...(0, callable_flow_captures_js_1.synthesizeCallableFlowCaptures)(tree.rootNode, CPP_CALLABLE_CAPTURE_OPTIONS));
507
+ return out;
508
+ }
509
+ function cppFunctionDeclaratorSignature(node) {
510
+ const declarator = cppFindDescendantOfType(node, 'function_declarator');
511
+ const parameters = declarator?.childForFieldName('parameters');
512
+ if (parameters === null || parameters === undefined) {
513
+ return recoverCppMemberPointerSignature(node.text);
514
+ }
515
+ const parameterNodes = parameters.namedChildren.filter((child) => child !== null && child.type.includes('parameter_declaration'));
516
+ const hasEllipsis = parameters.children.some((child) => child.type === '...' || (!child.isNamed && child.text === '...')) || parameterNodes.some((parameter) => parameter.type === 'variadic_parameter_declaration');
517
+ const isVoidOnly = parameterNodes.length === 1 &&
518
+ parameterNodes[0].namedChildCount === 1 &&
519
+ parameterNodes[0].firstNamedChild?.text === 'void';
520
+ if (isVoidOnly) {
521
+ return { parameterCount: 0, parameterTypes: [], parameterTypeClasses: [] };
522
+ }
523
+ const parameterTypes = [];
524
+ const parameterTypeClasses = [];
525
+ for (const parameter of parameterNodes) {
526
+ if (parameter.type === 'variadic_parameter_declaration') {
527
+ parameterTypes.push('...');
528
+ parameterTypeClasses.push({
529
+ base: '...',
530
+ cv: 'unknown',
531
+ indirection: 'unknown',
532
+ pointerDepth: 0,
533
+ });
534
+ continue;
535
+ }
536
+ const rawType = parameter.childForFieldName('type')?.text ?? 'unknown';
537
+ const declaratorText = parameter.childForFieldName('declarator')?.text;
538
+ parameterTypes.push((0, arity_metadata_js_1.normalizeCppParamType)(rawType));
539
+ parameterTypeClasses.push((0, arity_metadata_js_1.classifyCppParameterType)(rawType, declaratorText, parameter.text));
540
+ }
541
+ if (hasEllipsis && !parameterTypes.includes('...')) {
542
+ parameterTypes.push('...');
543
+ parameterTypeClasses.push({
544
+ base: '...',
545
+ cv: 'unknown',
546
+ indirection: 'unknown',
547
+ pointerDepth: 0,
548
+ });
549
+ }
550
+ return {
551
+ ...(hasEllipsis ? {} : { parameterCount: parameterNodes.length }),
552
+ parameterTypes,
553
+ parameterTypeClasses,
554
+ isConst: /\)\s*const(?:\s|$)/.test(declarator.text),
555
+ };
556
+ }
557
+ /**
558
+ * tree-sitter-cpp parses a non-const pointer-to-member variable such as
559
+ * `void (Base::*member)()` as nested call expressions (while the cv-qualified
560
+ * twin is a declaration). Recover the callable shape from the declarator text
561
+ * so `const`/non-`const` overload sets remain distinguishable.
562
+ */
563
+ function recoverCppMemberPointerSignature(text) {
564
+ const match = text.match(/\(\s*[^()]*::\s*\*\s*[A-Za-z_]\w*\s*\)\s*\(([^()]*)\)\s*(const\b)?/);
565
+ if (match === null)
566
+ return undefined;
567
+ const rawParameters = match[1].trim();
568
+ const parameterCount = rawParameters === '' || rawParameters === 'void'
569
+ ? 0
570
+ : splitTopLevelCppParameters(rawParameters).length;
571
+ return { parameterCount, isConst: match[2] !== undefined };
572
+ }
573
+ function splitTopLevelCppParameters(text) {
574
+ const out = [];
575
+ let start = 0;
576
+ let angleDepth = 0;
577
+ let parenDepth = 0;
578
+ let bracketDepth = 0;
579
+ for (let index = 0; index < text.length; index++) {
580
+ switch (text[index]) {
581
+ case '<':
582
+ angleDepth++;
583
+ break;
584
+ case '>':
585
+ angleDepth = Math.max(0, angleDepth - 1);
586
+ break;
587
+ case '(':
588
+ parenDepth++;
589
+ break;
590
+ case ')':
591
+ parenDepth = Math.max(0, parenDepth - 1);
592
+ break;
593
+ case '[':
594
+ bracketDepth++;
595
+ break;
596
+ case ']':
597
+ bracketDepth = Math.max(0, bracketDepth - 1);
598
+ break;
599
+ case ',':
600
+ if (angleDepth === 0 && parenDepth === 0 && bracketDepth === 0) {
601
+ out.push(text.slice(start, index).trim());
602
+ start = index + 1;
603
+ }
604
+ break;
605
+ }
606
+ }
607
+ out.push(text.slice(start).trim());
608
+ return out.filter((parameter) => parameter.length > 0);
609
+ }
610
+ function cppContainsNodeType(root, type) {
611
+ return cppFindDescendantOfType(root, type) !== null;
612
+ }
613
+ function cppFindDescendantOfType(root, type) {
614
+ const stack = [root];
615
+ while (stack.length > 0) {
616
+ const node = stack.pop();
617
+ if (node.type === type)
618
+ return node;
619
+ for (const child of node.namedChildren)
620
+ if (child !== null)
621
+ stack.push(child);
622
+ }
623
+ return null;
624
+ }
625
+ function extractCppDeclarationReturnType(fnNode) {
626
+ const typeNode = fnNode.childForFieldName('type');
627
+ if (typeNode === null)
628
+ return undefined;
629
+ const funcDeclarator = findFunctionDeclarator(fnNode);
630
+ if (funcDeclarator !== null && isCppUnsupportedReturnTypeDeclarator(funcDeclarator)) {
631
+ return undefined;
632
+ }
633
+ const typeText = typeNode.text.trim();
634
+ if (typeText !== 'auto')
635
+ return typeText.length > 0 ? typeText : undefined;
636
+ if (funcDeclarator === null)
637
+ return typeText;
638
+ for (let i = 0; i < funcDeclarator.namedChildCount; i++) {
639
+ const child = funcDeclarator.namedChild(i);
640
+ if (child?.type !== 'trailing_return_type')
641
+ continue;
642
+ const typeDesc = child.firstNamedChild;
643
+ return typeDesc?.text.trim() || typeText;
644
+ }
645
+ return typeText;
646
+ }
647
+ function isCppUnsupportedReturnTypeDeclarator(funcDeclarator) {
648
+ const text = funcDeclarator.text;
649
+ return /\boperator\b/.test(text) || /(^|[(:\s])~\s*[A-Za-z_]\w*/.test(text);
650
+ }
651
+ /**
652
+ * Walk every C++ class/struct base clause and emit `@reference.inherits`
653
+ * captures for each base so scope resolution can resolve them into EXTENDS
654
+ * edges. Lookup names are normalized to bare class names (`Base<T>` → `Base`,
655
+ * `outer::v1::Base<T>` → `Base`) to match the V1 simple-name
656
+ * `findClassBindingInScope` contract. This intentionally preserves the
657
+ * existing scope-chain tradeoff: qualified namespace context is discarded
658
+ * here instead of introducing a C++-only name-resolution lane in shared
659
+ * ingestion infrastructure.
660
+ */
661
+ function emitCppInheritanceCaptures(root, out, filePath) {
662
+ const stack = [root];
663
+ while (stack.length > 0) {
664
+ const node = stack.pop();
665
+ if (node.type === 'class_specifier' || node.type === 'struct_specifier') {
666
+ const baseClause = findChildOfType(node, ['base_class_clause']);
667
+ if (baseClause !== null) {
668
+ for (const base of iterBaseClasses(baseClause)) {
669
+ if (base.isPackExpansion) {
670
+ markClassWithPackExpandedBase(filePath, node);
671
+ continue;
672
+ }
673
+ const baseName = extractBaseLookupName(base.node);
674
+ if (baseName.length === 0)
675
+ continue;
676
+ // Preserve the qualified form (`Other::Inner`, template-stripped) when the
677
+ // source wrote one, so a same-tail nested base resolves to the matching
678
+ // qualified node instead of the first-inserted same-tail one (#1982). The
679
+ // bare `@reference.name` stays the V1 simple-name contract; the qualifier
680
+ // is an additive sidecar resolution tries first (see resolveInheritanceBaseInScope).
681
+ const qualifiedBaseName = extractQualifiedBaseName(base.node);
682
+ out.push({
683
+ '@reference.inherits': (0, ast_helpers_js_1.nodeToCapture)('@reference.inherits', base.node),
684
+ '@reference.name': (0, ast_helpers_js_1.syntheticCapture)('@reference.name', base.node, baseName),
685
+ ...(qualifiedBaseName.length > 0 && qualifiedBaseName !== baseName
686
+ ? {
687
+ '@reference.qualified-name': (0, ast_helpers_js_1.syntheticCapture)('@reference.qualified-name', base.node, qualifiedBaseName),
688
+ }
689
+ : {}),
690
+ });
691
+ }
692
+ }
693
+ }
694
+ for (let i = 0; i < node.childCount; i++) {
695
+ const child = node.child(i);
696
+ if (child !== null)
697
+ stack.push(child);
698
+ }
699
+ }
700
+ }
701
+ /**
702
+ * Walk the AST finding every template_declaration containing a class or
703
+ * struct definition with a dependent base. Records (className, baseName)
704
+ * pairs into the module-level state via `markCppDependentBase`.
705
+ *
706
+ * A base is "dependent" when its name (typically a template_type like
707
+ * `Base<T>`) uses a template parameter of the enclosing template_declaration.
708
+ * Conservative bias: `typename T::U`, `decltype(...)` and template-template
709
+ * parameter shapes are also treated as dependent.
710
+ */
711
+ function detectCppDependentBases(root, filePath) {
712
+ const stack = [root];
713
+ while (stack.length > 0) {
714
+ const node = stack.pop();
715
+ if (node.type === 'template_declaration') {
716
+ // Collect template-parameter names declared by this declaration.
717
+ // Inner template_declarations shadow outer ones — handled by the
718
+ // recursive descent below (each template_declaration creates its
719
+ // own parameter scope).
720
+ const params = collectTemplateParameterNames(node);
721
+ // Find the class/struct definition inside this template_declaration.
722
+ const classNode = findChildOfType(node, ['class_specifier', 'struct_specifier']);
723
+ if (classNode !== null) {
724
+ const className = getTypeIdentifierName(classNode);
725
+ if (className !== '') {
726
+ const baseClause = findChildOfType(classNode, ['base_class_clause']);
727
+ if (baseClause !== null) {
728
+ for (const base of iterBaseClasses(baseClause)) {
729
+ if (base.isPackExpansion || isBaseDependent(base.node, params)) {
730
+ if (base.isPackExpansion) {
731
+ markClassWithPackExpandedBase(filePath, classNode);
732
+ }
733
+ const baseName = extractBaseLookupName(base.node);
734
+ const baseQualifier = extractBaseLookupQualifier(base.node);
735
+ if (baseName !== '') {
736
+ (0, two_phase_lookup_js_1.markCppDependentBase)(filePath, className, baseName, baseQualifier);
737
+ }
738
+ }
739
+ }
740
+ }
741
+ }
742
+ }
743
+ }
744
+ for (let i = 0; i < node.childCount; i++) {
745
+ const child = node.child(i);
746
+ if (child !== null)
747
+ stack.push(child);
748
+ }
749
+ }
750
+ }
751
+ /** Collect simple template parameter names from a template_declaration. */
752
+ function collectTemplateParameterNames(templateDecl) {
753
+ const names = new Set();
754
+ const paramList = findChildOfType(templateDecl, ['template_parameter_list']);
755
+ if (paramList === null)
756
+ return names;
757
+ for (let i = 0; i < paramList.childCount; i++) {
758
+ const param = paramList.child(i);
759
+ if (param === null)
760
+ continue;
761
+ if (param.type === 'type_parameter_declaration' ||
762
+ param.type === 'optional_type_parameter_declaration' ||
763
+ param.type === 'variadic_type_parameter_declaration') {
764
+ const idNode = findFirstDescendantOfType(param, 'type_identifier');
765
+ if (idNode !== null)
766
+ names.add(idNode.text);
767
+ }
768
+ else if (param.type === 'parameter_declaration' ||
769
+ param.type === 'optional_parameter_declaration' ||
770
+ param.type === 'variadic_parameter_declaration') {
771
+ // Non-type template parameter (e.g. `template<int N>`).
772
+ const idNode = findFirstDescendantOfType(param, 'identifier');
773
+ if (idNode !== null)
774
+ names.add(idNode.text);
775
+ }
776
+ else if (param.type === 'template_template_parameter_declaration') {
777
+ // template-template parameter (e.g. `template<template<class> class TT>`)
778
+ const idNode = findFirstDescendantOfType(param, 'type_identifier');
779
+ if (idNode !== null)
780
+ names.add(idNode.text);
781
+ }
782
+ }
783
+ return names;
784
+ }
785
+ function markClassWithPackExpandedBase(filePath, classNode) {
786
+ const className = getTypeIdentifierName(classNode);
787
+ if (className !== '')
788
+ (0, two_phase_lookup_js_1.markCppDependentPackBase)(filePath, className);
789
+ }
790
+ /** Yield each base-class entry from a `base_class_clause`. */
791
+ function* iterBaseClasses(baseClause) {
792
+ for (let i = 0; i < baseClause.childCount; i++) {
793
+ const child = baseClause.child(i);
794
+ if (child === null)
795
+ continue;
796
+ // Skip ':', ',', and access_specifier nodes — the base names are
797
+ // type_identifier, template_type, or qualified_identifier.
798
+ if (child.type === 'type_identifier' ||
799
+ child.type === 'template_type' ||
800
+ child.type === 'qualified_identifier') {
801
+ yield { node: child, isPackExpansion: isFollowedByPackExpansion(baseClause, i) };
802
+ }
803
+ }
804
+ }
805
+ function isFollowedByPackExpansion(baseClause, childIndex) {
806
+ for (let i = childIndex + 1; i < baseClause.childCount; i++) {
807
+ const sibling = baseClause.child(i);
808
+ if (sibling === null)
809
+ continue;
810
+ if (sibling.type === '...' || (!sibling.isNamed && sibling.text === '...'))
811
+ return true;
812
+ if (sibling.type === ',' || sibling.type === 'access_specifier')
813
+ return false;
814
+ if (sibling.type === 'comment')
815
+ continue;
816
+ if (sibling.isNamed)
817
+ return false;
818
+ }
819
+ return false;
820
+ }
821
+ /**
822
+ * A base is dependent when:
823
+ * - it's a `template_type` and its argument list contains a
824
+ * `type_identifier` matching one of the enclosing template's params
825
+ * (e.g., `Base<T>` where `T` is a template parameter), OR
826
+ * - it contains a `typename`, `decltype`, or `template_template_parameter`
827
+ * shape (conservatively treated as dependent).
828
+ *
829
+ * Non-dependent: `Base<int>`, `ConcreteBase`, `Base<MyConcrete>` where
830
+ * `MyConcrete` is not a template parameter.
831
+ */
832
+ function isBaseDependent(baseNode, templateParams) {
833
+ if (baseNode.type !== 'template_type') {
834
+ if (baseNode.type === 'qualified_identifier') {
835
+ // Qualified identifier bases (e.g. `detail::Inner<T>`) may contain
836
+ // template_type children — descend into them for template param check.
837
+ // Fall through to the stack walk below.
838
+ }
839
+ else {
840
+ // Bare `type_identifier` bases — not dependent.
841
+ return false;
842
+ }
843
+ }
844
+ // Walk all descendants of the template_argument_list looking for any
845
+ // type_identifier matching a template parameter, or any conservative-
846
+ // dependent shape.
847
+ const stack = [baseNode];
848
+ while (stack.length > 0) {
849
+ const node = stack.pop();
850
+ if (node.type === 'type_identifier' && templateParams.has(node.text)) {
851
+ return true;
852
+ }
853
+ if (node.type === 'decltype' ||
854
+ node.type === 'dependent_type' ||
855
+ node.type === 'template_template_parameter_declaration') {
856
+ return true;
857
+ }
858
+ if (node.type === 'qualified_identifier') {
859
+ // `typename T::U` or `T::nested` — if any inner identifier matches
860
+ // a template parameter, dependent.
861
+ for (let i = 0; i < node.childCount; i++) {
862
+ const c = node.child(i);
863
+ if (c !== null)
864
+ stack.push(c);
865
+ }
866
+ continue;
867
+ }
868
+ for (let i = 0; i < node.childCount; i++) {
869
+ const c = node.child(i);
870
+ if (c !== null)
871
+ stack.push(c);
872
+ }
873
+ }
874
+ return false;
875
+ }
876
+ /**
877
+ * Recursively extract the bare lookup name of a base class node.
878
+ * Examples: `Base` → `Base`, `Base<T>` → `Base`,
879
+ * `outer::v1::Base<T>` → `Base`. Namespace qualifiers are intentionally
880
+ * dropped to align with V1 scope-chain lookup everywhere else in the
881
+ * registry-primary pipeline.
882
+ */
883
+ function extractBaseLookupName(baseNode) {
884
+ if (baseNode.type === 'type_identifier' || baseNode.type === 'identifier')
885
+ return baseNode.text;
886
+ if (baseNode.type === 'template_type') {
887
+ const nameNode = baseNode.childForFieldName('name');
888
+ if (nameNode !== null)
889
+ return extractBaseLookupName(nameNode);
890
+ const id = findFirstDescendantOfType(baseNode, 'type_identifier') ??
891
+ findFirstDescendantOfType(baseNode, 'identifier');
892
+ if (id !== null)
893
+ return id.text;
894
+ }
895
+ if (baseNode.type === 'qualified_identifier') {
896
+ const nameNode = baseNode.childForFieldName('name');
897
+ if (nameNode !== null) {
898
+ const nested = extractBaseLookupName(nameNode);
899
+ if (nested.length > 0)
900
+ return nested;
901
+ }
902
+ for (let i = baseNode.childCount - 1; i >= 0; i--) {
903
+ const child = baseNode.child(i);
904
+ if (child === null)
905
+ continue;
906
+ const nested = extractBaseLookupName(child);
907
+ if (nested.length > 0)
908
+ return nested;
909
+ }
910
+ }
911
+ return '';
912
+ }
913
+ /**
914
+ * Like `extractBaseLookupName` but PRESERVES the namespace/class qualifier
915
+ * (`Other::Inner`, `ns::v1::Base`) while stripping template arguments
916
+ * (`ns::Base<T>` → `ns::Base`). Returns `''` for shapes it can't qualify, and
917
+ * returns the bare name unchanged for an unqualified base (the emit site then
918
+ * skips the sidecar capture). Powers `@reference.qualified-name` so #1982
919
+ * resolution can pick the matching same-tail nested base via the full-path
920
+ * QualifiedNameIndex instead of the first-inserted same-tail sibling.
921
+ */
922
+ function extractQualifiedBaseName(baseNode) {
923
+ if (baseNode.type === 'template_type') {
924
+ const nameNode = baseNode.childForFieldName('name');
925
+ return nameNode !== null ? extractQualifiedBaseName(nameNode) : '';
926
+ }
927
+ if (baseNode.type === 'qualified_identifier') {
928
+ // No template args anywhere → the raw text already IS the qualified name.
929
+ if (!baseNode.text.includes('<'))
930
+ return baseNode.text;
931
+ // Template args present: reconstruct scope::name, recursing to strip them.
932
+ const scopeNode = baseNode.childForFieldName('scope');
933
+ const nameNode = baseNode.childForFieldName('name');
934
+ const left = scopeNode !== null ? extractQualifiedBaseName(scopeNode) : '';
935
+ const right = nameNode !== null ? extractQualifiedBaseName(nameNode) : '';
936
+ if (left.length > 0 && right.length > 0)
937
+ return `${left}::${right}`;
938
+ return right.length > 0 ? right : left;
939
+ }
940
+ if (baseNode.type === 'namespace_identifier' ||
941
+ baseNode.type === 'type_identifier' ||
942
+ baseNode.type === 'identifier') {
943
+ return baseNode.text;
944
+ }
945
+ return '';
946
+ }
947
+ /** Extract the syntactic namespace qualifier from a base class node.
948
+ * For `detail::Inner<T>`, returns `'detail'`.
949
+ * For unqualified bases (`Inner<T>`, `Base<int>`), returns `''`.
950
+ * Nested qualifiers (`a::b::Inner<T>`) return the full scope text.
951
+ */
952
+ function extractBaseLookupQualifier(baseNode) {
953
+ if (baseNode.type === 'qualified_identifier') {
954
+ const scopeNode = baseNode.childForFieldName('scope');
955
+ if (scopeNode !== null)
956
+ return scopeNode.text;
957
+ }
958
+ // template_type nodes may have a qualified_identifier as their name child
959
+ if (baseNode.type === 'template_type') {
960
+ const nameNode = baseNode.childForFieldName('name');
961
+ if (nameNode !== null && nameNode.type === 'qualified_identifier') {
962
+ const scopeNode = nameNode.childForFieldName('scope');
963
+ if (scopeNode !== null)
964
+ return scopeNode.text;
965
+ }
966
+ }
967
+ return '';
968
+ }
969
+ /**
970
+ * Walk parent chain from a function_definition / declaration / field_declaration
971
+ * to find the enclosing `template_declaration`. Returns null when the function
972
+ * isn't templated. The walk only ascends through wrapper nodes the C++
973
+ * grammar inserts between `template_declaration` and the function — direct
974
+ * parent in the common case, two hops for member templates whose outer
975
+ * class is also templated (we return the INNERMOST template_declaration,
976
+ * which carries this function's own template parameters).
977
+ */
978
+ function findEnclosingTemplateDeclaration(fnNode) {
979
+ let cur = fnNode.parent;
980
+ // Cap the walk — `template_declaration` is typically the immediate parent
981
+ // or one wrapper away. Anything deeper is an inline-method-in-template
982
+ // shape and we still want the innermost templates_declaration whose body
983
+ // wraps `fnNode`.
984
+ let hops = 8;
985
+ while (cur !== null && hops-- > 0) {
986
+ if (cur.type === 'template_declaration')
987
+ return cur;
988
+ // Don't ascend past structural boundaries that should reset template scope.
989
+ if (cur.type === 'translation_unit')
990
+ return null;
991
+ cur = cur.parent;
992
+ }
993
+ return null;
994
+ }
995
+ /**
996
+ * Locate the `function_declarator` AST node within a function definition
997
+ * or declaration. Unwraps pointer/reference declarator wrappers. Returns
998
+ * null when no function_declarator is found (e.g. variable declaration
999
+ * mis-classified upstream).
1000
+ */
1001
+ function findFunctionDeclarator(fnNode) {
1002
+ const direct = fnNode.childForFieldName('declarator');
1003
+ let cur = direct;
1004
+ let hops = 8;
1005
+ while (cur !== null && hops-- > 0) {
1006
+ if (cur.type === 'function_declarator')
1007
+ return cur;
1008
+ if (cur.type === 'pointer_declarator' || cur.type === 'reference_declarator') {
1009
+ cur = cur.childForFieldName('declarator');
1010
+ continue;
1011
+ }
1012
+ break;
1013
+ }
1014
+ return findFirstDescendantOfType(fnNode, 'function_declarator');
1015
+ }
1016
+ /** Find the first direct child matching one of the given types. */
1017
+ function findChildOfType(node, types) {
1018
+ for (let i = 0; i < node.childCount; i++) {
1019
+ const c = node.child(i);
1020
+ if (c !== null && types.includes(c.type))
1021
+ return c;
1022
+ }
1023
+ return null;
1024
+ }
1025
+ /** Recursive search for the first descendant of a given type. */
1026
+ function findFirstDescendantOfType(node, type) {
1027
+ if (node.type === type)
1028
+ return node;
1029
+ for (let i = 0; i < node.childCount; i++) {
1030
+ const c = node.child(i);
1031
+ if (c === null)
1032
+ continue;
1033
+ const hit = findFirstDescendantOfType(c, type);
1034
+ if (hit !== null)
1035
+ return hit;
1036
+ }
1037
+ return null;
1038
+ }
1039
+ /** Get the name of a class/struct/template_type node via its `name` field. */
1040
+ function getTypeIdentifierName(node) {
1041
+ const nameNode = node.childForFieldName('name');
1042
+ if (nameNode !== null)
1043
+ return nameNode.text;
1044
+ const id = findFirstDescendantOfType(node, 'type_identifier');
1045
+ return id !== null ? id.text : '';
1046
+ }
1047
+ /**
1048
+ * Infer argument types from a call_expression or new_expression node.
1049
+ * Used for overload disambiguation by parameter types.
1050
+ *
1051
+ * Only literal types are inferred — identifiers and complex expressions
1052
+ * return empty string (unknown) so narrowOverloadCandidates treats them
1053
+ * as any-match.
1054
+ */
1055
+ function inferCppCallArgTypes(node) {
1056
+ const argList = node.childForFieldName('arguments');
1057
+ if (argList === null)
1058
+ return undefined;
1059
+ const types = [];
1060
+ for (let i = 0; i < argList.childCount; i++) {
1061
+ const child = argList.child(i);
1062
+ if (child === null)
1063
+ continue;
1064
+ if (child.type === ',' || child.type === '(' || child.type === ')')
1065
+ continue;
1066
+ const litType = inferCppLiteralType(child);
1067
+ if (litType !== '') {
1068
+ types.push(litType);
1069
+ }
1070
+ else if (child.type === 'identifier') {
1071
+ // Variable reference — look up declared type in enclosing scope
1072
+ types.push(lookupDeclaredTypeForIdentifier(child));
1073
+ }
1074
+ else {
1075
+ types.push('');
1076
+ }
1077
+ }
1078
+ return types.length > 0 ? types : undefined;
1079
+ }
1080
+ function inferCppCallArgTypeClasses(node) {
1081
+ const argList = node.childForFieldName('arguments');
1082
+ if (argList === null)
1083
+ return undefined;
1084
+ const classes = [];
1085
+ for (let i = 0; i < argList.childCount; i++) {
1086
+ const child = argList.child(i);
1087
+ if (child === null)
1088
+ continue;
1089
+ if (child.type === ',' || child.type === '(' || child.type === ')')
1090
+ continue;
1091
+ const litType = inferCppLiteralType(child);
1092
+ if (litType !== '') {
1093
+ classes.push(valueTypeClass(litType));
1094
+ }
1095
+ else if (child.type === 'identifier') {
1096
+ classes.push(lookupDeclaredTypeClassForIdentifier(child));
1097
+ }
1098
+ else {
1099
+ classes.push(unknownTypeClass('unknown'));
1100
+ }
1101
+ }
1102
+ return classes.length > 0 ? classes : undefined;
1103
+ }
1104
+ function inferCppBinaryOperatorArgTypes(node, includeLeftOperand) {
1105
+ const operands = binaryOperatorOperands(node, includeLeftOperand);
1106
+ if (operands.length === 0)
1107
+ return undefined;
1108
+ const types = operands.map(inferCppExpressionType);
1109
+ return types.length > 0 ? types : undefined;
1110
+ }
1111
+ function inferCppBinaryOperatorArgTypeClasses(node, includeLeftOperand) {
1112
+ const operands = binaryOperatorOperands(node, includeLeftOperand);
1113
+ if (operands.length === 0)
1114
+ return undefined;
1115
+ const classes = operands.map(inferCppExpressionTypeClass);
1116
+ return classes.length > 0 ? classes : undefined;
1117
+ }
1118
+ function binaryOperatorOperands(node, includeLeftOperand) {
1119
+ const operands = [];
1120
+ const left = node.childForFieldName('left');
1121
+ const right = node.childForFieldName('right');
1122
+ if (includeLeftOperand && left !== null)
1123
+ operands.push(left);
1124
+ if (right !== null)
1125
+ operands.push(right);
1126
+ return operands;
1127
+ }
1128
+ function isPrimitiveOnlyBinaryOperator(node) {
1129
+ const operands = binaryOperatorOperands(node, true);
1130
+ return operands.length > 0 && operands.every((operand) => isBuiltinOperatorType(operand));
1131
+ }
1132
+ function isBuiltinOperatorType(node) {
1133
+ const type = inferCppExpressionType(node);
1134
+ return (type === 'bool' ||
1135
+ type === 'char' ||
1136
+ type === 'double' ||
1137
+ type === 'float' ||
1138
+ type === 'int' ||
1139
+ type === 'long' ||
1140
+ type === 'short' ||
1141
+ type === 'signed' ||
1142
+ type === 'unsigned');
1143
+ }
1144
+ function inferCppExpressionType(node) {
1145
+ const litType = inferCppLiteralType(node);
1146
+ if (litType !== '')
1147
+ return litType;
1148
+ if (node.type === 'identifier')
1149
+ return lookupDeclaredTypeForIdentifier(node);
1150
+ return '';
1151
+ }
1152
+ function inferCppExpressionTypeClass(node) {
1153
+ const litType = inferCppLiteralType(node);
1154
+ if (litType !== '')
1155
+ return valueTypeClass(litType);
1156
+ if (node.type === 'identifier')
1157
+ return lookupDeclaredTypeClassForIdentifier(node);
1158
+ return unknownTypeClass('unknown');
1159
+ }
1160
+ function valueTypeClass(base) {
1161
+ return { base, cv: 'none', indirection: 'value', pointerDepth: 0 };
1162
+ }
1163
+ function unknownTypeClass(base) {
1164
+ return { base, cv: 'unknown', indirection: 'unknown', pointerDepth: 0 };
1165
+ }
1166
+ /**
1167
+ * Infer the canonical type name of a C++ literal AST node.
1168
+ * Returns empty string for non-literal / unknown nodes.
1169
+ */
1170
+ function inferCppLiteralType(node) {
1171
+ switch (node.type) {
1172
+ case 'initializer_list':
1173
+ return inferCppBracedInitType(node);
1174
+ case 'number_literal': {
1175
+ const text = node.text;
1176
+ // Floating-point literals contain '.', 'e', 'E', or end with 'f'/'F'
1177
+ if (text.includes('.') ||
1178
+ text.includes('e') ||
1179
+ text.includes('E') ||
1180
+ text.endsWith('f') ||
1181
+ text.endsWith('F')) {
1182
+ return 'double';
1183
+ }
1184
+ return 'int';
1185
+ }
1186
+ case 'string_literal':
1187
+ case 'raw_string_literal':
1188
+ case 'concatenated_string':
1189
+ return 'string';
1190
+ case 'char_literal':
1191
+ return 'char';
1192
+ case 'true':
1193
+ case 'false':
1194
+ return 'bool';
1195
+ case 'null':
1196
+ case 'nullptr':
1197
+ return 'null';
1198
+ default:
1199
+ return '';
1200
+ }
1201
+ }
1202
+ function inferCppBracedInitType(node) {
1203
+ const elementTypes = [];
1204
+ for (let i = 0; i < node.childCount; i++) {
1205
+ const child = node.child(i);
1206
+ if (child === null)
1207
+ continue;
1208
+ if (child.type === ',' || child.type === '{' || child.type === '}')
1209
+ continue;
1210
+ const elementType = inferCppLiteralType(child);
1211
+ if (elementType === '' || elementType.startsWith(conversion_rank_js_1.CPP_BRACED_INIT_TYPE_PREFIX)) {
1212
+ return `${conversion_rank_js_1.CPP_BRACED_INIT_TYPE_PREFIX}unknown:${elementTypes.length + 1}`;
1213
+ }
1214
+ elementTypes.push(elementType);
1215
+ }
1216
+ if (elementTypes.length === 0)
1217
+ return `${conversion_rank_js_1.CPP_BRACED_INIT_TYPE_PREFIX}unknown:0`;
1218
+ const first = elementTypes[0];
1219
+ return elementTypes.every((type) => type === first)
1220
+ ? `${conversion_rank_js_1.CPP_BRACED_INIT_TYPE_PREFIX}${first}:${elementTypes.length}`
1221
+ : `${conversion_rank_js_1.CPP_BRACED_INIT_TYPE_PREFIX}unknown:${elementTypes.length}`;
1222
+ }
1223
+ let fileLookupIndex = {
1224
+ enumNames: null,
1225
+ scopeDecls: new Map(),
1226
+ fnParams: new Map(),
1227
+ };
1228
+ function resetCppFileLookupIndex() {
1229
+ fileLookupIndex = { enumNames: null, scopeDecls: new Map(), fnParams: new Map() };
1230
+ }
1231
+ /**
1232
+ * First-declaration-wins map of the scope's `declaration` children that
1233
+ * carry a concrete (non-placeholder) type and a nameable declarator —
1234
+ * exactly the entries the replaced per-identifier scans could match.
1235
+ */
1236
+ function scopeDeclarationsFor(scope) {
1237
+ const cached = fileLookupIndex.scopeDecls.get(scope.id);
1238
+ if (cached !== undefined)
1239
+ return cached;
1240
+ const decls = new Map();
1241
+ for (let i = 0; i < scope.childCount; i++) {
1242
+ const stmt = scope.child(i);
1243
+ if (stmt === null || stmt.type !== 'declaration')
1244
+ continue;
1245
+ const typeNode = stmt.childForFieldName('type');
1246
+ if (typeNode === null)
1247
+ continue;
1248
+ if (typeNode.type === 'placeholder_type_specifier')
1249
+ continue;
1250
+ const declarator = stmt.childForFieldName('declarator');
1251
+ if (declarator === null)
1252
+ continue;
1253
+ const nameChild = declaredNameNode(declarator);
1254
+ if (nameChild === null)
1255
+ continue;
1256
+ const name = extractDeclaratorLeafName(nameChild);
1257
+ if (name === '' || decls.has(name))
1258
+ continue;
1259
+ decls.set(name, stmt);
1260
+ }
1261
+ fileLookupIndex.scopeDecls.set(scope.id, decls);
1262
+ return decls;
1263
+ }
1264
+ /**
1265
+ * Look up the declared type of a variable by scanning sibling declarations
1266
+ * in the enclosing compound_statement (function body). Handles:
1267
+ * - `std::string result = ...` → 'string'
1268
+ * - `int n = ...` → 'int'
1269
+ * - `const int n = ...` → 'int'
1270
+ * Returns empty string if no declaration found or type is auto/placeholder.
1271
+ *
1272
+ * Limitation: only `declaration` siblings inside the enclosing
1273
+ * `compound_statement` are inspected. Function parameters live in the
1274
+ * `function_declarator`'s `parameter_list` and are NOT resolved here, so
1275
+ * `void run(int n) { process(n); }`
1276
+ * infers `''` for `n` and the constraint filter falls through to
1277
+ * `'unknown'` → ambiguity suppression → 0 CALLS edges. This is a
1278
+ * "degrade not lie" gap (no wrong edges, just missing ones); extending
1279
+ * the scan to `parameter_list` is tracked under #1579 as a follow-up.
1280
+ */
1281
+ function lookupDeclaredTypeForIdentifier(identNode) {
1282
+ const varName = identNode.text;
1283
+ // Walk up to the enclosing compound_statement (function body)
1284
+ let scope = identNode.parent;
1285
+ while (scope !== null &&
1286
+ scope.type !== 'compound_statement' &&
1287
+ scope.type !== 'translation_unit') {
1288
+ scope = scope.parent;
1289
+ }
1290
+ if (scope === null)
1291
+ return '';
1292
+ const paramType = lookupFunctionParameterType(scope, varName);
1293
+ if (paramType !== '')
1294
+ return paramType;
1295
+ // Indexed scope-declaration lookup (#2432; was a per-identifier scan).
1296
+ const stmt = scopeDeclarationsFor(scope).get(varName);
1297
+ if (stmt === undefined)
1298
+ return '';
1299
+ const typeNode = stmt.childForFieldName('type');
1300
+ if (typeNode === null)
1301
+ return '';
1302
+ return normalizeCppTypeText(typeNode.text);
1303
+ }
1304
+ function lookupDeclaredTypeClassForIdentifier(identNode) {
1305
+ const varName = identNode.text;
1306
+ let scope = identNode.parent;
1307
+ while (scope !== null &&
1308
+ scope.type !== 'compound_statement' &&
1309
+ scope.type !== 'translation_unit') {
1310
+ scope = scope.parent;
1311
+ }
1312
+ if (scope === null)
1313
+ return unknownTypeClass('unknown');
1314
+ const paramTypeClass = lookupFunctionParameterTypeClass(scope, varName, identNode);
1315
+ if (paramTypeClass !== undefined)
1316
+ return paramTypeClass;
1317
+ // Indexed scope-declaration lookup (#2432; was a per-identifier scan).
1318
+ const stmt = scopeDeclarationsFor(scope).get(varName);
1319
+ if (stmt === undefined)
1320
+ return unknownTypeClass('unknown');
1321
+ const typeNode = stmt.childForFieldName('type');
1322
+ const declarator = stmt.childForFieldName('declarator');
1323
+ const nameChild = declarator !== null ? declaredNameNode(declarator) : null;
1324
+ if (typeNode === null || nameChild === null)
1325
+ return unknownTypeClass('unknown');
1326
+ const typeClass = (0, arity_metadata_js_1.classifyCppParameterType)(typeNode.text, nameChild.text, stmt.text.replace(/;\s*$/, ''));
1327
+ if (isKnownEnumName(identNode, typeClass.base)) {
1328
+ return { ...typeClass, base: `enum:${typeClass.base}` };
1329
+ }
1330
+ return typeClass;
1331
+ }
1332
+ function lookupFunctionParameterType(scope, varName) {
1333
+ const param = findEnclosingFunctionParameter(scope, varName);
1334
+ if (param === null)
1335
+ return '';
1336
+ const typeNode = param.childForFieldName('type');
1337
+ if (typeNode === null)
1338
+ return '';
1339
+ return normalizeCppTypeText(typeNode.text);
1340
+ }
1341
+ function lookupFunctionParameterTypeClass(scope, varName, identNode) {
1342
+ const param = findEnclosingFunctionParameter(scope, varName);
1343
+ if (param === null)
1344
+ return undefined;
1345
+ const typeNode = param.childForFieldName('type');
1346
+ if (typeNode === null)
1347
+ return undefined;
1348
+ const declarator = param.childForFieldName('declarator');
1349
+ if (declarator === null)
1350
+ return undefined;
1351
+ const typeClass = (0, arity_metadata_js_1.classifyCppParameterType)(typeNode.text, declarator.text, param.text);
1352
+ if (isKnownEnumName(identNode, typeClass.base)) {
1353
+ return { ...typeClass, base: `enum:${typeClass.base}` };
1354
+ }
1355
+ return typeClass;
1356
+ }
1357
+ function findEnclosingFunctionParameter(scope, varName) {
1358
+ let node = scope.parent;
1359
+ while (node !== null) {
1360
+ if (node.type === 'function_definition' || node.type === 'function_declarator') {
1361
+ return enclosingFunctionParametersFor(node)?.get(varName) ?? null;
1362
+ }
1363
+ node = node.parent;
1364
+ }
1365
+ return null;
1366
+ }
1367
+ /**
1368
+ * First-wins map of a function's `parameter_declaration`s by declarator
1369
+ * leaf name (#2432; was a per-identifier scan). `null` when the function
1370
+ * has no parameter list — the caller returns null without walking further
1371
+ * up, preserving the replaced scan's early-return.
1372
+ */
1373
+ function enclosingFunctionParametersFor(fnNode) {
1374
+ const cached = fileLookupIndex.fnParams.get(fnNode.id);
1375
+ if (cached !== undefined)
1376
+ return cached;
1377
+ const fnDecl = fnNode.type === 'function_declarator'
1378
+ ? fnNode
1379
+ : findFirstDescendantOfType(fnNode, 'function_declarator');
1380
+ const params = fnDecl?.childForFieldName('parameters') ?? null;
1381
+ let index = null;
1382
+ if (params !== null) {
1383
+ index = new Map();
1384
+ for (let i = 0; i < params.namedChildCount; i++) {
1385
+ const param = params.namedChild(i);
1386
+ if (param === null || param.type !== 'parameter_declaration')
1387
+ continue;
1388
+ const declarator = param.childForFieldName('declarator');
1389
+ if (declarator === null)
1390
+ continue;
1391
+ const name = extractDeclaratorLeafName(declarator);
1392
+ if (name === '' || index.has(name))
1393
+ continue;
1394
+ index.set(name, param);
1395
+ }
1396
+ }
1397
+ fileLookupIndex.fnParams.set(fnNode.id, index);
1398
+ return index;
1399
+ }
1400
+ function declaredNameNode(declarator) {
1401
+ if (declarator.type !== 'init_declarator')
1402
+ return declarator;
1403
+ for (let i = 0; i < declarator.namedChildCount; i++) {
1404
+ const child = declarator.namedChild(i);
1405
+ if (child === null)
1406
+ continue;
1407
+ if (child.type === 'identifier')
1408
+ return child;
1409
+ if (child.type.endsWith('_declarator'))
1410
+ return child;
1411
+ }
1412
+ return declarator.childForFieldName('declarator');
1413
+ }
1414
+ /** Normalize a type-specifier text for argument type matching.
1415
+ * Strips qualifiers (const, volatile), namespace prefixes (std::),
1416
+ * and pointer/reference markers. */
1417
+ function normalizeCppTypeText(text) {
1418
+ let t = text.trim();
1419
+ t = t.replace(/\b(const|volatile|static|extern|mutable)\b/g, '').trim();
1420
+ t = t.replace(/^.*::/, ''); // strip namespace prefix
1421
+ t = t.replace(/[*&]/g, '').trim();
1422
+ return t;
1423
+ }
1424
+ function isKnownEnumName(node, typeName) {
1425
+ if (typeName === '' || typeName === 'unknown')
1426
+ return false;
1427
+ // One full-tree DFS per FILE (lazy), not per identifier argument — the
1428
+ // per-identifier walk here was the dominant cost of #2432 (87s of a 151s
1429
+ // extraction on a file that parses in 46ms).
1430
+ if (fileLookupIndex.enumNames === null) {
1431
+ let root = node;
1432
+ while (root.parent !== null)
1433
+ root = root.parent;
1434
+ const names = new Set();
1435
+ const stack = [root];
1436
+ while (stack.length > 0) {
1437
+ const cur = stack.pop();
1438
+ if (cur.type === 'enum_specifier') {
1439
+ const name = cur.childForFieldName('name');
1440
+ if (name !== null)
1441
+ names.add(name.text);
1442
+ }
1443
+ for (let i = 0; i < cur.childCount; i++) {
1444
+ const child = cur.child(i);
1445
+ if (child !== null)
1446
+ stack.push(child);
1447
+ }
1448
+ }
1449
+ fileLookupIndex.enumNames = names;
1450
+ }
1451
+ return fileLookupIndex.enumNames.has(typeName);
1452
+ }
1453
+ /**
1454
+ * Detect whether a `namespace_definition` AST node is inline.
1455
+ * Tree-sitter-cpp exposes the `inline` keyword as an anonymous child
1456
+ * node — we scan direct children for that keyword.
1457
+ */
1458
+ function isInlineNamespace(nsNode) {
1459
+ for (let i = 0; i < nsNode.childCount; i++) {
1460
+ const c = nsNode.child(i);
1461
+ if (c === null)
1462
+ continue;
1463
+ if (c.type === 'inline')
1464
+ return true;
1465
+ // Some grammar variants surface keywords by their text rather than
1466
+ // by a dedicated node type; check both for resilience.
1467
+ if (c.text === 'inline' && (c.type === 'storage_class_specifier' || c.type === 'inline')) {
1468
+ return true;
1469
+ }
1470
+ }
1471
+ return false;
1472
+ }
1473
+ /**
1474
+ * Detect `(f)(args)` shape — the call-expression's `function` field is a
1475
+ * `parenthesized_expression`. ISO C++ specifies that this form suppresses
1476
+ * ADL (`[basic.lookup.argdep]/3.1`): the parenthesized name is treated as
1477
+ * an ordinary unqualified-lookup-only callee.
1478
+ */
1479
+ function isParenthesizedFunctionCall(callNode) {
1480
+ const fn = callNode.childForFieldName('function');
1481
+ return fn !== null && fn.type === 'parenthesized_expression';
1482
+ }
1483
+ /**
1484
+ * Per-argument ADL classification: walk each argument of a free call and
1485
+ * classify its declared type for associated-namespace lookup.
1486
+ *
1487
+ * Value/pointer/reference class-typed args and template specializations
1488
+ * with explicit type arguments contribute; function pointers, primitives,
1489
+ * literals, and other unsupported shapes produce an empty result.
1490
+ *
1491
+ * Class-typed values/pointers/references (`N::S`, `N::S*`, `N::S&`) all
1492
+ * preserve the class name for associated-namespace lookup.
1493
+ * Function pointers remain excluded even when their return type names a
1494
+ * class, because the associated entity is the pointed-to function type,
1495
+ * not the return type.
1496
+ */
1497
+ function inferCppCallAdlArgs(callNode) {
1498
+ const argList = callNode.childForFieldName('arguments');
1499
+ if (argList === null)
1500
+ return [];
1501
+ const out = [];
1502
+ for (let i = 0; i < argList.childCount; i++) {
1503
+ const child = argList.child(i);
1504
+ if (child === null)
1505
+ continue;
1506
+ if (child.type === ',' || child.type === '(' || child.type === ')')
1507
+ continue;
1508
+ out.push(classifyAdlArg(child));
1509
+ }
1510
+ return out;
1511
+ }
1512
+ const ADL_TEMPLATE_RECURSION_MAX_DEPTH = 8;
1513
+ const EMPTY_ADL_ARG = {
1514
+ simpleClassName: '',
1515
+ templateSimpleClassName: '',
1516
+ templateNamespace: '',
1517
+ templateArgClassNames: [],
1518
+ templateArgNamespaces: [],
1519
+ };
1520
+ function classifyAdlArg(argNode) {
1521
+ // Literals and primitive-shaped expressions never have associated namespaces.
1522
+ if (argNode.type === 'number_literal' ||
1523
+ argNode.type === 'string_literal' ||
1524
+ argNode.type === 'raw_string_literal' ||
1525
+ argNode.type === 'char_literal' ||
1526
+ argNode.type === 'true' ||
1527
+ argNode.type === 'false' ||
1528
+ argNode.type === 'null' ||
1529
+ argNode.type === 'nullptr') {
1530
+ return EMPTY_ADL_ARG;
1531
+ }
1532
+ // Qualified expression (a::b) — may be a function, variable, enum value,
1533
+ // or static member. Record as a potential function reference; resolution
1534
+ // time verifies via workspace lookup that a Function/Method with this simple
1535
+ // name exists in the extracted namespace before contributing to the set.
1536
+ if (argNode.type === 'qualified_identifier') {
1537
+ return {
1538
+ simpleClassName: '',
1539
+ templateSimpleClassName: '',
1540
+ templateNamespace: '',
1541
+ templateArgClassNames: [],
1542
+ templateArgNamespaces: [],
1543
+ functionRefText: argNode.text,
1544
+ };
1545
+ }
1546
+ // Variable reference — look up its declared type (preserving pointer /
1547
+ // reference / qualified-name shape; the existing arity-narrowing helper
1548
+ // strips this info).
1549
+ if (argNode.type === 'identifier') {
1550
+ const result = lookupAdlIdentifierType(argNode);
1551
+ if (result === null) {
1552
+ // Not found in the local compound_statement scope — could be a
1553
+ // free-function reference (unqualified name, namespace scope).
1554
+ return {
1555
+ simpleClassName: '',
1556
+ templateSimpleClassName: '',
1557
+ templateNamespace: '',
1558
+ templateArgClassNames: [],
1559
+ templateArgNamespaces: [],
1560
+ functionRefText: argNode.text,
1561
+ };
1562
+ }
1563
+ return result;
1564
+ }
1565
+ // Other shapes (calls, member access, operators) — V1 unsupported.
1566
+ return EMPTY_ADL_ARG;
1567
+ }
1568
+ /**
1569
+ * Returns `true` when `varName` appears as a parameter name in the nearest
1570
+ * enclosing `function_definition` or `function_declarator` that contains
1571
+ * `identNode`. Parameters live in `parameter_list` (a sibling of the
1572
+ * `compound_statement`), so the `compound_statement`-local declaration scan
1573
+ * in `lookupAdlIdentifierType` would not find them — causing them to be
1574
+ * mistakenly classified as potential free-function references.
1575
+ *
1576
+ * In tree-sitter-cpp a `function_definition` does NOT expose `parameters`
1577
+ * as a direct named field; parameters live inside the nested
1578
+ * `function_declarator`. For `function_declarator` nodes the `parameters`
1579
+ * field IS direct. Both cases are handled below.
1580
+ */
1581
+ function isIdentifierAFunctionParameter(identNode, varName) {
1582
+ let node = identNode.parent;
1583
+ let safety = 64;
1584
+ while (node !== null && safety-- > 0) {
1585
+ let params = null;
1586
+ if (node.type === 'function_declarator') {
1587
+ // parameters is a direct field on function_declarator.
1588
+ params = node.childForFieldName('parameters');
1589
+ }
1590
+ else if (node.type === 'function_definition') {
1591
+ // function_definition carries parameters inside its `declarator` field
1592
+ // (which is a function_declarator). Walk through it.
1593
+ const decl = node.childForFieldName('declarator');
1594
+ if (decl !== null && decl.type === 'function_declarator') {
1595
+ params = decl.childForFieldName('parameters');
1596
+ }
1597
+ }
1598
+ if (params !== null) {
1599
+ for (let i = 0; i < params.namedChildCount; i++) {
1600
+ const param = params.namedChild(i);
1601
+ if (param === null)
1602
+ continue;
1603
+ const declNode = param.childForFieldName('declarator');
1604
+ if (declNode === null)
1605
+ continue;
1606
+ const leafName = extractDeclaratorLeafName(declNode);
1607
+ if (leafName === varName)
1608
+ return true;
1609
+ }
1610
+ // Only check the immediately enclosing function — do not climb further.
1611
+ break;
1612
+ }
1613
+ if (node.type === 'translation_unit')
1614
+ break;
1615
+ node = node.parent;
1616
+ }
1617
+ return false;
1618
+ }
1619
+ function lookupAdlIdentifierType(identNode) {
1620
+ const varName = identNode.text;
1621
+ let scope = identNode.parent;
1622
+ while (scope !== null &&
1623
+ scope.type !== 'compound_statement' &&
1624
+ scope.type !== 'translation_unit') {
1625
+ scope = scope.parent;
1626
+ }
1627
+ if (scope === null)
1628
+ return null;
1629
+ // Function parameters live in the enclosing function's `parameter_list`,
1630
+ // NOT inside the `compound_statement`, so the declaration scan below would
1631
+ // never find them and would return `null` — incorrectly triggering the
1632
+ // free-function-reference path. Check the parameter_list first.
1633
+ if (isIdentifierAFunctionParameter(identNode, varName)) {
1634
+ return EMPTY_ADL_ARG;
1635
+ }
1636
+ let foundAsLocalFunctionPointer = false;
1637
+ for (let i = 0; i < scope.childCount; i++) {
1638
+ const stmt = scope.child(i);
1639
+ if (stmt === null || stmt.type !== 'declaration')
1640
+ continue;
1641
+ const typeNode = stmt.childForFieldName('type');
1642
+ if (typeNode === null)
1643
+ continue;
1644
+ if (typeNode.type === 'placeholder_type_specifier')
1645
+ continue;
1646
+ const declarator = stmt.childForFieldName('declarator');
1647
+ if (declarator === null)
1648
+ continue;
1649
+ // Unwrap declarator chain to find pointer/reference markers and the
1650
+ // variable name. `init_declarator > pointer_declarator > identifier`
1651
+ // means pointer-typed; repeated pointer wrappers still count as pointer
1652
+ // typed; `init_declarator > reference_declarator > ...` (or
1653
+ // `rvalue_reference_declarator`) means reference-typed; bare
1654
+ // `init_declarator > identifier` is value.
1655
+ // Function-pointer wrappers (`pointer_declarator > function_declarator`)
1656
+ // must not contribute ADL associated namespaces.
1657
+ let isFunctionPointer = false;
1658
+ let inner = declarator;
1659
+ let nameText = null;
1660
+ let safety = 16; // bound walk depth defensively
1661
+ while (safety-- > 0) {
1662
+ if (inner.type === 'pointer_declarator') {
1663
+ if (findFirstDescendantOfType(inner, 'function_declarator') !== null) {
1664
+ isFunctionPointer = true;
1665
+ // Extract the name from within the function-pointer declarator chain
1666
+ // so `foundAsLocalFunctionPointer` can detect a matching declaration.
1667
+ nameText = extractDeclaratorLeafName(inner);
1668
+ break;
1669
+ }
1670
+ const next = inner.childForFieldName('declarator');
1671
+ if (next === null)
1672
+ break;
1673
+ inner = next;
1674
+ continue;
1675
+ }
1676
+ if (inner.type === 'reference_declarator') {
1677
+ // reference_declarator has a single child (the inner declarator).
1678
+ let next = null;
1679
+ for (let j = 0; j < inner.namedChildCount; j++) {
1680
+ const c = inner.namedChild(j);
1681
+ if (c !== null) {
1682
+ next = c;
1683
+ break;
1684
+ }
1685
+ }
1686
+ if (next === null)
1687
+ break;
1688
+ inner = next;
1689
+ continue;
1690
+ }
1691
+ if (inner.type === 'init_declarator') {
1692
+ const next = inner.childForFieldName('declarator');
1693
+ if (next === null)
1694
+ break;
1695
+ inner = next;
1696
+ continue;
1697
+ }
1698
+ if (inner.type === 'function_declarator') {
1699
+ isFunctionPointer = true;
1700
+ // Extract the name from the inner declarator (e.g. `(*g)` in `void (*g)()`).
1701
+ const innerDecl = inner.childForFieldName('declarator');
1702
+ if (innerDecl !== null)
1703
+ nameText = extractDeclaratorLeafName(innerDecl);
1704
+ break;
1705
+ }
1706
+ // Reached the leaf — usually `identifier`. Take its text.
1707
+ nameText = inner.text;
1708
+ break;
1709
+ }
1710
+ if (nameText === varName && isFunctionPointer) {
1711
+ // Explicitly declared as a function-pointer variable — must not be
1712
+ // treated as a free-function reference by the caller.
1713
+ foundAsLocalFunctionPointer = true;
1714
+ continue;
1715
+ }
1716
+ if (isFunctionPointer || nameText !== varName)
1717
+ continue;
1718
+ const simpleClassName = extractAdlSimpleTypeName(typeNode);
1719
+ const { templateSimpleClassName, templateNamespace, templateArgClassNames, templateArgNamespaces, } = extractAdlTemplateInfo(typeNode);
1720
+ return {
1721
+ simpleClassName,
1722
+ templateSimpleClassName,
1723
+ templateNamespace,
1724
+ templateArgClassNames,
1725
+ templateArgNamespaces,
1726
+ };
1727
+ }
1728
+ // If the identifier was found in local scope as a function-pointer variable,
1729
+ // return EMPTY_ADL_ARG so the caller does NOT treat it as a free-function
1730
+ // reference. Otherwise return null to indicate "not in local scope".
1731
+ //
1732
+ // Known limitation (Finding 4): variables whose type is a typedef/using alias
1733
+ // for a function-pointer type are NOT detected here. For example:
1734
+ // using Callback = void (*)();
1735
+ // Callback g;
1736
+ // foo(g); // `g`'s declarator is `identifier` with type `Callback`
1737
+ // The declarator has no `pointer_declarator` wrapper, so `isFunctionPointer`
1738
+ // stays false and `extractAdlSimpleTypeName` returns `"Callback"`. ADL then
1739
+ // looks for a class named `Callback`; if none exists, this degrades to
1740
+ // EMPTY_ADL_ARG (class not found → no namespace contributed). If a class
1741
+ // named `Callback` does exist, a spurious namespace contribution could occur.
1742
+ // Risk is low in practice; a future fix should resolve the typedef/alias chain.
1743
+ return foundAsLocalFunctionPointer ? EMPTY_ADL_ARG : null;
1744
+ }
1745
+ /** Extract the simple class-like type name from a `type:` field node.
1746
+ * Returns '' for primitives and any other
1747
+ * unsupported type-only shape. Function pointers are filtered at the
1748
+ * declarator level in `lookupAdlIdentifierType`. */
1749
+ function extractAdlSimpleTypeName(typeNode) {
1750
+ if (typeNode.type === 'type_descriptor') {
1751
+ const innerType = typeNode.childForFieldName('type');
1752
+ if (innerType !== null)
1753
+ return extractAdlSimpleTypeName(innerType);
1754
+ for (let i = 0; i < typeNode.childCount; i++) {
1755
+ const child = typeNode.child(i);
1756
+ if (child === null)
1757
+ continue;
1758
+ if (child.type === 'type_identifier' ||
1759
+ child.type === 'qualified_identifier' ||
1760
+ child.type === 'template_type') {
1761
+ return extractAdlSimpleTypeName(child);
1762
+ }
1763
+ }
1764
+ return '';
1765
+ }
1766
+ if (typeNode.type === 'primitive_type')
1767
+ return '';
1768
+ if (typeNode.type === 'sized_type_specifier')
1769
+ return '';
1770
+ if (typeNode.type === 'type_identifier')
1771
+ return typeNode.text;
1772
+ if (typeNode.type === 'template_type') {
1773
+ const nameNode = typeNode.childForFieldName('name');
1774
+ if (nameNode !== null)
1775
+ return extractAdlSimpleTypeName(nameNode);
1776
+ const id = findFirstDescendantOfType(typeNode, 'type_identifier');
1777
+ return id !== null ? id.text : '';
1778
+ }
1779
+ if (typeNode.type === 'qualified_identifier') {
1780
+ const nameNode = typeNode.childForFieldName('name');
1781
+ if (nameNode !== null)
1782
+ return extractAdlSimpleTypeName(nameNode);
1783
+ const id = findFirstDescendantOfType(typeNode, 'type_identifier');
1784
+ return id !== null ? id.text : '';
1785
+ }
1786
+ // Function pointers, decltype, etc — unsupported for ADL participation.
1787
+ return '';
1788
+ }
1789
+ function extractAdlTypeNamespace(typeNode) {
1790
+ if (typeNode.type === 'type_descriptor') {
1791
+ const innerType = typeNode.childForFieldName('type');
1792
+ if (innerType !== null)
1793
+ return extractAdlTypeNamespace(innerType);
1794
+ for (let i = 0; i < typeNode.childCount; i++) {
1795
+ const child = typeNode.child(i);
1796
+ if (child === null)
1797
+ continue;
1798
+ if (child.type === 'qualified_identifier' ||
1799
+ child.type === 'template_type' ||
1800
+ child.type === 'type_identifier') {
1801
+ return extractAdlTypeNamespace(child);
1802
+ }
1803
+ }
1804
+ return '';
1805
+ }
1806
+ if (typeNode.type === 'template_type') {
1807
+ const nameNode = typeNode.childForFieldName('name');
1808
+ return nameNode !== null ? extractAdlTypeNamespace(nameNode) : '';
1809
+ }
1810
+ if (typeNode.type === 'qualified_identifier') {
1811
+ const scope = typeNode.childForFieldName('scope');
1812
+ if (scope !== null)
1813
+ return (0, qualified_name_js_1.normalizeQualifiedName)(scope.text);
1814
+ return extractNamespaceFromQualifiedText(typeNode.text);
1815
+ }
1816
+ return '';
1817
+ }
1818
+ function extractAdlTemplateInfo(typeNode) {
1819
+ const templateTypeNode = findTemplateTypeNode(typeNode);
1820
+ if (templateTypeNode === null) {
1821
+ return {
1822
+ templateSimpleClassName: '',
1823
+ templateNamespace: '',
1824
+ templateArgClassNames: [],
1825
+ templateArgNamespaces: [],
1826
+ };
1827
+ }
1828
+ const templateArgClassNames = [];
1829
+ const templateArgNamespaces = [];
1830
+ collectAdlTemplateArgs(templateTypeNode, 0, templateArgClassNames, templateArgNamespaces);
1831
+ return {
1832
+ templateSimpleClassName: extractAdlSimpleTypeName(templateTypeNode),
1833
+ templateNamespace: extractAdlTypeNamespace(typeNode),
1834
+ templateArgClassNames,
1835
+ templateArgNamespaces,
1836
+ };
1837
+ }
1838
+ function collectAdlTemplateArgs(templateTypeNode, depth, outClassNames, outNamespaces) {
1839
+ if (depth >= ADL_TEMPLATE_RECURSION_MAX_DEPTH)
1840
+ return;
1841
+ if (templateTypeNode.type !== 'template_type')
1842
+ return;
1843
+ const argList = templateTypeNode.childForFieldName('arguments') ??
1844
+ findChildOfType(templateTypeNode, ['template_argument_list']);
1845
+ if (argList === null)
1846
+ return;
1847
+ for (let i = 0; i < argList.namedChildCount; i++) {
1848
+ const arg = argList.namedChild(i);
1849
+ if (arg === null || arg.type !== 'type_descriptor')
1850
+ continue;
1851
+ const simpleClassName = extractAdlSimpleTypeName(arg);
1852
+ if (simpleClassName.length > 0)
1853
+ outClassNames.push(simpleClassName);
1854
+ const ns = extractAdlTypeNamespace(arg);
1855
+ if (ns.length > 0)
1856
+ outNamespaces.push(ns);
1857
+ const nestedType = arg.childForFieldName('type');
1858
+ const nestedTemplate = nestedType !== null ? findTemplateTypeNode(nestedType) : null;
1859
+ if (nestedTemplate !== null) {
1860
+ collectAdlTemplateArgs(nestedTemplate, depth + 1, outClassNames, outNamespaces);
1861
+ }
1862
+ }
1863
+ }
1864
+ function findTemplateTypeNode(typeNode) {
1865
+ if (typeNode.type === 'template_type')
1866
+ return typeNode;
1867
+ if (typeNode.type === 'type_descriptor') {
1868
+ const innerType = typeNode.childForFieldName('type');
1869
+ if (innerType !== null)
1870
+ return findTemplateTypeNode(innerType);
1871
+ return null;
1872
+ }
1873
+ if (typeNode.type === 'qualified_identifier') {
1874
+ const nameNode = typeNode.childForFieldName('name');
1875
+ if (nameNode !== null)
1876
+ return findTemplateTypeNode(nameNode);
1877
+ return null;
1878
+ }
1879
+ return null;
1880
+ }
1881
+ function extractNamespaceFromQualifiedText(text) {
1882
+ const cleaned = text.replace(/\s+/g, '');
1883
+ const idx = cleaned.lastIndexOf('::');
1884
+ if (idx <= 0)
1885
+ return '';
1886
+ return (0, qualified_name_js_1.normalizeQualifiedName)(cleaned.slice(0, idx));
1887
+ }
1888
+ /**
1889
+ * Walk a declarator node chain, unwrapping pointer/reference/function/
1890
+ * parenthesized wrappers, and return the text of the innermost identifier.
1891
+ * Returns `null` when no identifier is found within `safety` steps.
1892
+ * Used by `lookupAdlIdentifierType` to extract the variable name from
1893
+ * function-pointer declarator trees such as `(*g)()` in `void (*g)()`.
1894
+ */
1895
+ function extractDeclaratorLeafName(node) {
1896
+ let cur = node;
1897
+ let safety = 16;
1898
+ while (safety-- > 0) {
1899
+ if (cur.type === 'identifier' ||
1900
+ cur.type === 'type_identifier' ||
1901
+ cur.type === 'operator_name') {
1902
+ return cur.text;
1903
+ }
1904
+ // Common wrapper nodes — follow the 'declarator' field when present.
1905
+ const next = cur.childForFieldName('declarator') ??
1906
+ // parenthesized_declarator: single named child
1907
+ (cur.type === 'parenthesized_declarator' || cur.type.endsWith('_declarator')
1908
+ ? cur.namedChild(0)
1909
+ : null);
1910
+ if (next === null)
1911
+ return null;
1912
+ cur = next;
1913
+ }
1914
+ return null;
1915
+ }
1916
+ /**
1917
+ * Check if a C++ declaration has an `explicit` specifier. Tree-sitter-cpp
1918
+ * exposes `explicit` as a direct keyword child on constructor declarations in
1919
+ * current grammar builds; the bounded text prefix keeps this resilient across
1920
+ * small grammar shape differences without scanning whole function bodies.
1921
+ */
1922
+ function hasExplicitSpecifier(node) {
1923
+ for (let i = 0; i < node.childCount; i++) {
1924
+ const child = node.child(i);
1925
+ if (child !== null && child.text === 'explicit')
1926
+ return true;
1927
+ }
1928
+ return /\bexplicit\b/.test(node.text.slice(0, 128));
1929
+ }
1930
+ function hasDeletedMethodClause(node, callableName) {
1931
+ for (let i = 0; i < node.namedChildCount; i++) {
1932
+ const child = node.namedChild(i);
1933
+ if (child?.type === 'delete_method_clause')
1934
+ return true;
1935
+ // tree-sitter-cpp 0.23 parses a deleted free-function declaration as
1936
+ // `declaration > init_declarator > delete_expression`, while class
1937
+ // members use the dedicated `delete_method_clause`.
1938
+ if (child?.type === 'init_declarator' &&
1939
+ child.childForFieldName('value')?.type === 'delete_expression' &&
1940
+ callableName !== undefined &&
1941
+ extractDeclaratorLeafName(child.childForFieldName('declarator') ?? child) === callableName) {
1942
+ return true;
1943
+ }
1944
+ }
1945
+ return false;
1946
+ }
1947
+ /**
1948
+ * Check if a C++ function_definition or declaration has `static` storage class.
1949
+ */
1950
+ function hasStaticStorageClass(node) {
1951
+ for (let i = 0; i < node.childCount; i++) {
1952
+ const child = node.child(i);
1953
+ if (child !== null && child.type === 'storage_class_specifier' && child.text === 'static') {
1954
+ return true;
1955
+ }
1956
+ }
1957
+ return false;
1958
+ }
1959
+ /**
1960
+ * Check if a node is inside an anonymous namespace (file-local linkage in C++).
1961
+ * Anonymous namespaces have no `name` field in tree-sitter-cpp.
1962
+ */
1963
+ function isInsideAnonymousNamespace(node) {
1964
+ let ancestor = node.parent ?? null;
1965
+ while (ancestor !== null) {
1966
+ if (ancestor.type === 'namespace_definition') {
1967
+ // Anonymous namespace: has declaration_list but no name child
1968
+ const nameChild = ancestor.childForFieldName?.('name') ?? null;
1969
+ if (nameChild === null)
1970
+ return true;
1971
+ }
1972
+ ancestor = ancestor.parent;
1973
+ }
1974
+ return false;
1975
+ }