cgraphx 2.0.2 → 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 (680) hide show
  1. package/dist/core/code/engine/cli/analyze-config.js +320 -0
  2. package/dist/core/code/engine/cli/analyze.js +1086 -0
  3. package/dist/core/code/engine/cli/cli-message.js +83 -0
  4. package/dist/core/code/engine/cli/detect-changes-format.js +58 -0
  5. package/dist/core/code/engine/cli/embedding-dims.js +43 -0
  6. package/dist/core/code/engine/cli/format-elapsed.js +12 -0
  7. package/dist/core/code/engine/cli/help-i18n.js +144 -0
  8. package/dist/core/code/engine/cli/i18n/en.js +110 -0
  9. package/dist/core/code/engine/cli/i18n/index.js +47 -0
  10. package/dist/core/code/engine/cli/i18n/resources.js +9 -0
  11. package/dist/core/code/engine/cli/i18n/zh-CN.js +110 -0
  12. package/dist/core/code/engine/cli/lazy-action.js +67 -0
  13. package/dist/core/code/engine/cli/optional-grammars.js +136 -0
  14. package/dist/core/code/engine/cli/resolve-invocation.js +76 -0
  15. package/dist/core/code/engine/cli/status.js +156 -0
  16. package/dist/core/code/engine/cli/tool.js +384 -0
  17. package/dist/core/code/engine/config/ignore-service.js +511 -0
  18. package/dist/core/code/engine/config/supported-languages.js +17 -0
  19. package/dist/core/code/engine/core/analysis-features.js +64 -0
  20. package/dist/core/code/engine/core/analyzer-identity.js +2171 -0
  21. package/dist/core/code/engine/core/git-staleness.js +180 -0
  22. package/dist/core/code/engine/core/graph/graph.js +180 -0
  23. package/dist/core/code/engine/core/graph/import-cycles.js +106 -0
  24. package/dist/core/code/engine/core/graph/types.js +2 -0
  25. package/dist/core/code/engine/core/index-freshness.js +12 -0
  26. package/dist/core/code/engine/core/ingestion/binding-accumulator.js +341 -0
  27. package/dist/core/code/engine/core/ingestion/call-extractors/configs/c-cpp.js +168 -0
  28. package/dist/core/code/engine/core/ingestion/call-extractors/configs/csharp.js +9 -0
  29. package/dist/core/code/engine/core/ingestion/call-extractors/configs/dart.js +8 -0
  30. package/dist/core/code/engine/core/ingestion/call-extractors/configs/go.js +8 -0
  31. package/dist/core/code/engine/core/ingestion/call-extractors/configs/jvm.js +54 -0
  32. package/dist/core/code/engine/core/ingestion/call-extractors/configs/php.js +8 -0
  33. package/dist/core/code/engine/core/ingestion/call-extractors/configs/python.js +8 -0
  34. package/dist/core/code/engine/core/ingestion/call-extractors/configs/ruby.js +8 -0
  35. package/dist/core/code/engine/core/ingestion/call-extractors/configs/rust.js +8 -0
  36. package/dist/core/code/engine/core/ingestion/call-extractors/configs/swift.js +8 -0
  37. package/dist/core/code/engine/core/ingestion/call-extractors/configs/typescript-javascript.js +11 -0
  38. package/dist/core/code/engine/core/ingestion/call-extractors/generic.js +62 -0
  39. package/dist/core/code/engine/core/ingestion/call-processor.js +503 -0
  40. package/dist/core/code/engine/core/ingestion/call-routing.js +98 -0
  41. package/dist/core/code/engine/core/ingestion/call-types.js +3 -0
  42. package/dist/core/code/engine/core/ingestion/cfg/callee-cell-format.js +45 -0
  43. package/dist/core/code/engine/core/ingestion/cfg/cfg-builder.js +202 -0
  44. package/dist/core/code/engine/core/ingestion/cfg/collect.js +81 -0
  45. package/dist/core/code/engine/core/ingestion/cfg/control-dependence.js +185 -0
  46. package/dist/core/code/engine/core/ingestion/cfg/control-flow-context.js +130 -0
  47. package/dist/core/code/engine/core/ingestion/cfg/emit.js +646 -0
  48. package/dist/core/code/engine/core/ingestion/cfg/post-dominators.js +182 -0
  49. package/dist/core/code/engine/core/ingestion/cfg/reaching-def-reason-codec.js +139 -0
  50. package/dist/core/code/engine/core/ingestion/cfg/reaching-defs-graph.js +322 -0
  51. package/dist/core/code/engine/core/ingestion/cfg/reaching-defs.js +792 -0
  52. package/dist/core/code/engine/core/ingestion/cfg/synthetic-escape.js +305 -0
  53. package/dist/core/code/engine/core/ingestion/cfg/traversal-result.js +6 -0
  54. package/dist/core/code/engine/core/ingestion/cfg/types.js +14 -0
  55. package/dist/core/code/engine/core/ingestion/cfg/visitors/c-cpp-harvest.js +545 -0
  56. package/dist/core/code/engine/core/ingestion/cfg/visitors/c-cpp.js +590 -0
  57. package/dist/core/code/engine/core/ingestion/cfg/visitors/call-site-harvest.js +356 -0
  58. package/dist/core/code/engine/core/ingestion/cfg/visitors/csharp-harvest.js +593 -0
  59. package/dist/core/code/engine/core/ingestion/cfg/visitors/csharp.js +871 -0
  60. package/dist/core/code/engine/core/ingestion/cfg/visitors/dart-harvest.js +874 -0
  61. package/dist/core/code/engine/core/ingestion/cfg/visitors/dart.js +840 -0
  62. package/dist/core/code/engine/core/ingestion/cfg/visitors/go-harvest.js +625 -0
  63. package/dist/core/code/engine/core/ingestion/cfg/visitors/go.js +642 -0
  64. package/dist/core/code/engine/core/ingestion/cfg/visitors/java-harvest.js +517 -0
  65. package/dist/core/code/engine/core/ingestion/cfg/visitors/java.js +816 -0
  66. package/dist/core/code/engine/core/ingestion/cfg/visitors/kotlin-harvest.js +723 -0
  67. package/dist/core/code/engine/core/ingestion/cfg/visitors/kotlin.js +813 -0
  68. package/dist/core/code/engine/core/ingestion/cfg/visitors/php-harvest.js +630 -0
  69. package/dist/core/code/engine/core/ingestion/cfg/visitors/php.js +725 -0
  70. package/dist/core/code/engine/core/ingestion/cfg/visitors/python-harvest.js +776 -0
  71. package/dist/core/code/engine/core/ingestion/cfg/visitors/python.js +562 -0
  72. package/dist/core/code/engine/core/ingestion/cfg/visitors/ruby-harvest.js +591 -0
  73. package/dist/core/code/engine/core/ingestion/cfg/visitors/ruby.js +760 -0
  74. package/dist/core/code/engine/core/ingestion/cfg/visitors/rust-harvest.js +877 -0
  75. package/dist/core/code/engine/core/ingestion/cfg/visitors/rust.js +562 -0
  76. package/dist/core/code/engine/core/ingestion/cfg/visitors/scope-tree-harvest.js +120 -0
  77. package/dist/core/code/engine/core/ingestion/cfg/visitors/swift-harvest.js +683 -0
  78. package/dist/core/code/engine/core/ingestion/cfg/visitors/swift.js +791 -0
  79. package/dist/core/code/engine/core/ingestion/cfg/visitors/typescript-harvest.js +1060 -0
  80. package/dist/core/code/engine/core/ingestion/cfg/visitors/typescript.js +587 -0
  81. package/dist/core/code/engine/core/ingestion/class-extractors/configs/c-cpp.js +77 -0
  82. package/dist/core/code/engine/core/ingestion/class-extractors/configs/csharp.js +24 -0
  83. package/dist/core/code/engine/core/ingestion/class-extractors/configs/dart.js +10 -0
  84. package/dist/core/code/engine/core/ingestion/class-extractors/configs/go.js +28 -0
  85. package/dist/core/code/engine/core/ingestion/class-extractors/configs/jvm.js +67 -0
  86. package/dist/core/code/engine/core/ingestion/class-extractors/configs/php.js +10 -0
  87. package/dist/core/code/engine/core/ingestion/class-extractors/configs/python.js +10 -0
  88. package/dist/core/code/engine/core/ingestion/class-extractors/configs/ruby.js +13 -0
  89. package/dist/core/code/engine/core/ingestion/class-extractors/configs/rust.js +10 -0
  90. package/dist/core/code/engine/core/ingestion/class-extractors/configs/swift.js +21 -0
  91. package/dist/core/code/engine/core/ingestion/class-extractors/configs/typescript-javascript.js +31 -0
  92. package/dist/core/code/engine/core/ingestion/class-extractors/generic.js +144 -0
  93. package/dist/core/code/engine/core/ingestion/class-types.js +2 -0
  94. package/dist/core/code/engine/core/ingestion/cluster-enricher.js +174 -0
  95. package/dist/core/code/engine/core/ingestion/community-processor.js +604 -0
  96. package/dist/core/code/engine/core/ingestion/constants.js +26 -0
  97. package/dist/core/code/engine/core/ingestion/cpp-ue-preprocessor.js +263 -0
  98. package/dist/core/code/engine/core/ingestion/csharp-namespace-gate.js +133 -0
  99. package/dist/core/code/engine/core/ingestion/di-extractors/index.js +38 -0
  100. package/dist/core/code/engine/core/ingestion/di-extractors/spring.js +310 -0
  101. package/dist/core/code/engine/core/ingestion/emit-references.js +244 -0
  102. package/dist/core/code/engine/core/ingestion/entry-point-scoring.js +201 -0
  103. package/dist/core/code/engine/core/ingestion/export-detection.js +244 -0
  104. package/dist/core/code/engine/core/ingestion/field-extractor.js +29 -0
  105. package/dist/core/code/engine/core/ingestion/field-extractors/configs/c-cpp.js +107 -0
  106. package/dist/core/code/engine/core/ingestion/field-extractors/configs/csharp.js +124 -0
  107. package/dist/core/code/engine/core/ingestion/field-extractors/configs/dart.js +99 -0
  108. package/dist/core/code/engine/core/ingestion/field-extractors/configs/go.js +102 -0
  109. package/dist/core/code/engine/core/ingestion/field-extractors/configs/helpers.js +198 -0
  110. package/dist/core/code/engine/core/ingestion/field-extractors/configs/jvm.js +172 -0
  111. package/dist/core/code/engine/core/ingestion/field-extractors/configs/php.js +67 -0
  112. package/dist/core/code/engine/core/ingestion/field-extractors/configs/python.js +94 -0
  113. package/dist/core/code/engine/core/ingestion/field-extractors/configs/ruby.js +79 -0
  114. package/dist/core/code/engine/core/ingestion/field-extractors/configs/rust.js +55 -0
  115. package/dist/core/code/engine/core/ingestion/field-extractors/configs/swift.js +93 -0
  116. package/dist/core/code/engine/core/ingestion/field-extractors/configs/typescript-javascript.js +59 -0
  117. package/dist/core/code/engine/core/ingestion/field-extractors/generic.js +147 -0
  118. package/dist/core/code/engine/core/ingestion/field-extractors/typescript.js +266 -0
  119. package/dist/core/code/engine/core/ingestion/field-types.js +3 -0
  120. package/dist/core/code/engine/core/ingestion/filesystem-walker.js +136 -0
  121. package/dist/core/code/engine/core/ingestion/finalize-orchestrator.js +159 -0
  122. package/dist/core/code/engine/core/ingestion/framework-detection.js +432 -0
  123. package/dist/core/code/engine/core/ingestion/frameworks/spring/analysis-features.js +38 -0
  124. package/dist/core/code/engine/core/ingestion/frameworks/spring/annotation-arguments.js +234 -0
  125. package/dist/core/code/engine/core/ingestion/frameworks/spring/aop-candidates.js +88 -0
  126. package/dist/core/code/engine/core/ingestion/frameworks/spring/aop.js +487 -0
  127. package/dist/core/code/engine/core/ingestion/frameworks/spring/auto-configuration.js +21 -0
  128. package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-candidates.js +189 -0
  129. package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-catalog.js +32 -0
  130. package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-factories.js +73 -0
  131. package/dist/core/code/engine/core/ingestion/frameworks/spring/conditionals.js +323 -0
  132. package/dist/core/code/engine/core/ingestion/frameworks/spring/config-bindings.js +119 -0
  133. package/dist/core/code/engine/core/ingestion/frameworks/spring/di-metadata.js +385 -0
  134. package/dist/core/code/engine/core/ingestion/frameworks/spring/resource-injection.js +96 -0
  135. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/c-cpp.js +17 -0
  136. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/csharp.js +46 -0
  137. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/dart.js +59 -0
  138. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/go.js +30 -0
  139. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/jvm.js +73 -0
  140. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/php.js +19 -0
  141. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/python.js +45 -0
  142. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/ruby.js +20 -0
  143. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/rust.js +58 -0
  144. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/swift.js +94 -0
  145. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/typescript-javascript.js +26 -0
  146. package/dist/core/code/engine/core/ingestion/import-resolvers/csharp.js +128 -0
  147. package/dist/core/code/engine/core/ingestion/import-resolvers/go.js +50 -0
  148. package/dist/core/code/engine/core/ingestion/import-resolvers/jvm.js +112 -0
  149. package/dist/core/code/engine/core/ingestion/import-resolvers/php.js +80 -0
  150. package/dist/core/code/engine/core/ingestion/import-resolvers/python.js +75 -0
  151. package/dist/core/code/engine/core/ingestion/import-resolvers/resolver-factory.js +36 -0
  152. package/dist/core/code/engine/core/ingestion/import-resolvers/ruby.js +20 -0
  153. package/dist/core/code/engine/core/ingestion/import-resolvers/rust.js +79 -0
  154. package/dist/core/code/engine/core/ingestion/import-resolvers/standard.js +180 -0
  155. package/dist/core/code/engine/core/ingestion/import-resolvers/types.js +7 -0
  156. package/dist/core/code/engine/core/ingestion/import-resolvers/utils.js +153 -0
  157. package/dist/core/code/engine/core/ingestion/import-target-adapter.js +99 -0
  158. package/dist/core/code/engine/core/ingestion/language-config.js +391 -0
  159. package/dist/core/code/engine/core/ingestion/language-provider.js +25 -0
  160. package/dist/core/code/engine/core/ingestion/languages/c/arity-metadata.js +98 -0
  161. package/dist/core/code/engine/core/ingestion/languages/c/arity.js +21 -0
  162. package/dist/core/code/engine/core/ingestion/languages/c/capture-side-channel.js +69 -0
  163. package/dist/core/code/engine/core/ingestion/languages/c/captures.js +189 -0
  164. package/dist/core/code/engine/core/ingestion/languages/c/header-scan.js +58 -0
  165. package/dist/core/code/engine/core/ingestion/languages/c/import-decomposer.js +68 -0
  166. package/dist/core/code/engine/core/ingestion/languages/c/import-target.js +103 -0
  167. package/dist/core/code/engine/core/ingestion/languages/c/index.js +33 -0
  168. package/dist/core/code/engine/core/ingestion/languages/c/interpret.js +53 -0
  169. package/dist/core/code/engine/core/ingestion/languages/c/merge-bindings.js +26 -0
  170. package/dist/core/code/engine/core/ingestion/languages/c/query.js +210 -0
  171. package/dist/core/code/engine/core/ingestion/languages/c/scope-resolver.js +112 -0
  172. package/dist/core/code/engine/core/ingestion/languages/c/simple-hooks.js +24 -0
  173. package/dist/core/code/engine/core/ingestion/languages/c/static-linkage.js +109 -0
  174. package/dist/core/code/engine/core/ingestion/languages/c-cpp.js +506 -0
  175. package/dist/core/code/engine/core/ingestion/languages/cpp/adl.js +804 -0
  176. package/dist/core/code/engine/core/ingestion/languages/cpp/arity-metadata.js +258 -0
  177. package/dist/core/code/engine/core/ingestion/languages/cpp/arity.js +37 -0
  178. package/dist/core/code/engine/core/ingestion/languages/cpp/capture-side-channel.js +89 -0
  179. package/dist/core/code/engine/core/ingestion/languages/cpp/captures.js +1975 -0
  180. package/dist/core/code/engine/core/ingestion/languages/cpp/constraint-extractor.js +311 -0
  181. package/dist/core/code/engine/core/ingestion/languages/cpp/constraint-filter.js +210 -0
  182. package/dist/core/code/engine/core/ingestion/languages/cpp/conversion-rank.js +163 -0
  183. package/dist/core/code/engine/core/ingestion/languages/cpp/file-local-linkage.js +327 -0
  184. package/dist/core/code/engine/core/ingestion/languages/cpp/header-scan.js +53 -0
  185. package/dist/core/code/engine/core/ingestion/languages/cpp/import-decomposer.js +134 -0
  186. package/dist/core/code/engine/core/ingestion/languages/cpp/import-target.js +16 -0
  187. package/dist/core/code/engine/core/ingestion/languages/cpp/index.js +33 -0
  188. package/dist/core/code/engine/core/ingestion/languages/cpp/inline-namespaces.js +379 -0
  189. package/dist/core/code/engine/core/ingestion/languages/cpp/interpret.js +239 -0
  190. package/dist/core/code/engine/core/ingestion/languages/cpp/member-lookup.js +470 -0
  191. package/dist/core/code/engine/core/ingestion/languages/cpp/merge-bindings.js +32 -0
  192. package/dist/core/code/engine/core/ingestion/languages/cpp/query.js +763 -0
  193. package/dist/core/code/engine/core/ingestion/languages/cpp/range-bindings.js +230 -0
  194. package/dist/core/code/engine/core/ingestion/languages/cpp/scope-resolver.js +354 -0
  195. package/dist/core/code/engine/core/ingestion/languages/cpp/simple-hooks.js +67 -0
  196. package/dist/core/code/engine/core/ingestion/languages/cpp/two-phase-lookup.js +348 -0
  197. package/dist/core/code/engine/core/ingestion/languages/cpp/type-classifier.js +56 -0
  198. package/dist/core/code/engine/core/ingestion/languages/cpp/user-defined-conversions.js +128 -0
  199. package/dist/core/code/engine/core/ingestion/languages/csharp/accessor-unwrap.js +67 -0
  200. package/dist/core/code/engine/core/ingestion/languages/csharp/arity-metadata.js +49 -0
  201. package/dist/core/code/engine/core/ingestion/languages/csharp/arity.js +40 -0
  202. package/dist/core/code/engine/core/ingestion/languages/csharp/cache-stats.js +32 -0
  203. package/dist/core/code/engine/core/ingestion/languages/csharp/captures.js +557 -0
  204. package/dist/core/code/engine/core/ingestion/languages/csharp/import-decomposer.js +96 -0
  205. package/dist/core/code/engine/core/ingestion/languages/csharp/import-target.js +176 -0
  206. package/dist/core/code/engine/core/ingestion/languages/csharp/index.js +95 -0
  207. package/dist/core/code/engine/core/ingestion/languages/csharp/interpret.js +150 -0
  208. package/dist/core/code/engine/core/ingestion/languages/csharp/merge-bindings.js +58 -0
  209. package/dist/core/code/engine/core/ingestion/languages/csharp/namespace-siblings.js +708 -0
  210. package/dist/core/code/engine/core/ingestion/languages/csharp/qualified-type-names.js +62 -0
  211. package/dist/core/code/engine/core/ingestion/languages/csharp/query.js +578 -0
  212. package/dist/core/code/engine/core/ingestion/languages/csharp/receiver-binding.js +142 -0
  213. package/dist/core/code/engine/core/ingestion/languages/csharp/resolution-config.js +18 -0
  214. package/dist/core/code/engine/core/ingestion/languages/csharp/scope-resolver.js +84 -0
  215. package/dist/core/code/engine/core/ingestion/languages/csharp/simple-hooks.js +81 -0
  216. package/dist/core/code/engine/core/ingestion/languages/csharp.js +204 -0
  217. package/dist/core/code/engine/core/ingestion/languages/dart/arity-metadata.js +38 -0
  218. package/dist/core/code/engine/core/ingestion/languages/dart/arity.js +34 -0
  219. package/dist/core/code/engine/core/ingestion/languages/dart/built-ins.js +37 -0
  220. package/dist/core/code/engine/core/ingestion/languages/dart/cache-stats.js +30 -0
  221. package/dist/core/code/engine/core/ingestion/languages/dart/captures.js +1096 -0
  222. package/dist/core/code/engine/core/ingestion/languages/dart/expand-wildcards.js +34 -0
  223. package/dist/core/code/engine/core/ingestion/languages/dart/extension-type-preprocess.js +33 -0
  224. package/dist/core/code/engine/core/ingestion/languages/dart/import-target.js +68 -0
  225. package/dist/core/code/engine/core/ingestion/languages/dart/index.js +45 -0
  226. package/dist/core/code/engine/core/ingestion/languages/dart/interpret.js +101 -0
  227. package/dist/core/code/engine/core/ingestion/languages/dart/merge-bindings.js +42 -0
  228. package/dist/core/code/engine/core/ingestion/languages/dart/query.js +246 -0
  229. package/dist/core/code/engine/core/ingestion/languages/dart/receiver-binding.js +90 -0
  230. package/dist/core/code/engine/core/ingestion/languages/dart/scope-resolver.js +197 -0
  231. package/dist/core/code/engine/core/ingestion/languages/dart/signature-bindings.js +54 -0
  232. package/dist/core/code/engine/core/ingestion/languages/dart/simple-hooks.js +61 -0
  233. package/dist/core/code/engine/core/ingestion/languages/dart.js +138 -0
  234. package/dist/core/code/engine/core/ingestion/languages/go/arity-metadata.js +71 -0
  235. package/dist/core/code/engine/core/ingestion/languages/go/arity.js +17 -0
  236. package/dist/core/code/engine/core/ingestion/languages/go/cache-stats.js +21 -0
  237. package/dist/core/code/engine/core/ingestion/languages/go/captures.js +492 -0
  238. package/dist/core/code/engine/core/ingestion/languages/go/expand-wildcards.js +97 -0
  239. package/dist/core/code/engine/core/ingestion/languages/go/generic-type-parameters.js +146 -0
  240. package/dist/core/code/engine/core/ingestion/languages/go/import-decomposer.js +47 -0
  241. package/dist/core/code/engine/core/ingestion/languages/go/import-target.js +70 -0
  242. package/dist/core/code/engine/core/ingestion/languages/go/index.js +39 -0
  243. package/dist/core/code/engine/core/ingestion/languages/go/interface-impls.js +955 -0
  244. package/dist/core/code/engine/core/ingestion/languages/go/interpret.js +177 -0
  245. package/dist/core/code/engine/core/ingestion/languages/go/merge-bindings.js +21 -0
  246. package/dist/core/code/engine/core/ingestion/languages/go/method-owners.js +131 -0
  247. package/dist/core/code/engine/core/ingestion/languages/go/namespace-mirror.js +56 -0
  248. package/dist/core/code/engine/core/ingestion/languages/go/package-clause.js +79 -0
  249. package/dist/core/code/engine/core/ingestion/languages/go/package-siblings.js +83 -0
  250. package/dist/core/code/engine/core/ingestion/languages/go/query.js +298 -0
  251. package/dist/core/code/engine/core/ingestion/languages/go/range-binding.js +127 -0
  252. package/dist/core/code/engine/core/ingestion/languages/go/receiver-binding.js +24 -0
  253. package/dist/core/code/engine/core/ingestion/languages/go/scope-resolver.js +75 -0
  254. package/dist/core/code/engine/core/ingestion/languages/go/simple-hooks.js +31 -0
  255. package/dist/core/code/engine/core/ingestion/languages/go/type-binding.js +279 -0
  256. package/dist/core/code/engine/core/ingestion/languages/go.js +160 -0
  257. package/dist/core/code/engine/core/ingestion/languages/index.js +66 -0
  258. package/dist/core/code/engine/core/ingestion/languages/java/analysis-features.js +16 -0
  259. package/dist/core/code/engine/core/ingestion/languages/java/arity-metadata.js +43 -0
  260. package/dist/core/code/engine/core/ingestion/languages/java/arity.js +27 -0
  261. package/dist/core/code/engine/core/ingestion/languages/java/cache-stats.js +32 -0
  262. package/dist/core/code/engine/core/ingestion/languages/java/capture-side-channel.js +123 -0
  263. package/dist/core/code/engine/core/ingestion/languages/java/captures.js +791 -0
  264. package/dist/core/code/engine/core/ingestion/languages/java/import-decomposer.js +88 -0
  265. package/dist/core/code/engine/core/ingestion/languages/java/import-target.js +103 -0
  266. package/dist/core/code/engine/core/ingestion/languages/java/index.js +43 -0
  267. package/dist/core/code/engine/core/ingestion/languages/java/interpret.js +146 -0
  268. package/dist/core/code/engine/core/ingestion/languages/java/merge-bindings.js +43 -0
  269. package/dist/core/code/engine/core/ingestion/languages/java/package-facts.js +16 -0
  270. package/dist/core/code/engine/core/ingestion/languages/java/package-siblings.js +11 -0
  271. package/dist/core/code/engine/core/ingestion/languages/java/query.js +319 -0
  272. package/dist/core/code/engine/core/ingestion/languages/java/receiver-binding.js +98 -0
  273. package/dist/core/code/engine/core/ingestion/languages/java/scope-resolver.js +213 -0
  274. package/dist/core/code/engine/core/ingestion/languages/java/simple-hooks.js +39 -0
  275. package/dist/core/code/engine/core/ingestion/languages/java/spring-aop.js +53 -0
  276. package/dist/core/code/engine/core/ingestion/languages/java/spring-bean-metadata.js +11 -0
  277. package/dist/core/code/engine/core/ingestion/languages/java/spring-conditionals.js +52 -0
  278. package/dist/core/code/engine/core/ingestion/languages/java/spring-config-bindings.js +222 -0
  279. package/dist/core/code/engine/core/ingestion/languages/java/spring-di.js +165 -0
  280. package/dist/core/code/engine/core/ingestion/languages/java.js +192 -0
  281. package/dist/core/code/engine/core/ingestion/languages/javascript/arity.js +15 -0
  282. package/dist/core/code/engine/core/ingestion/languages/javascript/captures.js +1122 -0
  283. package/dist/core/code/engine/core/ingestion/languages/javascript/import-target.js +56 -0
  284. package/dist/core/code/engine/core/ingestion/languages/javascript/index.js +109 -0
  285. package/dist/core/code/engine/core/ingestion/languages/javascript/interpret.js +45 -0
  286. package/dist/core/code/engine/core/ingestion/languages/javascript/merge-bindings.js +21 -0
  287. package/dist/core/code/engine/core/ingestion/languages/javascript/query.js +659 -0
  288. package/dist/core/code/engine/core/ingestion/languages/javascript/scope-resolver.js +78 -0
  289. package/dist/core/code/engine/core/ingestion/languages/javascript/simple-hooks.js +44 -0
  290. package/dist/core/code/engine/core/ingestion/languages/jvm/package-facts.js +46 -0
  291. package/dist/core/code/engine/core/ingestion/languages/jvm/package-siblings.js +200 -0
  292. package/dist/core/code/engine/core/ingestion/languages/kotlin/arity-metadata.js +23 -0
  293. package/dist/core/code/engine/core/ingestion/languages/kotlin/arity.js +18 -0
  294. package/dist/core/code/engine/core/ingestion/languages/kotlin/cache-stats.js +21 -0
  295. package/dist/core/code/engine/core/ingestion/languages/kotlin/capture-side-channel.js +160 -0
  296. package/dist/core/code/engine/core/ingestion/languages/kotlin/captures.js +1262 -0
  297. package/dist/core/code/engine/core/ingestion/languages/kotlin/companion-scopes.js +72 -0
  298. package/dist/core/code/engine/core/ingestion/languages/kotlin/import-decomposer.js +40 -0
  299. package/dist/core/code/engine/core/ingestion/languages/kotlin/import-target.js +135 -0
  300. package/dist/core/code/engine/core/ingestion/languages/kotlin/index.js +26 -0
  301. package/dist/core/code/engine/core/ingestion/languages/kotlin/interpret.js +75 -0
  302. package/dist/core/code/engine/core/ingestion/languages/kotlin/merge-bindings.js +28 -0
  303. package/dist/core/code/engine/core/ingestion/languages/kotlin/owners.js +134 -0
  304. package/dist/core/code/engine/core/ingestion/languages/kotlin/package-facts.js +16 -0
  305. package/dist/core/code/engine/core/ingestion/languages/kotlin/package-siblings.js +11 -0
  306. package/dist/core/code/engine/core/ingestion/languages/kotlin/query.js +243 -0
  307. package/dist/core/code/engine/core/ingestion/languages/kotlin/receiver-binding.js +103 -0
  308. package/dist/core/code/engine/core/ingestion/languages/kotlin/scope-resolver.js +207 -0
  309. package/dist/core/code/engine/core/ingestion/languages/kotlin/simple-hooks.js +42 -0
  310. package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-aop.js +68 -0
  311. package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-bean-metadata.js +11 -0
  312. package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-conditionals.js +53 -0
  313. package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-di.js +304 -0
  314. package/dist/core/code/engine/core/ingestion/languages/kotlin.js +189 -0
  315. package/dist/core/code/engine/core/ingestion/languages/php/arity-metadata.js +66 -0
  316. package/dist/core/code/engine/core/ingestion/languages/php/arity.js +43 -0
  317. package/dist/core/code/engine/core/ingestion/languages/php/cache-stats.js +32 -0
  318. package/dist/core/code/engine/core/ingestion/languages/php/captures.js +1166 -0
  319. package/dist/core/code/engine/core/ingestion/languages/php/import-decomposer.js +238 -0
  320. package/dist/core/code/engine/core/ingestion/languages/php/import-target.js +213 -0
  321. package/dist/core/code/engine/core/ingestion/languages/php/index.js +85 -0
  322. package/dist/core/code/engine/core/ingestion/languages/php/interpret.js +256 -0
  323. package/dist/core/code/engine/core/ingestion/languages/php/merge-bindings.js +50 -0
  324. package/dist/core/code/engine/core/ingestion/languages/php/namespace-siblings.js +353 -0
  325. package/dist/core/code/engine/core/ingestion/languages/php/query.js +391 -0
  326. package/dist/core/code/engine/core/ingestion/languages/php/receiver-binding.js +135 -0
  327. package/dist/core/code/engine/core/ingestion/languages/php/scope-resolver.js +361 -0
  328. package/dist/core/code/engine/core/ingestion/languages/php/simple-hooks.js +116 -0
  329. package/dist/core/code/engine/core/ingestion/languages/php.js +302 -0
  330. package/dist/core/code/engine/core/ingestion/languages/python/arity-metadata.js +49 -0
  331. package/dist/core/code/engine/core/ingestion/languages/python/arity.js +41 -0
  332. package/dist/core/code/engine/core/ingestion/languages/python/cache-stats.js +34 -0
  333. package/dist/core/code/engine/core/ingestion/languages/python/captures.js +299 -0
  334. package/dist/core/code/engine/core/ingestion/languages/python/depends-references.js +68 -0
  335. package/dist/core/code/engine/core/ingestion/languages/python/import-decomposer.js +115 -0
  336. package/dist/core/code/engine/core/ingestion/languages/python/import-target.js +440 -0
  337. package/dist/core/code/engine/core/ingestion/languages/python/index-stats.js +30 -0
  338. package/dist/core/code/engine/core/ingestion/languages/python/index.js +96 -0
  339. package/dist/core/code/engine/core/ingestion/languages/python/interpret.js +430 -0
  340. package/dist/core/code/engine/core/ingestion/languages/python/merge-bindings.js +47 -0
  341. package/dist/core/code/engine/core/ingestion/languages/python/query.js +323 -0
  342. package/dist/core/code/engine/core/ingestion/languages/python/receiver-binding.js +310 -0
  343. package/dist/core/code/engine/core/ingestion/languages/python/scope-resolver.js +80 -0
  344. package/dist/core/code/engine/core/ingestion/languages/python/simple-hooks.js +53 -0
  345. package/dist/core/code/engine/core/ingestion/languages/python.js +140 -0
  346. package/dist/core/code/engine/core/ingestion/languages/ruby/arity.js +41 -0
  347. package/dist/core/code/engine/core/ingestion/languages/ruby/cache-stats.js +21 -0
  348. package/dist/core/code/engine/core/ingestion/languages/ruby/captures.js +864 -0
  349. package/dist/core/code/engine/core/ingestion/languages/ruby/import-target.js +88 -0
  350. package/dist/core/code/engine/core/ingestion/languages/ruby/index.js +29 -0
  351. package/dist/core/code/engine/core/ingestion/languages/ruby/interpret.js +115 -0
  352. package/dist/core/code/engine/core/ingestion/languages/ruby/merge-bindings.js +21 -0
  353. package/dist/core/code/engine/core/ingestion/languages/ruby/query.js +349 -0
  354. package/dist/core/code/engine/core/ingestion/languages/ruby/receiver-binding.js +70 -0
  355. package/dist/core/code/engine/core/ingestion/languages/ruby/scope-resolver.js +263 -0
  356. package/dist/core/code/engine/core/ingestion/languages/ruby/simple-hooks.js +68 -0
  357. package/dist/core/code/engine/core/ingestion/languages/ruby.js +215 -0
  358. package/dist/core/code/engine/core/ingestion/languages/rust/arity.js +16 -0
  359. package/dist/core/code/engine/core/ingestion/languages/rust/cache-stats.js +21 -0
  360. package/dist/core/code/engine/core/ingestion/languages/rust/captures.js +304 -0
  361. package/dist/core/code/engine/core/ingestion/languages/rust/import-decomposer.js +167 -0
  362. package/dist/core/code/engine/core/ingestion/languages/rust/import-target.js +108 -0
  363. package/dist/core/code/engine/core/ingestion/languages/rust/index.js +29 -0
  364. package/dist/core/code/engine/core/ingestion/languages/rust/interpret.js +201 -0
  365. package/dist/core/code/engine/core/ingestion/languages/rust/merge-bindings.js +21 -0
  366. package/dist/core/code/engine/core/ingestion/languages/rust/method-owners.js +76 -0
  367. package/dist/core/code/engine/core/ingestion/languages/rust/module-path.js +222 -0
  368. package/dist/core/code/engine/core/ingestion/languages/rust/qualified-call.js +482 -0
  369. package/dist/core/code/engine/core/ingestion/languages/rust/query.js +280 -0
  370. package/dist/core/code/engine/core/ingestion/languages/rust/range-binding.js +687 -0
  371. package/dist/core/code/engine/core/ingestion/languages/rust/receiver-binding.js +148 -0
  372. package/dist/core/code/engine/core/ingestion/languages/rust/scope-resolver.js +151 -0
  373. package/dist/core/code/engine/core/ingestion/languages/rust/simple-hooks.js +32 -0
  374. package/dist/core/code/engine/core/ingestion/languages/rust.js +183 -0
  375. package/dist/core/code/engine/core/ingestion/languages/swift/arity-metadata.js +44 -0
  376. package/dist/core/code/engine/core/ingestion/languages/swift/arity.js +45 -0
  377. package/dist/core/code/engine/core/ingestion/languages/swift/base-type.js +30 -0
  378. package/dist/core/code/engine/core/ingestion/languages/swift/cache-stats.js +32 -0
  379. package/dist/core/code/engine/core/ingestion/languages/swift/captures.js +594 -0
  380. package/dist/core/code/engine/core/ingestion/languages/swift/conditional-directive-preprocess.js +256 -0
  381. package/dist/core/code/engine/core/ingestion/languages/swift/implicit-imports.js +60 -0
  382. package/dist/core/code/engine/core/ingestion/languages/swift/import-decomposer.js +87 -0
  383. package/dist/core/code/engine/core/ingestion/languages/swift/import-target.js +84 -0
  384. package/dist/core/code/engine/core/ingestion/languages/swift/index.js +56 -0
  385. package/dist/core/code/engine/core/ingestion/languages/swift/interpret.js +93 -0
  386. package/dist/core/code/engine/core/ingestion/languages/swift/merge-bindings.js +51 -0
  387. package/dist/core/code/engine/core/ingestion/languages/swift/query.js +226 -0
  388. package/dist/core/code/engine/core/ingestion/languages/swift/receiver-binding.js +169 -0
  389. package/dist/core/code/engine/core/ingestion/languages/swift/scope-resolver.js +192 -0
  390. package/dist/core/code/engine/core/ingestion/languages/swift/sibling-type-bindings.js +68 -0
  391. package/dist/core/code/engine/core/ingestion/languages/swift/signature-bindings.js +69 -0
  392. package/dist/core/code/engine/core/ingestion/languages/swift/simple-hooks.js +65 -0
  393. package/dist/core/code/engine/core/ingestion/languages/swift/target-grouping.js +97 -0
  394. package/dist/core/code/engine/core/ingestion/languages/swift/target-siblings.js +74 -0
  395. package/dist/core/code/engine/core/ingestion/languages/swift.js +246 -0
  396. package/dist/core/code/engine/core/ingestion/languages/typescript/arity-metadata.js +106 -0
  397. package/dist/core/code/engine/core/ingestion/languages/typescript/arity.js +57 -0
  398. package/dist/core/code/engine/core/ingestion/languages/typescript/array-callback.js +58 -0
  399. package/dist/core/code/engine/core/ingestion/languages/typescript/cache-stats.js +34 -0
  400. package/dist/core/code/engine/core/ingestion/languages/typescript/captures.js +956 -0
  401. package/dist/core/code/engine/core/ingestion/languages/typescript/cjs-export-assignment.js +535 -0
  402. package/dist/core/code/engine/core/ingestion/languages/typescript/cjs-module-exports.js +196 -0
  403. package/dist/core/code/engine/core/ingestion/languages/typescript/import-decomposer.js +374 -0
  404. package/dist/core/code/engine/core/ingestion/languages/typescript/import-target.js +65 -0
  405. package/dist/core/code/engine/core/ingestion/languages/typescript/index.js +108 -0
  406. package/dist/core/code/engine/core/ingestion/languages/typescript/interpret.js +344 -0
  407. package/dist/core/code/engine/core/ingestion/languages/typescript/merge-bindings.js +161 -0
  408. package/dist/core/code/engine/core/ingestion/languages/typescript/nuxt-auto-imports.js +325 -0
  409. package/dist/core/code/engine/core/ingestion/languages/typescript/query.js +1328 -0
  410. package/dist/core/code/engine/core/ingestion/languages/typescript/receiver-binding.js +201 -0
  411. package/dist/core/code/engine/core/ingestion/languages/typescript/scope-resolver.js +293 -0
  412. package/dist/core/code/engine/core/ingestion/languages/typescript/simple-hooks.js +139 -0
  413. package/dist/core/code/engine/core/ingestion/languages/typescript.js +455 -0
  414. package/dist/core/code/engine/core/ingestion/languages/vue/captures.js +70 -0
  415. package/dist/core/code/engine/core/ingestion/languages/vue/import-target.js +61 -0
  416. package/dist/core/code/engine/core/ingestion/languages/vue/index.js +55 -0
  417. package/dist/core/code/engine/core/ingestion/languages/vue/scope-resolver.js +295 -0
  418. package/dist/core/code/engine/core/ingestion/languages/vue.js +96 -0
  419. package/dist/core/code/engine/core/ingestion/local-symbol-pruner.js +68 -0
  420. package/dist/core/code/engine/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
  421. package/dist/core/code/engine/core/ingestion/method-extractors/configs/csharp.js +290 -0
  422. package/dist/core/code/engine/core/ingestion/method-extractors/configs/dart.js +392 -0
  423. package/dist/core/code/engine/core/ingestion/method-extractors/configs/go.js +179 -0
  424. package/dist/core/code/engine/core/ingestion/method-extractors/configs/jvm.js +350 -0
  425. package/dist/core/code/engine/core/ingestion/method-extractors/configs/php.js +306 -0
  426. package/dist/core/code/engine/core/ingestion/method-extractors/configs/python.js +312 -0
  427. package/dist/core/code/engine/core/ingestion/method-extractors/configs/ruby.js +289 -0
  428. package/dist/core/code/engine/core/ingestion/method-extractors/configs/rust.js +198 -0
  429. package/dist/core/code/engine/core/ingestion/method-extractors/configs/swift.js +286 -0
  430. package/dist/core/code/engine/core/ingestion/method-extractors/configs/typescript-javascript.js +341 -0
  431. package/dist/core/code/engine/core/ingestion/method-extractors/generic.js +209 -0
  432. package/dist/core/code/engine/core/ingestion/method-types.js +3 -0
  433. package/dist/core/code/engine/core/ingestion/model/field-registry.js +41 -0
  434. package/dist/core/code/engine/core/ingestion/model/index.js +52 -0
  435. package/dist/core/code/engine/core/ingestion/model/method-registry.js +138 -0
  436. package/dist/core/code/engine/core/ingestion/model/owned-members-lookup.js +46 -0
  437. package/dist/core/code/engine/core/ingestion/model/registration-table.js +234 -0
  438. package/dist/core/code/engine/core/ingestion/model/resolve.js +183 -0
  439. package/dist/core/code/engine/core/ingestion/model/scope-resolution-indexes.js +43 -0
  440. package/dist/core/code/engine/core/ingestion/model/semantic-model.js +179 -0
  441. package/dist/core/code/engine/core/ingestion/model/symbol-table.js +216 -0
  442. package/dist/core/code/engine/core/ingestion/model/type-registry.js +84 -0
  443. package/dist/core/code/engine/core/ingestion/mro-processor.js +709 -0
  444. package/dist/core/code/engine/core/ingestion/parsing-processor.js +312 -0
  445. package/dist/core/code/engine/core/ingestion/pipeline-phases/communities.js +69 -0
  446. package/dist/core/code/engine/core/ingestion/pipeline-phases/cross-file.js +71 -0
  447. package/dist/core/code/engine/core/ingestion/pipeline-phases/di.js +338 -0
  448. package/dist/core/code/engine/core/ingestion/pipeline-phases/http-api-calls.js +312 -0
  449. package/dist/core/code/engine/core/ingestion/pipeline-phases/index.js +54 -0
  450. package/dist/core/code/engine/core/ingestion/pipeline-phases/mro.js +40 -0
  451. package/dist/core/code/engine/core/ingestion/pipeline-phases/orm.js +78 -0
  452. package/dist/core/code/engine/core/ingestion/pipeline-phases/parse-impl.js +1286 -0
  453. package/dist/core/code/engine/core/ingestion/pipeline-phases/parse.js +41 -0
  454. package/dist/core/code/engine/core/ingestion/pipeline-phases/processes.js +193 -0
  455. package/dist/core/code/engine/core/ingestion/pipeline-phases/prune-local-symbols.js +29 -0
  456. package/dist/core/code/engine/core/ingestion/pipeline-phases/registry.js +52 -0
  457. package/dist/core/code/engine/core/ingestion/pipeline-phases/routes.js +409 -0
  458. package/dist/core/code/engine/core/ingestion/pipeline-phases/rpc-edges.js +301 -0
  459. package/dist/core/code/engine/core/ingestion/pipeline-phases/runner.js +207 -0
  460. package/dist/core/code/engine/core/ingestion/pipeline-phases/scan.js +49 -0
  461. package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-aop.js +442 -0
  462. package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-auto-configuration.js +264 -0
  463. package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-config.js +440 -0
  464. package/dist/core/code/engine/core/ingestion/pipeline-phases/structure.js +38 -0
  465. package/dist/core/code/engine/core/ingestion/pipeline-phases/tools.js +89 -0
  466. package/dist/core/code/engine/core/ingestion/pipeline-phases/types.js +40 -0
  467. package/dist/core/code/engine/core/ingestion/pipeline.js +152 -0
  468. package/dist/core/code/engine/core/ingestion/process-processor.js +325 -0
  469. package/dist/core/code/engine/core/ingestion/resolve-references.js +205 -0
  470. package/dist/core/code/engine/core/ingestion/route-extractors/constant-resolver.js +135 -0
  471. package/dist/core/code/engine/core/ingestion/route-extractors/django-root-discovery.js +221 -0
  472. package/dist/core/code/engine/core/ingestion/route-extractors/django.js +428 -0
  473. package/dist/core/code/engine/core/ingestion/route-extractors/expo.js +39 -0
  474. package/dist/core/code/engine/core/ingestion/route-extractors/fastapi-router-bindings.js +264 -0
  475. package/dist/core/code/engine/core/ingestion/route-extractors/laravel.js +501 -0
  476. package/dist/core/code/engine/core/ingestion/route-extractors/middleware.js +175 -0
  477. package/dist/core/code/engine/core/ingestion/route-extractors/nextjs.js +81 -0
  478. package/dist/core/code/engine/core/ingestion/route-extractors/php.js +25 -0
  479. package/dist/core/code/engine/core/ingestion/route-extractors/python-const-resolver.js +307 -0
  480. package/dist/core/code/engine/core/ingestion/route-extractors/response-shapes.js +299 -0
  481. package/dist/core/code/engine/core/ingestion/route-extractors/route-path.js +71 -0
  482. package/dist/core/code/engine/core/ingestion/route-extractors/spring-shared.js +310 -0
  483. package/dist/core/code/engine/core/ingestion/route-extractors/spring.js +441 -0
  484. package/dist/core/code/engine/core/ingestion/scope-extractor-bridge.js +60 -0
  485. package/dist/core/code/engine/core/ingestion/scope-extractor.js +1373 -0
  486. package/dist/core/code/engine/core/ingestion/scope-resolution/contract/scope-resolver.js +282 -0
  487. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +72 -0
  488. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/edges.js +194 -0
  489. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/ids.js +472 -0
  490. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/imports-to-edges.js +49 -0
  491. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/method-dispatch.js +43 -0
  492. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +274 -0
  493. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +93 -0
  494. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/callable-value-flow.js +1240 -0
  495. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/compound-receiver.js +1174 -0
  496. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/free-call-fallback.js +873 -0
  497. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/imported-return-types.js +226 -0
  498. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/mro.js +107 -0
  499. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/overload-narrowing.js +441 -0
  500. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/property-dispatch.js +122 -0
  501. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +1720 -0
  502. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/phase.js +395 -0
  503. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +208 -0
  504. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/registry.js +49 -0
  505. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/run.js +632 -0
  506. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/validate-bindings-immutability.js +112 -0
  507. package/dist/core/code/engine/core/ingestion/scope-resolution/resolution-outcome.js +41 -0
  508. package/dist/core/code/engine/core/ingestion/scope-resolution/scope/namespace-targets.js +81 -0
  509. package/dist/core/code/engine/core/ingestion/scope-resolution/scope/walkers.js +1835 -0
  510. package/dist/core/code/engine/core/ingestion/scope-resolution/unresolved-receivers.js +242 -0
  511. package/dist/core/code/engine/core/ingestion/scope-resolution/utils/definition-id.js +22 -0
  512. package/dist/core/code/engine/core/ingestion/scope-resolution/workspace-index.js +151 -0
  513. package/dist/core/code/engine/core/ingestion/structure-processor.js +40 -0
  514. package/dist/core/code/engine/core/ingestion/tree-sitter-queries.js +2244 -0
  515. package/dist/core/code/engine/core/ingestion/ts-js-hoc-utils.js +115 -0
  516. package/dist/core/code/engine/core/ingestion/type-env.js +1136 -0
  517. package/dist/core/code/engine/core/ingestion/type-extractors/c-cpp.js +555 -0
  518. package/dist/core/code/engine/core/ingestion/type-extractors/csharp.js +570 -0
  519. package/dist/core/code/engine/core/ingestion/type-extractors/dart.js +372 -0
  520. package/dist/core/code/engine/core/ingestion/type-extractors/go.js +508 -0
  521. package/dist/core/code/engine/core/ingestion/type-extractors/jvm.js +875 -0
  522. package/dist/core/code/engine/core/ingestion/type-extractors/php.js +537 -0
  523. package/dist/core/code/engine/core/ingestion/type-extractors/python.js +477 -0
  524. package/dist/core/code/engine/core/ingestion/type-extractors/ruby.js +380 -0
  525. package/dist/core/code/engine/core/ingestion/type-extractors/rust.js +502 -0
  526. package/dist/core/code/engine/core/ingestion/type-extractors/shared.js +843 -0
  527. package/dist/core/code/engine/core/ingestion/type-extractors/swift.js +490 -0
  528. package/dist/core/code/engine/core/ingestion/type-extractors/types.js +2 -0
  529. package/dist/core/code/engine/core/ingestion/type-extractors/typescript.js +690 -0
  530. package/dist/core/code/engine/core/ingestion/utils/ast-helpers.js +1693 -0
  531. package/dist/core/code/engine/core/ingestion/utils/call-analysis.js +779 -0
  532. package/dist/core/code/engine/core/ingestion/utils/callable-flow-captures.js +932 -0
  533. package/dist/core/code/engine/core/ingestion/utils/callable-labels.js +49 -0
  534. package/dist/core/code/engine/core/ingestion/utils/deferred-resolution-profile.js +151 -0
  535. package/dist/core/code/engine/core/ingestion/utils/effective-ram.js +67 -0
  536. package/dist/core/code/engine/core/ingestion/utils/env.js +60 -0
  537. package/dist/core/code/engine/core/ingestion/utils/event-loop.js +9 -0
  538. package/dist/core/code/engine/core/ingestion/utils/graph-sort.js +103 -0
  539. package/dist/core/code/engine/core/ingestion/utils/heap-probe.js +45 -0
  540. package/dist/core/code/engine/core/ingestion/utils/heritage-marker.js +47 -0
  541. package/dist/core/code/engine/core/ingestion/utils/line-base.js +24 -0
  542. package/dist/core/code/engine/core/ingestion/utils/max-file-size.js +59 -0
  543. package/dist/core/code/engine/core/ingestion/utils/method-props.js +198 -0
  544. package/dist/core/code/engine/core/ingestion/utils/qualified-name.js +73 -0
  545. package/dist/core/code/engine/core/ingestion/utils/receiver-chain-captures.js +60 -0
  546. package/dist/core/code/engine/core/ingestion/utils/receiver-chain-codec.js +188 -0
  547. package/dist/core/code/engine/core/ingestion/utils/scope-tree-walk.js +36 -0
  548. package/dist/core/code/engine/core/ingestion/utils/symbol-labels.js +48 -0
  549. package/dist/core/code/engine/core/ingestion/utils/template-arguments.js +187 -0
  550. package/dist/core/code/engine/core/ingestion/utils/type-parameters.js +209 -0
  551. package/dist/core/code/engine/core/ingestion/utils/verbose.js +6 -0
  552. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/c-cpp.js +133 -0
  553. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/csharp.js +66 -0
  554. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/dart.js +111 -0
  555. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/go.js +153 -0
  556. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/jvm.js +145 -0
  557. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/php.js +61 -0
  558. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/python.js +104 -0
  559. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/ruby.js +55 -0
  560. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/rust.js +79 -0
  561. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/swift.js +91 -0
  562. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/typescript-javascript.js +86 -0
  563. package/dist/core/code/engine/core/ingestion/variable-extractors/generic.js +111 -0
  564. package/dist/core/code/engine/core/ingestion/variable-types.js +3 -0
  565. package/dist/core/code/engine/core/ingestion/vue-sfc-extractor.js +544 -0
  566. package/dist/core/code/engine/core/ingestion/workers/callable-id.js +122 -0
  567. package/dist/core/code/engine/core/ingestion/workers/clone-safety.js +470 -0
  568. package/dist/core/code/engine/core/ingestion/workers/parse-worker.js +2456 -0
  569. package/dist/core/code/engine/core/ingestion/workers/post-result.js +90 -0
  570. package/dist/core/code/engine/core/ingestion/workers/quarantine.js +41 -0
  571. package/dist/core/code/engine/core/ingestion/workers/result-merge.js +59 -0
  572. package/dist/core/code/engine/core/ingestion/workers/worker-pool.js +1725 -0
  573. package/dist/core/code/engine/core/ingestion/workspace-config.js +139 -0
  574. package/dist/core/code/engine/core/lbug/conn-lock.js +72 -0
  575. package/dist/core/code/engine/core/lbug/csv-generator.js +710 -0
  576. package/dist/core/code/engine/core/lbug/cypher-escape.js +24 -0
  577. package/dist/core/code/engine/core/lbug/extension-load-error.js +339 -0
  578. package/dist/core/code/engine/core/lbug/extension-loader.js +261 -0
  579. package/dist/core/code/engine/core/lbug/graph-emit-sink.js +584 -0
  580. package/dist/core/code/engine/core/lbug/lbug-adapter.js +2703 -0
  581. package/dist/core/code/engine/core/lbug/lbug-config.js +1029 -0
  582. package/dist/core/code/engine/core/lbug/native-check.js +435 -0
  583. package/dist/core/code/engine/core/lbug/pool-adapter.js +973 -0
  584. package/dist/core/code/engine/core/lbug/query-params.js +25 -0
  585. package/dist/core/code/engine/core/lbug/query-result-utils.js +31 -0
  586. package/dist/core/code/engine/core/lbug/rel-pair-routing.js +373 -0
  587. package/dist/core/code/engine/core/lbug/schema.js +771 -0
  588. package/dist/core/code/engine/core/lbug/shutdown-helpers.js +40 -0
  589. package/dist/core/code/engine/core/lbug/sidecar-recovery.js +716 -0
  590. package/dist/core/code/engine/core/lbug/stdio-capture.js +49 -0
  591. package/dist/core/code/engine/core/lbug/sync-csv-writer.js +115 -0
  592. package/dist/core/code/engine/core/lbug/wal-checkpoint-driver.js +215 -0
  593. package/dist/core/code/engine/core/lbug/wal-driver-state.js +28 -0
  594. package/dist/core/code/engine/core/logger.js +339 -0
  595. package/dist/core/code/engine/core/platform/capabilities.js +91 -0
  596. package/dist/core/code/engine/core/run-analyze.js +1098 -0
  597. package/dist/core/code/engine/core/tree-sitter/parser-loader.js +281 -0
  598. package/dist/core/code/engine/core/tree-sitter/safe-parse.js +258 -0
  599. package/dist/core/code/engine/core/tree-sitter/vendored-grammars.js +64 -0
  600. package/dist/core/code/engine/lib/utils.js +121 -0
  601. package/dist/core/code/engine/mcp/core/lbug-adapter.js +27 -0
  602. package/dist/core/code/engine/mcp/local/aop-metadata.js +230 -0
  603. package/dist/core/code/engine/mcp/local/bean-metadata.js +49 -0
  604. package/dist/core/code/engine/mcp/local/limits.js +15 -0
  605. package/dist/core/code/engine/mcp/local/line-display.js +6 -0
  606. package/dist/core/code/engine/mcp/local/local-backend.js +4142 -0
  607. package/dist/core/code/engine/storage/branch-index.js +72 -0
  608. package/dist/core/code/engine/storage/file-hash.js +95 -0
  609. package/dist/core/code/engine/storage/fs-atomic.js +34 -0
  610. package/dist/core/code/engine/storage/git.js +555 -0
  611. package/dist/core/code/engine/storage/index-lock.js +664 -0
  612. package/dist/core/code/engine/storage/parse-cache.js +650 -0
  613. package/dist/core/code/engine/storage/parsedfile-store.js +620 -0
  614. package/dist/core/code/engine/storage/repo-manager.js +1061 -0
  615. package/dist/core/code/engine/storage/scope-index-store.js +247 -0
  616. package/dist/core/code/engine/types/pipeline.js +2 -0
  617. package/dist/core/code/scripts/install-duckdb-extension.mjs +125 -0
  618. package/dist/core/code/scripts/resolve-analyze-cmd.cjs +346 -0
  619. package/dist/core/code/shared/graph/types.js +8 -0
  620. package/dist/core/code/shared/index.js +105 -0
  621. package/dist/core/code/shared/integrations/circuit-breaker.js +242 -0
  622. package/dist/core/code/shared/integrations/resilient-fetch.js +224 -0
  623. package/dist/core/code/shared/integrations/retry.js +70 -0
  624. package/dist/core/code/shared/integrations/understand-quickly.js +145 -0
  625. package/dist/core/code/shared/language-detection.js +162 -0
  626. package/dist/core/code/shared/languages.js +27 -0
  627. package/dist/core/code/shared/lbug/schema-constants.js +98 -0
  628. package/dist/core/code/shared/mro-strategy.js +2 -0
  629. package/dist/core/code/shared/pipeline.js +5 -0
  630. package/dist/core/code/shared/scope-resolution/callable-flow-site.js +11 -0
  631. package/dist/core/code/shared/scope-resolution/def-index.js +53 -0
  632. package/dist/core/code/shared/scope-resolution/evidence-weights.js +87 -0
  633. package/dist/core/code/shared/scope-resolution/finalize-algorithm.js +807 -0
  634. package/dist/core/code/shared/scope-resolution/language-classification.js +46 -0
  635. package/dist/core/code/shared/scope-resolution/method-dispatch-index.js +100 -0
  636. package/dist/core/code/shared/scope-resolution/module-scope-index.js +59 -0
  637. package/dist/core/code/shared/scope-resolution/origin-priority.js +23 -0
  638. package/dist/core/code/shared/scope-resolution/parsed-file.js +54 -0
  639. package/dist/core/code/shared/scope-resolution/position-index.js +136 -0
  640. package/dist/core/code/shared/scope-resolution/qualified-name-index.js +77 -0
  641. package/dist/core/code/shared/scope-resolution/reference-site.js +24 -0
  642. package/dist/core/code/shared/scope-resolution/registries/class-registry.js +32 -0
  643. package/dist/core/code/shared/scope-resolution/registries/context.js +52 -0
  644. package/dist/core/code/shared/scope-resolution/registries/evidence.js +152 -0
  645. package/dist/core/code/shared/scope-resolution/registries/field-registry.js +33 -0
  646. package/dist/core/code/shared/scope-resolution/registries/lookup-core.js +392 -0
  647. package/dist/core/code/shared/scope-resolution/registries/lookup-qualified.js +58 -0
  648. package/dist/core/code/shared/scope-resolution/registries/macro-registry.js +34 -0
  649. package/dist/core/code/shared/scope-resolution/registries/method-registry.js +34 -0
  650. package/dist/core/code/shared/scope-resolution/registries/tie-breaks.js +63 -0
  651. package/dist/core/code/shared/scope-resolution/resolve-type-ref.js +128 -0
  652. package/dist/core/code/shared/scope-resolution/scope-id.js +49 -0
  653. package/dist/core/code/shared/scope-resolution/scope-tree.js +225 -0
  654. package/dist/core/code/shared/scope-resolution/symbol-definition.js +12 -0
  655. package/dist/core/code/shared/scope-resolution/types.js +25 -0
  656. package/dist/core/code/shared/test-helpers.js +17 -0
  657. package/dist/core/code/vendor/leiden/index.cjs +355 -0
  658. package/dist/core/code/vendor/leiden/utils.cjs +419 -0
  659. package/dist/core/timeline/cli.d.ts.map +1 -1
  660. package/dist/core/timeline/cli.js +13 -6
  661. package/dist/core/timeline/cli.js.map +1 -1
  662. package/dist/core/timeline/debris.d.ts +20 -0
  663. package/dist/core/timeline/debris.d.ts.map +1 -0
  664. package/dist/core/timeline/debris.js +124 -0
  665. package/dist/core/timeline/debris.js.map +1 -0
  666. package/dist/core/timeline/hook-runner.d.ts.map +1 -1
  667. package/dist/core/timeline/hook-runner.js +3 -1
  668. package/dist/core/timeline/hook-runner.js.map +1 -1
  669. package/dist/core/timeline/hooks.d.ts.map +1 -1
  670. package/dist/core/timeline/hooks.js +13 -5
  671. package/dist/core/timeline/hooks.js.map +1 -1
  672. package/dist/core/timeline/installer.d.ts +2 -0
  673. package/dist/core/timeline/installer.d.ts.map +1 -1
  674. package/dist/core/timeline/installer.js +12 -0
  675. package/dist/core/timeline/installer.js.map +1 -1
  676. package/dist/core/timeline/project-root.d.ts +21 -0
  677. package/dist/core/timeline/project-root.d.ts.map +1 -0
  678. package/dist/core/timeline/project-root.js +83 -0
  679. package/dist/core/timeline/project-root.js.map +1 -0
  680. package/package.json +1 -1
@@ -0,0 +1,1373 @@
1
+ "use strict";
2
+ /**
3
+ * `ScopeExtractor` — the central, source-agnostic driver that turns a
4
+ * language provider's `CaptureMatch[]` into a `ParsedFile`
5
+ * (RFC §5.3 + §3.2 Phase 1; Ring 2 PKG #919).
6
+ *
7
+ * Exactly one entry point: `extract(matches, filePath, provider) → ParsedFile`.
8
+ * Runs a five-pass pipeline over the matches. Each pass is internal; the
9
+ * public contract is the output `ParsedFile`.
10
+ *
11
+ * ## Design principles
12
+ *
13
+ * - **Source-agnostic.** Consumes `CaptureMatch[]` from providers;
14
+ * doesn't know whether they came from tree-sitter queries or COBOL's
15
+ * regex tagger. No `Tree` / `SyntaxNode` types leak into this file.
16
+ * - **One AST walk per language.** Providers do the AST walk inside
17
+ * their `emitScopeCaptures` hook; this driver does zero further
18
+ * traversal — it consumes captures only.
19
+ * - **Pure-ish.** The extractor itself is pure (same matches →
20
+ * same ParsedFile) when providers are pure. No side effects, no I/O.
21
+ * - **Centralized invariant enforcement.** Structural invariants on the
22
+ * scope tree (non-module has parent; parent contains child; siblings
23
+ * don't overlap) are enforced by `buildScopeTree` from Ring 2 SHARED
24
+ * (#912). Malformed inputs throw `ScopeTreeInvariantError`.
25
+ *
26
+ * ## The five passes
27
+ *
28
+ * 1. **Build scope tree.** Walk `@scope.*` matches. For each, consult
29
+ * `provider.resolveScopeKind` (default: suffix of the capture name).
30
+ * Derive parent by lexical-range containment. Hand the resulting
31
+ * `Scope[]` to `buildScopeTree` for validation.
32
+ * 2. **Attach declarations + local bindings.** Walk `@declaration.*`
33
+ * matches. For each, build a `SymbolDefinition` and attach it to
34
+ * `provider.bindingScopeFor` (default: innermost containing scope)
35
+ * as `ownedDefs` + a local `BindingRef { origin: 'local' }`.
36
+ * 3. **Collect raw imports.** Walk `@import.*` matches. Call
37
+ * `provider.interpretImport` per match; attach the returned
38
+ * `ParsedImport` to the ParsedFile (not to any `Scope` — finalize
39
+ * reconstructs the owning scope via `provider.importOwningScope`
40
+ * during Phase 2).
41
+ * 4. **Collect type bindings.** Walk `@type-binding.*` matches. Call
42
+ * `provider.interpretTypeBinding` per match. Attach the resulting
43
+ * `TypeRef` to the innermost containing scope's `typeBindings`
44
+ * (or override via `provider.bindingScopeFor` if set).
45
+ * 5. **Collect reference sites.** Walk `@reference.*` matches. Emit
46
+ * one `ReferenceSite` per match. Classify call form via
47
+ * `provider.classifyCallForm` (default: the capture's sub-tag if
48
+ * present; else `'free'`).
49
+ *
50
+ * ## What gets attached where
51
+ *
52
+ * - `Scope.bindings` — **local bindings only** at this stage (Pass 2).
53
+ * Finalize (#915) merges imports/wildcards on top.
54
+ * - `Scope.ownedDefs` — declarations structurally owned by this scope.
55
+ * - `Scope.typeBindings` — local type facts (parameter annotations, `self`).
56
+ * - `Scope.imports` — empty here. Populated by the finalize algorithm
57
+ * when it resolves `ParsedImport.targetRaw`.
58
+ * - `ParsedFile.parsedImports` — every raw import in this file.
59
+ * - `ParsedFile.localDefs` — flattened union of `Scope.ownedDefs`.
60
+ * - `ParsedFile.referenceSites` — pre-resolution usage facts.
61
+ */
62
+ Object.defineProperty(exports, "__esModule", { value: true });
63
+ exports.extract = extract;
64
+ exports.selectNodeBearingDef = selectNodeBearingDef;
65
+ const index_js_1 = require("../../../shared/index.js");
66
+ const receiver_chain_codec_js_1 = require("./utils/receiver-chain-codec.js");
67
+ const template_arguments_js_1 = require("./utils/template-arguments.js");
68
+ const type_parameters_js_1 = require("./utils/type-parameters.js");
69
+ // ─── Public entry point ─────────────────────────────────────────────────────
70
+ /**
71
+ * Drive the five extraction passes and return a `ParsedFile`.
72
+ *
73
+ * Throws `ScopeTreeInvariantError` (from #912) when the provider emits
74
+ * captures that violate structural scope invariants (e.g., overlapping
75
+ * sibling scopes). When no `@scope.module` capture is present, a
76
+ * synthetic Module scope is created spanning all captures, and orphan
77
+ * non-Module scopes are re-parented under it. This enables indexing of
78
+ * files where tree-sitter produces an ERROR root (e.g., complex .phtml
79
+ * templates with mixed PHP/HTML/JS).
80
+ */
81
+ function extract(matches, filePath, provider) {
82
+ // Partition matches by topic up front — one linear pass over the input.
83
+ const partitioned = partitionByTopic(matches);
84
+ // ── Pass 1: build the scope tree ─────────────────────────────────────
85
+ const scopeDrafts = pass1BuildScopes(partitioned.scope, filePath, provider);
86
+ const moduleScope = ensureModuleScope(scopeDrafts, filePath, matches);
87
+ // Re-parent orphan drafts (parent === null, non-Module) under the
88
+ // Module scope. Replaces drafts with new ones carrying the correct
89
+ // parent — runs before content passes so bindings/ownedDefs are empty.
90
+ for (let i = 0; i < scopeDrafts.length; i++) {
91
+ const d = scopeDrafts[i];
92
+ if (d.parent === null && d.kind !== 'Module') {
93
+ // `ownsReceivers` must be carried across: it is decided from the scope's
94
+ // own capture in pass 1 and re-parenting does not change what the scope
95
+ // binds. Dropping it here would silently un-mark every function scope in
96
+ // a file whose root parsed as ERROR (the only way a scope is orphaned).
97
+ scopeDrafts[i] = makeDraft(d.id, moduleScope.id, d.kind, d.range, d.filePath, d.ownsReceivers, d.lexicalNames);
98
+ }
99
+ }
100
+ const scopes = scopeDrafts.map(draftToScope);
101
+ // buildScopeTree validates invariants (throws on violation) and exposes
102
+ // the lookup contract consumed by Passes 2-5.
103
+ //
104
+ // **Snapshot semantics.** Both `scopeTree` and `positionIndex` are built
105
+ // from the post-Pass-1 `scopes` — parent/range/kind are accurate, but
106
+ // `bindings`, `ownedDefs`, and `typeBindings` are all empty here. Later
107
+ // passes write into the *drafts*, not into these snapshots; any hook
108
+ // that reads `scope.bindings` etc. via the `scopeTree` argument sees a
109
+ // structural view only. This is by design — hooks use scopeTree for
110
+ // "what's the parent chain?" queries, not for content queries.
111
+ const scopeTree = (0, index_js_1.buildScopeTree)(scopes);
112
+ const positionIndex = (0, index_js_1.buildPositionIndex)(scopes);
113
+ // ── Pass 2: attach declarations + local bindings ────────────────────
114
+ const localDefs = [];
115
+ pass2AttachDeclarations(partitioned.declaration, scopeDrafts, positionIndex, localDefs, filePath, provider, scopeTree);
116
+ // ── Pass 3: collect raw imports ─────────────────────────────────────
117
+ const parsedImports = [];
118
+ pass3CollectImports(partitioned.import_, parsedImports, provider);
119
+ // ── Pass 4: collect type bindings ───────────────────────────────────
120
+ pass4CollectTypeBindings(partitioned.typeBinding, scopeDrafts, positionIndex, filePath, provider, scopeTree);
121
+ // ── Pass 5: collect reference sites ─────────────────────────────────
122
+ const referenceSites = [];
123
+ pass5CollectReferences(partitioned.reference, positionIndex, filePath, referenceSites, provider, scopeTree);
124
+ // ── Pass 6: collect normalized callable-value-flow facts ───────────
125
+ // Kept after (and independent from) Pass 5 so existing reference-site
126
+ // extraction remains byte-identical.
127
+ const callableFlowSites = [];
128
+ pass6CollectCallableFlows(partitioned.callableFlow, positionIndex, filePath, callableFlowSites);
129
+ // Freeze Scope drafts into final shape and return.
130
+ const frozenScopes = scopeDrafts.map(draftToScope);
131
+ return Object.freeze({
132
+ filePath,
133
+ moduleScope: moduleScope.id,
134
+ scopes: Object.freeze(frozenScopes),
135
+ parsedImports: Object.freeze(parsedImports.slice()),
136
+ localDefs: Object.freeze(localDefs.slice()),
137
+ referenceSites: Object.freeze(referenceSites.slice()),
138
+ ...(callableFlowSites.length > 0
139
+ ? { callableFlowSites: Object.freeze(callableFlowSites.slice()) }
140
+ : {}),
141
+ });
142
+ }
143
+ /**
144
+ * Bucket each match by every topic represented by its anchor captures. An
145
+ * emitter may deliberately group a lexical scope and its declaration in one
146
+ * match so both passes observe the exact same source range.
147
+ *
148
+ * A match may contain additional captures (e.g., `@import.source`,
149
+ * `@declaration.class.name`) that are used by the provider hooks to
150
+ * decode details. Those live inside the `CaptureMatch` and are surfaced
151
+ * to hooks verbatim — the extractor itself only routes by anchor.
152
+ */
153
+ function partitionByTopic(matches) {
154
+ const scope = [];
155
+ const declaration = [];
156
+ const import_ = [];
157
+ const typeBinding = [];
158
+ const reference = [];
159
+ const callableFlow = [];
160
+ for (const match of matches) {
161
+ for (const topic of topicsOf(match)) {
162
+ switch (topic) {
163
+ case 'scope':
164
+ scope.push(match);
165
+ break;
166
+ case 'declaration':
167
+ declaration.push(match);
168
+ break;
169
+ case 'import':
170
+ import_.push(match);
171
+ break;
172
+ case 'type-binding':
173
+ typeBinding.push(match);
174
+ break;
175
+ case 'reference':
176
+ reference.push(match);
177
+ break;
178
+ case 'callable-flow':
179
+ callableFlow.push(match);
180
+ break;
181
+ }
182
+ }
183
+ }
184
+ return { scope, declaration, import_, typeBinding, reference, callableFlow };
185
+ }
186
+ function topicsOf(match) {
187
+ const topics = new Set();
188
+ for (const name of Object.keys(match)) {
189
+ if (name.startsWith('@scope.'))
190
+ topics.add('scope');
191
+ else if (name.startsWith('@declaration.'))
192
+ topics.add('declaration');
193
+ else if (name.startsWith('@import.'))
194
+ topics.add('import');
195
+ else if (name.startsWith('@type-binding.'))
196
+ topics.add('type-binding');
197
+ else if (name.startsWith('@reference.'))
198
+ topics.add('reference');
199
+ else if (name.startsWith('@callable-flow.'))
200
+ topics.add('callable-flow');
201
+ }
202
+ return topics;
203
+ }
204
+ function ensureModuleScope(scopeDrafts, filePath, allMatches) {
205
+ const moduleScope = scopeDrafts.find((s) => s.kind === 'Module');
206
+ if (moduleScope !== undefined)
207
+ return moduleScope;
208
+ // Synthesize a Module scope spanning all captures in the file.
209
+ // Computed from ALL captures (scope, declaration, reference, etc.)
210
+ // so the range covers top-level references that appear after the
211
+ // last inner scope — not just inner Function/Class scopes.
212
+ let endLine = 0;
213
+ let endCol = 0;
214
+ for (const match of allMatches) {
215
+ for (const capture of Object.values(match)) {
216
+ if (capture.range.endLine > endLine ||
217
+ (capture.range.endLine === endLine && capture.range.endCol > endCol)) {
218
+ endLine = capture.range.endLine;
219
+ endCol = capture.range.endCol;
220
+ }
221
+ }
222
+ }
223
+ const range = { startLine: 0, startCol: 0, endLine, endCol };
224
+ const synthetic = makeDraft((0, index_js_1.makeScopeId)({ filePath, range, kind: 'Module' }), null, 'Module', range, filePath);
225
+ scopeDrafts.push(synthetic);
226
+ return synthetic;
227
+ }
228
+ function draftToScope(draft) {
229
+ const frozenBindings = new Map();
230
+ for (const [name, refs] of draft.bindings) {
231
+ frozenBindings.set(name, Object.freeze(refs.slice()));
232
+ }
233
+ return {
234
+ id: draft.id,
235
+ parent: draft.parent,
236
+ kind: draft.kind,
237
+ range: draft.range,
238
+ filePath: draft.filePath,
239
+ bindings: frozenBindings,
240
+ ownedDefs: Object.freeze(draft.ownedDefs.slice()),
241
+ imports: Object.freeze(draft.imports.slice()),
242
+ typeBindings: new Map(draft.typeBindings),
243
+ lexicalNames: draft.lexicalNames,
244
+ ownsReceivers: draft.ownsReceivers,
245
+ };
246
+ }
247
+ // ─── Pass 1: build scope tree ──────────────────────────────────────────────
248
+ /**
249
+ * Convert `@scope.*` matches into `ScopeDraft[]`. Parent relationships
250
+ * are derived from range containment (outermost scope containing `range`
251
+ * becomes the parent).
252
+ */
253
+ function pass1BuildScopes(matches, filePath, provider) {
254
+ const candidates = [];
255
+ for (const match of matches) {
256
+ const anchor = anchorCaptureFor(match, '@scope.');
257
+ if (anchor === undefined)
258
+ continue;
259
+ const kind = resolveKindForScopeMatch(match, anchor, provider);
260
+ if (kind === null)
261
+ continue;
262
+ const id = (0, index_js_1.makeScopeId)({ filePath, range: anchor.range, kind });
263
+ candidates.push({ match, range: anchor.range, kind, id });
264
+ }
265
+ // Sort by (startLine, startCol) ASC, (endLine, endCol) DESC so outer
266
+ // scopes appear before their children for parent-resolution. When two
267
+ // candidates have exactly equal ranges (e.g. a `compilation_unit` and
268
+ // the only top-level scope in the file — see `canParentScope`), Module
269
+ // sorts first so it lands on the stack ahead of the candidate that will
270
+ // claim it as parent.
271
+ candidates.sort((a, b) => {
272
+ if (a.range.startLine !== b.range.startLine)
273
+ return a.range.startLine - b.range.startLine;
274
+ if (a.range.startCol !== b.range.startCol)
275
+ return a.range.startCol - b.range.startCol;
276
+ if (a.range.endLine !== b.range.endLine)
277
+ return b.range.endLine - a.range.endLine;
278
+ if (a.range.endCol !== b.range.endCol)
279
+ return b.range.endCol - a.range.endCol;
280
+ if (a.kind === b.kind)
281
+ return 0;
282
+ if (a.kind === 'Module')
283
+ return -1;
284
+ if (b.kind === 'Module')
285
+ return 1;
286
+ return 0;
287
+ });
288
+ const drafts = [];
289
+ const stack = []; // enclosing real scopes, outermost at [0]
290
+ for (const cand of candidates) {
291
+ // Pop the stack until the top can parent this candidate (strict
292
+ // containment, plus the equal-range Module carve-out).
293
+ while (stack.length > 0 &&
294
+ !(0, index_js_1.canParentScope)(stack[stack.length - 1].range, cand.range, stack[stack.length - 1].kind, cand.kind)) {
295
+ stack.pop();
296
+ }
297
+ const parent = stack.length > 0 ? stack[stack.length - 1].id : null;
298
+ drafts.push(makeDraft(cand.id, parent, cand.kind, cand.range, filePath, provider.scopeOwnsReceivers?.(cand.match), parseScopeLexicalNames(cand.match)));
299
+ stack.push(cand);
300
+ }
301
+ return drafts;
302
+ }
303
+ function resolveKindForScopeMatch(match, anchor, provider) {
304
+ // Provider override takes precedence.
305
+ const override = provider.resolveScopeKind?.(match);
306
+ if (override !== undefined && override !== null)
307
+ return override;
308
+ // Default: derive from capture name suffix (`@scope.function` → 'Function').
309
+ const suffix = anchor.name.slice('@scope.'.length);
310
+ switch (suffix.toLowerCase()) {
311
+ case 'module':
312
+ return 'Module';
313
+ case 'namespace':
314
+ return 'Namespace';
315
+ case 'class':
316
+ return 'Class';
317
+ case 'function':
318
+ return 'Function';
319
+ case 'block':
320
+ return 'Block';
321
+ case 'expression':
322
+ return 'Expression';
323
+ case 'object':
324
+ return 'Object';
325
+ default:
326
+ return null;
327
+ }
328
+ }
329
+ function makeDraft(id, parent, kind, range, filePath, ownsReceivers, lexicalNames) {
330
+ return {
331
+ id,
332
+ parent,
333
+ kind,
334
+ range,
335
+ filePath,
336
+ bindings: new Map(),
337
+ ownedDefs: [],
338
+ imports: [],
339
+ typeBindings: new Map(),
340
+ lexicalNames,
341
+ ownsReceivers,
342
+ };
343
+ }
344
+ function parseScopeLexicalNames(match) {
345
+ const raw = match['@scope.lexical-names']?.text;
346
+ if (raw === undefined)
347
+ return undefined;
348
+ try {
349
+ const parsed = JSON.parse(raw);
350
+ if (!Array.isArray(parsed))
351
+ return undefined;
352
+ const names = parsed.filter((name) => typeof name === 'string' && name.length > 0);
353
+ return names.length > 0 ? new Set(names) : undefined;
354
+ }
355
+ catch {
356
+ return undefined;
357
+ }
358
+ }
359
+ // ─── Pass 2: attach declarations + local bindings ──────────────────────────
360
+ function pass2AttachDeclarations(matches, drafts, positionIndex, localDefs, filePath, provider, scopeTree) {
361
+ const draftById = new Map();
362
+ for (const d of drafts)
363
+ draftById.set(d.id, d);
364
+ // First def seen per `nodeId`, for the duplicate backfill below. Two query
365
+ // patterns can legitimately match ONE declaration — a C++ templated struct
366
+ // matches both the standalone `struct_specifier` rule and the
367
+ // `template_declaration` rule that wraps it — and both mint the same def id.
368
+ const firstDefByNodeId = new Map();
369
+ for (const match of matches) {
370
+ const anchor = anchorCaptureFor(match, '@declaration.');
371
+ if (anchor === undefined)
372
+ continue;
373
+ const def = buildDefFromDeclarationMatch(match, anchor, filePath);
374
+ if (def === undefined)
375
+ continue;
376
+ // ── Duplicate-declaration backfill ───────────────────────────────────────
377
+ // `buildDefIndex` is FIRST-WRITE-WINS, so when one declaration produces two
378
+ // defs under one id, whichever match tree-sitter reported first is the one
379
+ // resolution sees. That was harmless while the twins were byte-identical.
380
+ // It stops being harmless the moment one twin can carry a field the other
381
+ // structurally cannot: a C++ `template <class T> struct Vec` has its
382
+ // parameter list on the ENCLOSING `template_declaration`, so the standalone
383
+ // `struct_specifier` twin can never see it, and match order would silently
384
+ // decide whether `Vec` remembers `T`. Source order deciding a resolution
385
+ // fact is the failure mode this subsystem rejects everywhere else.
386
+ //
387
+ // Copying the field onto BOTH twins makes the outcome identical whichever
388
+ // one wins. Deliberately narrow — only `typeParameters`, the one field with
389
+ // an asymmetric twin today. Widening this to "merge all metadata" would
390
+ // change what every existing duplicate resolves to, which is a different
391
+ // change with a different blast radius and no evidence behind it yet.
392
+ const first = firstDefByNodeId.get(def.nodeId);
393
+ if (first === undefined) {
394
+ firstDefByNodeId.set(def.nodeId, def);
395
+ }
396
+ else if (first.typeParameters === undefined && def.typeParameters !== undefined) {
397
+ first.typeParameters = def.typeParameters;
398
+ }
399
+ else if (def.typeParameters === undefined && first.typeParameters !== undefined) {
400
+ def.typeParameters = first.typeParameters;
401
+ }
402
+ // Find the innermost scope that contains the declaration's anchor range.
403
+ const innermostId = positionIndex.atPosition(filePath, anchor.range.startLine, anchor.range.startCol);
404
+ if (innermostId === undefined)
405
+ continue;
406
+ const innermost = draftById.get(innermostId);
407
+ if (innermost === undefined)
408
+ continue;
409
+ // Ownership: attach the def to the innermost scope's `ownedDefs` — that
410
+ // is the structural owner. `def.ownerId` is NOT populated here — the
411
+ // extractor has no clean path to the parent's own DefId mid-extraction
412
+ // (the parent declaration may not yet have been processed, or may live
413
+ // in a different scope entirely). Providers that need `ownerId` should
414
+ // set it directly from the declaration hook (e.g., derive from the
415
+ // `@declaration.owner` capture or the parent scope id); otherwise
416
+ // `finalize` populates method/field `ownerId` via `MethodDispatchIndex`
417
+ // (#914) in a follow-up pass that sees every def already in place.
418
+ innermost.ownedDefs.push(def);
419
+ localDefs.push(def);
420
+ // Binding visibility: default to innermost; allow hoisting via
421
+ // `provider.bindingScopeFor`. `draftToScope(innermost)` here is a
422
+ // **structural** snapshot — parent/range/kind only. Hooks MUST NOT
423
+ // rely on `scope.bindings`, `ownedDefs`, or `typeBindings` being
424
+ // populated during Pass 2: those fields are written across passes,
425
+ // so reading them mid-extraction yields a partial view. The
426
+ // `scopeTree` argument is similarly snapshot-before-mutation.
427
+ //
428
+ // Auto-hoist for scope-creating declarations: when the declaration's
429
+ // anchor range is the same node that produced `innermost` (e.g. a
430
+ // `function_definition` is both `@scope.function` and the
431
+ // `@declaration.function` anchor), the name is visible OUTSIDE the
432
+ // body, not inside. Hoisting to the parent scope is what every
433
+ // mainstream language wants for function/class declarations. Hooks
434
+ // can override by returning a non-null scope id.
435
+ const autoHostedId = innermost.parent !== null && rangesEqual(anchor.range, innermost.range)
436
+ ? innermost.parent
437
+ : innermost.id;
438
+ const bindingScopeId = provider.bindingScopeFor?.(match, draftToScope(innermost), scopeTree) ?? autoHostedId;
439
+ const bindingHost = draftById.get(bindingScopeId) ?? innermost;
440
+ const nameKey = deriveDeclarationName(match, def);
441
+ if (nameKey === undefined)
442
+ continue;
443
+ const existing = bindingHost.bindings.get(nameKey) ?? [];
444
+ existing.push({ def, origin: 'local' });
445
+ bindingHost.bindings.set(nameKey, existing);
446
+ }
447
+ }
448
+ function buildDefFromDeclarationMatch(match, anchor, filePath) {
449
+ // Anchor name pattern: `@declaration.<kind>` where <kind> maps to NodeLabel.
450
+ const kindStr = anchor.name.slice('@declaration.'.length);
451
+ const type = normalizeNodeLabel(kindStr);
452
+ if (type === undefined)
453
+ return undefined;
454
+ const nameCap = match['@declaration.name'] ?? match[`@declaration.${kindStr}.name`] ?? match[anchor.name];
455
+ if (nameCap === undefined)
456
+ return undefined;
457
+ const qualifiedCap = match['@declaration.qualified_name'];
458
+ const qualifiedName = qualifiedCap?.text;
459
+ const templateArguments = (0, template_arguments_js_1.extractTemplateArguments)(match['@declaration.template-arguments']?.text ?? '') ??
460
+ (0, template_arguments_js_1.extractTemplateArguments)(qualifiedName ?? nameCap.text);
461
+ // Optional arity metadata — producers (e.g. Python emit-captures)
462
+ // synthesize these on function/method declarations. Their absence is
463
+ // the normal case for other producers; readers treat undefined as
464
+ // "unknown" per `SymbolDefinition` contract.
465
+ const parameterCount = parseIntCapture(match['@declaration.parameter-count']);
466
+ const requiredParameterCount = parseIntCapture(match['@declaration.required-parameter-count']);
467
+ const parameterTypes = parseJsonStringArrayCapture(match['@declaration.parameter-types']);
468
+ const parameterTypeClasses = parseJsonParameterTypeClassesCapture(match['@declaration.parameter-type-classes']);
469
+ const declaredType = match['@declaration.field-type']?.text;
470
+ const returnType = match['@declaration.return-type']?.text;
471
+ const templateConstraints = parseJsonCapture(match['@declaration.template-constraints']);
472
+ // The DECLARED parameters, a different axis from `templateArguments` above:
473
+ // that reads the arguments written on the name, this reads the list the
474
+ // declaration was written in terms of. A declaration can carry both, and for a
475
+ // C++ partial specialization the pairing is the only thing that tells it apart
476
+ // from a full specialization with the identical arguments.
477
+ const typeParameters = (0, type_parameters_js_1.parseTypeParameterList)(match['@declaration.type-parameters']?.text ?? '');
478
+ const isExplicit = parseBooleanCapture(match['@declaration.is-explicit']);
479
+ const isDeleted = parseBooleanCapture(match['@declaration.is-deleted']);
480
+ return {
481
+ nodeId: makeDefId(filePath, anchor.range, type, nameCap.text),
482
+ filePath,
483
+ type,
484
+ ...(qualifiedName !== undefined ? { qualifiedName } : { qualifiedName: nameCap.text }),
485
+ ...(parameterCount !== undefined ? { parameterCount } : {}),
486
+ ...(requiredParameterCount !== undefined ? { requiredParameterCount } : {}),
487
+ ...(parameterTypes !== undefined ? { parameterTypes } : {}),
488
+ ...(parameterTypeClasses !== undefined ? { parameterTypeClasses } : {}),
489
+ ...(declaredType !== undefined ? { declaredType } : {}),
490
+ ...(returnType !== undefined ? { returnType } : {}),
491
+ ...(templateArguments !== undefined ? { templateArguments } : {}),
492
+ ...(typeParameters !== undefined ? { typeParameters } : {}),
493
+ ...(templateConstraints !== undefined ? { templateConstraints } : {}),
494
+ ...(isExplicit === true ? { isExplicit: true } : {}),
495
+ ...(isDeleted === true ? { isDeleted: true } : {}),
496
+ };
497
+ }
498
+ /** Parse an opaque JSON payload synthesized by per-language captures
499
+ * (e.g. C++ `@declaration.template-constraints`). Producer owns the
500
+ * shape; shared code threads it through as `unknown` per the
501
+ * `SymbolDefinition.templateConstraints` contract. */
502
+ function parseJsonCapture(cap) {
503
+ if (cap === undefined)
504
+ return undefined;
505
+ try {
506
+ return JSON.parse(cap.text);
507
+ }
508
+ catch {
509
+ return undefined;
510
+ }
511
+ }
512
+ function parseIntCapture(cap) {
513
+ if (cap === undefined)
514
+ return undefined;
515
+ const n = Number.parseInt(cap.text, 10);
516
+ return Number.isFinite(n) ? n : undefined;
517
+ }
518
+ function parseBooleanCapture(cap) {
519
+ if (cap === undefined)
520
+ return undefined;
521
+ if (cap.text === 'true')
522
+ return true;
523
+ if (cap.text === 'false')
524
+ return false;
525
+ return undefined;
526
+ }
527
+ function parseJsonParameterTypeClassesCapture(cap) {
528
+ if (cap === undefined)
529
+ return undefined;
530
+ try {
531
+ const parsed = JSON.parse(cap.text);
532
+ if (!Array.isArray(parsed))
533
+ return undefined;
534
+ const out = [];
535
+ for (const item of parsed) {
536
+ if (item === null || typeof item !== 'object')
537
+ return undefined;
538
+ const o = item;
539
+ if (typeof o.base !== 'string')
540
+ return undefined;
541
+ if (o.cv !== 'none' &&
542
+ o.cv !== 'const' &&
543
+ o.cv !== 'volatile' &&
544
+ o.cv !== 'const volatile' &&
545
+ o.cv !== 'unknown') {
546
+ return undefined;
547
+ }
548
+ if (o.indirection !== 'value' &&
549
+ o.indirection !== 'lvalue-ref' &&
550
+ o.indirection !== 'rvalue-ref' &&
551
+ o.indirection !== 'pointer' &&
552
+ o.indirection !== 'unknown') {
553
+ return undefined;
554
+ }
555
+ if (typeof o.pointerDepth !== 'number' || !Number.isFinite(o.pointerDepth)) {
556
+ return undefined;
557
+ }
558
+ const shape = {
559
+ base: o.base,
560
+ cv: o.cv,
561
+ indirection: o.indirection,
562
+ pointerDepth: o.pointerDepth,
563
+ };
564
+ if (Array.isArray(o.templateArguments)) {
565
+ if (!o.templateArguments.every((x) => typeof x === 'string')) {
566
+ return undefined;
567
+ }
568
+ shape.templateArguments = [...o.templateArguments];
569
+ }
570
+ out.push(shape);
571
+ }
572
+ return out;
573
+ }
574
+ catch {
575
+ return undefined;
576
+ }
577
+ }
578
+ function parseJsonStringArrayCapture(cap) {
579
+ if (cap === undefined)
580
+ return undefined;
581
+ try {
582
+ const parsed = JSON.parse(cap.text);
583
+ if (!Array.isArray(parsed))
584
+ return undefined;
585
+ return parsed.every((x) => typeof x === 'string') ? parsed : undefined;
586
+ }
587
+ catch {
588
+ return undefined;
589
+ }
590
+ }
591
+ function deriveDeclarationName(match, def) {
592
+ const nameCap = match['@declaration.binding-name'] ??
593
+ match['@declaration.name'] ??
594
+ match[Object.keys(match).find((k) => k.startsWith('@declaration.') && k.endsWith('.name')) ?? ''];
595
+ if (nameCap !== undefined)
596
+ return nameCap.text;
597
+ // Fall back to qualifiedName tail.
598
+ const q = def.qualifiedName;
599
+ if (q !== undefined && q.length > 0) {
600
+ const dot = q.lastIndexOf('.');
601
+ return dot === -1 ? q : q.slice(dot + 1);
602
+ }
603
+ return undefined;
604
+ }
605
+ /**
606
+ * Map a lower-case declaration kind (from `@declaration.<kind>`) to a
607
+ * graph `NodeLabel`. Silently returns `undefined` for kinds we don't
608
+ * recognize — providers can emit richer captures without breaking the
609
+ * driver.
610
+ */
611
+ function normalizeNodeLabel(kindStr) {
612
+ switch (kindStr.toLowerCase()) {
613
+ case 'class':
614
+ return 'Class';
615
+ case 'interface':
616
+ return 'Interface';
617
+ case 'enum':
618
+ return 'Enum';
619
+ case 'struct':
620
+ return 'Struct';
621
+ case 'union':
622
+ return 'Union';
623
+ case 'trait':
624
+ return 'Trait';
625
+ case 'method':
626
+ return 'Method';
627
+ case 'function':
628
+ return 'Function';
629
+ case 'constructor':
630
+ return 'Constructor';
631
+ case 'field':
632
+ case 'property':
633
+ return 'Property';
634
+ case 'variable':
635
+ return 'Variable';
636
+ // `const` / `let` declarations align with the legacy DAG parse phase,
637
+ // which emits `Const` graph nodes via `@definition.const` capture for
638
+ // `lexical_declaration`. Returning `'Const'` here lets resolveDefGraphId's
639
+ // qualified-key path succeed for value receivers without relying on the
640
+ // simple-key fallback (PR #1718 review Finding 1 / 2026-05-21-002 U4).
641
+ case 'const':
642
+ return 'Const';
643
+ case 'typealias':
644
+ case 'type_alias':
645
+ return 'TypeAlias';
646
+ case 'typedef':
647
+ return 'Typedef';
648
+ case 'record':
649
+ return 'Record';
650
+ case 'delegate':
651
+ return 'Delegate';
652
+ case 'annotation':
653
+ return 'Annotation';
654
+ case 'namespace':
655
+ return 'Namespace';
656
+ case 'program':
657
+ return 'Module';
658
+ case 'macro':
659
+ return 'Macro';
660
+ default:
661
+ return undefined;
662
+ }
663
+ }
664
+ /** Function-like labels: callable defs that must keep incoming CALLS edges. */
665
+ const NODE_BEARING_FUNCTION_LABELS = new Set([
666
+ 'Function',
667
+ 'Method',
668
+ 'Constructor',
669
+ ]);
670
+ /** Value labels: non-callable bindings (a `const`/`let`/`var` holds a value). */
671
+ const NODE_BEARING_VALUE_LABELS = new Set([
672
+ 'Const',
673
+ 'Variable',
674
+ ]);
675
+ /**
676
+ * Collapse rule for the deferred node-creation migration (#1876).
677
+ *
678
+ * When graph-node creation moves from the legacy DAG onto the
679
+ * registry-primary path, a single source binding can carry more than one
680
+ * `SymbolDefinition` for the same name in the same scope — e.g. a direct
681
+ * arrow `const fn = () => {}` is classified BOTH as a `Function` (the
682
+ * arrow) and a `Variable` (the binding). Emitting one graph node per def
683
+ * would reproduce exactly the duplicate-node bug this issue tracks.
684
+ *
685
+ * `selectNodeBearingDef` picks the ONE def that should bear the graph node
686
+ * for such a binding group:
687
+ *
688
+ * 1. a function-like def (`Function` / `Method` / `Constructor`) if any —
689
+ * the binding is callable and must keep incoming `CALLS` edges;
690
+ * 2. otherwise a value def (`Const` / `Variable`) — the binding holds a
691
+ * value (e.g. an array-method result after the U1/U2 narrowing);
692
+ * 3. otherwise the first def — deterministic fallback for label sets this
693
+ * rule does not rank.
694
+ *
695
+ * INPUT CONTRACT: `group` must be the defs bound to ONE name within ONE
696
+ * scope (a binding group). It deliberately does NOT dedup by range —
697
+ * `SymbolDefinition` carries no range and `makeDefId` encodes only the
698
+ * start position, so containment is uncomputable here; the caller forms the
699
+ * group (e.g. from a scope's `ownedDefs` keyed by name) before calling.
700
+ *
701
+ * Pure. No production call site yet — this dead export is intentional and
702
+ * tracked by #1876 (the deferred node-creation migration); it is the
703
+ * executable contract that follow-up will consume, pinned today by the
704
+ * scope-extractor unit test.
705
+ */
706
+ function selectNodeBearingDef(group) {
707
+ if (group.length === 0)
708
+ return undefined;
709
+ const functionLike = group.find((def) => NODE_BEARING_FUNCTION_LABELS.has(def.type));
710
+ if (functionLike !== undefined)
711
+ return functionLike;
712
+ const value = group.find((def) => NODE_BEARING_VALUE_LABELS.has(def.type));
713
+ if (value !== undefined)
714
+ return value;
715
+ return group[0];
716
+ }
717
+ function makeDefId(filePath, range, type, name) {
718
+ return `def:${filePath}#${range.startLine}:${range.startCol}:${type}:${name}`;
719
+ }
720
+ // ─── Pass 3: collect raw imports ───────────────────────────────────────────
721
+ function pass3CollectImports(matches, parsedImports, provider) {
722
+ if (provider.interpretImport === undefined)
723
+ return;
724
+ for (const match of matches) {
725
+ const anchor = anchorCaptureFor(match, '@import.');
726
+ if (anchor === undefined)
727
+ continue;
728
+ const parsed = provider.interpretImport(match);
729
+ if (parsed === null)
730
+ continue;
731
+ parsedImports.push(parsed);
732
+ }
733
+ }
734
+ // ─── Pass 4: collect type bindings ─────────────────────────────────────────
735
+ /** Cap on the retained as-written annotation. Real container spellings are a
736
+ * handful of characters; a multi-line mapped/conditional type is neither a
737
+ * container any `elementTypeOf` parses nor worth keeping one copy of per
738
+ * binding on a kernel-scale repo. Over the cap the spelling is dropped, which
739
+ * makes an index step decline — the safe direction. */
740
+ const MAX_DECLARED_SPELLING_LENGTH = 256;
741
+ function pass4CollectTypeBindings(matches, drafts, positionIndex, filePath, provider, scopeTree) {
742
+ const draftById = new Map();
743
+ for (const d of drafts)
744
+ draftById.set(d.id, d);
745
+ for (const match of matches) {
746
+ const anchor = anchorCaptureFor(match, '@type-binding.');
747
+ if (anchor === undefined)
748
+ continue;
749
+ const parsed = provider.interpretTypeBinding?.(match);
750
+ if (parsed === null || parsed === undefined)
751
+ continue;
752
+ const innermostId = positionIndex.atPosition(filePath, anchor.range.startLine, anchor.range.startCol);
753
+ if (innermostId === undefined)
754
+ continue;
755
+ const innermost = draftById.get(innermostId);
756
+ if (innermost === undefined)
757
+ continue;
758
+ // Auto-hoist for scope-creating type bindings (e.g. Python's
759
+ // `@type-binding.return` whose anchor is the function_definition
760
+ // itself). Same condition as Pass 2 — when the anchor coincides
761
+ // with the innermost scope's range, the binding belongs in the
762
+ // enclosing scope (callers, not the function body, look up the
763
+ // return type by the function's name).
764
+ const autoHostedId = innermost.parent !== null && rangesEqual(anchor.range, innermost.range)
765
+ ? innermost.parent
766
+ : innermost.id;
767
+ // `bindingScopeFor` may hoist the type binding to an outer scope.
768
+ const hostId = provider.bindingScopeFor?.(match, draftToScope(innermost), scopeTree) ?? autoHostedId;
769
+ const host = draftById.get(hostId) ?? innermost;
770
+ // The annotation as the source wrote it, kept only when the provider's
771
+ // interpretation is not already it. `interpretTypeBinding` normalizes
772
+ // container spellings away (`User[]` → `User`, `List[User]` → `User`,
773
+ // `[]*User` → `User`), which makes a reduced container indistinguishable
774
+ // from a class of the same name — and an index step folding on that
775
+ // ambiguity typed `grid[0]` as `Grid`. Read at the one place the
776
+ // distinction matters; see `TypeRef.declaredSpelling`.
777
+ //
778
+ // Read from the capture rather than from `ParsedTypeBinding` deliberately:
779
+ // `@type-binding.type` is the shared anchor EVERY provider already reads to
780
+ // build `rawTypeName`, so nothing has to be threaded through fourteen
781
+ // interpreters (and none can forget to).
782
+ // A provider may override when its grammar keeps part of the written type
783
+ // outside `@type-binding.type` (C++ hangs `*` on the declarator).
784
+ const writtenType = (parsed.declaredSpelling ?? match['@type-binding.type']?.text)?.trim();
785
+ const declaredSpelling = writtenType !== undefined &&
786
+ writtenType.length > 0 &&
787
+ writtenType.length <= MAX_DECLARED_SPELLING_LENGTH &&
788
+ writtenType !== parsed.rawTypeName
789
+ ? writtenType
790
+ : undefined;
791
+ const typeRef = declaredSpelling === undefined
792
+ ? {
793
+ rawName: parsed.rawTypeName,
794
+ declaredAtScope: host.id,
795
+ source: parsed.source,
796
+ }
797
+ : {
798
+ rawName: parsed.rawTypeName,
799
+ declaredSpelling,
800
+ declaredAtScope: host.id,
801
+ source: parsed.source,
802
+ };
803
+ // Prefer stronger sources when multiple matches fire for the same
804
+ // bound name in the same scope. Example: `u: User = find()` matches
805
+ // both the annotation and constructor-inferred patterns; the explicit
806
+ // annotation (stronger source) must win over the call-site guess
807
+ // regardless of query-match arrival order.
808
+ const existing = host.typeBindings.get(parsed.boundName);
809
+ if (existing === undefined ||
810
+ typeBindingStrength(typeRef.source) >= typeBindingStrength(existing.source)) {
811
+ host.typeBindings.set(parsed.boundName, typeRef);
812
+ }
813
+ }
814
+ // ── Transitive closure over identifier-chain type bindings ─────────
815
+ // Captures like `(assignment left: (ident) right: (ident))` emit a
816
+ // TypeRef whose `rawName` is the RHS identifier. When the RHS name is
817
+ // itself a bound variable with a known type in the same scope (or a
818
+ // parent scope), follow the chain so `alias` ultimately points at the
819
+ // class type — not at another local variable name. Without this,
820
+ // `resolveTypeRef` hits the chained name, sees it's a local Variable
821
+ // (non-type kind), and strict-returns null.
822
+ for (const draft of drafts) {
823
+ for (const [name, ref] of draft.typeBindings) {
824
+ const resolved = followChainedRef(ref, draftById);
825
+ if (resolved !== ref)
826
+ draft.typeBindings.set(name, resolved);
827
+ }
828
+ }
829
+ }
830
+ /** Max chain depth: practical programs rarely exceed 4-5 re-bindings;
831
+ * the cap just prevents runaway loops when providers emit cycles. */
832
+ const CHAIN_MAX_DEPTH = 16;
833
+ /**
834
+ * Follow an identifier-chain TypeRef through successive typeBindings
835
+ * lookups in the declaring scope and its ancestors. Returns the terminal
836
+ * TypeRef (or the original if the chain dead-ends or cycles).
837
+ */
838
+ function followChainedRef(start, draftById) {
839
+ let current = start;
840
+ const visited = new Set();
841
+ for (let depth = 0; depth < CHAIN_MAX_DEPTH; depth++) {
842
+ // A rawName containing a dot (`models.User`) goes through
843
+ // `QualifiedNameIndex` at resolution time — don't follow it here.
844
+ if (current.rawName.includes('.'))
845
+ return current;
846
+ // Look up the current rawName in the declaring scope and walk up
847
+ // the chain until we hit a scope that has a binding for it.
848
+ let scopeId = current.declaredAtScope;
849
+ let next;
850
+ while (scopeId !== null) {
851
+ const scope = draftById.get(scopeId);
852
+ if (scope === undefined)
853
+ break;
854
+ next = scope.typeBindings.get(current.rawName);
855
+ if (next !== undefined)
856
+ break;
857
+ scopeId = scope.parent;
858
+ }
859
+ if (next === undefined)
860
+ return current; // dead end — nothing to chain to
861
+ if (next === current)
862
+ return current; // self-ref
863
+ if (visited.has(next.rawName))
864
+ return current; // cycle guard
865
+ visited.add(next.rawName);
866
+ current = next;
867
+ }
868
+ return current;
869
+ }
870
+ /**
871
+ * Priority ordering when multiple `TypeRef`s compete for the same bound
872
+ * name in the same scope. Higher number wins; ties keep the later match
873
+ * (last-write-wins preserves historical order within a tier).
874
+ *
875
+ * Rationale: explicit variable and field annotations always beat bindings
876
+ * derived from parameter annotations or inference because they reflect the
877
+ * most specific user intent. `self`/`cls` are treated as strongly as other
878
+ * declared types because they are language-required receiver types.
879
+ */
880
+ function typeBindingStrength(source) {
881
+ switch (source) {
882
+ case 'annotation':
883
+ return 3;
884
+ case 'parameter-annotation':
885
+ case 'return-annotation':
886
+ case 'self':
887
+ return 2;
888
+ case 'assignment-inferred':
889
+ case 'constructor-inferred':
890
+ case 'receiver-propagated':
891
+ return 1;
892
+ default:
893
+ return 0;
894
+ }
895
+ }
896
+ // ─── Pass 5: collect reference sites ───────────────────────────────────────
897
+ function pass5CollectReferences(matches, positionIndex, filePath, referenceSites, provider, scopeTree) {
898
+ for (const match of matches) {
899
+ const anchor = anchorCaptureFor(match, '@reference.');
900
+ if (anchor === undefined)
901
+ continue;
902
+ const kind = referenceKindFromAnchor(anchor.name);
903
+ if (kind === undefined)
904
+ continue;
905
+ const nameCap = match['@reference.name'] ?? anchor;
906
+ // Optional qualified form of the reference (e.g. a C++ base `Other::Inner`),
907
+ // threaded to resolution so a same-tail nested base resolves to the correct
908
+ // sibling via the full-path QualifiedNameIndex before the simple-tail walk
909
+ // (#1982). Absent for unqualified references — resolution stays unchanged.
910
+ const qualifiedCap = match['@reference.qualified-name'];
911
+ const inScopeId = positionIndex.atPosition(filePath, anchor.range.startLine, anchor.range.startCol);
912
+ if (inScopeId === undefined)
913
+ continue;
914
+ const callForm = kind === 'call'
915
+ ? classifyCallFormForMatch(match, anchor.name, provider, scopeTree, inScopeId)
916
+ : undefined;
917
+ const explicitReceiver = extractExplicitReceiver(match);
918
+ const arity = extractArity(match);
919
+ const argumentTypes = extractArgumentTypes(match);
920
+ const argumentTypeClasses = parseJsonParameterTypeClassesCapture(match['@reference.parameter-type-classes']);
921
+ // Object-literal key for value-ref sites (`{ key: fn }` / shorthand);
922
+ // consumed by the property-dispatch pass (#2437).
923
+ const propertyKeyCap = match['@reference.property-key'];
924
+ // Compact receiver chain, when the emitter produced one. Validated HERE as
925
+ // well as at the store boundary: bounds applied only on load are a
926
+ // recurring defect in this codebase — the writer keeps minting payloads the
927
+ // reader keeps rejecting, which is a permanent warm-cache-miss reparse loop
928
+ // that logs nothing.
929
+ const receiverChain = extractReceiverChain(match);
930
+ // Callee-position marker: a member-read capture that is actually the callee
931
+ // of an enclosing call (`obj.f` in `obj.f()`). Recorded, not acted on —
932
+ // whether the read is a phantom or a genuine func-typed-field read depends
933
+ // on the resolved tail's kind, which only edge emission knows. Emitted by
934
+ // languages whose read pattern has no call-position exclusion; absent
935
+ // everywhere else, so the site stays byte-identical for them.
936
+ const inCalleePosition = match['@reference.callee-position'] !== undefined;
937
+ // Pointer-embedding marker: `struct S { *T }` rather than `struct S { T }`.
938
+ // Recorded, not acted on — Go's method-set rules make the two forms differ
939
+ // (see `ReferenceSite.embeddedAsPointer`), and only structural interface
940
+ // detection knows what to do with that. Absent for every language without
941
+ // pointer embedding, so their sites stay byte-identical.
942
+ const embeddedAsPointer = match['@reference.embedded-pointer'] !== undefined;
943
+ const site = {
944
+ name: nameCap.text,
945
+ atRange: anchor.range,
946
+ inScope: inScopeId,
947
+ kind,
948
+ ...(qualifiedCap?.text !== undefined && qualifiedCap.text.length > 0
949
+ ? { rawQualifiedName: qualifiedCap.text }
950
+ : {}),
951
+ ...(propertyKeyCap?.text !== undefined && propertyKeyCap.text.length > 0
952
+ ? { propertyKey: propertyKeyCap.text }
953
+ : {}),
954
+ ...(callForm !== undefined ? { callForm } : {}),
955
+ ...(explicitReceiver !== undefined ? { explicitReceiver } : {}),
956
+ ...(arity !== undefined ? { arity } : {}),
957
+ ...(argumentTypes !== undefined ? { argumentTypes } : {}),
958
+ ...(argumentTypeClasses !== undefined ? { argumentTypeClasses } : {}),
959
+ ...(receiverChain !== undefined ? { receiverChain } : {}),
960
+ ...(inCalleePosition ? { inCalleePosition: true } : {}),
961
+ ...(embeddedAsPointer ? { embeddedAsPointer: true } : {}),
962
+ };
963
+ referenceSites.push(site);
964
+ }
965
+ }
966
+ function referenceKindFromAnchor(name) {
967
+ const suffix = name.slice('@reference.'.length);
968
+ // Strip sub-tag after the kind (`@reference.call.member` → `call`).
969
+ const firstDot = suffix.indexOf('.');
970
+ const head = firstDot === -1 ? suffix : suffix.slice(0, firstDot);
971
+ switch (head.toLowerCase()) {
972
+ case 'call':
973
+ return 'call';
974
+ case 'read':
975
+ return 'read';
976
+ case 'write':
977
+ return 'write';
978
+ case 'type':
979
+ case 'type_reference':
980
+ return 'type-reference';
981
+ case 'inherits':
982
+ return 'inherits';
983
+ case 'import_use':
984
+ case 'import-use':
985
+ return 'import-use';
986
+ case 'macro':
987
+ return 'macro';
988
+ case 'value-ref':
989
+ return 'value-ref';
990
+ default:
991
+ return undefined;
992
+ }
993
+ }
994
+ function classifyCallFormForMatch(match, anchorName, provider, scopeTree, inScopeId) {
995
+ // Declarative sub-tag path first: `@reference.call.member` → 'member'.
996
+ const suffix = anchorName.slice('@reference.call.'.length);
997
+ switch (suffix.toLowerCase()) {
998
+ case 'free':
999
+ return 'free';
1000
+ case 'member':
1001
+ return 'member';
1002
+ case 'constructor':
1003
+ return 'constructor';
1004
+ case 'index':
1005
+ return 'index';
1006
+ }
1007
+ // Hook-based path: provider knows.
1008
+ const hook = provider.classifyCallForm;
1009
+ if (hook !== undefined) {
1010
+ const scope = scopeTree.getScope(inScopeId);
1011
+ if (scope !== undefined)
1012
+ return hook(match, scope);
1013
+ }
1014
+ return 'free';
1015
+ }
1016
+ function extractExplicitReceiver(match) {
1017
+ const cap = match['@reference.receiver'];
1018
+ if (cap === undefined)
1019
+ return undefined;
1020
+ return { name: cap.text };
1021
+ }
1022
+ /**
1023
+ * The compact receiver chain, when the language emitter synthesized one.
1024
+ *
1025
+ * Returns `undefined` for anything that does not decode, so a malformed or
1026
+ * over-bound payload degrades to the existing text cascade rather than
1027
+ * poisoning the durable store. Never throws — this runs per reference site.
1028
+ */
1029
+ function extractReceiverChain(match) {
1030
+ const cap = match['@reference.receiver-chain'];
1031
+ if (cap === undefined)
1032
+ return undefined;
1033
+ return (0, receiver_chain_codec_js_1.isValidReceiverChain)(cap.text) ? cap.text : undefined;
1034
+ }
1035
+ function extractArity(match) {
1036
+ const cap = match['@reference.arity'];
1037
+ if (cap === undefined)
1038
+ return undefined;
1039
+ const n = Number.parseInt(cap.text, 10);
1040
+ return Number.isFinite(n) ? n : undefined;
1041
+ }
1042
+ function extractArgumentTypes(match) {
1043
+ const cap = match['@reference.parameter-types'];
1044
+ if (cap === undefined)
1045
+ return undefined;
1046
+ try {
1047
+ const parsed = JSON.parse(cap.text);
1048
+ if (Array.isArray(parsed) && parsed.every((x) => typeof x === 'string'))
1049
+ return parsed;
1050
+ }
1051
+ catch {
1052
+ /* malformed — fall through */
1053
+ }
1054
+ return undefined;
1055
+ }
1056
+ // ─── Pass 6: collect callable-value-flow facts ─────────────────────────────
1057
+ const CALLABLE_FLOW_KINDS = [
1058
+ 'seed',
1059
+ 'copy',
1060
+ 'alias',
1061
+ 'address',
1062
+ 'store',
1063
+ 'load',
1064
+ 'formal',
1065
+ 'argument',
1066
+ 'invoke',
1067
+ ];
1068
+ function pass6CollectCallableFlows(matches, positionIndex, filePath, out) {
1069
+ for (const match of matches) {
1070
+ const kind = callableFlowKind(match);
1071
+ if (kind === undefined)
1072
+ continue;
1073
+ const anchor = match[`@callable-flow.${kind}`];
1074
+ if (anchor === undefined)
1075
+ continue;
1076
+ switch (kind) {
1077
+ case 'seed': {
1078
+ const destination = callableFlowOperand(match, 'destination', positionIndex, filePath);
1079
+ const target = match['@callable-flow.target'];
1080
+ const targetName = match['@callable-flow.target-name']?.text ?? target?.text;
1081
+ if (destination === undefined || target === undefined || !nonEmpty(targetName))
1082
+ continue;
1083
+ const expectedSignature = callableFlowExpectedSignature(match);
1084
+ out.push({
1085
+ kind,
1086
+ destination,
1087
+ targetName,
1088
+ targetRange: target.range,
1089
+ ...(nonEmpty(match['@callable-flow.target-qualified-name']?.text)
1090
+ ? { targetQualifiedName: match['@callable-flow.target-qualified-name'].text }
1091
+ : {}),
1092
+ ...(expectedSignature !== undefined ? { expectedSignature } : {}),
1093
+ });
1094
+ break;
1095
+ }
1096
+ case 'copy':
1097
+ case 'alias': {
1098
+ const source = callableFlowOperand(match, 'source', positionIndex, filePath);
1099
+ const destination = callableFlowOperand(match, 'destination', positionIndex, filePath);
1100
+ if (source === undefined || destination === undefined)
1101
+ continue;
1102
+ out.push({ kind, source, destination });
1103
+ break;
1104
+ }
1105
+ case 'address': {
1106
+ const source = callableFlowOperand(match, 'source', positionIndex, filePath);
1107
+ const destination = callableFlowOperand(match, 'destination', positionIndex, filePath);
1108
+ if (source === undefined || destination === undefined)
1109
+ continue;
1110
+ out.push({ kind, source, destination });
1111
+ break;
1112
+ }
1113
+ case 'store': {
1114
+ const source = callableFlowOperand(match, 'source', positionIndex, filePath);
1115
+ const pointer = callableFlowOperand(match, 'pointer', positionIndex, filePath);
1116
+ if (source === undefined || pointer === undefined)
1117
+ continue;
1118
+ out.push({ kind, source, pointer });
1119
+ break;
1120
+ }
1121
+ case 'load': {
1122
+ const pointer = callableFlowOperand(match, 'pointer', positionIndex, filePath);
1123
+ const destination = callableFlowOperand(match, 'destination', positionIndex, filePath);
1124
+ if (pointer === undefined || destination === undefined)
1125
+ continue;
1126
+ out.push({ kind, pointer, destination });
1127
+ break;
1128
+ }
1129
+ case 'formal': {
1130
+ const owner = match['@callable-flow.owner'];
1131
+ const binding = callableFlowOperand(match, 'binding', positionIndex, filePath);
1132
+ const parameterIndex = parseNonNegativeInt(match['@callable-flow.parameter-index']?.text);
1133
+ const passingMode = parseCallablePassingMode(match['@callable-flow.passing-mode']?.text);
1134
+ if (owner === undefined ||
1135
+ !nonEmpty(owner.text) ||
1136
+ binding === undefined ||
1137
+ parameterIndex === undefined ||
1138
+ passingMode === undefined) {
1139
+ continue;
1140
+ }
1141
+ const expectedSignature = callableFlowExpectedSignature(match);
1142
+ out.push({
1143
+ kind,
1144
+ ownerName: owner.text,
1145
+ ownerRange: owner.range,
1146
+ parameterIndex,
1147
+ binding,
1148
+ passingMode,
1149
+ ...(expectedSignature !== undefined ? { expectedSignature } : {}),
1150
+ });
1151
+ break;
1152
+ }
1153
+ case 'argument': {
1154
+ const source = callableFlowOperand(match, 'source', positionIndex, filePath);
1155
+ const parameterIndex = parseNonNegativeInt(match['@callable-flow.parameter-index']?.text);
1156
+ if (source === undefined || parameterIndex === undefined)
1157
+ continue;
1158
+ out.push({
1159
+ kind,
1160
+ callSite: anchor.range,
1161
+ parameterIndex,
1162
+ source,
1163
+ ...(nonEmpty(match['@callable-flow.direct-callee-name']?.text)
1164
+ ? { directCalleeName: match['@callable-flow.direct-callee-name'].text }
1165
+ : {}),
1166
+ });
1167
+ break;
1168
+ }
1169
+ case 'invoke': {
1170
+ const callee = callableFlowOperand(match, 'callee', positionIndex, filePath);
1171
+ const inScope = positionIndex.atPosition(filePath, anchor.range.startLine, anchor.range.startCol);
1172
+ const invocationKind = parseCallableInvocationKind(match['@callable-flow.invocation-kind']?.text);
1173
+ if (callee === undefined || inScope === undefined || invocationKind === undefined)
1174
+ continue;
1175
+ const receiver = callableFlowOperand(match, 'receiver', positionIndex, filePath);
1176
+ const arity = parseNonNegativeInt(match['@callable-flow.arity']?.text);
1177
+ out.push({
1178
+ kind,
1179
+ callSite: anchor.range,
1180
+ inScope,
1181
+ callee,
1182
+ invocationKind,
1183
+ ...(receiver !== undefined ? { receiver } : {}),
1184
+ ...(arity !== undefined ? { arity } : {}),
1185
+ });
1186
+ break;
1187
+ }
1188
+ }
1189
+ }
1190
+ }
1191
+ function callableFlowKind(match) {
1192
+ return CALLABLE_FLOW_KINDS.find((kind) => match[`@callable-flow.${kind}`] !== undefined);
1193
+ }
1194
+ function callableFlowOperand(match, role, positionIndex, filePath) {
1195
+ const cap = match[`@callable-flow.${role}`];
1196
+ if (cap === undefined || !nonEmpty(cap.text))
1197
+ return undefined;
1198
+ const inScope = positionIndex.atPosition(filePath, cap.range.startLine, cap.range.startCol);
1199
+ if (inScope === undefined)
1200
+ return undefined;
1201
+ const expressionKind = parseCallableOperandKind(match[`@callable-flow.${role}-kind`]?.text);
1202
+ const indirection = parseNonNegativeInt(match[`@callable-flow.${role}-indirection`]?.text);
1203
+ if (indirection !== undefined && indirection > 16)
1204
+ return undefined;
1205
+ return {
1206
+ name: cap.text,
1207
+ inScope,
1208
+ atRange: cap.range,
1209
+ indirection: indirection ?? 0,
1210
+ addressOf: match[`@callable-flow.${role}-address`]?.text === 'true',
1211
+ ...(expressionKind !== undefined ? { expressionKind } : {}),
1212
+ ...(nonEmpty(match[`@callable-flow.${role}-qualified-name`]?.text)
1213
+ ? { qualifiedName: match[`@callable-flow.${role}-qualified-name`].text }
1214
+ : {}),
1215
+ };
1216
+ }
1217
+ function callableFlowExpectedSignature(match) {
1218
+ const parameterCount = parseNonNegativeInt(match['@callable-flow.expected-arity']?.text);
1219
+ const parameterTypes = parseJsonStringArray(match['@callable-flow.expected-types']?.text);
1220
+ const parameterTypeClasses = parseJsonParameterTypeClassesCapture(match['@callable-flow.expected-type-classes']);
1221
+ const isConst = parseBooleanText(match['@callable-flow.expected-const']?.text);
1222
+ if (parameterCount === undefined &&
1223
+ parameterTypes === undefined &&
1224
+ parameterTypeClasses === undefined &&
1225
+ isConst === undefined) {
1226
+ return undefined;
1227
+ }
1228
+ return {
1229
+ ...(parameterCount !== undefined ? { parameterCount } : {}),
1230
+ ...(parameterTypes !== undefined ? { parameterTypes } : {}),
1231
+ ...(parameterTypeClasses !== undefined ? { parameterTypeClasses } : {}),
1232
+ ...(isConst !== undefined ? { isConst } : {}),
1233
+ };
1234
+ }
1235
+ function parseCallableOperandKind(text) {
1236
+ switch (text) {
1237
+ case 'binding':
1238
+ case 'callable-designator':
1239
+ case 'bound-member':
1240
+ case 'anonymous-callable':
1241
+ return text;
1242
+ default:
1243
+ return undefined;
1244
+ }
1245
+ }
1246
+ function parseBooleanText(text) {
1247
+ if (text === 'true')
1248
+ return true;
1249
+ if (text === 'false')
1250
+ return false;
1251
+ return undefined;
1252
+ }
1253
+ function parseJsonStringArray(text) {
1254
+ if (text === undefined)
1255
+ return undefined;
1256
+ try {
1257
+ const parsed = JSON.parse(text);
1258
+ return Array.isArray(parsed) && parsed.every((value) => typeof value === 'string')
1259
+ ? parsed
1260
+ : undefined;
1261
+ }
1262
+ catch {
1263
+ return undefined;
1264
+ }
1265
+ }
1266
+ function parseNonNegativeInt(text) {
1267
+ if (text === undefined || !/^\d+$/.test(text))
1268
+ return undefined;
1269
+ const value = Number.parseInt(text, 10);
1270
+ return Number.isSafeInteger(value) ? value : undefined;
1271
+ }
1272
+ function parseCallablePassingMode(text) {
1273
+ switch (text) {
1274
+ case 'value':
1275
+ case 'reference':
1276
+ case 'pointer':
1277
+ return text;
1278
+ default:
1279
+ return undefined;
1280
+ }
1281
+ }
1282
+ function parseCallableInvocationKind(text) {
1283
+ switch (text) {
1284
+ case 'indirect':
1285
+ case 'member-pointer':
1286
+ case 'callable-object':
1287
+ return text;
1288
+ default:
1289
+ return undefined;
1290
+ }
1291
+ }
1292
+ function nonEmpty(value) {
1293
+ return value !== undefined && value.length > 0;
1294
+ }
1295
+ // ─── Internal: range + capture utilities ───────────────────────────────────
1296
+ function rangesEqual(a, b) {
1297
+ return (a.startLine === b.startLine &&
1298
+ a.startCol === b.startCol &&
1299
+ a.endLine === b.endLine &&
1300
+ a.endCol === b.endCol);
1301
+ }
1302
+ /**
1303
+ * Capture names that are never anchors — they are sub-tags nested inside a
1304
+ * larger anchor (e.g., the receiver expression inside a `@reference.call`
1305
+ * may span more source than the called name, but is not the call itself).
1306
+ *
1307
+ * The list is maintained here centrally rather than per-pass because the
1308
+ * set is small and stable; adding a new sub-tag convention is a one-line
1309
+ * change.
1310
+ */
1311
+ const KNOWN_SUB_TAGS = new Set([
1312
+ '@scope.lexical-names',
1313
+ '@declaration.name',
1314
+ '@declaration.qualified_name',
1315
+ '@import.name',
1316
+ '@import.source',
1317
+ '@import.alias',
1318
+ '@type-binding.name',
1319
+ '@type-binding.type',
1320
+ '@reference.name',
1321
+ '@reference.qualified-name',
1322
+ '@reference.property-key',
1323
+ '@reference.callee-position',
1324
+ '@reference.embedded-pointer',
1325
+ '@reference.receiver',
1326
+ '@reference.operator',
1327
+ '@reference.arity',
1328
+ '@reference.parameter-types',
1329
+ '@reference.parameter-type-classes',
1330
+ '@declaration.parameter-count',
1331
+ '@declaration.required-parameter-count',
1332
+ '@declaration.parameter-types',
1333
+ '@declaration.parameter-type-classes',
1334
+ '@declaration.return-type',
1335
+ '@declaration.template-constraints',
1336
+ // MUST be listed, and the failure it prevents is silent def LOSS rather than
1337
+ // a missing field. `anchorCaptureFor` picks the broadest-span `@declaration.*`
1338
+ // capture that is not a known sub-tag; a type-parameter list is normally
1339
+ // narrower than the declaration that owns it, but a C++ `template <class A,
1340
+ // class B, …>` or a multi-line Java `<T extends A & B>` written above a short
1341
+ // declaration can out-span it. The anchor would then be `type-parameters`,
1342
+ // `normalizeNodeLabel` would return undefined for it, and the whole class def
1343
+ // would be dropped rather than merely losing its parameters.
1344
+ '@declaration.type-parameters',
1345
+ '@declaration.is-explicit',
1346
+ '@declaration.is-deleted',
1347
+ ]);
1348
+ /**
1349
+ * Return the anchor capture for a match — the one whose name begins with
1350
+ * `prefix` AND is not in the known-sub-tag set. When multiple candidates
1351
+ * remain, the broadest-ranged one wins: tree-sitter queries often tag
1352
+ * both a whole statement and a sub-token under the same topic
1353
+ * (`@scope.function` + `@scope.function.name`); the anchor is the
1354
+ * statement-level one.
1355
+ */
1356
+ function anchorCaptureFor(match, prefix) {
1357
+ let best;
1358
+ let bestSpan = -1;
1359
+ for (const name of Object.keys(match)) {
1360
+ if (!name.startsWith(prefix))
1361
+ continue;
1362
+ if (KNOWN_SUB_TAGS.has(name))
1363
+ continue;
1364
+ const cap = match[name];
1365
+ const span = (cap.range.endLine - cap.range.startLine) * 1_000_000 +
1366
+ (cap.range.endCol - cap.range.startCol);
1367
+ if (span > bestSpan) {
1368
+ bestSpan = span;
1369
+ best = cap;
1370
+ }
1371
+ }
1372
+ return best;
1373
+ }