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,1174 @@
1
+ "use strict";
2
+ /**
3
+ * Resolve a compound-receiver expression's TYPE — `user.address.save()`,
4
+ * `svc.get_user().save()`, `c.greet().save()` — to the class def of
5
+ * the value the receiver expression produces.
6
+ *
7
+ * Three shapes (parsed C-family-style):
8
+ * - bare identifier `name` — look up via typeBinding chain
9
+ * - dotted `obj.field[.field]…` — walk fields via class-scope typeBindings
10
+ * - call `expr.method()` — recurse into expr, find method's return-type
11
+ * typeBinding on its class, resolve to a class
12
+ *
13
+ * **Field-fallback heuristic** (Phase-9C "unified fixpoint"): when the
14
+ * receiver class has no `methodName`, walk its fields and try the
15
+ * lookup on each field's type. Useful for dynamically-typed languages
16
+ * (Python). Strictly-typed languages should pass
17
+ * `fieldFallbackOnMethodLookup: false` via `ScopeResolver`.
18
+ *
19
+ * Generic for any C-family language (`.` member access, `()` call
20
+ * syntax). Languages with non-C-family syntax (Ruby blocks, COBOL)
21
+ * either don't trigger the call branch or skip this pass entirely.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.foldReceiverChain = foldReceiverChain;
25
+ exports.resolveCompoundReceiverClass = resolveCompoundReceiverClass;
26
+ exports.stripCastWrappers = stripCastWrappers;
27
+ const template_arguments_js_1 = require("../../utils/template-arguments.js");
28
+ const receiver_chain_codec_js_1 = require("../../utils/receiver-chain-codec.js");
29
+ const walkers_js_1 = require("../scope/walkers.js");
30
+ /** Max depth for compound-receiver chain resolution (`a().b().c().d()`).
31
+ * Practical code rarely exceeds 3-4 _syntactic_ hops, but languages
32
+ * with type-binding-mediated chains (Ruby's `x = obj.method()` binds
33
+ * `x → obj.method()` and recurses through the compound resolver) can
34
+ * triple the depth count because each intermediate step contributes
35
+ * two recursions (bare-ident → compound rawName → call-expr parse).
36
+ * 8 covers 3-level chains with headroom while still capping
37
+ * pathological recursion. */
38
+ const COMPOUND_RECEIVER_MAX_DEPTH = 8;
39
+ const MAP_TUPLE_SENTINEL_RE = /^__MAP_TUPLE_(\d+)__:(.+)$/;
40
+ /** Cast type the resolver can look up directly: a simple identifier. */
41
+ const SIMPLE_CAST_TYPE_RE = /^[a-zA-Z_]\w*$/;
42
+ /** Classification-only shape for a cast type that is recognizable but
43
+ * NOT resolvable here: dotted qualifier (`com.example.Foo`), generic
44
+ * (`List<String>`), array (`Foo[]`), or combinations
45
+ * (`com.example.List<Foo>[]`) — shape `Ident(.Ident)*(<…>)?([])*`,
46
+ * whitespace-tolerant. No attempt is made to parse generic contents;
47
+ * `[^()]*` merely keeps expression-like paren content from matching.
48
+ * Matching this shape (when the simple-identifier shape doesn't)
49
+ * means the paren group IS a C-style cast whose target type we cannot
50
+ * look up — the only safe outcome is to resolve nothing, never to
51
+ * fall through to the pre-cast expression's own declared type. */
52
+ const UNPARSEABLE_CAST_TYPE_RE = /^[a-zA-Z_]\w*(?:\s*\.\s*[a-zA-Z_]\w*)*(?:\s*<[^()]*>)?(?:\s*\[\s*\])*$/;
53
+ function parseMapTupleSentinel(text) {
54
+ const match = MAP_TUPLE_SENTINEL_RE.exec(text);
55
+ if (match === null)
56
+ return null;
57
+ const [, idxStr, rhs] = match;
58
+ if (idxStr === undefined || rhs === undefined)
59
+ return null;
60
+ return { tupleIdx: Number(idxStr), rhs };
61
+ }
62
+ /** Is this hop the language's construction selector applied to the class
63
+ * itself — `Factory.new` — rather than an ordinary member named `new` on a
64
+ * value? Both call sites ask the identical question, so it is asked in one
65
+ * place (#2708). `onClassConstant` is what separates `Factory.new` from
66
+ * `factory.new`; see the contract field for the known limitation around a
67
+ * class-level override of the selector. */
68
+ function isConstructionSelectorHop(memberName, receiverClass, onClassConstant, options) {
69
+ return (onClassConstant &&
70
+ options.constructionSyntax?.selector === memberName &&
71
+ (0, walkers_js_1.isClassLike)(receiverClass.type));
72
+ }
73
+ /** Escape a literal for embedding in a RegExp. The construction keyword comes
74
+ * from a language provider, so it is not user input, but a keyword containing
75
+ * a metacharacter would otherwise silently build a wrong pattern. */
76
+ function escapeForRegExp(literal) {
77
+ return literal.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
78
+ }
79
+ /**
80
+ * Type of a construction expression's callee — the class it constructs.
81
+ *
82
+ * `Service` (bare, when the language constructs without a keyword) and
83
+ * `new Service` (keyword form) both name the class being built, so the
84
+ * expression's type is that class. Together with
85
+ * `isConstructionSelectorHop` (the `Class.new` spelling), this is where the
86
+ * rule "constructing a class yields an instance of it" lives; the
87
+ * per-language surface syntax arrives via `constructionSyntax` (#2708).
88
+ *
89
+ * Returns undefined when the language declares no construction syntax,
90
+ * when the callee names no class-like symbol reachable from `inScope`,
91
+ * or when the keyword is required but absent — never a guess.
92
+ */
93
+ function resolveConstructionExpressionClass(fnExpr, inScope, scopes, index, options) {
94
+ const syntax = options.constructionSyntax;
95
+ if (syntax === undefined)
96
+ return undefined;
97
+ let calleeName;
98
+ // The keyword is separated from the type by whatever trivia the source
99
+ // used — `new Service`, `new\tService`, or a line break — so match the
100
+ // keyword as a whole token followed by at least one whitespace character
101
+ // rather than by exactly one space (#2708). `newService()` keeps failing
102
+ // the match, which is the point: it is an ordinary call.
103
+ const keywordMatch = syntax.keyword === undefined
104
+ ? null
105
+ : new RegExp(`^${escapeForRegExp(syntax.keyword)}\\s+`).exec(fnExpr);
106
+ if (keywordMatch !== null) {
107
+ calleeName = fnExpr.slice(keywordMatch[0].length).trim();
108
+ }
109
+ else if (syntax.bare === true) {
110
+ calleeName = fnExpr;
111
+ }
112
+ // A `new`-keyword language reaching here without the keyword is an
113
+ // ordinary free call, not a construction — resolving it to the class
114
+ // would fabricate an edge (a factory function may share the class's
115
+ // name).
116
+ if (calleeName === undefined || calleeName.length === 0)
117
+ return undefined;
118
+ // Generic construction — `new Box<string>()` arrives here as `Box<string>`,
119
+ // which names no class binding. Retry on the base name, the same
120
+ // normalization `resolveClassBindingForName` (in `scope/walkers.ts`) already
121
+ // applies for typed receivers (#2708).
122
+ const baseName = (0, template_arguments_js_1.stripTemplateArguments)(calleeName).trim();
123
+ const lastDot = baseName.lastIndexOf('.');
124
+ if (lastDot !== -1) {
125
+ const namespaceName = baseName.slice(0, lastDot);
126
+ const exportedName = baseName.slice(lastDot + 1);
127
+ const namespaceFiles = options.namespaceTargets?.get(namespaceName) ?? [];
128
+ // A verified namespace is authoritative: do not fall through to the
129
+ // workspace-wide simple-name heuristics on either a miss or ambiguity.
130
+ if (namespaceFiles.length > 0) {
131
+ if ((0, walkers_js_1.isNamespaceNameShadowed)(namespaceName, inScope, scopes))
132
+ return undefined;
133
+ const namespaceMatches = namespaceFiles
134
+ .map((targetFile) => (0, walkers_js_1.findExportedDef)(targetFile, exportedName, index))
135
+ .filter((def) => def !== undefined && (0, walkers_js_1.isClassLike)(def.type));
136
+ return namespaceMatches.length === 1 ? namespaceMatches[0] : undefined;
137
+ }
138
+ }
139
+ const direct = (0, walkers_js_1.findClassBindingInScope)(inScope, calleeName, scopes);
140
+ if (direct !== undefined && (0, walkers_js_1.isClassLike)(direct.type))
141
+ return direct;
142
+ if (baseName.length > 0 && baseName !== calleeName) {
143
+ const viaBaseName = (0, walkers_js_1.findClassBindingInScope)(inScope, baseName, scopes);
144
+ if (viaBaseName !== undefined && (0, walkers_js_1.isClassLike)(viaBaseName.type))
145
+ return viaBaseName;
146
+ }
147
+ // Qualified callee — `new ns.Service()` / `new Outer.Inner()`. Prefer an
148
+ // unambiguous qualified-name match, then fall back to the trailing simple
149
+ // name the way receiver resolution does elsewhere (#2708).
150
+ if (lastDot === -1)
151
+ return undefined;
152
+ const qualifiedIds = scopes.qualifiedNames.get(baseName);
153
+ if (qualifiedIds.length === 1) {
154
+ const qualified = scopes.defs.get(qualifiedIds[0]);
155
+ if (qualified !== undefined && (0, walkers_js_1.isClassLike)(qualified.type))
156
+ return qualified;
157
+ }
158
+ const simpleName = baseName.slice(lastDot + 1);
159
+ if (simpleName.length === 0)
160
+ return undefined;
161
+ const viaSimpleName = (0, walkers_js_1.findClassBindingInScope)(inScope, simpleName, scopes);
162
+ return viaSimpleName !== undefined && (0, walkers_js_1.isClassLike)(viaSimpleName.type) ? viaSimpleName : undefined;
163
+ }
164
+ /**
165
+ * The class a receiver position's DECLARED TYPE denotes — the one lookup every
166
+ * route in this file uses to turn a `TypeRef` into an owner to look the next
167
+ * member up on.
168
+ *
169
+ * ── WHY NOT `findClassBindingInScope(scope, typeRef.rawName)` ────────────────
170
+ *
171
+ * `rawName` is post-normalization, and several providers reduce a type
172
+ * APPLICATION to its base name at capture time (`Mapped[User]` → `Mapped`,
173
+ * `Repo<User>` → `Repo`). Handing that base name to the bare lookup takes its
174
+ * workspace-wide qualified-name fallback, which consults no scope, no import
175
+ * and no module: it binds whatever the workspace happens to declare under that
176
+ * name. A third-party `Mapped[User]` beside an unrelated workspace
177
+ * `class Mapped` then produces a confident WRONG edge — strictly worse than the
178
+ * missing one it replaced, and not recoverable downstream.
179
+ *
180
+ * `resolveClassBindingForName` owns the grounding rule for exactly this
181
+ * ({@link resolveErasedBaseName}: the scope chain binds the name, or the
182
+ * declaration is in the same file, or the index proves the name is a template
183
+ * family, or the file has no cross-file class channel to be absent from), but it
184
+ * is entered on the SPELLING — a name that already lost its arguments is
185
+ * indistinguishable from an ordinary class name. {@link erasedTypeApplication}
186
+ * restores the application from `declaredSpelling`, which is what puts a
187
+ * capture-time-erased receiver back on the grounded route.
188
+ *
189
+ * ── WHY IT IS ONE HELPER AND NOT FIVE CALL SITES ─────────────────────────────
190
+ *
191
+ * This file types a receiver position from a `TypeRef` in five places — the
192
+ * structural fold's member step and its module-hoist branch, the cascade's
193
+ * bare-identifier binding, the cascade's dotted-chain HEAD, and the cascade's
194
+ * per-segment member walk. They are five routes to ONE question, and only three
195
+ * were wired to the grounded lookup, which is what left the hole: a Python
196
+ * `self.m.save(u)` whose fold step correctly refused fell THROUGH to the
197
+ * cascade — a declined fold is documented as "no answer", never a veto — and
198
+ * the cascade's own ungrounded member walk re-minted the very edge the grounds
199
+ * had just rejected. One shared helper is what makes "the fold refused" and
200
+ * "the cascade refused" the same sentence, rather than two lookups that happen
201
+ * to agree until one of them is edited.
202
+ *
203
+ * `stripDecoration` stays a per-caller argument because it is a DIFFERENT
204
+ * normalization with its own risk — its own docstring records that turning a
205
+ * former `undefined` into a hit suppresses the `?? otherResolver(...)`
206
+ * fallbacks two dozen call sites rely on. The three fold/binding callers pass
207
+ * the provider's stripper as they always have; the two cascade callers pass
208
+ * nothing, as they always have. So the only behaviour this helper changes
209
+ * anywhere is the erasure grounding, and a `TypeRef` that was never reduced
210
+ * resolves through the identical `findClassBindingInScope` call it did before
211
+ * (`resolveClassBindingForName` tries that first, and a name with no `<`
212
+ * returns immediately after it).
213
+ */
214
+ function classOfDeclaredType(typeRef, scopes, stripDecoration) {
215
+ // `declaredAtScope`, never a scope the caller chose: all five sites passed
216
+ // exactly this `TypeRef`'s own anchor, and taking it as a parameter is what
217
+ // would let a sixth quietly not — which is the hole this helper exists to
218
+ // close, one level up.
219
+ return (0, walkers_js_1.resolveClassBindingForName)(typeRef.declaredAtScope, (0, template_arguments_js_1.erasedTypeApplication)(typeRef) ?? typeRef.rawName, scopes, stripDecoration);
220
+ }
221
+ function typeOfMemberOnClass(owner, memberName, scopes, index, options) {
222
+ const classScopeByDefId = index.classScopeByDefId;
223
+ const ownerChain = [owner.nodeId, ...scopes.methodDispatch.mroFor(owner.nodeId)];
224
+ for (const ownerId of ownerChain) {
225
+ const classScope = classScopeByDefId.get(ownerId);
226
+ const memberType = classScope?.typeBindings.get(memberName);
227
+ if (memberType !== undefined) {
228
+ const def = classOfDeclaredType(memberType, scopes, options.stripTypePreservingDecoration);
229
+ // The declared type is reported even when it resolved to no class:
230
+ // `Promise<User>` and `[]Repo` name nothing in the workspace, and an
231
+ // await or index step unwrapping them is exactly how they become
232
+ // resolvable. Returning `undefined` here would strand those shapes. A
233
+ // `def` that stayed absent is reported as absent, NOT as the previous
234
+ // owner, so nothing may fold an ordinary member off this position.
235
+ return {
236
+ def,
237
+ declaredType: memberType.declaredSpelling ?? memberType.rawName,
238
+ declaredAtScope: memberType.declaredAtScope,
239
+ };
240
+ }
241
+ // Languages whose binding-scope hook hoists a method's return-type binding
242
+ // out of the class body and onto an ancestor (Module) scope keep NOTHING in
243
+ // the class scope to find — TypeScript is one, via `tsBindingScopeFor`, so
244
+ // without this walk the fold cannot type a single step in the first
245
+ // language it ships for. Gated on the same contract flag
246
+ // `resolveCompoundReceiverClass` uses, so a language that does not hoist
247
+ // cannot pick up an unrelated module-level binding of the same name.
248
+ if (classScope !== undefined && options.hoistTypeBindingsToModule === true) {
249
+ let curId = classScope.parent;
250
+ while (curId !== null) {
251
+ const curScope = scopes.scopeTree.getScope(curId);
252
+ if (curScope === undefined)
253
+ break;
254
+ const hoisted = curScope.typeBindings.get(memberName);
255
+ if (hoisted !== undefined) {
256
+ // Same stripper the primary branch above passes. Omitting it here
257
+ // meant a decorated declared type (`*Host`) resolved on one branch and
258
+ // not the other, for the same member of the same class.
259
+ const def = classOfDeclaredType(hoisted, scopes, options.stripTypePreservingDecoration);
260
+ // Identical to the primary branch: a declared type that named no
261
+ // class is still a usable position when the next step unwraps it.
262
+ // Returning `undefined` here made `svc.getMap()['k'].run()` decline
263
+ // while byte-identical `byId['k'].run()` resolved, purely because ten
264
+ // languages route return-type bindings through this hoisted branch
265
+ // and the other through the class scope.
266
+ return {
267
+ def,
268
+ declaredType: hoisted.declaredSpelling ?? hoisted.rawName,
269
+ declaredAtScope: hoisted.declaredAtScope,
270
+ };
271
+ }
272
+ curId = curScope.parent;
273
+ }
274
+ }
275
+ }
276
+ return undefined;
277
+ }
278
+ /**
279
+ * Type a receiver from its decoded structure instead of from its source text.
280
+ *
281
+ * Resolves the base, then folds the steps base-first, each step typed against
282
+ * the class the previous step produced. Returns `undefined` the moment any step
283
+ * fails to type, so the caller falls back to the existing text cascade rather
284
+ * than receiving a partially-folded guess — a missing edge is recoverable, a
285
+ * confidently wrong one is not.
286
+ *
287
+ * The base is resolved by handing it to `resolveCompoundReceiverClass`, which
288
+ * already owns the bare-identifier path in full: type binding, static
289
+ * class-name receivers, map-tuple sentinels, member aliases and call-result
290
+ * aliases. A second implementation of that would drift from it.
291
+ *
292
+ * Called from `resolveCompoundReceiverClass` ahead of the text cascade, and only
293
+ * when the site carries a `receiverChain` (see the `depth === 0` gate below).
294
+ */
295
+ function foldReceiverChain(chain, inScope, scopes, index, options = {}) {
296
+ // A truncated chain is missing the head that decides the final type. The
297
+ // producer refuses to mint one, so this is defence in depth against a
298
+ // future producer that does.
299
+ if (chain.truncated)
300
+ return undefined;
301
+ if (chain.steps.length === 0)
302
+ return undefined;
303
+ // `receiverChain` is dropped before resolving the base: it describes the
304
+ // whole receiver, and handing it back to the resolver would re-enter this
305
+ // fold on the base and never terminate.
306
+ const baseDef = resolveCompoundReceiverClass(chain.baseReceiverName, inScope, scopes, index, {
307
+ ...options,
308
+ fieldFallback: false,
309
+ receiverChain: undefined,
310
+ strictBaseBinding: true,
311
+ });
312
+ // The base's own declared type is carried too, so a chain whose FIRST step is
313
+ // an unwrap (`repos[0].save()` — index applied directly to the base) has the
314
+ // container spelling available. Without it that shape declines at step 1.
315
+ // Looked up ONLY when something will read it: the base failed to resolve (so
316
+ // an unwrap step is the last chance), or an index step will unwrap the
317
+ // container. `resolveCompoundReceiverClass` already walked the scope chain for
318
+ // this same name above, so doing it unconditionally duplicated that walk on
319
+ // every fold — and the U10 census says 86% of chains are pure field/call and
320
+ // never read it.
321
+ const needsBaseDeclaredType = baseDef === undefined || chain.steps.some((step) => step.kind === 'index');
322
+ const baseBinding = needsBaseDeclaredType
323
+ ? (0, walkers_js_1.findReceiverTypeBinding)(inScope, chain.baseReceiverName, scopes)
324
+ : undefined;
325
+ // A base whose declared type names no class is NOT automatically a dead end:
326
+ // `repos: User[]` binds to the literal `User[]`, which matches no class
327
+ // because a container is not one. That position is still usable IF the next
328
+ // step unwraps it — which is exactly what an index step does. Carrying it
329
+ // forward with the marker lets that step recover; every other step kind
330
+ // declines on the marker, so nothing folds against a phantom owner.
331
+ if (baseDef === undefined && baseBinding === undefined)
332
+ return undefined;
333
+ let current = {
334
+ def: baseDef,
335
+ declaredType: baseBinding?.declaredSpelling ?? baseBinding?.rawName,
336
+ declaredAtScope: baseBinding?.declaredAtScope,
337
+ };
338
+ for (const step of chain.steps) {
339
+ // A position whose declared type named no class can only be advanced by an
340
+ // unwrapping step. Folding an ordinary member off it would look the member
341
+ // up on the PREVIOUS class — a wrong owner, silently.
342
+ //
343
+ // `await` IS identity, and soundly so: every language whose capture layer
344
+ // reduces the wrapper has ALREADY done it by the time a binding reaches the
345
+ // fold (TypeScript strips `Promise<X>`, C# strips `Task<X>`), and awaiting a
346
+ // value that is NOT a thenable yields that same value — so both regimes land
347
+ // on the identical answer and there is nothing to distinguish.
348
+ if (step.kind === 'await')
349
+ continue;
350
+ if (step.kind === 'index') {
351
+ // An index step is NOT identity, and that asymmetry with `await` above is
352
+ // the whole point. `await` on a non-promise is a no-op; a subscript on a
353
+ // non-container is not — it yields the element of an indexer whose type
354
+ // is a different class entirely.
355
+ //
356
+ // The NORMALIZED type name cannot tell the two regimes apart: capture
357
+ // reduces `repos: User[]` to `User`, so a reduced container and a class
358
+ // the source merely subscripted (`grid: Grid` where `Grid` declares an
359
+ // index signature) both arrive as a bare, resolvable class name. Falling
360
+ // back to identity there kept `current` on the CONTAINER and looked the
361
+ // next member up on it — `grid[0].run()` → `Grid.run`, `t[0].Render()` →
362
+ // `Table.Render`. A confidently wrong owner, which is strictly worse than
363
+ // no edge and invisible to a bench that scores edge PRESENCE.
364
+ //
365
+ // So the step demands positive evidence instead: `declaredType`, the
366
+ // AS-WRITTEN spelling (`TypeRef.declaredSpelling`, preserved precisely
367
+ // because `rawName` threw it away), handed to the language's
368
+ // `elementTypeOf`. A provider that does not recognize the spelling as a
369
+ // container is answering "not a container", and the only sound move is to
370
+ // decline — a language must therefore answer the `index` route to get
371
+ // index folding at all.
372
+ const declared = current.declaredType;
373
+ const element = declared === undefined ? undefined : options.elementTypeOf?.(declared, { kind: 'index' });
374
+ if (element === undefined)
375
+ return undefined;
376
+ const scopeForLookup = current.declaredAtScope ?? inScope;
377
+ const elementClass = (0, walkers_js_1.findClassBindingInScope)(scopeForLookup, element, scopes, options.stripTypePreservingDecoration);
378
+ if (elementClass === undefined)
379
+ return undefined;
380
+ current = {
381
+ def: elementClass,
382
+ declaredType: element,
383
+ declaredAtScope: scopeForLookup,
384
+ };
385
+ continue;
386
+ }
387
+ // Construction is NOT an ordinary member lookup. `Factory.new` on a class
388
+ // constant denotes an instance of Factory, and the cascade already encodes
389
+ // that (`isConstructionSelectorHop`) along with the class-constant test that
390
+ // separates it from an instance method genuinely named `new`. The fold
391
+ // carries no such distinction — a chain step records a name, not whether its
392
+ // base was a class reference or a value — so folding one would resolve
393
+ // `Factory.new.run` against whatever member named `new` the lookup reaches
394
+ // first. That turned a correct edge into a WRONG one (Ruby
395
+ // `Factory.new.run` → `Product.run`), which is the failure mode this whole
396
+ // line of work exists to avoid. Decline and let the cascade answer.
397
+ //
398
+ // Placed AFTER the name-free continues above, deliberately. When it sat
399
+ // first, `options.constructionSyntax?.selector === step.name` compared
400
+ // `undefined === undefined` for every await/index step in a language with no
401
+ // construction selector, vetoing the entire fold before it ran — which is
402
+ // why those receivers minted a chain, fired the gate, and produced no edge.
403
+ // Position, not a guard, is what makes that unreachable: only named steps
404
+ // get here.
405
+ if (options.constructionSyntax?.selector === step.name)
406
+ return undefined;
407
+ if (current.def === undefined)
408
+ return undefined;
409
+ const next = typeOfMemberOnClass(current.def, step.name, scopes, index, options);
410
+ if (next === undefined)
411
+ return undefined;
412
+ current = next;
413
+ }
414
+ // A chain that ended without a class returns undefined naturally — no
415
+ // separate guard, because `def` IS the signal.
416
+ return current.def;
417
+ }
418
+ function resolveCompoundReceiverClass(receiverText, inScope, scopes, index, options = {}, depth = 0) {
419
+ const classScopeByDefId = index.classScopeByDefId;
420
+ if (depth > COMPOUND_RECEIVER_MAX_DEPTH)
421
+ return undefined;
422
+ const text = receiverText.trim();
423
+ if (text.length === 0)
424
+ return undefined;
425
+ const fieldFallback = options.fieldFallback ?? true;
426
+ // ── Structural fold, ahead of the text cascade ───────────────────
427
+ // When the capture layer produced a chain for this site, type the receiver
428
+ // from that structure. The cascade below dispatches on enumerated textual
429
+ // shapes, so every new spelling (`?.`, `!`, `<T>`, `->`) needs another branch;
430
+ // the AST already knew the answer and the chain carries it.
431
+ //
432
+ // Only at depth 0 — the chain describes THIS site's receiver, not the inner
433
+ // expressions the cascade recurses into.
434
+ //
435
+ // A failed fold falls through rather than returning: structure is an
436
+ // additional route to an answer, never a veto on the existing one, so a site
437
+ // the cascade could already resolve keeps resolving.
438
+ if (depth === 0 && options.receiverChain !== undefined) {
439
+ const decoded = (0, receiver_chain_codec_js_1.decodeReceiverChain)(options.receiverChain);
440
+ if (decoded !== undefined) {
441
+ const folded = foldReceiverChain(decoded, inScope, scopes, index, options);
442
+ if (folded !== undefined)
443
+ return folded;
444
+ }
445
+ }
446
+ // ── Pre-processing: strip C-style cast expressions (opt-in) ──────
447
+ // Cast-wrapped receivers like ((Type)((Object)this.field)).method()
448
+ // produce parenthesized-expression receiver text. For languages that
449
+ // opt in via `stripReceiverCastExpressions`, peel outer (Type)
450
+ // layers so the resolver sees the actual receiver (e.g. this.field)
451
+ // — `stripCastWrappers` documents the classification rules. When
452
+ // the toggle is off, the text reaches the resolver untouched and no
453
+ // cast logic runs.
454
+ let workingText = text;
455
+ if (options.stripReceiverCastExpressions === true && text.startsWith('(')) {
456
+ const stripped = stripCastWrappers(text);
457
+ // A recognized cast whose target type cannot be looked up here:
458
+ // the only safe outcome is to resolve nothing — falling through
459
+ // to the pre-cast expression's own declared type would emit a
460
+ // confident wrong edge.
461
+ if (stripped.unresolvableCast)
462
+ return undefined;
463
+ workingText = stripped.workingText;
464
+ // A captured cast type names the exact receiver type for method
465
+ // resolution — the cast narrows the receiver's declared type, so
466
+ // resolve to the CAST type, not the underlying expression's type.
467
+ if (stripped.castType !== undefined) {
468
+ const cls = (0, walkers_js_1.findClassBindingInScope)(inScope, stripped.castType, scopes);
469
+ if (cls !== undefined)
470
+ return cls;
471
+ }
472
+ }
473
+ // ── End pre-processing ─────────────────────────────────────────
474
+ // Bare identifier — resolve via typeBinding first, then fall back to
475
+ // a direct class-name lookup. The class-name fallback handles
476
+ // "static receiver" shapes like `UserService.findUser()` where
477
+ // `UserService` isn't a variable but a class imported into scope.
478
+ if (!workingText.includes('.') && !workingText.includes('(')) {
479
+ const mapTuple = parseMapTupleSentinel(workingText);
480
+ if (mapTuple !== null) {
481
+ const rhsTb = (0, walkers_js_1.findReceiverTypeBinding)(inScope, mapTuple.rhs, scopes);
482
+ if (rhsTb === undefined)
483
+ return undefined;
484
+ const arg = extractShallowMapTypeArgByIndex(rhsTb.rawName, mapTuple.tupleIdx);
485
+ if (arg === undefined)
486
+ return undefined;
487
+ return (0, walkers_js_1.findClassBindingInScope)(rhsTb.declaredAtScope, arg, scopes);
488
+ }
489
+ // A language may declare that `this` IS the enclosing class rather than a
490
+ // per-function-scope binding (`ScopeResolver.resolveThisViaEnclosingClass`,
491
+ // the same flag Case 0.5 in `receiver-bound-calls` uses for a BARE `this`
492
+ // receiver). Such a language synthesizes no `this` typeBinding anywhere, so
493
+ // a chain whose BASE is `this` — `this->repo.save(u)`, `this.repo.save(u)` —
494
+ // had no way to seed its head and folded to nothing. Measured for the
495
+ // NON-generic control too, so it was never a generics gap.
496
+ // Placed before the typeBinding read: a language that DOES bind `this` per
497
+ // function scope never sets the flag, so nothing else can reach this.
498
+ if (workingText === 'this' && options.resolveThisViaEnclosingClass === true) {
499
+ const enclosing = (0, walkers_js_1.findEnclosingClassDef)(inScope, scopes);
500
+ if (enclosing !== undefined)
501
+ return enclosing;
502
+ }
503
+ const tb = (0, walkers_js_1.findReceiverTypeBinding)(inScope, workingText, scopes);
504
+ if (tb !== undefined) {
505
+ // Map for-of: binding name is `user` but rawType is
506
+ // `__MAP_TUPLE_i__:entries` (see captures.ts) — same extraction as
507
+ // the literal-sentinel branch above.
508
+ const boundMapTuple = parseMapTupleSentinel(tb.rawName);
509
+ if (boundMapTuple !== null) {
510
+ const rhsTb = (0, walkers_js_1.findReceiverTypeBinding)(inScope, boundMapTuple.rhs, scopes);
511
+ if (rhsTb === undefined)
512
+ return undefined;
513
+ const arg = extractShallowMapTypeArgByIndex(rhsTb.rawName, boundMapTuple.tupleIdx);
514
+ if (arg === undefined)
515
+ return undefined;
516
+ return (0, walkers_js_1.findClassBindingInScope)(rhsTb.declaredAtScope, arg, scopes);
517
+ }
518
+ const viaTb = classOfDeclaredType(tb, scopes, options.stripTypePreservingDecoration);
519
+ if (viaTb !== undefined)
520
+ return viaTb;
521
+ // Member-alias / call-result shapes store the RHS path on rawName
522
+ // (`user.address`, `addr.getCity`) — resolve as a compound chain.
523
+ if (tb.rawName.includes('.') && !tb.rawName.includes('(')) {
524
+ const dotted = resolveCompoundReceiverClass(tb.rawName, inScope, scopes, index, options, depth + 1);
525
+ if (dotted !== undefined)
526
+ return dotted;
527
+ const dottedCall = resolveCompoundReceiverClass(`${tb.rawName}()`, inScope, scopes, index, options, depth + 1);
528
+ if (dottedCall !== undefined)
529
+ return dottedCall;
530
+ }
531
+ // Callable alias (`const user = getUser()` → type rawName `getUser`)
532
+ if (!tb.rawName.includes('.') && !tb.rawName.includes('(')) {
533
+ const callAlias = resolveCompoundReceiverClass(`${tb.rawName}()`, inScope, scopes, index, options, depth + 1);
534
+ if (callAlias !== undefined)
535
+ return callAlias;
536
+ }
537
+ // Compound member-call alias: rawName has both `.` and `()`
538
+ // (`user = Factory.get_user()` → rawName `Factory.get_user()`).
539
+ // Recurse into the compound resolver with the raw compound
540
+ // expression so the mixed-chain parser can split at top-level
541
+ // `.` and resolve the receiver + method return type.
542
+ if (tb.rawName.includes('.') && tb.rawName.includes('(')) {
543
+ const compound = resolveCompoundReceiverClass(tb.rawName, inScope, scopes, index, options, depth + 1);
544
+ if (compound !== undefined)
545
+ return compound;
546
+ }
547
+ }
548
+ // Mirror the dotted-chain head rule below (`headType ? … : …`): a binding
549
+ // that EXISTS but resolves to no class means "not a typed receiver", not
550
+ // "try the class namespace instead". Only the structural fold opts in; the
551
+ // cascade keeps its historical fallthrough so no existing edge moves.
552
+ if (tb !== undefined && options.strictBaseBinding === true)
553
+ return undefined;
554
+ return (0, walkers_js_1.findClassBindingInScope)(inScope, workingText, scopes);
555
+ }
556
+ // Trailing `()` — call expression. Strip it and resolve the function
557
+ // expression's return type. We only handle the canonical `f()` /
558
+ // `obj.method()` shape; nested-arg expressions like `f(g())` are
559
+ // out of scope for V1 (depth-capped recursion catches infinite loops).
560
+ if (workingText.endsWith(')')) {
561
+ const openIdx = matchingOpenParen(workingText);
562
+ if (openIdx === -1)
563
+ return undefined;
564
+ const fnExpr = workingText.slice(0, openIdx).trim();
565
+ if (fnExpr.length === 0)
566
+ return undefined;
567
+ // A keyword-marked construction is never an `obj.method()` call, even when
568
+ // the type is qualified (`new ns.Service()`), so it must be resolved before
569
+ // the dot-split below routes it into member resolution (#2708).
570
+ const keyword = options.constructionSyntax?.keyword;
571
+ if (keyword !== undefined && new RegExp(`^${escapeForRegExp(keyword)}\\s`).test(fnExpr)) {
572
+ return resolveConstructionExpressionClass(fnExpr, inScope, scopes, index, options);
573
+ }
574
+ const lastDot = fnExpr.lastIndexOf('.');
575
+ if (lastDot === -1) {
576
+ // Free call `name()`. Look up function in scope, then its
577
+ // return-type typeBinding (which lives in the function's
578
+ // enclosing scope per the language's return-type hoist rule).
579
+ const fnDef = (0, walkers_js_1.findExportedDefByName)(fnExpr, inScope, scopes, index);
580
+ if (fnDef !== undefined) {
581
+ const retType = (0, walkers_js_1.findReceiverTypeBinding)(inScope, fnExpr, scopes);
582
+ const viaReturn = retType === undefined
583
+ ? undefined
584
+ : (0, walkers_js_1.findClassBindingInScope)(retType.declaredAtScope, retType.rawName, scopes);
585
+ if (viaReturn !== undefined)
586
+ return viaReturn;
587
+ }
588
+ // Inline construction — `Service(db).m()` / `new Service(db).m()`.
589
+ // The constructed value IS the receiver, so there is no binding to
590
+ // read a type off; the return-type path above cannot help either,
591
+ // because a class has no return-type binding. Type it from the
592
+ // class the callee names (#2708).
593
+ return resolveConstructionExpressionClass(fnExpr, inScope, scopes, index, options);
594
+ }
595
+ // `obj.method()` — resolve obj's class, look up method's return
596
+ // type on that class scope (or the MRO).
597
+ const objExpr = fnExpr.slice(0, lastDot);
598
+ const methodName = fnExpr.slice(lastDot + 1);
599
+ const objClass = resolveCompoundReceiverClass(objExpr, inScope, scopes, index, options, depth + 1);
600
+ if (objClass === undefined) {
601
+ // A verified namespace-qualified bare constructor is syntactically
602
+ // indistinguishable from an untyped member call here. Only the namespace
603
+ // map makes the constructor interpretation safe.
604
+ if (options.namespaceTargets?.has(objExpr) === true) {
605
+ return resolveConstructionExpressionClass(fnExpr, inScope, scopes, index, options);
606
+ }
607
+ return undefined;
608
+ }
609
+ // Does `objExpr` name the CLASS ITSELF (`Factory.new`) rather than a
610
+ // value whose type is that class (`factory.new`)? Only the former is
611
+ // a construction — see the selector fallback below. A bare identifier
612
+ // that resolves straight to the class binding is the class constant;
613
+ // anything reached through a typeBinding is an instance.
614
+ const objIsClassConstant = !objExpr.includes('(') &&
615
+ !objExpr.includes('.') &&
616
+ (0, walkers_js_1.findClassBindingInScope)(inScope, objExpr, scopes)?.nodeId === objClass.nodeId;
617
+ // Selector-form construction — `Factory.new.do_work` (#2708). Gated on the
618
+ // receiver naming the CLASS: `factory.new` is an ordinary call to a member
619
+ // named `new` on an instance, and reading that as construction replaced a
620
+ // correct edge with a wrong one. For the class constant, construction wins
621
+ // over any recorded binding for the selector, because a member named `new`
622
+ // on a class is an instance method Ruby never reaches through the constant
623
+ // (see the contract's KNOWN LIMITATION note for the `def self.new` case).
624
+ if (isConstructionSelectorHop(methodName, objClass, objIsClassConstant, options)) {
625
+ return objClass;
626
+ }
627
+ let retType;
628
+ const ownerChain = [objClass.nodeId, ...scopes.methodDispatch.mroFor(objClass.nodeId)];
629
+ for (const ownerId of ownerChain) {
630
+ const cs = classScopeByDefId.get(ownerId);
631
+ const candidate = cs?.typeBindings.get(methodName);
632
+ if (candidate !== undefined) {
633
+ retType = candidate;
634
+ break;
635
+ }
636
+ // Fallback: walk up from the class scope looking for a return-
637
+ // type binding on an ancestor (Module) scope. Gated on
638
+ // `hoistTypeBindingsToModule` because only languages that hoist
639
+ // method return-type bindings to Module scope need this path;
640
+ // enabling it unconditionally would let other languages pick up
641
+ // unrelated module-level bindings. See contract doc for the
642
+ // invariant and `propagateImportedReturnTypes` for how the
643
+ // hoisted bindings originate.
644
+ if (cs !== undefined && options.hoistTypeBindingsToModule === true) {
645
+ let curId = cs.parent;
646
+ while (curId !== null) {
647
+ const curScope = scopes.scopeTree.getScope(curId);
648
+ if (curScope === undefined)
649
+ break;
650
+ const cand = curScope.typeBindings.get(methodName);
651
+ if (cand !== undefined) {
652
+ retType = cand;
653
+ break;
654
+ }
655
+ curId = curScope.parent;
656
+ }
657
+ if (retType !== undefined)
658
+ break;
659
+ }
660
+ }
661
+ if (retType === undefined && fieldFallback) {
662
+ const objCs = classScopeByDefId.get(objClass.nodeId);
663
+ if (objCs !== undefined) {
664
+ for (const [, fieldType] of objCs.typeBindings) {
665
+ const fieldClass = (0, walkers_js_1.findClassBindingInScope)(fieldType.declaredAtScope, fieldType.rawName, scopes);
666
+ if (fieldClass === undefined)
667
+ continue;
668
+ const fcs = classScopeByDefId.get(fieldClass.nodeId);
669
+ const candidate = fcs?.typeBindings.get(methodName);
670
+ if (candidate !== undefined) {
671
+ retType = candidate;
672
+ break;
673
+ }
674
+ }
675
+ }
676
+ }
677
+ // `Map<K,V>.values()` / `this.repos.values()` — lib `Map` often has no
678
+ // parsed return-type binding; infer `V` from the receiver field's
679
+ // `Map<…>` annotation when the method is `values`.
680
+ if (retType === undefined && methodName === 'values') {
681
+ const mapVal = resolveMapValueTypeNameFromPrefix(objExpr, inScope, scopes, index, options);
682
+ if (mapVal !== undefined) {
683
+ retType = {
684
+ rawName: mapVal,
685
+ declaredAtScope: inScope,
686
+ source: 'return-annotation',
687
+ };
688
+ }
689
+ }
690
+ if (retType === undefined)
691
+ return undefined;
692
+ return (0, walkers_js_1.findClassBindingInScope)(retType.declaredAtScope, retType.rawName, scopes);
693
+ }
694
+ // Mixed dotted + call chain: `obj.field.method().field.method()…`.
695
+ // Split at top-level `.` (those NOT inside balanced `(...)`) so a
696
+ // middle segment like `getUser()` stays intact. Each segment is
697
+ // either a bare identifier `field` OR `method(...)` — the former
698
+ // resolves via the current class's typeBindings (field → type),
699
+ // the latter resolves via the current class's typeBindings
700
+ // (method return-type). We accept both on each hop because class
701
+ // scopes store both method return types and field types under
702
+ // `typeBindings` keyed by the member name.
703
+ const parts = splitChainAtTopLevel(workingText);
704
+ // Language-specific collection-accessor suffix (C#'s `data.Values`
705
+ // on Dictionary<K,V>, etc.). When the provider hook recognizes
706
+ // the final segment and unwraps the receiver's generic, return
707
+ // the element class directly. Resolved before the field-walk
708
+ // because Dictionary-family types aren't local class defs.
709
+ if (options.elementTypeOf !== undefined && parts.length >= 2) {
710
+ const last = parts[parts.length - 1];
711
+ const headInner = parts[0];
712
+ if (last === undefined || headInner === undefined)
713
+ return undefined;
714
+ const prefix = parts.slice(0, -1).join('.');
715
+ let prefixType;
716
+ if (parts.length === 2) {
717
+ prefixType = (0, walkers_js_1.findReceiverTypeBinding)(inScope, prefix, scopes);
718
+ }
719
+ else {
720
+ // Recursive resolution: walk the prefix as a dotted class chain
721
+ // to find its typeRef. We need the TypeRef (not the class def)
722
+ // because the hook inspects the raw generic args (e.g.
723
+ // `Dictionary<string, User>`).
724
+ let cur = (0, walkers_js_1.findReceiverTypeBinding)(inScope, headInner, scopes);
725
+ for (let i = 1; i < parts.length - 1 && cur !== undefined; i++) {
726
+ const segment = parts[i];
727
+ if (segment === undefined)
728
+ break;
729
+ const cls = (0, walkers_js_1.findClassBindingInScope)(cur.declaredAtScope, cur.rawName, scopes);
730
+ if (cls === undefined) {
731
+ cur = undefined;
732
+ break;
733
+ }
734
+ const cs = classScopeByDefId.get(cls.nodeId);
735
+ cur = cs?.typeBindings.get(segment);
736
+ }
737
+ prefixType = cur;
738
+ }
739
+ if (prefixType !== undefined) {
740
+ // `rawName`, not `declaredSpelling`, and deliberately: the accessor route
741
+ // only fires on a multi-arg container (`Dictionary<K,V>`), which every
742
+ // provider's capture-time normalization leaves ALONE — so the two are the
743
+ // same string here, and reading the spelling would change nothing except
744
+ // to widen an unmeasured surface.
745
+ const elemName = options.elementTypeOf(prefixType.rawName, { kind: 'accessor', name: last });
746
+ if (elemName !== undefined) {
747
+ return (0, walkers_js_1.findClassBindingInScope)(prefixType.declaredAtScope, elemName, scopes);
748
+ }
749
+ }
750
+ }
751
+ const head = parts[0];
752
+ if (head === undefined)
753
+ return undefined;
754
+ const headMemberName = stripCallParens(head);
755
+ const headType = (0, walkers_js_1.findReceiverTypeBinding)(inScope, headMemberName, scopes);
756
+ // The typed arm reads a DECLARED TYPE and so goes through the grounded lookup
757
+ // (see {@link classOfDeclaredType}); the untyped arm resolves the head NAME as
758
+ // the source WROTE it — a static class receiver — which was never erased and
759
+ // keeps the bare lookup.
760
+ //
761
+ // NO MEASURED CASE OF ITS OWN, and that is worth saying plainly: every fixture
762
+ // reaching here has an un-erased head (`self`, `this`, a local), for which the
763
+ // two lookups are the same call. It is changed because leaving one of five
764
+ // sibling reads of a `TypeRef` on the ungrounded lookup is precisely how the
765
+ // hole below survived — three were wired, two were not, and only one of the
766
+ // two had a fixture. See `classOfDeclaredType` for why this cannot change a
767
+ // `TypeRef` that was never reduced.
768
+ let currentClass = headType
769
+ ? classOfDeclaredType(headType, scopes)
770
+ : (0, walkers_js_1.findClassBindingInScope)(inScope, headMemberName, scopes);
771
+ // Whether the walk currently sits on the CLASS ITSELF rather than on a
772
+ // value of that class. Seeded true only when the head resolved straight to
773
+ // a class binding (`Factory.new…`); a head reached through a typeBinding
774
+ // (`factory = Factory.new` then `factory.new…`) is already an instance.
775
+ // Every hop past the head yields a value, so it clears below (#2708).
776
+ let currentIsClassConstant = headType === undefined && currentClass !== undefined;
777
+ // Head seed for a literal `this` head with no receiver typeBinding in
778
+ // scope: languages synthesize `this` typeBindings per function scope,
779
+ // so a chain site outside any function scope (a field initializer or
780
+ // an instance initializer block) has none — there, the enclosing
781
+ // class definition IS the receiver type. Restricted to initializer
782
+ // contexts (no Function scope between the site and its class): a
783
+ // Function scope WITHOUT a `this` typeBinding means the language
784
+ // deliberately left `this` unbound there (object-literal methods,
785
+ // nested plain functions, static contexts), and seeding the
786
+ // lexically enclosing class would fabricate edges. Head resolution
787
+ // only; the per-segment walk below is shared with every other
788
+ // chain shape.
789
+ //
790
+ // A language may ALSO declare that `this` is always the enclosing class —
791
+ // `ScopeResolver.resolveThisViaEnclosingClass`, the same flag Case 0.5 in
792
+ // `receiver-bound-calls` already uses for a bare `this` receiver. Such a
793
+ // language deliberately synthesizes no `this` typeBinding anywhere, so the
794
+ // initializer-context test above can never be true inside a method body and
795
+ // every `this->field.m()` / `this.field.m()` chain folded to nothing —
796
+ // measured for the NON-generic control too, so it was never a generics gap.
797
+ // Reading the provider flag keeps the rule language-free: a language that
798
+ // does bind `this` per function scope does not set it, and is unaffected.
799
+ if (currentClass === undefined &&
800
+ headType === undefined &&
801
+ headMemberName === 'this' &&
802
+ (isInitializerContext(inScope, scopes) || options.resolveThisViaEnclosingClass === true)) {
803
+ currentClass = (0, walkers_js_1.findEnclosingClassDef)(inScope, scopes);
804
+ }
805
+ // `const user = getUser(); user.address` — the typeBinding for `user`
806
+ // is an alias to the callee name (`getUser`), not a class. When
807
+ // `findClassBinding` on that rawName fails, treat it as a zero-arg
808
+ // call so return-type hoisting resolves to the class (`User`).
809
+ if (currentClass === undefined &&
810
+ headType !== undefined &&
811
+ !headType.rawName.includes('.') &&
812
+ !headType.rawName.includes('(')) {
813
+ currentClass = resolveCompoundReceiverClass(`${headType.rawName}()`, inScope, scopes, index, options, depth + 1);
814
+ }
815
+ // Construction in the chain HEAD — `new Service().inner.doWork()` (#2708).
816
+ // The head arrives as `new Service()`, which `stripCallParens` reduces to
817
+ // `new Service`: no binding and no class of that name, so the walk was never
818
+ // seeded and the whole chain resolved to nothing. A constructed value is an
819
+ // instance, so `currentIsClassConstant` correctly stays false here.
820
+ if (currentClass === undefined) {
821
+ currentClass = resolveConstructionExpressionClass(headMemberName, inScope, scopes, index, options);
822
+ }
823
+ for (let i = 1; i < parts.length && currentClass !== undefined; i++) {
824
+ const segment = parts[i];
825
+ if (segment === undefined)
826
+ break;
827
+ const memberName = stripCallParens(segment);
828
+ // Selector-form construction mid-chain — `Factory.new.do_work`, including
829
+ // the parenthesis-less spelling that never reaches the call branch above
830
+ // (#2708). Gated on the walk sitting on the CLASS itself: after
831
+ // `factory = Factory.new`, `factory.new` is an ordinary instance-member
832
+ // call and must keep normal resolution.
833
+ if (isConstructionSelectorHop(memberName, currentClass, currentIsClassConstant, options)) {
834
+ // Constructing yields an INSTANCE of the same class: the walk stays on
835
+ // `currentClass` but no longer sits on the class constant.
836
+ currentIsClassConstant = false;
837
+ continue;
838
+ }
839
+ const cs = classScopeByDefId.get(currentClass.nodeId);
840
+ let memberType = cs?.typeBindings.get(memberName);
841
+ if (memberType === undefined &&
842
+ options.hoistTypeBindingsToModule === true &&
843
+ cs !== undefined) {
844
+ let curId = cs.parent;
845
+ while (curId !== null) {
846
+ const curScope = scopes.scopeTree.getScope(curId);
847
+ if (curScope === undefined)
848
+ break;
849
+ const cand = curScope.typeBindings.get(memberName);
850
+ if (cand !== undefined) {
851
+ memberType = cand;
852
+ break;
853
+ }
854
+ curId = curScope.parent;
855
+ }
856
+ }
857
+ if (memberType === undefined) {
858
+ // Trailing segment may be a method name without `()` — e.g.
859
+ // `this.repos.values` from a for-of iterable capture. Try the
860
+ // call-shaped resolver before giving up.
861
+ if (!segment.includes('(')) {
862
+ const prefix = parts.slice(0, i).join('.');
863
+ const asCall = resolveCompoundReceiverClass(`${prefix}.${memberName}()`, inScope, scopes, index, options, depth + 1);
864
+ if (asCall !== undefined)
865
+ return asCall;
866
+ }
867
+ return undefined;
868
+ }
869
+ // THE MEASURED HOLE (#2833 follow-up). This is the cascade's copy of the
870
+ // fold's member step, and it read the possibly-erased `rawName` directly.
871
+ // A Python `self.m.save(u)` whose fold step refused `Mapped[User]` on
872
+ // grounds fell through here — a declined fold is documented as "no answer",
873
+ // never a veto — and this walk re-minted `other.py:Mapped` from the
874
+ // workspace index. Same rule, same lookup, so the two routes now agree.
875
+ let nextClass = classOfDeclaredType(memberType, scopes);
876
+ if (nextClass === undefined) {
877
+ const fromMap = unwrapMapValueToClass(memberType, scopes);
878
+ if (fromMap !== undefined)
879
+ nextClass = fromMap;
880
+ }
881
+ currentClass = nextClass;
882
+ currentIsClassConstant = false;
883
+ }
884
+ return currentClass;
885
+ }
886
+ /**
887
+ * Split a chain expression like `a.b().c.d()` at top-level `.`
888
+ * separators — i.e. `.` characters NOT nested inside balanced
889
+ * `(...)`, `[...]`, or `<...>` delimiters. Returns the segments in
890
+ * order: `['a', 'b()', 'c', 'd()']`. Malformed input falls back to
891
+ * a plain `split('.')`.
892
+ */
893
+ function splitChainAtTopLevel(text) {
894
+ const out = [];
895
+ let depth = 0;
896
+ let last = 0;
897
+ for (let i = 0; i < text.length; i++) {
898
+ const ch = text[i];
899
+ if (ch === '(' || ch === '[' || ch === '<')
900
+ depth++;
901
+ else if (ch === ')' || ch === ']' || ch === '>')
902
+ depth = Math.max(0, depth - 1);
903
+ else if (ch === '.' && depth === 0) {
904
+ out.push(text.slice(last, i));
905
+ last = i + 1;
906
+ }
907
+ }
908
+ out.push(text.slice(last));
909
+ // Guard against pathological input (`a.` / `.a`) — drop empties.
910
+ return out.filter((s) => s.length > 0);
911
+ }
912
+ /**
913
+ * Strip a trailing `(...)` from a chain segment so typeBinding lookup
914
+ * uses the member name: `'getUser()'` → `'getUser'`. Leaves bare
915
+ * identifiers (`'address'`) unchanged. Arguments inside the parens
916
+ * are discarded — the compound resolver is return-type only.
917
+ */
918
+ function stripCallParens(segment) {
919
+ if (!segment.endsWith(')'))
920
+ return segment;
921
+ const open = segment.indexOf('(');
922
+ if (open === -1)
923
+ return segment;
924
+ return segment.slice(0, open);
925
+ }
926
+ /** True when `startScope` sits under a Class scope with no Function
927
+ * scope in between — a field-initializer or instance-initializer
928
+ * context, the only place a literal `this` chain head may be seeded
929
+ * from the lexically enclosing class. Function bodies are excluded
930
+ * on purpose: a Function scope carrying no `this` typeBinding means
931
+ * the language deliberately left `this` unbound there. */
932
+ function isInitializerContext(startScope, scopes) {
933
+ let currentId = startScope;
934
+ const visited = new Set();
935
+ while (currentId !== null) {
936
+ if (visited.has(currentId))
937
+ return false;
938
+ visited.add(currentId);
939
+ const scope = scopes.scopeTree.getScope(currentId);
940
+ if (scope === undefined)
941
+ return false;
942
+ if (scope.kind === 'Class')
943
+ return true;
944
+ if (scope.kind === 'Function')
945
+ return false;
946
+ currentId = scope.parent;
947
+ }
948
+ return false;
949
+ }
950
+ /** Find the index of the `(` that matches the trailing `)` of a
951
+ * call-expression text. Returns -1 if unbalanced. */
952
+ function matchingOpenParen(text) {
953
+ if (!text.endsWith(')'))
954
+ return -1;
955
+ let depth = 0;
956
+ for (let i = text.length - 1; i >= 0; i--) {
957
+ const ch = text[i];
958
+ if (ch === ')')
959
+ depth++;
960
+ else if (ch === '(') {
961
+ depth--;
962
+ if (depth === 0)
963
+ return i;
964
+ }
965
+ }
966
+ return -1;
967
+ }
968
+ /** Max peel iterations for `stripCastWrappers`. Real cast nesting —
969
+ * including decompiler output like `((Target)((Object)expr))` —
970
+ * is a handful of levels, and each cast level costs at most two
971
+ * peels (a redundant-paren unwrap plus the cast group itself), so
972
+ * 16 covers 8-level nesting with headroom. Each peel rescans the
973
+ * working text for its matching close paren, so pathological input
974
+ * like `((((…))))` would otherwise cost O(N²); the cap bounds it at
975
+ * O(N · MAX_CAST_PEEL). Exceeding the cap bails with the not-a-cast
976
+ * outcome and the ORIGINAL text — all-or-nothing, never a
977
+ * partially-peeled result. */
978
+ const MAX_CAST_PEEL = 16;
979
+ /**
980
+ * Peel C-style cast layers off a receiver-position expression:
981
+ * `((Target)((Other)expr))` → `workingText` `expr`, `castType`
982
+ * `Target`. Pure text scan — no scope or index access — consumed by
983
+ * `resolveCompoundReceiverClass` when a language opts in via
984
+ * `stripReceiverCastExpressions`. Track the outermost meaningful cast
985
+ * type: the cast narrows the receiver's declared type, so the caller
986
+ * resolves the CAST type, not the underlying expression's type.
987
+ *
988
+ * Each peeled paren group with a non-empty trailing expression (a
989
+ * cast candidate) is classified three ways:
990
+ * (a) simple identifier (`SIMPLE_CAST_TYPE_RE`) → cast type
991
+ * captured (outermost capture wins; later simple groups are
992
+ * noise casts, as in decompiler output like
993
+ * `((Target)((Object)expr))`);
994
+ * (b) type-shaped but unparseable here — dotted / generic / array
995
+ * (`UNPARSEABLE_CAST_TYPE_RE`) → this IS a cast, but its type
996
+ * cannot be looked up: report `unresolvableCast: true` so the
997
+ * caller resolves nothing rather than falling through to the
998
+ * pre-cast expression's own declared type (the pre-#2353 safe
999
+ * no-op for these shapes);
1000
+ * (c) anything else → not a cast: stop scanning and return the
1001
+ * text peeled so far for the normal resolver.
1002
+ * A paren group with an EMPTY remainder is never a cast candidate —
1003
+ * `((…))` / `(foo)` is a redundant-paren unwrap: unwrap and re-scan
1004
+ * without capturing anything.
1005
+ *
1006
+ * Known limitation: the paren scan is not string-literal-aware — a
1007
+ * `)` inside a quoted call argument (e.g. `((T)f(")")).g`) mis-scans
1008
+ * the group boundary. Such shapes classify as not-a-cast and fall
1009
+ * through safely to the normal resolver.
1010
+ */
1011
+ function stripCastWrappers(text) {
1012
+ let castType;
1013
+ let workingText = text;
1014
+ let peels = 0;
1015
+ while (true) {
1016
+ if (!workingText.startsWith('('))
1017
+ break;
1018
+ peels++;
1019
+ if (peels > MAX_CAST_PEEL) {
1020
+ return { workingText: text, castType: undefined, unresolvableCast: false };
1021
+ }
1022
+ let d = 1;
1023
+ let closeIdx = -1;
1024
+ for (let i = 1; i < workingText.length; i++) {
1025
+ if (workingText[i] === '(')
1026
+ d++;
1027
+ else if (workingText[i] === ')') {
1028
+ d--;
1029
+ if (d === 0) {
1030
+ closeIdx = i;
1031
+ break;
1032
+ }
1033
+ }
1034
+ }
1035
+ if (closeIdx === -1)
1036
+ break;
1037
+ const insideParens = workingText.slice(1, closeIdx).trim();
1038
+ const remainder = workingText.slice(closeIdx + 1).trim();
1039
+ // Empty remainder: redundant outer parens — `((…))`, or a plain
1040
+ // parenthesized expression like `(foo)`. Unwrap and re-scan.
1041
+ // Never a cast candidate: a cast needs a trailing expression, so
1042
+ // nothing is captured from this group.
1043
+ if (remainder.length === 0) {
1044
+ workingText = insideParens;
1045
+ continue;
1046
+ }
1047
+ // A cast operand starts with `(`, an identifier, or `this`. Any
1048
+ // other remainder shape (e.g. `.member` access on the paren
1049
+ // group) means this group is not a cast — leave the text for the
1050
+ // normal resolver.
1051
+ if (!remainder.startsWith('(') && !/^[a-zA-Z_]/.test(remainder))
1052
+ break;
1053
+ if (SIMPLE_CAST_TYPE_RE.test(insideParens)) {
1054
+ // (a) Resolvable cast type — capture the FIRST (outermost) one.
1055
+ if (castType === undefined)
1056
+ castType = insideParens;
1057
+ }
1058
+ else if (UNPARSEABLE_CAST_TYPE_RE.test(insideParens)) {
1059
+ // (b) Type-shaped but unparseable cast. Once a simple cast type
1060
+ // has been captured, later unparseable groups are noise casts
1061
+ // and the captured type wins; otherwise report the whole
1062
+ // expression as an unresolvable cast so the caller bails out.
1063
+ if (castType === undefined) {
1064
+ return { workingText, castType: undefined, unresolvableCast: true };
1065
+ }
1066
+ }
1067
+ else {
1068
+ // (c) Not a cast.
1069
+ break;
1070
+ }
1071
+ workingText = remainder;
1072
+ }
1073
+ return { workingText, castType, unresolvableCast: false };
1074
+ }
1075
+ /** Type arguments of a shallow `Map<K,V>` / `ReadonlyMap<K,V>` (depth-aware). */
1076
+ function extractShallowMapTypeArgByIndex(mapText, wantIndex) {
1077
+ const t = mapText.trim();
1078
+ const m = /^(?:ReadonlyMap|Map)\s*</.exec(t);
1079
+ if (m === null || m.index !== 0)
1080
+ return undefined;
1081
+ const openIdx = m[0].length - 1;
1082
+ if (t[openIdx] !== '<')
1083
+ return undefined;
1084
+ let depth = 1;
1085
+ const args = [];
1086
+ let segStart = openIdx + 1;
1087
+ for (let i = openIdx + 1; i < t.length; i++) {
1088
+ const ch = t[i];
1089
+ if (ch === '<')
1090
+ depth++;
1091
+ else if (ch === '>') {
1092
+ depth--;
1093
+ if (depth === 0) {
1094
+ const tail = t.slice(segStart, i).trim();
1095
+ if (tail.length > 0)
1096
+ args.push(tail);
1097
+ break;
1098
+ }
1099
+ }
1100
+ else if (ch === ',' && depth === 1) {
1101
+ args.push(t.slice(segStart, i).trim());
1102
+ segStart = i + 1;
1103
+ }
1104
+ }
1105
+ const picked = args[wantIndex]?.trim();
1106
+ return picked !== undefined && picked.length > 0 ? picked : undefined;
1107
+ }
1108
+ function unwrapMapValueToClass(memberType, scopes) {
1109
+ const v = extractShallowMapTypeArgByIndex(memberType.rawName, 1);
1110
+ if (v === undefined)
1111
+ return undefined;
1112
+ return (0, walkers_js_1.findClassBindingInScope)(memberType.declaredAtScope, v, scopes);
1113
+ }
1114
+ /**
1115
+ * Walk `objExpr` as a field chain (`this.repos`) and return the `V`
1116
+ * type name from a terminal `Map<K,V>` field binding — used when
1117
+ * resolving `.values()` without a parsed stdlib return type.
1118
+ */
1119
+ function resolveMapValueTypeNameFromPrefix(objExpr, inScope, scopes, index, options) {
1120
+ const classScopeByDefId = index.classScopeByDefId;
1121
+ const parts = splitChainAtTopLevel(objExpr);
1122
+ const head = parts[0];
1123
+ if (head === undefined)
1124
+ return undefined;
1125
+ const headMemberName = stripCallParens(head);
1126
+ const headType = (0, walkers_js_1.findReceiverTypeBinding)(inScope, headMemberName, scopes);
1127
+ let currentClass = headType
1128
+ ? (0, walkers_js_1.findClassBindingInScope)(headType.declaredAtScope, headType.rawName, scopes)
1129
+ : (0, walkers_js_1.findClassBindingInScope)(inScope, headMemberName, scopes);
1130
+ if (currentClass === undefined &&
1131
+ headType !== undefined &&
1132
+ !headType.rawName.includes('.') &&
1133
+ !headType.rawName.includes('(')) {
1134
+ currentClass = resolveCompoundReceiverClass(`${headType.rawName}()`, inScope, scopes, index, options, 1);
1135
+ }
1136
+ let lastMemberType;
1137
+ for (let i = 1; i < parts.length && currentClass !== undefined; i++) {
1138
+ const segment = parts[i];
1139
+ if (segment === undefined)
1140
+ break;
1141
+ const memberName = stripCallParens(segment);
1142
+ const cs = classScopeByDefId.get(currentClass.nodeId);
1143
+ if (cs === undefined)
1144
+ return undefined;
1145
+ let memberType = cs.typeBindings.get(memberName);
1146
+ if (memberType === undefined && options.hoistTypeBindingsToModule === true) {
1147
+ let curId = cs.parent;
1148
+ while (curId !== null) {
1149
+ const curScope = scopes.scopeTree.getScope(curId);
1150
+ if (curScope === undefined)
1151
+ break;
1152
+ const cand = curScope.typeBindings.get(memberName);
1153
+ if (cand !== undefined) {
1154
+ memberType = cand;
1155
+ break;
1156
+ }
1157
+ curId = curScope.parent;
1158
+ }
1159
+ }
1160
+ if (memberType === undefined)
1161
+ return undefined;
1162
+ lastMemberType = memberType;
1163
+ let nextClass = (0, walkers_js_1.findClassBindingInScope)(memberType.declaredAtScope, memberType.rawName, scopes);
1164
+ if (nextClass === undefined) {
1165
+ const fromMap = unwrapMapValueToClass(memberType, scopes);
1166
+ if (fromMap !== undefined)
1167
+ nextClass = fromMap;
1168
+ }
1169
+ currentClass = nextClass;
1170
+ }
1171
+ if (lastMemberType === undefined)
1172
+ return undefined;
1173
+ return extractShallowMapTypeArgByIndex(lastMemberType.rawName, 1);
1174
+ }