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,1262 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.emitKotlinScopeCaptures = emitKotlinScopeCaptures;
4
+ const index_js_1 = require("../../../../../shared/index.js");
5
+ const bean_candidates_js_1 = require("../../frameworks/spring/bean-candidates.js");
6
+ const ast_helpers_js_1 = require("../../utils/ast-helpers.js");
7
+ const constants_js_1 = require("../../constants.js");
8
+ const safe_parse_js_1 = require("../../../tree-sitter/safe-parse.js");
9
+ const arity_metadata_js_1 = require("./arity-metadata.js");
10
+ const import_decomposer_js_1 = require("./import-decomposer.js");
11
+ const cache_stats_js_1 = require("./cache-stats.js");
12
+ const interpret_js_1 = require("./interpret.js");
13
+ const receiver_binding_js_1 = require("./receiver-binding.js");
14
+ const query_js_1 = require("./query.js");
15
+ const companion_scopes_js_1 = require("./companion-scopes.js");
16
+ const capture_side_channel_js_1 = require("./capture-side-channel.js");
17
+ const package_facts_js_1 = require("./package-facts.js");
18
+ const callable_flow_captures_js_1 = require("../../utils/callable-flow-captures.js");
19
+ const spring_di_js_1 = require("./spring-di.js");
20
+ const receiver_chain_captures_js_1 = require("../../utils/receiver-chain-captures.js");
21
+ const spring_aop_js_1 = require("./spring-aop.js");
22
+ const spring_conditionals_js_1 = require("./spring-conditionals.js");
23
+ const FUNCTION_DECL_TAGS = ['@declaration.function'];
24
+ const KOTLIN_CALLABLE_CAPTURE_OPTIONS = {
25
+ functionNodeTypes: new Set(['function_declaration', 'anonymous_function', 'lambda_literal']),
26
+ callNodeTypes: new Set(['call_expression']),
27
+ parameterListNodeTypes: new Set(['function_value_parameters', 'value_arguments']),
28
+ parameterNodeTypes: new Set(['parameter']),
29
+ bindingNodeTypes: new Set(['property_declaration']),
30
+ assignmentNodeTypes: new Set(['assignment']),
31
+ identifierNodeTypes: new Set(['simple_identifier', 'type_identifier']),
32
+ callableReferenceNodeTypes: new Set(['callable_reference']),
33
+ callableProtocolMethods: new Set(['invoke']),
34
+ functionName: (node) => node.namedChildren.find((child) => child !== null && child.type === 'simple_identifier')?.text,
35
+ extractAssignment: (node) => {
36
+ // tree-sitter-kotlin's `assignment` node is FIELDLESS (positional
37
+ // `directly_assignable_expression` then the value), so the shared
38
+ // field-based fallback returned nothing and nested reassignments
39
+ // (`chosen = ::target` inside a block) never produced flow facts
40
+ // (#2522 review, shallow-coverage gap).
41
+ if (node.type === 'assignment') {
42
+ const named = node.namedChildren.filter((child) => child !== null);
43
+ if (named.length < 2)
44
+ return undefined;
45
+ return { destination: named[0], source: named[named.length - 1] };
46
+ }
47
+ if (node.type !== 'property_declaration')
48
+ return undefined;
49
+ if (!node.children.some((child) => child.text === '='))
50
+ return undefined;
51
+ const destination = node.namedChildren.find((child) => child !== null && child.type === 'variable_declaration');
52
+ const source = [...node.namedChildren]
53
+ .reverse()
54
+ .find((child) => child !== null && child.id !== destination?.id && child.type !== 'binding_pattern_kind');
55
+ return destination === undefined || source === undefined ? undefined : { destination, source };
56
+ },
57
+ normalizeQualifiedName: (raw) => raw.replaceAll('::', '.'),
58
+ };
59
+ function emitKotlinScopeCaptures(sourceText, filePath, cachedTree) {
60
+ let tree = cachedTree;
61
+ if (tree === undefined) {
62
+ tree = (0, safe_parse_js_1.parseSourceSafe)((0, query_js_1.getKotlinParser)(), sourceText, undefined, {
63
+ bufferSize: (0, constants_js_1.getTreeSitterBufferSize)(sourceText),
64
+ });
65
+ (0, cache_stats_js_1.recordKotlinCacheMiss)();
66
+ }
67
+ else {
68
+ (0, cache_stats_js_1.recordKotlinCacheHit)();
69
+ }
70
+ (0, package_facts_js_1.captureKotlinPackageFact)(filePath, tree.rootNode);
71
+ const out = [];
72
+ const classAnnotations = new Map();
73
+ const springAopFacts = [];
74
+ const springAopTypeNodeIds = new Set();
75
+ const springConditionalFacts = [];
76
+ const springDiFacts = [];
77
+ const springDiClassNodeIds = new Set();
78
+ const returnTypes = collectKotlinReturnTypeTexts(tree.rootNode);
79
+ out.push(...synthesizeKotlinLocalAssignmentBindings(tree.rootNode, returnTypes));
80
+ out.push(...synthesizeKotlinLoopBindings(tree.rootNode, returnTypes));
81
+ out.push(...synthesizeKotlinSmartCastBindings(tree.rootNode));
82
+ out.push(...synthesizeKotlinLambdaBindings(tree.rootNode, returnTypes));
83
+ out.push(...synthesizeKotlinInheritanceReferences(tree.rootNode));
84
+ out.push(...synthesizeKotlinSecondaryConstructorDeclarations(tree.rootNode));
85
+ for (const match of (0, query_js_1.getKotlinScopeQuery)().matches(tree.rootNode)) {
86
+ const grouped = {};
87
+ // Parallel tag -> captured SyntaxNode map. The query hands us each matched
88
+ // node as capture.node, so anchors resolve via a type-guarded lookup
89
+ // (nodeIfType) instead of re-deriving them with
90
+ // findNodeAtRange(tree.rootNode, ...) per match — the O(matches x N)
91
+ // root-walk fixed for go #1915 / python #1918 / csharp, mirrored here.
92
+ const groupedNodes = {};
93
+ for (const capture of match.captures) {
94
+ const tag = '@' + capture.name;
95
+ grouped[tag] = (0, ast_helpers_js_1.nodeToCapture)(tag, capture.node);
96
+ groupedNodes[tag] = capture.node;
97
+ }
98
+ if (Object.keys(grouped).length === 0)
99
+ continue;
100
+ // tree-sitter-kotlin represents both classes and interfaces with
101
+ // `class_declaration`; `object_declaration` is the separate object form.
102
+ const springAopTypeNode = [
103
+ (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@scope.class'], 'class_declaration'),
104
+ (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@scope.class'], 'object_declaration'),
105
+ (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@scope.class'], 'companion_object'),
106
+ ].find((node) => node !== null);
107
+ if (springAopTypeNode !== undefined && !springAopTypeNodeIds.has(springAopTypeNode.id)) {
108
+ springAopTypeNodeIds.add(springAopTypeNode.id);
109
+ springAopFacts.push(...(0, spring_aop_js_1.captureKotlinSpringAopFacts)(springAopTypeNode, filePath));
110
+ }
111
+ const springDiClassNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@scope.class'], 'class_declaration');
112
+ if (springDiClassNode !== null && !springDiClassNodeIds.has(springDiClassNode.id)) {
113
+ springDiClassNodeIds.add(springDiClassNode.id);
114
+ springConditionalFacts.push(...(0, spring_conditionals_js_1.captureKotlinSpringConditionalFacts)(springDiClassNode, filePath));
115
+ const fact = (0, spring_di_js_1.captureKotlinSpringDiClassFact)(springDiClassNode, filePath);
116
+ if (fact !== null)
117
+ springDiFacts.push(fact);
118
+ }
119
+ const annotatedClass = grouped['@class-annotation.class'];
120
+ const annotationName = grouped['@class-annotation.name'];
121
+ if (annotatedClass !== undefined && annotationName !== undefined) {
122
+ const classNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@class-annotation.class'], 'class_declaration');
123
+ if (classNode !== null && isKotlinBeanCandidateClass(classNode)) {
124
+ (0, bean_candidates_js_1.recordClassAnnotationCapture)(classAnnotations, filePath, annotatedClass, annotationName.text);
125
+ }
126
+ continue;
127
+ }
128
+ // Companion-object marker (#1756 / U4). The `@scope.companion`
129
+ // capture is a side-channel marker — it shares its range with the
130
+ // existing `(companion_object) @scope.class` rule, so the Class
131
+ // scope already exists in the scope tree. Record the scope id into
132
+ // the per-file companion-scope set so `populateCompanionMembersOn
133
+ // EnclosingClass` (owners.ts) can identify companion scopes
134
+ // unambiguously, regardless of whether they are anonymous, named,
135
+ // or contain nested classes. The match itself is consumed here and
136
+ // NOT pushed to the output — the scope-extractor would reject the
137
+ // `companion` kind suffix anyway, but suppressing the emit keeps
138
+ // downstream pipelines from re-processing the same range twice.
139
+ if (grouped['@scope.companion'] !== undefined) {
140
+ const scopeId = (0, index_js_1.makeScopeId)({
141
+ filePath,
142
+ range: grouped['@scope.companion'].range,
143
+ kind: 'Class',
144
+ });
145
+ (0, companion_scopes_js_1.markCompanionScope)(filePath, scopeId);
146
+ continue;
147
+ }
148
+ if (grouped['@import.statement'] !== undefined) {
149
+ const importNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@import.statement'], 'import_header');
150
+ if (importNode !== null) {
151
+ const decomposed = (0, import_decomposer_js_1.splitKotlinImportHeader)(importNode);
152
+ if (decomposed !== null) {
153
+ out.push(decomposed);
154
+ continue;
155
+ }
156
+ }
157
+ }
158
+ // Callable references (`::method`, `Type::new`, `obj::m`) — F47 (#1919).
159
+ // The query captures the referenced member as `@reference.name`, an
160
+ // optional receiver type as `@reference.receiver`, and the whole node as
161
+ // `@reference.callable`. Rewrite into a call reference so it participates
162
+ // in call-graph resolution: a bare `::member` resolves as a free call;
163
+ // a `Receiver::member` resolves as a member call against the receiver
164
+ // type. The function/constructor is referenced (not invoked), so no
165
+ // arity/argument metadata is attached.
166
+ if (grouped['@reference.callable'] !== undefined) {
167
+ const nameCap = grouped['@reference.name'];
168
+ const callableNode = groupedNodes['@reference.callable'];
169
+ if (nameCap !== undefined && callableNode !== undefined) {
170
+ const receiverCap = grouped['@reference.receiver'];
171
+ // The anchor Capture must carry the call-form tag as its `name` —
172
+ // the scope-extractor reads `Capture.name` (not the map key) to
173
+ // classify the reference kind, so re-wrap via nodeToCapture rather
174
+ // than reusing the `@reference.callable`-named Capture (whose head
175
+ // `callable` resolves to no ReferenceKind and silently drops it).
176
+ if (receiverCap !== undefined) {
177
+ out.push({
178
+ '@reference.call.member': (0, ast_helpers_js_1.nodeToCapture)('@reference.call.member', callableNode),
179
+ '@reference.name': nameCap,
180
+ '@reference.receiver': receiverCap,
181
+ });
182
+ }
183
+ else {
184
+ out.push({
185
+ '@reference.call.free': (0, ast_helpers_js_1.nodeToCapture)('@reference.call.free', callableNode),
186
+ '@reference.name': nameCap,
187
+ });
188
+ }
189
+ }
190
+ continue;
191
+ }
192
+ if (grouped['@reference.call.free'] !== undefined &&
193
+ grouped['@reference.receiver'] !== undefined) {
194
+ continue;
195
+ }
196
+ if (grouped['@reference.read.member'] !== undefined) {
197
+ const navNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@reference.read.member'], 'navigation_expression');
198
+ if (navNode === null || !shouldEmitReadMember(navNode))
199
+ continue;
200
+ }
201
+ // Virtual dispatch via constructor type (#1762). When a property
202
+ // declaration carries BOTH an explicit type annotation AND a
203
+ // constructor-style call value (e.g. `val animal: Animal = Dog()`),
204
+ // suppress the annotation capture so the constructor-inferred
205
+ // binding wins. This matches Kotlin's virtual dispatch semantics:
206
+ // `animal.speak()` should resolve to the overriding `Dog.speak`
207
+ // (the dynamic type), not `Animal.speak` (the static annotation).
208
+ //
209
+ // The annotation source has higher precedence than constructor-
210
+ // inferred in the generic scope-extractor (see
211
+ // `typeBindingStrength` in scope-extractor.ts), so the only way to
212
+ // make the constructor type prevail is to drop the annotation at
213
+ // emission time.
214
+ if (grouped['@type-binding.annotation'] !== undefined &&
215
+ grouped['@type-binding.name'] !== undefined &&
216
+ grouped['@type-binding.type'] !== undefined) {
217
+ const propNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@type-binding.annotation'], 'property_declaration');
218
+ if (propNode !== null && propertyDeclHasConstructorValue(propNode)) {
219
+ continue;
220
+ }
221
+ }
222
+ if (grouped['@scope.function'] !== undefined) {
223
+ // Structural receiver chain for a call whose receiver is itself an
224
+ // expression, so resolution can type it by folding over structure
225
+ // instead of re-parsing the receiver's source text. Self-gating: a
226
+ // non-call match, an absent receiver, or a chain with no nameable base
227
+ // all leave `grouped` untouched.
228
+ (0, receiver_chain_captures_js_1.synthesizeReceiverChainCapture)(grouped, groupedNodes['@reference.receiver']);
229
+ out.push(grouped);
230
+ const fnNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@scope.function'], 'function_declaration');
231
+ if (fnNode !== null) {
232
+ out.push(...(0, receiver_binding_js_1.synthesizeKotlinReceiverBinding)(fnNode));
233
+ }
234
+ continue;
235
+ }
236
+ const declTag = FUNCTION_DECL_TAGS.find((tag) => grouped[tag] !== undefined);
237
+ if (declTag !== undefined) {
238
+ const fnNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes[declTag], 'function_declaration');
239
+ if (fnNode !== null) {
240
+ const arity = (0, arity_metadata_js_1.computeKotlinArityMetadata)(fnNode);
241
+ if (arity.parameterCount !== undefined) {
242
+ grouped['@declaration.parameter-count'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-count', fnNode, String(arity.parameterCount));
243
+ }
244
+ if (arity.requiredParameterCount !== undefined) {
245
+ grouped['@declaration.required-parameter-count'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.required-parameter-count', fnNode, String(arity.requiredParameterCount));
246
+ }
247
+ if (arity.parameterTypes !== undefined) {
248
+ grouped['@declaration.parameter-types'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-types', fnNode, JSON.stringify(arity.parameterTypes));
249
+ }
250
+ }
251
+ }
252
+ const callTag = ['@reference.call.free', '@reference.call.member', '@reference.call.constructor'].find((tag) => grouped[tag] !== undefined);
253
+ if (callTag !== undefined && grouped['@reference.arity'] === undefined) {
254
+ const callNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes[callTag], 'call_expression');
255
+ if (callNode !== null) {
256
+ const args = callArguments(callNode);
257
+ grouped['@reference.arity'] = (0, ast_helpers_js_1.syntheticCapture)('@reference.arity', callNode, String(args.length));
258
+ grouped['@reference.parameter-types'] = (0, ast_helpers_js_1.syntheticCapture)('@reference.parameter-types', callNode, JSON.stringify(args.map(inferArgType)));
259
+ }
260
+ }
261
+ // Structural receiver chain for a call whose receiver is itself an
262
+ // expression, so resolution can type it by folding over structure
263
+ // instead of re-parsing the receiver's source text. Self-gating: a
264
+ // non-call match, an absent receiver, or a chain with no nameable base
265
+ // all leave `grouped` untouched.
266
+ (0, receiver_chain_captures_js_1.synthesizeReceiverChainCapture)(grouped, groupedNodes['@reference.receiver']);
267
+ out.push(grouped);
268
+ const extensionFallback = extensionFreeCallFallback(grouped, groupedNodes);
269
+ if (extensionFallback !== null)
270
+ out.push(extensionFallback);
271
+ }
272
+ (0, capture_side_channel_js_1.setKotlinClassAnnotationFacts)(filePath, (0, bean_candidates_js_1.materializeClassAnnotationFacts)(classAnnotations));
273
+ (0, capture_side_channel_js_1.setKotlinSpringAopFacts)(filePath, springAopFacts);
274
+ (0, capture_side_channel_js_1.setKotlinSpringConditionalFacts)(filePath, springConditionalFacts);
275
+ (0, capture_side_channel_js_1.setKotlinSpringDiFacts)(filePath, springDiFacts);
276
+ out.push(...(0, callable_flow_captures_js_1.synthesizeCallableFlowCaptures)(tree.rootNode, KOTLIN_CALLABLE_CAPTURE_OPTIONS));
277
+ return out;
278
+ }
279
+ function isKotlinBeanCandidateClass(classNode) {
280
+ if (classNode.children.some((child) => child.type === 'interface' || child.type === 'enum')) {
281
+ return false;
282
+ }
283
+ const modifiers = classNode.namedChildren.find((child) => child.type === 'modifiers');
284
+ return !modifiers?.namedChildren.some((child) => child.type === 'class_modifier' && child.text.trim() === 'annotation');
285
+ }
286
+ /**
287
+ * Synthesize `@reference.inherits` captures from Kotlin `class_declaration`
288
+ * delegation specifiers so the registry-primary scope-resolution path emits
289
+ * EXTENDS / IMPLEMENTS edges (mirrors C# `synthesizeCsharpInheritanceReferences`
290
+ * and C++ `emitCppInheritanceCaptures`). Without this, Kotlin inheritance edges
291
+ * came only from the legacy heritage-capture leg (removed in #942), which the
292
+ * worker pipeline drops for registry-primary languages → 0 inheritance edges in
293
+ * worker mode (#1951).
294
+ *
295
+ * Scope mirrors the legacy KOTLIN_QUERIES heritage patterns exactly
296
+ * (the config-driven `kotlinHeritageShapes`: `user_type`,
297
+ * `constructor_invocation`, `explicit_delegation`). Each `delegation_specifier`
298
+ * child of a `class_declaration`, in one of three forms —
299
+ * - bare interface/superclass: `class Foo : Bar`
300
+ * `(delegation_specifier (user_type (type_identifier)))`
301
+ * - constructor-call superclass: `class Foo : Bar()`
302
+ * `(delegation_specifier (constructor_invocation (user_type (type_identifier))))`
303
+ * - interface delegation: `class Foo : Bar by delegate`
304
+ * `(delegation_specifier (explicit_delegation (user_type (type_identifier)) …))`
305
+ * — the delegated interface is the LEADING `user_type`; the trailing
306
+ * delegate expression (`by delegate`) is NOT a supertype (#1951). This is
307
+ * the dropped shape the registry-primary synth previously skipped, leaving
308
+ * `class F : Iface by d` with no IMPLEMENTS edge in worker mode.
309
+ *
310
+ * Kotlin uses `:` for BOTH superclass and interfaces — the EXTENDS-vs-IMPLEMENTS
311
+ * split is decided downstream from the resolved target's symbol kind
312
+ * (`preEmitInheritanceEdges`), so every base is emitted with the same `inherits`
313
+ * kind here. The bare lookup name is normalized to the simple identifier
314
+ * (`Base()` → `Base`, `Base<T>` → `Base`, `pkg.Base` → `Base`,
315
+ * `Iface by d` → `Iface`) so V1's simple-name `findClassBindingInScope`
316
+ * resolves it. The extracted bare name agrees with the legacy leg's
317
+ * `normalizeSupertypeName` for every shape (verified by real-parse).
318
+ */
319
+ function synthesizeKotlinInheritanceReferences(rootNode) {
320
+ const out = [];
321
+ for (const classNode of descendantsOfType(rootNode, 'class_declaration')) {
322
+ for (const child of classNode.namedChildren) {
323
+ if (child.type !== 'delegation_specifier')
324
+ continue;
325
+ // Three wrappers, all resolving to a leading `user_type` →
326
+ // `type_identifier`:
327
+ // - `(delegation_specifier (constructor_invocation (user_type …)))` for `Base()`
328
+ // - `(delegation_specifier (explicit_delegation (user_type …) <delegate>))`
329
+ // for `Iface by d` — the supertype is the FIRST `user_type`; the
330
+ // delegate expression that trails `by` is ignored.
331
+ // - `(delegation_specifier (user_type …))` for a bare interface/superclass.
332
+ const ctor = child.namedChildren.find((n) => n.type === 'constructor_invocation');
333
+ const delegation = child.namedChildren.find((n) => n.type === 'explicit_delegation');
334
+ const userType = ctor?.namedChildren.find((n) => n.type === 'user_type') ??
335
+ delegation?.namedChildren.find((n) => n.type === 'user_type') ??
336
+ child.namedChildren.find((n) => n.type === 'user_type');
337
+ if (userType === undefined)
338
+ continue;
339
+ const nameNode = kotlinUserTypeNameNode(userType);
340
+ if (nameNode === null)
341
+ continue;
342
+ out.push({
343
+ '@reference.inherits': (0, ast_helpers_js_1.nodeToCapture)('@reference.inherits', child),
344
+ '@reference.name': (0, ast_helpers_js_1.nodeToCapture)('@reference.name', nameNode),
345
+ });
346
+ }
347
+ }
348
+ return out;
349
+ }
350
+ /**
351
+ * The enclosing type name for a node nested in a class/object/companion body.
352
+ * Walks up to the first `class_declaration` / `object_declaration` /
353
+ * `companion_object` ancestor and returns its `type_identifier` name node.
354
+ * Used to qualify a secondary-constructor declaration as `<ClassName>.constructor`.
355
+ */
356
+ function kotlinEnclosingTypeNameNode(node) {
357
+ for (let cur = node.parent; cur !== null; cur = cur.parent) {
358
+ if (cur.type === 'class_declaration' ||
359
+ cur.type === 'object_declaration' ||
360
+ cur.type === 'companion_object') {
361
+ const nameNode = cur.namedChildren.find((c) => c.type === 'type_identifier');
362
+ return nameNode ?? null;
363
+ }
364
+ }
365
+ return null;
366
+ }
367
+ /**
368
+ * Synthesize a `@declaration.constructor` capture for each Kotlin
369
+ * `secondary_constructor` (issue #1919 review CF1). The structure phase already
370
+ * materializes a `Constructor` graph node (`Constructor:file:Class.constructor#<arity>`),
371
+ * but the registry-primary scope-resolution path had no Constructor *def* in the
372
+ * scope tree — so a call inside the constructor body resolved its caller anchor
373
+ * up to the enclosing Class def, mis-attributing the CALLS edge to the class.
374
+ *
375
+ * Paired with `(secondary_constructor) @scope.function` in query.ts: that rule
376
+ * makes the constructor body its own Function scope; this declaration places a
377
+ * Constructor def in that scope so `pickCallerCallableDef` anchors calls on the
378
+ * Constructor. The def is keyed to match the structure-phase node id:
379
+ * - `@declaration.qualified_name` = `<ClassName>.constructor` so the bridge's
380
+ * qualified key (`<q>:file::Constructor::Class.constructor`) hits the node.
381
+ * - `@declaration.parameter-types` so two same-name secondary constructors are
382
+ * disambiguated by the bridge's parameter-types key (`~Int,Int`), matching
383
+ * the `#<arity>`-suffixed structure node for the overload with the same
384
+ * parameter shape. (The zero-arg overload carries no parameter types and
385
+ * resolves via the qualified/simple key to the `#0` node.)
386
+ *
387
+ * The anchor spans the whole `secondary_constructor` node — same range as the
388
+ * `@scope.function` it pairs with — so the def is owned by that Function scope
389
+ * and the constructor name auto-hoists to the enclosing class scope (exactly the
390
+ * binding shape a normal method declaration produces).
391
+ */
392
+ function synthesizeKotlinSecondaryConstructorDeclarations(rootNode) {
393
+ const out = [];
394
+ for (const ctorNode of descendantsOfType(rootNode, 'secondary_constructor')) {
395
+ const keyword = ctorNode.namedChildren.find((c) => c.type === 'constructor');
396
+ // The `constructor` keyword is an anonymous token; fall back to the node
397
+ // itself for the name capture position when the named-child lookup misses.
398
+ const nameAnchor = keyword ?? ctorNode;
399
+ const classNameNode = kotlinEnclosingTypeNameNode(ctorNode);
400
+ const qualifiedName = classNameNode !== null ? `${classNameNode.text}.constructor` : 'constructor';
401
+ const match = {
402
+ '@declaration.constructor': (0, ast_helpers_js_1.nodeToCapture)('@declaration.constructor', ctorNode),
403
+ '@declaration.name': (0, ast_helpers_js_1.syntheticCapture)('@declaration.name', nameAnchor, 'constructor'),
404
+ '@declaration.qualified_name': (0, ast_helpers_js_1.syntheticCapture)('@declaration.qualified_name', ctorNode, qualifiedName),
405
+ };
406
+ const arity = (0, arity_metadata_js_1.computeKotlinArityMetadata)(ctorNode);
407
+ if (arity.parameterCount !== undefined) {
408
+ match['@declaration.parameter-count'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-count', ctorNode, String(arity.parameterCount));
409
+ }
410
+ if (arity.requiredParameterCount !== undefined) {
411
+ match['@declaration.required-parameter-count'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.required-parameter-count', ctorNode, String(arity.requiredParameterCount));
412
+ }
413
+ if (arity.parameterTypes !== undefined) {
414
+ match['@declaration.parameter-types'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-types', ctorNode, JSON.stringify(arity.parameterTypes));
415
+ }
416
+ out.push(match);
417
+ }
418
+ return out;
419
+ }
420
+ /**
421
+ * The bare simple-name `type_identifier` of a `user_type`. Strips generic
422
+ * type arguments (`Base<T>` → `Base`) and qualifier tails (`pkg.Base` → `Base`)
423
+ * by taking the LAST direct `type_identifier` child, matching the legacy
424
+ * heritage capture of a `user_type`'s `type_identifier` and V1's
425
+ * simple-name `findClassBindingInScope` contract.
426
+ */
427
+ function kotlinUserTypeNameNode(userType) {
428
+ let nameNode = null;
429
+ for (const child of userType.namedChildren) {
430
+ if (child.type === 'type_identifier')
431
+ nameNode = child;
432
+ }
433
+ return nameNode;
434
+ }
435
+ function synthesizeKotlinLoopBindings(rootNode, returnTypes) {
436
+ const out = [];
437
+ for (const fnNode of descendantsOfType(rootNode, 'function_declaration')) {
438
+ const localTypes = collectKotlinLocalTypeTexts(fnNode, returnTypes);
439
+ for (const forNode of descendantsOfType(fnNode, 'for_statement')) {
440
+ const variable = forNode.namedChildren.find((child) => child.type === 'variable_declaration');
441
+ const name = variable?.namedChildren.find((child) => child.type === 'simple_identifier');
442
+ if (variable === undefined || name === undefined)
443
+ continue;
444
+ const explicitType = variable.namedChildren.find((child) => isKotlinTypeNode(child));
445
+ const iterable = forNode.namedChildren.find((child) => child.id !== variable.id && child.type !== 'control_structure_body');
446
+ const rawType = explicitType?.text ??
447
+ (iterable === undefined
448
+ ? null
449
+ : inferKotlinIterableElementType(iterable, localTypes, returnTypes));
450
+ if (rawType === null || rawType.trim() === '')
451
+ continue;
452
+ const anchor = forNode.namedChildren.find((child) => child.type === 'control_structure_body') ?? forNode;
453
+ out.push({
454
+ '@type-binding.annotation': (0, ast_helpers_js_1.nodeToCapture)('@type-binding.annotation', anchor),
455
+ '@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', name, name.text),
456
+ '@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', explicitType ?? iterable ?? name, (0, interpret_js_1.normalizeKotlinType)(rawType)),
457
+ });
458
+ }
459
+ }
460
+ return out;
461
+ }
462
+ /**
463
+ * Synthesize narrowed type-bindings for Kotlin smart-cast forms — issue #1758.
464
+ *
465
+ * For each `when (x) { is T -> body }` and `if (x is T) body`, emits a
466
+ * `@type-binding.annotation` capture binding `x → T` anchored on the body
467
+ * node. The capture lands in the matching `@scope.block` scope (see query.ts
468
+ * smart-cast scopes), shadowing the outer parameter binding for calls inside
469
+ * the body without leaking across sibling arms or to `else`.
470
+ *
471
+ * Only narrows when:
472
+ * - the `when` subject is a `simple_identifier` (not a call or field chain);
473
+ * - the `when_entry` condition is exactly one `type_test` (skips `!is`,
474
+ * compound conditions, range/`in`/value patterns);
475
+ * - the `if_expression` condition is a `check_expression` of the form
476
+ * `<simple_identifier> is <user_type>` and the then-branch is a
477
+ * `control_structure_body`.
478
+ *
479
+ * `else` arms and non-narrowing conditions emit nothing — the fall-through to
480
+ * the outer scope's declared type is the correct semantic.
481
+ */
482
+ function synthesizeKotlinSmartCastBindings(rootNode) {
483
+ const out = [];
484
+ for (const whenNode of descendantsOfType(rootNode, 'when_expression')) {
485
+ const subjectName = extractWhenSubjectIdentifier(whenNode);
486
+ if (subjectName === null)
487
+ continue;
488
+ for (const entry of whenNode.namedChildren) {
489
+ if (entry.type !== 'when_entry')
490
+ continue;
491
+ const narrowedType = extractIsTestTargetType(entry);
492
+ if (narrowedType === null)
493
+ continue;
494
+ const body = entry.namedChildren.find((child) => child.type === 'control_structure_body');
495
+ if (body === undefined)
496
+ continue;
497
+ out.push(buildNarrowedTypeBindingCapture(subjectName.node, body, narrowedType));
498
+ }
499
+ }
500
+ for (const ifNode of descendantsOfType(rootNode, 'if_expression')) {
501
+ const check = ifNode.namedChildren.find((child) => child.type === 'check_expression');
502
+ if (check === undefined)
503
+ continue;
504
+ const subject = check.namedChildren.find((child) => child.type === 'simple_identifier');
505
+ const typeNode = check.namedChildren.find((child) => isKotlinTypeNode(child));
506
+ if (subject === undefined || typeNode === undefined)
507
+ continue;
508
+ // The first control_structure_body sibling is the then-branch; else
509
+ // branches (when present) appear as the second control_structure_body
510
+ // and are intentionally not narrowed.
511
+ const body = ifNode.namedChildren.find((child) => child.type === 'control_structure_body');
512
+ if (body === undefined)
513
+ continue;
514
+ out.push(buildNarrowedTypeBindingCapture(subject, body, typeNode));
515
+ }
516
+ return out;
517
+ }
518
+ function extractWhenSubjectIdentifier(whenNode) {
519
+ const subject = whenNode.namedChildren.find((child) => child.type === 'when_subject');
520
+ if (subject === undefined)
521
+ return null;
522
+ const ident = subject.namedChildren.find((child) => child.type === 'simple_identifier');
523
+ return ident === undefined ? null : { node: ident };
524
+ }
525
+ function extractIsTestTargetType(whenEntry) {
526
+ const condition = whenEntry.namedChildren.find((child) => child.type === 'when_condition');
527
+ if (condition === undefined)
528
+ return null;
529
+ // Exactly one when_condition child must be a positive type_test.
530
+ // Compound conditions (multiple `when_condition` siblings joined with
531
+ // commas in some grammars) or negated `!is` are not safe to narrow.
532
+ if (condition.namedChildCount !== 1)
533
+ return null;
534
+ const test = condition.namedChild(0);
535
+ if (test === null || test.type !== 'type_test')
536
+ return null;
537
+ // `!is` produces a different node (`negated_type_test` in some grammars,
538
+ // or an extra `!` child in others) — defend by checking text prefix.
539
+ if (test.text.trim().startsWith('!'))
540
+ return null;
541
+ return test.namedChildren.find((child) => isKotlinTypeNode(child)) ?? null;
542
+ }
543
+ function buildNarrowedTypeBindingCapture(subject, bodyAnchor, typeNode) {
544
+ return {
545
+ '@type-binding.annotation': (0, ast_helpers_js_1.nodeToCapture)('@type-binding.annotation', bodyAnchor),
546
+ '@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', subject, subject.text),
547
+ '@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', typeNode, (0, interpret_js_1.normalizeKotlinType)(typeNode.text)),
548
+ // Marker consumed by `kotlinBindingScopeFor` in simple-hooks.ts to
549
+ // override the scope-extractor's auto-hoist. Unbraced arm bodies
550
+ // (`is User -> obj.save()`) make the body anchor coincide with the
551
+ // Block scope's range; without this marker the binding would hoist
552
+ // to the enclosing function scope and lose its arm-local narrowing.
553
+ '@type-binding.narrowed': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.narrowed', bodyAnchor, '1'),
554
+ };
555
+ }
556
+ /**
557
+ * Synthesize lambda-body type-bindings — issue #1757.
558
+ *
559
+ * For each `lambda_literal` we emit one or more `@type-binding.annotation`
560
+ * captures anchored INSIDE the lambda body (the lambda's `statements` child
561
+ * — or the `lambda_literal` itself when no statements child exists). The
562
+ * `@scope.block` query rule (see query.ts) makes each `lambda_literal` a
563
+ * Block scope, and the `@type-binding.lambda-scoped` marker forces the
564
+ * scope-extractor to keep the binding at the innermost (lambda body) scope
565
+ * via `kotlinBindingScopeFor`. This guarantees:
566
+ * - explicit parameter names (`{ user -> ... }`) bind only inside the
567
+ * body, NOT in the enclosing function scope;
568
+ * - implicit `it` is visible only inside the lambda body and shadows
569
+ * any same-named outer binding (`val it = "outer"; users.forEach
570
+ * { it.save() }` — inner `it` is the lambda parameter);
571
+ * - nested lambdas shadow deterministically (innermost lambda's `it`
572
+ * wins; outer lambda's parameters are still visible by their own
573
+ * names through the parent scope chain).
574
+ *
575
+ * Receiver-type inference is best-effort: the lambda's call-expression
576
+ * parent is inspected; if the receiver has a known local-variable type
577
+ * and the call's member is a well-known stdlib idiom (`forEach`/`map`/
578
+ * `filter` → element type of the collection; `let`/`apply`/`also`/`run`/
579
+ * `takeIf`/`takeUnless`/`use` → receiver type itself), the inferred type
580
+ * is attached. When inference fails (chained receivers, unknown member,
581
+ * non-stdlib idiom), we still emit the binding with a sentinel/erased
582
+ * type so the binding's scope semantics (no leak; no `it` cross-fire) are
583
+ * enforced — call-resolution from the body still falls through to free-
584
+ * call fallback, which is the correct behavior when the type is unknown.
585
+ *
586
+ * Standard-library coverage: `forEach`, `map`, `filter`, `flatMap`,
587
+ * `mapNotNull`, `filterNotNull`, `onEach`, `find`, `firstOrNull`,
588
+ * `lastOrNull`, `any`, `all`, `none`, `count`, `forEachIndexed`,
589
+ * `let`, `apply`, `also`, `run`, `takeIf`, `takeUnless`, `use`, `with`.
590
+ *
591
+ * Lambda-receiver typing for non-stdlib higher-order functions is a
592
+ * follow-up; the binding-existence guarantee above is the minimum
593
+ * acceptance criterion per the U9 plan.
594
+ */
595
+ function synthesizeKotlinLambdaBindings(rootNode, returnTypes) {
596
+ const out = [];
597
+ const classMembers = collectKotlinClassMembers(rootNode);
598
+ for (const fnNode of descendantsOfType(rootNode, 'function_declaration')) {
599
+ const localTypes = collectKotlinLocalTypeTexts(fnNode, returnTypes);
600
+ for (const lambdaNode of descendantsOfType(fnNode, 'lambda_literal')) {
601
+ const anchor = lambdaBodyAnchor(lambdaNode);
602
+ if (anchor === null)
603
+ continue;
604
+ const inferredType = inferKotlinLambdaReceiverType(lambdaNode, localTypes, returnTypes, classMembers);
605
+ const params = explicitLambdaParameters(lambdaNode);
606
+ if (params.length === 0) {
607
+ // No explicit `(x ->)` parameter list — implicit `it` is in
608
+ // scope inside the body. Synthesize the `it` type-binding so
609
+ // calls like `it.save()` resolve through the typeBinding chain.
610
+ const typeNode = inferredType?.typeNode ?? lambdaNode;
611
+ const typeText = inferredType?.typeText ?? '';
612
+ out.push(buildLambdaTypeBindingCapture(anchor, 'it', typeNode, typeText));
613
+ }
614
+ else {
615
+ // Explicit parameters: `{ user -> ... }`, `{ (a, b) -> ... }`,
616
+ // `{ key, value -> ... }`. Emit one binding per parameter.
617
+ // For multi-arg lambdas (destructuring, `forEachIndexed { i, x
618
+ // -> ... }`), the per-arg type inference is finer than what we
619
+ // currently support — we bind the FIRST parameter to the
620
+ // inferred receiver type (matches single-arg idioms) and bind
621
+ // additional parameters with an empty/erased type, which still
622
+ // gates leakage but won't drive call resolution for those names.
623
+ for (let i = 0; i < params.length; i++) {
624
+ const paramName = params[i].text;
625
+ const typeNode = i === 0 ? (inferredType?.typeNode ?? params[i]) : params[i];
626
+ const typeText = i === 0 ? (inferredType?.typeText ?? '') : '';
627
+ out.push(buildLambdaTypeBindingCapture(anchor, paramName, typeNode, typeText));
628
+ }
629
+ }
630
+ }
631
+ }
632
+ return out;
633
+ }
634
+ /** Anchor node used for synthesized lambda-body type-bindings.
635
+ * Prefers the `statements` child of `lambda_literal` (always strictly
636
+ * inside the lambda body, so the scope-extractor's `rangesEqual` auto-
637
+ * hoist check fails — the binding stays in the Block scope). Falls
638
+ * back to the lambda_literal itself when no statements child exists
639
+ * (e.g. empty lambda); the `@type-binding.lambda-scoped` marker in
640
+ * `kotlinBindingScopeFor` then forces no-hoist explicitly. */
641
+ function lambdaBodyAnchor(lambdaNode) {
642
+ const statements = lambdaNode.namedChildren.find((c) => c.type === 'statements');
643
+ return statements ?? lambdaNode;
644
+ }
645
+ /** Extract explicit lambda parameter `simple_identifier` nodes from a
646
+ * `lambda_literal`. Returns an empty array when no `lambda_parameters`
647
+ * is present (implicit `it` form). */
648
+ function explicitLambdaParameters(lambdaNode) {
649
+ const params = lambdaNode.namedChildren.find((c) => c.type === 'lambda_parameters');
650
+ if (params === undefined)
651
+ return [];
652
+ const out = [];
653
+ for (const child of params.namedChildren) {
654
+ if (child.type !== 'variable_declaration')
655
+ continue;
656
+ const ident = child.namedChildren.find((c) => c.type === 'simple_identifier');
657
+ if (ident !== undefined)
658
+ out.push(ident);
659
+ }
660
+ return out;
661
+ }
662
+ function buildLambdaTypeBindingCapture(anchor, name, typeNode, typeText) {
663
+ return {
664
+ '@type-binding.annotation': (0, ast_helpers_js_1.nodeToCapture)('@type-binding.annotation', anchor),
665
+ '@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', anchor, name),
666
+ '@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', typeNode, typeText === '' ? '' : (0, interpret_js_1.normalizeKotlinType)(typeText)),
667
+ // Marker consumed by `kotlinBindingScopeFor` (simple-hooks.ts) to
668
+ // pin this binding inside the lambda Block scope — without it the
669
+ // scope-extractor would auto-hoist the binding to the enclosing
670
+ // function scope and `it` (or the lambda parameter name) would
671
+ // leak past the closing brace.
672
+ '@type-binding.lambda-scoped': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.lambda-scoped', anchor, '1'),
673
+ };
674
+ }
675
+ /** Stdlib higher-order functions whose lambda parameter receives the
676
+ * ELEMENT type of the receiver collection (Map / Iterable element). */
677
+ const KOTLIN_ELEMENT_TYPE_LAMBDAS = new Set([
678
+ 'forEach',
679
+ 'forEachIndexed',
680
+ 'map',
681
+ 'mapNotNull',
682
+ 'mapIndexed',
683
+ 'filter',
684
+ 'filterNot',
685
+ 'filterNotNull',
686
+ 'filterIsInstance',
687
+ 'flatMap',
688
+ 'flatten',
689
+ 'onEach',
690
+ 'find',
691
+ 'findLast',
692
+ 'firstOrNull',
693
+ 'lastOrNull',
694
+ 'singleOrNull',
695
+ 'any',
696
+ 'all',
697
+ 'none',
698
+ 'count',
699
+ 'partition',
700
+ 'sortedBy',
701
+ 'sortedByDescending',
702
+ 'groupBy',
703
+ 'associate',
704
+ 'associateBy',
705
+ 'associateWith',
706
+ 'minByOrNull',
707
+ 'maxByOrNull',
708
+ 'sumOf',
709
+ 'distinctBy',
710
+ ]);
711
+ /** Stdlib scope functions whose lambda receives the RECEIVER itself as
712
+ * `it` (or as `this` for `apply`/`run`/`with`). For the binding-
713
+ * existence guarantee we treat both forms the same way — `it` binds
714
+ * to the receiver type; `apply`/`run`/`with` callers see free calls
715
+ * inside the body which fall through to free-call resolution against
716
+ * the enclosing scope (no `this`-aware dispatch yet — follow-up). */
717
+ const KOTLIN_SCOPE_FUNCTION_LAMBDAS = new Set(['let', 'also', 'takeIf', 'takeUnless', 'use']);
718
+ /** `apply`, `run`, `with` expose the receiver as `this` rather than
719
+ * `it`. We still synthesize an `it` binding because the lambda may
720
+ * reference the receiver elsewhere — but the more common usage
721
+ * (`user.apply { save() }`) goes through free-call resolution on the
722
+ * body, not through `it`. Including these here keeps the binding
723
+ * scope correct without claiming we resolve `this`-form correctly. */
724
+ const KOTLIN_THIS_RECEIVER_LAMBDAS = new Set(['apply', 'run', 'with']);
725
+ /** Walk up from `lambdaNode` to the enclosing `call_expression` and
726
+ * infer the lambda parameter's type from the call's receiver and
727
+ * member name. Returns null when the inference path is not yet
728
+ * supported (chained receivers, unknown member, non-stdlib idiom).
729
+ *
730
+ * Best-effort: a null return is harmless — `synthesizeKotlinLambda
731
+ * Bindings` still emits the binding with an empty type so the scope
732
+ * semantics (no leak, no cross-fire) are enforced; only the call-
733
+ * resolution path from `it.method()` may fall through to free-call
734
+ * fallback when the type isn't known. */
735
+ function inferKotlinLambdaReceiverType(lambdaNode, localTypes, returnTypes, classMembers) {
736
+ const callExpr = findEnclosingCallExpression(lambdaNode);
737
+ if (callExpr === null)
738
+ return null;
739
+ const callee = callExpr.namedChildren.find((c) => c.type === 'navigation_expression' || c.type === 'simple_identifier');
740
+ if (callee === undefined)
741
+ return null;
742
+ if (callee.type === 'simple_identifier') {
743
+ // `with(receiver) { ... }` — argument is the receiver. Not yet
744
+ // wired through; defer to follow-up.
745
+ return null;
746
+ }
747
+ // navigation_expression: <receiver>.<member>
748
+ const receiver = callee.namedChild(0);
749
+ const memberName = callee.namedChildren
750
+ .find((c) => c.type === 'navigation_suffix')
751
+ ?.namedChildren.find((c) => c.type === 'simple_identifier')?.text;
752
+ if (receiver === null || memberName === undefined)
753
+ return null;
754
+ const receiverType = inferKotlinLambdaReceiverExpressionType(receiver, localTypes, returnTypes, classMembers);
755
+ if (receiverType === null)
756
+ return null;
757
+ if (KOTLIN_ELEMENT_TYPE_LAMBDAS.has(memberName)) {
758
+ const element = kotlinContainerElementType(receiverType, 'values');
759
+ if (element === null || element === '')
760
+ return null;
761
+ return { typeText: element, typeNode: lambdaNode };
762
+ }
763
+ if (KOTLIN_SCOPE_FUNCTION_LAMBDAS.has(memberName) ||
764
+ KOTLIN_THIS_RECEIVER_LAMBDAS.has(memberName)) {
765
+ // Strip nullable suffix for `?.let { ... }` semantics — inside the
766
+ // body, the receiver is non-null per Kotlin smart-cast.
767
+ const stripped = (0, interpret_js_1.normalizeKotlinType)(receiverType);
768
+ return { typeText: stripped, typeNode: lambdaNode };
769
+ }
770
+ return null;
771
+ }
772
+ /** Infer the static type of the expression that produced the lambda's
773
+ * enclosing call. Supports: `simple_identifier` (lookup in
774
+ * `localTypes`), `indexing_expression` on a Map-typed receiver, and
775
+ * `call_expression` whose callee return type is in `returnTypes`. */
776
+ function inferKotlinLambdaReceiverExpressionType(receiver, localTypes, returnTypes, classMembers) {
777
+ if (receiver.type === 'simple_identifier') {
778
+ return localTypes.get(receiver.text) ?? null;
779
+ }
780
+ if (receiver.type === 'indexing_expression') {
781
+ // `posts[user]` — the underlying receiver's container type tells
782
+ // us the element/value type.
783
+ const base = receiver.namedChild(0);
784
+ if (base === null)
785
+ return null;
786
+ const baseType = base.type === 'simple_identifier' ? localTypes.get(base.text) : null;
787
+ if (baseType === undefined || baseType === null)
788
+ return null;
789
+ // Indexing a Map returns the value type; indexing a List returns
790
+ // the element type. `kotlinContainerElementType` already encodes
791
+ // both via the 'values' tag.
792
+ return kotlinContainerElementType(baseType, 'values');
793
+ }
794
+ if (receiver.type === 'navigation_expression') {
795
+ // `users.map { ... }` chain — receiver is itself a navigation/
796
+ // call. Tier-2 chain inference: try the navigation field/method.
797
+ const navField = inferKotlinNavigationFieldType(receiver, localTypes, classMembers);
798
+ if (navField !== null)
799
+ return navField;
800
+ const callee = receiver.namedChildren
801
+ .find((c) => c.type === 'navigation_suffix')
802
+ ?.namedChildren.find((c) => c.type === 'simple_identifier');
803
+ if (callee !== undefined) {
804
+ return inferKotlinNavigationCallReturnType(receiver, localTypes, classMembers);
805
+ }
806
+ return null;
807
+ }
808
+ if (receiver.type === 'call_expression') {
809
+ const callee = receiver.namedChildren.find((c) => c.type === 'simple_identifier');
810
+ if (callee === undefined)
811
+ return null;
812
+ return returnTypes.get(callee.text) ?? null;
813
+ }
814
+ return null;
815
+ }
816
+ /** Walk up from `lambdaNode` (lambda_literal) to the enclosing call:
817
+ * `lambda_literal → annotated_lambda → call_suffix → call_expression`
818
+ * for trailing lambdas, or `lambda_literal → value_argument →
819
+ * value_arguments → call_suffix → call_expression` for paren form.
820
+ * Returns null if the lambda is not inside a call. */
821
+ function findEnclosingCallExpression(lambdaNode) {
822
+ let current = lambdaNode.parent;
823
+ while (current !== null) {
824
+ if (current.type === 'call_expression')
825
+ return current;
826
+ // Don't cross out of the immediate call boundary — if we hit a
827
+ // function_body or function_declaration ancestor, the lambda is
828
+ // not call-bound.
829
+ if (current.type === 'function_body' || current.type === 'function_declaration') {
830
+ return null;
831
+ }
832
+ current = current.parent;
833
+ }
834
+ return null;
835
+ }
836
+ function synthesizeKotlinLocalAssignmentBindings(rootNode, returnTypes) {
837
+ const out = [];
838
+ const classMembers = collectKotlinClassMembers(rootNode);
839
+ for (const fnNode of descendantsOfType(rootNode, 'function_declaration')) {
840
+ const localTypes = new Map();
841
+ for (const prop of descendantsOfType(fnNode, 'property_declaration')) {
842
+ const inferred = inferKotlinPropertyType(prop, localTypes, returnTypes, classMembers);
843
+ if (inferred === null)
844
+ continue;
845
+ localTypes.set(inferred.name.text, inferred.rawType);
846
+ if (inferred.synthetic) {
847
+ out.push({
848
+ '@type-binding.annotation': (0, ast_helpers_js_1.nodeToCapture)('@type-binding.annotation', prop),
849
+ '@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', inferred.name, inferred.name.text),
850
+ '@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', inferred.source, (0, interpret_js_1.normalizeKotlinType)(inferred.rawType)),
851
+ });
852
+ }
853
+ }
854
+ }
855
+ return out;
856
+ }
857
+ /**
858
+ * Per-file class-member index — primary-constructor `val`/`var` params,
859
+ * body property declarations, and method return types. Used by
860
+ * `inferKotlinPropertyType` to walk single-level field and method chains
861
+ * like `val addr = user.address` and `val city = addr.getCity()` (#1760).
862
+ *
863
+ * Indexes by simple class name only. Multi-class collisions inside a
864
+ * single file will pick whichever class was visited last for that name
865
+ * — acceptable because Kotlin forbids same-name top-level classes in
866
+ * one file and per-file resolution is the design boundary here.
867
+ */
868
+ function collectKotlinClassMembers(rootNode) {
869
+ const fields = new Map();
870
+ const methods = new Map();
871
+ for (const cls of descendantsOfType(rootNode, 'class_declaration')) {
872
+ const className = cls.namedChildren.find((child) => child.type === 'type_identifier')?.text;
873
+ if (className === undefined)
874
+ continue;
875
+ const fmap = fields.get(className) ?? new Map();
876
+ const mmap = methods.get(className) ?? new Map();
877
+ const primary = cls.namedChildren.find((child) => child.type === 'primary_constructor');
878
+ if (primary !== undefined) {
879
+ for (const param of primary.namedChildren) {
880
+ if (param.type !== 'class_parameter')
881
+ continue;
882
+ // Constructor params are class fields ONLY when prefixed with
883
+ // `val`/`var` (binding_pattern_kind). Plain `fn(x: Int)`-style
884
+ // params remain locals to the constructor.
885
+ if (param.namedChildren.find((c) => c.type === 'binding_pattern_kind') === undefined) {
886
+ continue;
887
+ }
888
+ const fname = param.namedChildren.find((c) => c.type === 'simple_identifier')?.text;
889
+ const ftype = param.namedChildren.find((c) => isKotlinTypeNode(c))?.text;
890
+ if (fname !== undefined && ftype !== undefined)
891
+ fmap.set(fname, ftype);
892
+ }
893
+ }
894
+ const body = cls.namedChildren.find((child) => child.type === 'class_body');
895
+ if (body !== undefined) {
896
+ for (const member of body.namedChildren) {
897
+ if (member.type === 'property_declaration') {
898
+ const v = member.namedChildren.find((c) => c.type === 'variable_declaration');
899
+ const fname = v?.namedChildren.find((c) => c.type === 'simple_identifier')?.text;
900
+ const ftype = v?.namedChildren.find((c) => isKotlinTypeNode(c))?.text;
901
+ if (fname !== undefined && ftype !== undefined)
902
+ fmap.set(fname, ftype);
903
+ }
904
+ else if (member.type === 'function_declaration') {
905
+ collectKotlinFunctionReturn(member, mmap);
906
+ }
907
+ else if (member.type === 'companion_object') {
908
+ // Companion-object methods (`companion object { fun create() … }`)
909
+ // are addressable via the outer class name (`Logger.create()`).
910
+ // Register them on the outer class so chain-binding for
911
+ // `val x = Logger.create(...)` picks up the return type (#1756).
912
+ // The receiver-side filtering needed to prevent
913
+ // `instance.companionMethod()` crossover is handled elsewhere.
914
+ const compBody = member.namedChildren.find((c) => c.type === 'class_body');
915
+ if (compBody !== undefined) {
916
+ for (const compMember of compBody.namedChildren) {
917
+ if (compMember.type !== 'function_declaration')
918
+ continue;
919
+ collectKotlinFunctionReturn(compMember, mmap);
920
+ }
921
+ }
922
+ }
923
+ }
924
+ }
925
+ fields.set(className, fmap);
926
+ methods.set(className, mmap);
927
+ }
928
+ return { fields, methods };
929
+ }
930
+ function collectKotlinFunctionReturn(fnNode, target) {
931
+ const mname = fnNode.namedChildren.find((c) => c.type === 'simple_identifier')?.text;
932
+ const paramsIdx = fnNode.namedChildren.findIndex((c) => c.type === 'function_value_parameters');
933
+ const rtype = paramsIdx < 0
934
+ ? undefined
935
+ : fnNode.namedChildren.slice(paramsIdx + 1).find((c) => isKotlinTypeNode(c))?.text;
936
+ if (mname !== undefined && rtype !== undefined)
937
+ target.set(mname, rtype);
938
+ }
939
+ function collectKotlinLocalTypeTexts(fnNode, returnTypes) {
940
+ const out = new Map();
941
+ for (const node of descendants(fnNode)) {
942
+ if (node.type === 'parameter') {
943
+ const name = descendantsOfType(node, 'simple_identifier')[0];
944
+ const type = node.namedChildren.find((child) => isKotlinTypeNode(child));
945
+ if (name !== undefined && type !== undefined)
946
+ out.set(name.text, type.text);
947
+ continue;
948
+ }
949
+ if (node.type === 'property_declaration') {
950
+ const inferred = inferKotlinPropertyType(node, out, returnTypes);
951
+ if (inferred !== null)
952
+ out.set(inferred.name.text, inferred.rawType);
953
+ }
954
+ }
955
+ return out;
956
+ }
957
+ function collectKotlinReturnTypeTexts(rootNode) {
958
+ const out = new Map();
959
+ for (const fnNode of descendantsOfType(rootNode, 'function_declaration')) {
960
+ const name = fnNode.namedChildren.find((child) => child.type === 'simple_identifier');
961
+ const paramsIndex = fnNode.namedChildren.findIndex((child) => child.type === 'function_value_parameters');
962
+ const type = paramsIndex < 0
963
+ ? undefined
964
+ : fnNode.namedChildren.slice(paramsIndex + 1).find((child) => isKotlinTypeNode(child));
965
+ if (name !== undefined && type !== undefined)
966
+ out.set(name.text, type.text);
967
+ }
968
+ return out;
969
+ }
970
+ function inferKotlinPropertyType(prop, localTypes, returnTypes, classMembers) {
971
+ const variable = prop.namedChildren.find((child) => child.type === 'variable_declaration');
972
+ const name = variable?.namedChildren.find((child) => child.type === 'simple_identifier');
973
+ if (variable === undefined || name === undefined)
974
+ return null;
975
+ const explicitType = variable.namedChildren.find((child) => isKotlinTypeNode(child));
976
+ if (explicitType !== undefined) {
977
+ return { name, rawType: explicitType.text, source: explicitType, synthetic: false };
978
+ }
979
+ const value = prop.namedChildren.find((child) => child.id !== variable.id && child.type !== 'binding_pattern_kind');
980
+ if (value?.type === 'simple_identifier') {
981
+ const rawType = localTypes.get(value.text);
982
+ return rawType === undefined ? null : { name, rawType, source: value, synthetic: true };
983
+ }
984
+ if (value?.type === 'navigation_expression') {
985
+ // `val addr = user.address` — receiver type → field on that class (#1760).
986
+ const chained = inferKotlinNavigationFieldType(value, localTypes, classMembers);
987
+ if (chained === null)
988
+ return null;
989
+ return { name, rawType: chained, source: value, synthetic: true };
990
+ }
991
+ if (value?.type === 'call_expression') {
992
+ const callee = value.namedChildren.find((child) => child.type === 'simple_identifier' || child.type === 'navigation_expression');
993
+ if (callee === undefined)
994
+ return null;
995
+ if (callee.type === 'simple_identifier') {
996
+ const rawType = returnTypes.get(callee.text) ?? (isUppercaseName(callee.text) ? callee.text : null);
997
+ if (rawType === null)
998
+ return null;
999
+ return { name, rawType, source: callee, synthetic: true };
1000
+ }
1001
+ // `val city = addr.getCity()` — receiver type → method return on that class (#1760).
1002
+ const chained = inferKotlinNavigationCallReturnType(callee, localTypes, classMembers);
1003
+ if (chained === null)
1004
+ return null;
1005
+ return { name, rawType: chained, source: callee, synthetic: true };
1006
+ }
1007
+ return null;
1008
+ }
1009
+ /** Resolve `receiver.field` → field's declared type, where `receiver`
1010
+ * is a simple identifier whose type is in `localTypes` and `field`
1011
+ * is declared on that type in `classMembers.fields`. Returns null
1012
+ * when any link in the chain is unknown — safe over-conservative. */
1013
+ function inferKotlinNavigationFieldType(nav, localTypes, classMembers) {
1014
+ if (classMembers === undefined)
1015
+ return null;
1016
+ const receiver = nav.namedChild(0);
1017
+ if (receiver === null || receiver.type !== 'simple_identifier')
1018
+ return null;
1019
+ const member = nav.namedChildren
1020
+ .find((c) => c.type === 'navigation_suffix')
1021
+ ?.namedChildren.find((c) => c.type === 'simple_identifier')?.text;
1022
+ if (member === undefined)
1023
+ return null;
1024
+ const recvType = localTypes.get(receiver.text);
1025
+ if (recvType === undefined)
1026
+ return null;
1027
+ return classMembers.fields.get((0, interpret_js_1.normalizeKotlinType)(recvType))?.get(member) ?? null;
1028
+ }
1029
+ /** Resolve `receiver.method()` → method's declared return type. The
1030
+ * `receiver` is a simple identifier; we try two interpretations in
1031
+ * order:
1032
+ *
1033
+ * 1. `receiver` is a local variable whose type is in `localTypes` —
1034
+ * look up `method` on that type's class members.
1035
+ * 2. `receiver` is itself a class name (e.g. `Logger.create("app")`,
1036
+ * a companion-object call via the class) — look up `method` on
1037
+ * `classMembers.methods.get(receiver.text)` directly.
1038
+ *
1039
+ * Tier 2 supports `val logger = Logger.create(...)` patterns where the
1040
+ * RHS is a companion-object factory: the loop variable's type is the
1041
+ * factory's return type (#1756). */
1042
+ function inferKotlinNavigationCallReturnType(navCallee, localTypes, classMembers) {
1043
+ if (classMembers === undefined)
1044
+ return null;
1045
+ const receiver = navCallee.namedChild(0);
1046
+ if (receiver === null || receiver.type !== 'simple_identifier')
1047
+ return null;
1048
+ const methodName = navCallee.namedChildren
1049
+ .find((c) => c.type === 'navigation_suffix')
1050
+ ?.namedChildren.find((c) => c.type === 'simple_identifier')?.text;
1051
+ if (methodName === undefined)
1052
+ return null;
1053
+ const recvType = localTypes.get(receiver.text);
1054
+ if (recvType !== undefined) {
1055
+ return classMembers.methods.get((0, interpret_js_1.normalizeKotlinType)(recvType))?.get(methodName) ?? null;
1056
+ }
1057
+ return classMembers.methods.get(receiver.text)?.get(methodName) ?? null;
1058
+ }
1059
+ function inferKotlinIterableElementType(iterable, localTypes, returnTypes) {
1060
+ if (iterable.type === 'simple_identifier') {
1061
+ const raw = localTypes.get(iterable.text);
1062
+ return raw === undefined ? null : kotlinContainerElementType(raw, 'values');
1063
+ }
1064
+ if (iterable.type === 'navigation_expression') {
1065
+ const receiver = iterable.namedChildren[0];
1066
+ const member = iterable.namedChildren
1067
+ .find((child) => child.type === 'navigation_suffix')
1068
+ ?.namedChildren.find((child) => child.type === 'simple_identifier')?.text;
1069
+ if (receiver?.type !== 'simple_identifier')
1070
+ return null;
1071
+ const raw = localTypes.get(receiver.text);
1072
+ return raw === undefined ? null : kotlinContainerElementType(raw, member ?? 'values');
1073
+ }
1074
+ if (iterable.type === 'call_expression') {
1075
+ const callee = iterable.namedChildren.find((child) => child.type === 'simple_identifier');
1076
+ if (callee === undefined)
1077
+ return null;
1078
+ const raw = returnTypes.get(callee.text);
1079
+ if (raw !== undefined)
1080
+ return kotlinContainerElementType(raw, 'values');
1081
+ // Cross-file fallback (#1759): the callee's return type is unknown
1082
+ // locally because the function lives in another file. Emit the
1083
+ // callee name itself as the binding's rawName; `propagateImported
1084
+ // ReturnTypes` will chain-follow `loopvar → callee → <ElementType>`
1085
+ // once the imported module's `callee → ElementType` mirror lands at
1086
+ // module scope. If `callee` isn't actually an imported callable
1087
+ // (e.g. a local lambda or unrelated symbol), chain-follow fails
1088
+ // safely and no edge is emitted.
1089
+ return callee.text;
1090
+ }
1091
+ return null;
1092
+ }
1093
+ function isUppercaseName(text) {
1094
+ return /^[A-Z]/.test(text);
1095
+ }
1096
+ function kotlinContainerElementType(rawType, member) {
1097
+ const parsed = parseKotlinGeneric(rawType);
1098
+ if (parsed === null)
1099
+ return (0, interpret_js_1.normalizeKotlinType)(rawType);
1100
+ const base = parsed.base.split('.').pop() ?? parsed.base;
1101
+ if (isKotlinMapType(base)) {
1102
+ if (member === 'keys')
1103
+ return parsed.args[0] ?? null;
1104
+ return parsed.args[1] ?? null;
1105
+ }
1106
+ if (isKotlinIterableType(base))
1107
+ return parsed.args[0] ?? null;
1108
+ return (0, interpret_js_1.normalizeKotlinType)(rawType);
1109
+ }
1110
+ function parseKotlinGeneric(text) {
1111
+ const trimmed = text.trim().replace(/\?$/, '');
1112
+ const open = trimmed.indexOf('<');
1113
+ const close = trimmed.lastIndexOf('>');
1114
+ if (open < 0 || close < open)
1115
+ return null;
1116
+ return {
1117
+ base: trimmed.slice(0, open).trim(),
1118
+ args: splitTopLevelKotlinArgs(trimmed.slice(open + 1, close)),
1119
+ };
1120
+ }
1121
+ function splitTopLevelKotlinArgs(text) {
1122
+ const out = [];
1123
+ let depth = 0;
1124
+ let start = 0;
1125
+ for (let i = 0; i < text.length; i++) {
1126
+ const ch = text[i];
1127
+ if (ch === '<')
1128
+ depth++;
1129
+ else if (ch === '>')
1130
+ depth--;
1131
+ else if (ch === ',' && depth === 0) {
1132
+ out.push(text.slice(start, i).trim());
1133
+ start = i + 1;
1134
+ }
1135
+ }
1136
+ out.push(text.slice(start).trim());
1137
+ return out.filter((arg) => arg.length > 0);
1138
+ }
1139
+ function isKotlinMapType(base) {
1140
+ return ['Map', 'MutableMap', 'HashMap', 'LinkedHashMap'].includes(base);
1141
+ }
1142
+ function isKotlinIterableType(base) {
1143
+ return [
1144
+ 'List',
1145
+ 'MutableList',
1146
+ 'ArrayList',
1147
+ 'Set',
1148
+ 'MutableSet',
1149
+ 'Collection',
1150
+ 'Iterable',
1151
+ 'Sequence',
1152
+ 'Array',
1153
+ ].includes(base);
1154
+ }
1155
+ function isKotlinTypeNode(node) {
1156
+ return (node.type === 'user_type' || node.type === 'nullable_type' || node.type === 'function_type');
1157
+ }
1158
+ function descendantsOfType(node, type) {
1159
+ return descendants(node).filter((child) => child.type === type);
1160
+ }
1161
+ function descendants(node) {
1162
+ const out = [];
1163
+ for (let i = 0; i < node.namedChildCount; i++) {
1164
+ const child = node.namedChild(i);
1165
+ if (child === null)
1166
+ continue;
1167
+ out.push(child, ...descendants(child));
1168
+ }
1169
+ return out;
1170
+ }
1171
+ function shouldEmitReadMember(navNode) {
1172
+ const parent = navNode.parent;
1173
+ if (parent === null)
1174
+ return true;
1175
+ if (parent.type === 'call_expression')
1176
+ return false;
1177
+ if (parent.type === 'directly_assignable_expression')
1178
+ return false;
1179
+ return true;
1180
+ }
1181
+ /** True when the given `property_declaration` has a `call_expression`
1182
+ * value sibling (i.e. `val x: T = Foo()`). Used to suppress the
1183
+ * explicit-annotation type-binding capture so the constructor-inferred
1184
+ * binding wins (#1762). */
1185
+ function propertyDeclHasConstructorValue(propNode) {
1186
+ const variable = propNode.namedChildren.find((c) => c.type === 'variable_declaration');
1187
+ if (variable === undefined)
1188
+ return false;
1189
+ const value = propNode.namedChildren.find((c) => c.id !== variable.id && c.type !== 'binding_pattern_kind');
1190
+ return value?.type === 'call_expression';
1191
+ }
1192
+ function callArguments(callNode) {
1193
+ const suffix = callNode.namedChildren.find((child) => child.type === 'call_suffix');
1194
+ if (suffix === undefined)
1195
+ return [];
1196
+ const valueArgs = suffix?.namedChildren.find((child) => child.type === 'value_arguments');
1197
+ const args = valueArgs?.namedChildren.filter((child) => child.type === 'value_argument') ?? [];
1198
+ const trailingLambdas = suffix.namedChildren.filter((child) => child.type === 'annotated_lambda');
1199
+ return [...args, ...trailingLambdas];
1200
+ }
1201
+ function inferArgType(argNode) {
1202
+ const value = argNode.namedChild(0) ?? argNode;
1203
+ switch (value.type) {
1204
+ case 'integer_literal':
1205
+ case 'long_literal':
1206
+ return 'Int';
1207
+ case 'real_literal':
1208
+ return 'Double';
1209
+ case 'string_literal':
1210
+ case 'line_string_literal':
1211
+ case 'multi_line_string_literal':
1212
+ return 'String';
1213
+ case 'character_literal':
1214
+ return 'Char';
1215
+ case 'boolean_literal':
1216
+ return 'Boolean';
1217
+ case 'call_expression': {
1218
+ const first = value.namedChild(0);
1219
+ return first?.type === 'simple_identifier' ? first.text : '';
1220
+ }
1221
+ default:
1222
+ return '';
1223
+ }
1224
+ }
1225
+ function extensionFreeCallFallback(grouped, groupedNodes) {
1226
+ const member = grouped['@reference.call.member'];
1227
+ const receiver = grouped['@reference.receiver'];
1228
+ const name = grouped['@reference.name'];
1229
+ if (member === undefined || receiver === undefined || name === undefined)
1230
+ return null;
1231
+ // The `@reference.call.member` anchor IS the `call_expression`, and the
1232
+ // `@reference.receiver` anchor IS the receiver node — both threaded from the
1233
+ // query match (no per-match root walk).
1234
+ const callNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@reference.call.member'], 'call_expression');
1235
+ if (callNode === null)
1236
+ return null;
1237
+ const receiverNode = groupedNodes['@reference.receiver'];
1238
+ if (receiverNode === undefined || !isLiteralReceiver(receiverNode))
1239
+ return null;
1240
+ const out = {
1241
+ '@reference.call.free': (0, ast_helpers_js_1.syntheticCapture)('@reference.call.free', callNode, callNode.text),
1242
+ '@reference.name': (0, ast_helpers_js_1.syntheticCapture)('@reference.name', callNode, name.text),
1243
+ };
1244
+ if (grouped['@reference.arity'] !== undefined)
1245
+ out['@reference.arity'] = grouped['@reference.arity'];
1246
+ if (grouped['@reference.parameter-types'] !== undefined) {
1247
+ out['@reference.parameter-types'] = grouped['@reference.parameter-types'];
1248
+ }
1249
+ return out;
1250
+ }
1251
+ function isLiteralReceiver(node) {
1252
+ return [
1253
+ 'integer_literal',
1254
+ 'long_literal',
1255
+ 'real_literal',
1256
+ 'string_literal',
1257
+ 'line_string_literal',
1258
+ 'multi_line_string_literal',
1259
+ 'character_literal',
1260
+ 'boolean_literal',
1261
+ ].includes(node.type);
1262
+ }