gitnexus 1.6.8-rc.9 → 1.6.8

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 (430) hide show
  1. package/README.md +3 -3
  2. package/dist/_shared/graph/types.d.ts +31 -1
  3. package/dist/_shared/graph/types.d.ts.map +1 -1
  4. package/dist/_shared/language-detection.d.ts.map +1 -1
  5. package/dist/_shared/language-detection.js +11 -1
  6. package/dist/_shared/language-detection.js.map +1 -1
  7. package/dist/_shared/lbug/schema-constants.d.ts +1 -1
  8. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  9. package/dist/_shared/lbug/schema-constants.js +6 -0
  10. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  11. package/dist/_shared/scope-resolution/parsed-file.d.ts +21 -0
  12. package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
  13. package/dist/_shared/scope-resolution/symbol-definition.d.ts +6 -0
  14. package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
  15. package/dist/cli/ai-context.d.ts +31 -1
  16. package/dist/cli/ai-context.js +18 -16
  17. package/dist/cli/analyze-config.js +11 -0
  18. package/dist/cli/analyze.d.ts +14 -0
  19. package/dist/cli/analyze.js +98 -0
  20. package/dist/cli/embedding-dims.d.ts +33 -0
  21. package/dist/cli/embedding-dims.js +39 -0
  22. package/dist/cli/eval-server.d.ts +8 -0
  23. package/dist/cli/eval-server.js +242 -2
  24. package/dist/cli/help-i18n.js +19 -0
  25. package/dist/cli/i18n/en.d.ts +15 -1
  26. package/dist/cli/i18n/en.js +15 -1
  27. package/dist/cli/i18n/resources.d.ts +29 -1
  28. package/dist/cli/i18n/zh-CN.d.ts +14 -0
  29. package/dist/cli/i18n/zh-CN.js +15 -1
  30. package/dist/cli/index.js +89 -1
  31. package/dist/cli/mcp.d.ts +6 -1
  32. package/dist/cli/mcp.js +26 -1
  33. package/dist/cli/optional-grammars.d.ts +6 -8
  34. package/dist/cli/optional-grammars.js +8 -11
  35. package/dist/cli/setup.d.ts +3 -1
  36. package/dist/cli/setup.js +67 -17
  37. package/dist/cli/skill-gen.js +2 -1
  38. package/dist/cli/tool.d.ts +19 -1
  39. package/dist/cli/tool.js +96 -3
  40. package/dist/core/embeddings/hf-env.d.ts +0 -66
  41. package/dist/core/embeddings/http-client.d.ts +7 -0
  42. package/dist/core/embeddings/http-client.js +5 -3
  43. package/dist/core/embeddings/server-mapping.d.ts +1 -1
  44. package/dist/core/embeddings/server-mapping.js +7 -3
  45. package/dist/core/graph/import-cycles.d.ts +10 -0
  46. package/dist/core/graph/import-cycles.js +103 -0
  47. package/dist/core/group/cross-impact.d.ts +2 -1
  48. package/dist/core/group/cross-impact.js +5 -1
  49. package/dist/core/group/extractors/grpc-patterns/proto.js +10 -6
  50. package/dist/core/group/extractors/http-patterns/kotlin.js +7 -7
  51. package/dist/core/group/extractors/http-route-extractor.d.ts +24 -0
  52. package/dist/core/group/extractors/http-route-extractor.js +22 -4
  53. package/dist/core/group/extractors/include-extractor.js +22 -13
  54. package/dist/core/group/sync.d.ts +27 -1
  55. package/dist/core/group/sync.js +0 -0
  56. package/dist/core/incremental/subgraph-extract.js +18 -1
  57. package/dist/core/ingestion/cfg/cfg-builder.d.ts +114 -0
  58. package/dist/core/ingestion/cfg/cfg-builder.js +196 -0
  59. package/dist/core/ingestion/cfg/collect.d.ts +51 -0
  60. package/dist/core/ingestion/cfg/collect.js +77 -0
  61. package/dist/core/ingestion/cfg/control-dependence.d.ts +58 -0
  62. package/dist/core/ingestion/cfg/control-dependence.js +182 -0
  63. package/dist/core/ingestion/cfg/control-flow-context.d.ts +106 -0
  64. package/dist/core/ingestion/cfg/control-flow-context.js +124 -0
  65. package/dist/core/ingestion/cfg/emit.d.ts +293 -0
  66. package/dist/core/ingestion/cfg/emit.js +646 -0
  67. package/dist/core/ingestion/cfg/post-dominators.d.ts +79 -0
  68. package/dist/core/ingestion/cfg/post-dominators.js +176 -0
  69. package/dist/core/ingestion/cfg/reaching-def-reason-codec.d.ts +106 -0
  70. package/dist/core/ingestion/cfg/reaching-def-reason-codec.js +133 -0
  71. package/dist/core/ingestion/cfg/reaching-defs-graph.d.ts +18 -0
  72. package/dist/core/ingestion/cfg/reaching-defs-graph.js +312 -0
  73. package/dist/core/ingestion/cfg/reaching-defs.d.ts +162 -0
  74. package/dist/core/ingestion/cfg/reaching-defs.js +785 -0
  75. package/dist/core/ingestion/cfg/synthetic-escape.d.ts +124 -0
  76. package/dist/core/ingestion/cfg/synthetic-escape.js +300 -0
  77. package/dist/core/ingestion/cfg/traversal-result.d.ts +20 -0
  78. package/dist/core/ingestion/cfg/traversal-result.js +2 -0
  79. package/dist/core/ingestion/cfg/types.d.ts +274 -0
  80. package/dist/core/ingestion/cfg/types.js +13 -0
  81. package/dist/core/ingestion/cfg/visitors/c-cpp-harvest.d.ts +111 -0
  82. package/dist/core/ingestion/cfg/visitors/c-cpp-harvest.js +541 -0
  83. package/dist/core/ingestion/cfg/visitors/c-cpp.d.ts +74 -0
  84. package/dist/core/ingestion/cfg/visitors/c-cpp.js +584 -0
  85. package/dist/core/ingestion/cfg/visitors/call-site-harvest.d.ts +195 -0
  86. package/dist/core/ingestion/cfg/visitors/call-site-harvest.js +350 -0
  87. package/dist/core/ingestion/cfg/visitors/csharp-harvest.d.ts +124 -0
  88. package/dist/core/ingestion/cfg/visitors/csharp-harvest.js +589 -0
  89. package/dist/core/ingestion/cfg/visitors/csharp.d.ts +87 -0
  90. package/dist/core/ingestion/cfg/visitors/csharp.js +867 -0
  91. package/dist/core/ingestion/cfg/visitors/dart-harvest.d.ts +278 -0
  92. package/dist/core/ingestion/cfg/visitors/dart-harvest.js +870 -0
  93. package/dist/core/ingestion/cfg/visitors/dart.d.ts +119 -0
  94. package/dist/core/ingestion/cfg/visitors/dart.js +836 -0
  95. package/dist/core/ingestion/cfg/visitors/go-harvest.d.ts +160 -0
  96. package/dist/core/ingestion/cfg/visitors/go-harvest.js +621 -0
  97. package/dist/core/ingestion/cfg/visitors/go.d.ts +108 -0
  98. package/dist/core/ingestion/cfg/visitors/go.js +638 -0
  99. package/dist/core/ingestion/cfg/visitors/java-harvest.d.ts +108 -0
  100. package/dist/core/ingestion/cfg/visitors/java-harvest.js +513 -0
  101. package/dist/core/ingestion/cfg/visitors/java.d.ts +101 -0
  102. package/dist/core/ingestion/cfg/visitors/java.js +812 -0
  103. package/dist/core/ingestion/cfg/visitors/kotlin-harvest.d.ts +253 -0
  104. package/dist/core/ingestion/cfg/visitors/kotlin-harvest.js +719 -0
  105. package/dist/core/ingestion/cfg/visitors/kotlin.d.ts +121 -0
  106. package/dist/core/ingestion/cfg/visitors/kotlin.js +809 -0
  107. package/dist/core/ingestion/cfg/visitors/php-harvest.d.ts +172 -0
  108. package/dist/core/ingestion/cfg/visitors/php-harvest.js +626 -0
  109. package/dist/core/ingestion/cfg/visitors/php.d.ts +96 -0
  110. package/dist/core/ingestion/cfg/visitors/php.js +721 -0
  111. package/dist/core/ingestion/cfg/visitors/python-harvest.d.ts +212 -0
  112. package/dist/core/ingestion/cfg/visitors/python-harvest.js +739 -0
  113. package/dist/core/ingestion/cfg/visitors/python.d.ts +103 -0
  114. package/dist/core/ingestion/cfg/visitors/python.js +558 -0
  115. package/dist/core/ingestion/cfg/visitors/ruby-harvest.d.ts +223 -0
  116. package/dist/core/ingestion/cfg/visitors/ruby-harvest.js +587 -0
  117. package/dist/core/ingestion/cfg/visitors/ruby.d.ts +112 -0
  118. package/dist/core/ingestion/cfg/visitors/ruby.js +756 -0
  119. package/dist/core/ingestion/cfg/visitors/rust-harvest.d.ts +324 -0
  120. package/dist/core/ingestion/cfg/visitors/rust-harvest.js +873 -0
  121. package/dist/core/ingestion/cfg/visitors/rust.d.ts +95 -0
  122. package/dist/core/ingestion/cfg/visitors/rust.js +558 -0
  123. package/dist/core/ingestion/cfg/visitors/scope-tree-harvest.d.ts +87 -0
  124. package/dist/core/ingestion/cfg/visitors/scope-tree-harvest.js +116 -0
  125. package/dist/core/ingestion/cfg/visitors/swift-harvest.d.ts +255 -0
  126. package/dist/core/ingestion/cfg/visitors/swift-harvest.js +679 -0
  127. package/dist/core/ingestion/cfg/visitors/swift.d.ts +116 -0
  128. package/dist/core/ingestion/cfg/visitors/swift.js +787 -0
  129. package/dist/core/ingestion/cfg/visitors/typescript-harvest.d.ts +149 -0
  130. package/dist/core/ingestion/cfg/visitors/typescript-harvest.js +1056 -0
  131. package/dist/core/ingestion/cfg/visitors/typescript.d.ts +66 -0
  132. package/dist/core/ingestion/cfg/visitors/typescript.js +583 -0
  133. package/dist/core/ingestion/import-resolvers/utils.js +2 -0
  134. package/dist/core/ingestion/language-provider.d.ts +11 -0
  135. package/dist/core/ingestion/languages/c-cpp.js +6 -1
  136. package/dist/core/ingestion/languages/cobol.js +4 -0
  137. package/dist/core/ingestion/languages/cpp/arity-metadata.js +41 -2
  138. package/dist/core/ingestion/languages/cpp/captures.js +50 -1
  139. package/dist/core/ingestion/languages/cpp/conversion-rank.d.ts +2 -0
  140. package/dist/core/ingestion/languages/cpp/conversion-rank.js +89 -0
  141. package/dist/core/ingestion/languages/cpp/header-scan.d.ts +1 -1
  142. package/dist/core/ingestion/languages/cpp/header-scan.js +2 -2
  143. package/dist/core/ingestion/languages/cpp/inline-namespaces.js +7 -2
  144. package/dist/core/ingestion/languages/cpp/member-lookup.js +2 -1
  145. package/dist/core/ingestion/languages/cpp/query.js +23 -0
  146. package/dist/core/ingestion/languages/cpp/scope-resolver.js +2 -1
  147. package/dist/core/ingestion/languages/csharp.js +2 -0
  148. package/dist/core/ingestion/languages/dart.js +2 -0
  149. package/dist/core/ingestion/languages/go.js +2 -0
  150. package/dist/core/ingestion/languages/java.js +3 -0
  151. package/dist/core/ingestion/languages/kotlin/query.js +3 -2
  152. package/dist/core/ingestion/languages/kotlin.js +3 -0
  153. package/dist/core/ingestion/languages/php.js +2 -0
  154. package/dist/core/ingestion/languages/python.js +2 -0
  155. package/dist/core/ingestion/languages/ruby.js +2 -0
  156. package/dist/core/ingestion/languages/rust.js +2 -0
  157. package/dist/core/ingestion/languages/swift.js +2 -0
  158. package/dist/core/ingestion/languages/typescript.js +5 -0
  159. package/dist/core/ingestion/languages/vue.js +6 -0
  160. package/dist/core/ingestion/method-extractors/configs/c-cpp.js +6 -13
  161. package/dist/core/ingestion/method-extractors/generic.js +1 -0
  162. package/dist/core/ingestion/method-types.d.ts +2 -0
  163. package/dist/core/ingestion/model/symbol-table.d.ts +1 -0
  164. package/dist/core/ingestion/model/symbol-table.js +1 -0
  165. package/dist/core/ingestion/mro-processor.js +109 -0
  166. package/dist/core/ingestion/parsing-processor.js +23 -0
  167. package/dist/core/ingestion/pipeline-phases/call-summaries.d.ts +26 -0
  168. package/dist/core/ingestion/pipeline-phases/call-summaries.js +46 -0
  169. package/dist/core/ingestion/pipeline-phases/index.d.ts +2 -0
  170. package/dist/core/ingestion/pipeline-phases/index.js +2 -0
  171. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +0 -21
  172. package/dist/core/ingestion/pipeline-phases/parse-impl.js +18 -1
  173. package/dist/core/ingestion/pipeline-phases/routes.d.ts +10 -0
  174. package/dist/core/ingestion/pipeline-phases/routes.js +30 -1
  175. package/dist/core/ingestion/pipeline-phases/taint-summaries.d.ts +30 -0
  176. package/dist/core/ingestion/pipeline-phases/taint-summaries.js +81 -0
  177. package/dist/core/ingestion/pipeline.d.ts +92 -10
  178. package/dist/core/ingestion/pipeline.js +11 -2
  179. package/dist/core/ingestion/scope-extractor.js +12 -2
  180. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +9 -0
  181. package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.d.ts +75 -0
  182. package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +67 -0
  183. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +12 -2
  184. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +14 -2
  185. package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.d.ts +6 -1
  186. package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +13 -1
  187. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +9 -1
  188. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +28 -2
  189. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +4 -0
  190. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +9 -0
  191. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +6 -1
  192. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +174 -40
  193. package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +24 -0
  194. package/dist/core/ingestion/scope-resolution/pipeline/phase.js +276 -190
  195. package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +43 -3
  196. package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +75 -0
  197. package/dist/core/ingestion/scope-resolution/pipeline/run.js +349 -1
  198. package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +1 -1
  199. package/dist/core/ingestion/taint/call-summary-codec.d.ts +75 -0
  200. package/dist/core/ingestion/taint/call-summary-codec.js +128 -0
  201. package/dist/core/ingestion/taint/call-summary-emit.d.ts +43 -0
  202. package/dist/core/ingestion/taint/call-summary-emit.js +70 -0
  203. package/dist/core/ingestion/taint/call-summary-harvest.d.ts +77 -0
  204. package/dist/core/ingestion/taint/call-summary-harvest.js +179 -0
  205. package/dist/core/ingestion/taint/call-summary-model.d.ts +47 -0
  206. package/dist/core/ingestion/taint/call-summary-model.js +25 -0
  207. package/dist/core/ingestion/taint/emit.d.ts +125 -0
  208. package/dist/core/ingestion/taint/emit.js +208 -0
  209. package/dist/core/ingestion/taint/interproc-emit.d.ts +50 -0
  210. package/dist/core/ingestion/taint/interproc-emit.js +88 -0
  211. package/dist/core/ingestion/taint/interproc-solver.d.ts +110 -0
  212. package/dist/core/ingestion/taint/interproc-solver.js +312 -0
  213. package/dist/core/ingestion/taint/match.d.ts +153 -0
  214. package/dist/core/ingestion/taint/match.js +278 -0
  215. package/dist/core/ingestion/taint/path-codec.d.ts +134 -0
  216. package/dist/core/ingestion/taint/path-codec.js +190 -0
  217. package/dist/core/ingestion/taint/propagate.d.ts +216 -0
  218. package/dist/core/ingestion/taint/propagate.js +659 -0
  219. package/dist/core/ingestion/taint/site-safety.d.ts +29 -0
  220. package/dist/core/ingestion/taint/site-safety.js +98 -0
  221. package/dist/core/ingestion/taint/source-sink-config.d.ts +107 -23
  222. package/dist/core/ingestion/taint/source-sink-config.js +35 -12
  223. package/dist/core/ingestion/taint/source-sink-registry.d.ts +6 -4
  224. package/dist/core/ingestion/taint/source-sink-registry.js +6 -4
  225. package/dist/core/ingestion/taint/summary-harvest-driver.d.ts +80 -0
  226. package/dist/core/ingestion/taint/summary-harvest-driver.js +179 -0
  227. package/dist/core/ingestion/taint/summary-harvest.d.ts +89 -0
  228. package/dist/core/ingestion/taint/summary-harvest.js +537 -0
  229. package/dist/core/ingestion/taint/summary-model.d.ts +200 -0
  230. package/dist/core/ingestion/taint/summary-model.js +86 -0
  231. package/dist/core/ingestion/taint/typescript-model.d.ts +38 -0
  232. package/dist/core/ingestion/taint/typescript-model.js +102 -0
  233. package/dist/core/ingestion/type-extractors/c-cpp.js +21 -0
  234. package/dist/core/ingestion/utils/env.d.ts +7 -0
  235. package/dist/core/ingestion/utils/env.js +12 -0
  236. package/dist/core/ingestion/utils/method-props.js +1 -0
  237. package/dist/core/ingestion/workers/parse-worker.d.ts +13 -0
  238. package/dist/core/ingestion/workers/parse-worker.js +76 -17
  239. package/dist/core/ingestion/workers/worker-pool.d.ts +9 -40
  240. package/dist/core/ingestion/workers/worker-pool.js +15 -2
  241. package/dist/core/lbug/csv-generator.d.ts +51 -3
  242. package/dist/core/lbug/csv-generator.js +369 -255
  243. package/dist/core/lbug/lbug-adapter.d.ts +58 -18
  244. package/dist/core/lbug/lbug-adapter.js +346 -84
  245. package/dist/core/lbug/lbug-config.d.ts +19 -0
  246. package/dist/core/lbug/lbug-config.js +29 -0
  247. package/dist/core/lbug/pdg-emit-sink.d.ts +127 -0
  248. package/dist/core/lbug/pdg-emit-sink.js +358 -0
  249. package/dist/core/lbug/pool-adapter.d.ts +35 -0
  250. package/dist/core/lbug/pool-adapter.js +90 -1
  251. package/dist/core/lbug/rel-pair-routing.d.ts +54 -0
  252. package/dist/core/lbug/rel-pair-routing.js +140 -0
  253. package/dist/core/lbug/schema.d.ts +2 -2
  254. package/dist/core/lbug/schema.js +3 -0
  255. package/dist/core/logger.d.ts +0 -5
  256. package/dist/core/run-analyze.d.ts +96 -0
  257. package/dist/core/run-analyze.js +207 -3
  258. package/dist/core/tree-sitter/parser-loader.js +5 -4
  259. package/dist/core/tree-sitter/safe-parse.d.ts +0 -5
  260. package/dist/core/tree-sitter/vendored-grammars.d.ts +39 -0
  261. package/dist/core/tree-sitter/vendored-grammars.js +57 -0
  262. package/dist/core/wiki/generator.js +3 -1
  263. package/dist/core/wiki/graph-queries.d.ts +6 -0
  264. package/dist/core/wiki/graph-queries.js +9 -1
  265. package/dist/mcp/http-transport.d.ts +134 -0
  266. package/dist/mcp/http-transport.js +503 -0
  267. package/dist/mcp/local/local-backend.d.ts +110 -24
  268. package/dist/mcp/local/local-backend.js +1225 -19
  269. package/dist/mcp/local/pdg-impact.d.ts +384 -0
  270. package/dist/mcp/local/pdg-impact.js +1972 -0
  271. package/dist/mcp/resources.js +13 -1
  272. package/dist/mcp/tools.d.ts +12 -0
  273. package/dist/mcp/tools.js +214 -7
  274. package/dist/server/analyze-launch.d.ts +29 -0
  275. package/dist/server/analyze-launch.js +137 -0
  276. package/dist/server/analyze-upload.d.ts +33 -0
  277. package/dist/server/analyze-upload.js +123 -0
  278. package/dist/server/analyze-worker.d.ts +17 -1
  279. package/dist/server/api.d.ts +17 -0
  280. package/dist/server/api.js +132 -168
  281. package/dist/server/git-clone.d.ts +43 -2
  282. package/dist/server/git-clone.js +211 -16
  283. package/dist/server/mcp-http.d.ts +5 -6
  284. package/dist/server/mcp-http.js +9 -82
  285. package/dist/server/middleware.d.ts +40 -0
  286. package/dist/server/middleware.js +92 -0
  287. package/dist/server/private-ip.d.ts +1 -0
  288. package/dist/server/private-ip.js +15 -0
  289. package/dist/server/upload-ingest.d.ts +56 -0
  290. package/dist/server/upload-ingest.js +276 -0
  291. package/dist/server/upload-paths.d.ts +37 -0
  292. package/dist/server/upload-paths.js +57 -0
  293. package/dist/server/upload-sweep.d.ts +20 -0
  294. package/dist/server/upload-sweep.js +57 -0
  295. package/dist/storage/git.js +5 -8
  296. package/dist/storage/parse-cache.d.ts +22 -1
  297. package/dist/storage/parse-cache.js +41 -10
  298. package/dist/storage/repo-manager.d.ts +121 -10
  299. package/dist/storage/repo-manager.js +43 -5
  300. package/dist/types/pipeline.d.ts +9 -0
  301. package/hooks/antigravity/gitnexus-antigravity-hook.cjs +110 -10
  302. package/hooks/claude/gitnexus-hook.cjs +110 -13
  303. package/hooks/claude/hook-db-lock-probe.cjs +513 -26
  304. package/package.json +8 -2
  305. package/scripts/assert-publish-grammar-coverage.cjs +31 -0
  306. package/scripts/build-tree-sitter-grammars.cjs +16 -10
  307. package/scripts/cross-platform-tests.ts +1 -0
  308. package/skills/gitnexus-debugging.md +16 -4
  309. package/skills/gitnexus-exploring.md +3 -3
  310. package/skills/gitnexus-guide.md +33 -0
  311. package/skills/gitnexus-pdg-query.md +89 -0
  312. package/skills/gitnexus-refactoring.md +1 -1
  313. package/skills/gitnexus-taint-analysis.md +178 -0
  314. package/vendor/tree-sitter-c/package.json +1 -1
  315. package/vendor/tree-sitter-dart/package.json +1 -1
  316. package/vendor/tree-sitter-kotlin/package.json +1 -1
  317. package/vendor/tree-sitter-proto/package.json +1 -1
  318. package/vendor/tree-sitter-swift/package.json +1 -1
  319. package/web/assets/{agent-CKPMqImC.js → agent-D3Xd7zZE.js} +123 -123
  320. package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +1 -0
  321. package/web/assets/architectureDiagram-UL44E2DR-ChH9xW-N.js +36 -0
  322. package/web/assets/{blockDiagram-7IZFK4PR-B4niSLvR.js → blockDiagram-7IZFK4PR-BkWhpzWB.js} +1 -1
  323. package/web/assets/{c4Diagram-Y2BXMSZH-DIzEXalR.js → c4Diagram-Y2BXMSZH-DtBvpzWD.js} +1 -1
  324. package/web/assets/{chunk-3SSMPTDK-BzGeeheI.js → chunk-3SSMPTDK-B4_etUhr.js} +2 -2
  325. package/web/assets/{chunk-5IMINLNL-CnTLsXIV.js → chunk-5IMINLNL-DOdTeQri.js} +1 -1
  326. package/web/assets/{chunk-5VCL7Z4A-w1BCx98Z.js → chunk-5VCL7Z4A-CQ-2dYWj.js} +1 -1
  327. package/web/assets/chunk-6764PJDD-DpIS7hxD.js +1 -0
  328. package/web/assets/{chunk-67TQ5CYL-CChC2cAv.js → chunk-67TQ5CYL-4sNPJU1q.js} +3 -3
  329. package/web/assets/{chunk-7W6UQGC5-CgFyfZ6k.js → chunk-7W6UQGC5-KyEG0HQg.js} +1 -1
  330. package/web/assets/{chunk-AZZRMDJM-5E9ARdDQ.js → chunk-AZZRMDJM-y-xJBuMz.js} +1 -1
  331. package/web/assets/{chunk-INKRHTLW-ELpfuk9h.js → chunk-INKRHTLW-Nu4ri9P-.js} +1 -1
  332. package/web/assets/{chunk-JQRUD6KW-Dcq_Qnyy.js → chunk-JQRUD6KW-Dbva2Z17.js} +1 -1
  333. package/web/assets/{chunk-KGFNY3KK-W-VR57xb.js → chunk-KGFNY3KK-JGMJvKCK.js} +1 -1
  334. package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +161 -0
  335. package/web/assets/{chunk-KNLZD3CH-BuZBOcso.js → chunk-KNLZD3CH-BGlP6X9R.js} +1 -1
  336. package/web/assets/{chunk-KRXBNO2N-DH2NPM7I.js → chunk-KRXBNO2N-BW5o0KUN.js} +1 -1
  337. package/web/assets/{chunk-LCXTWHL2-Dfmux4m1.js → chunk-LCXTWHL2-zoomRtWX.js} +1 -1
  338. package/web/assets/{chunk-LII3EMHJ-3X33tCpU.js → chunk-LII3EMHJ-D-jm-dLa.js} +1 -1
  339. package/web/assets/{chunk-QA3QBVWF-D5Ha3GgB.js → chunk-QA3QBVWF-BgRW3SXd.js} +1 -1
  340. package/web/assets/{chunk-RG4AUYOV-CAkzcoRj.js → chunk-RG4AUYOV-DD0B2N2B.js} +1 -1
  341. package/web/assets/{chunk-T2UQINTJ-kGYG7ppP.js → chunk-T2UQINTJ-DSBqkzH7.js} +1 -1
  342. package/web/assets/chunk-T5OCTHI4-DdZvN-9i.js +1 -0
  343. package/web/assets/{chunk-UY5QBCOK-Du-c56gs.js → chunk-UY5QBCOK-DyF0vyGd.js} +1 -1
  344. package/web/assets/{chunk-W44A43WB-lrCpuupA.js → chunk-W44A43WB-JqMLIpR0.js} +1 -1
  345. package/web/assets/{chunk-ZXARS5L4-CSZRiyOf.js → chunk-ZXARS5L4-CxN8oiwI.js} +1 -1
  346. package/web/assets/classDiagram-KGZ6W3CR-DJm9BgF-.js +1 -0
  347. package/web/assets/classDiagram-v2-72OJOZXJ-DJm9BgF-.js +1 -0
  348. package/web/assets/{context-builder-_HS0v2ma.js → context-builder-BHiFUA8O.js} +10 -2
  349. package/web/assets/{cose-bilkent-UX7MHV2Q-BHv2bbtl.js → cose-bilkent-UX7MHV2Q-D71wNYRJ.js} +1 -1
  350. package/web/assets/dagre-ND4H6XIP-BIkxmhcu.js +4 -0
  351. package/web/assets/diagram-3NCE3AQN-BTa6iH0T.js +43 -0
  352. package/web/assets/diagram-GF46GFSD-DZDV0vBj.js +24 -0
  353. package/web/assets/{diagram-HNR7UZ2L-fUWreZzx.js → diagram-HNR7UZ2L-DFCfd5LI.js} +2 -2
  354. package/web/assets/diagram-QXG6HAR7-BzM--Jj0.js +24 -0
  355. package/web/assets/diagram-WEQXMOUZ-DFFwz0k4.js +10 -0
  356. package/web/assets/{erDiagram-L5TCEMPS-QN2eEP1e.js → erDiagram-L5TCEMPS-CfHMJJqo.js} +1 -1
  357. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +1 -0
  358. package/web/assets/{flowDiagram-H6V6AXG4-CXbXImlN.js → flowDiagram-H6V6AXG4-Be805QiJ.js} +3 -3
  359. package/web/assets/{ganttDiagram-JCBTUEKG-BHQssTz6.js → ganttDiagram-JCBTUEKG-D3iL2Aet.js} +1 -1
  360. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +1 -0
  361. package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +106 -0
  362. package/web/assets/index-BvYev1UJ.js +635 -0
  363. package/web/assets/index-_lgn7hs5.css +2 -0
  364. package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +1 -0
  365. package/web/assets/infoDiagram-3YFTVSEB-Y7BKSoke.js +2 -0
  366. package/web/assets/{ishikawaDiagram-BNXS4ZKH-6LKOvBfp.js → ishikawaDiagram-BNXS4ZKH-CT4SHFuI.js} +1 -1
  367. package/web/assets/{journeyDiagram-M6C3CM3L-DNPYCpvq.js → journeyDiagram-M6C3CM3L-CvArszLo.js} +1 -1
  368. package/web/assets/{kanban-definition-75IXJCU3-DgDi9oJT.js → kanban-definition-75IXJCU3-C6yDxr7N.js} +3 -3
  369. package/web/assets/{katex-K3KEBU37-CrVLz8l7.js → katex-K3KEBU37-CTc5BslQ.js} +1 -1
  370. package/web/assets/{mindmap-definition-2TDM6QVE-CwR5sBB-.js → mindmap-definition-2TDM6QVE-BOc2WEne.js} +1 -1
  371. package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +1 -0
  372. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +1 -0
  373. package/web/assets/{pieDiagram-CU6KROY3-By8g6f6B.js → pieDiagram-CU6KROY3-Cvc0f_Pd.js} +1 -1
  374. package/web/assets/{quadrantDiagram-VICAPDV7-bAm6Hi_5.js → quadrantDiagram-VICAPDV7-yXSZ2lLz.js} +1 -1
  375. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +1 -0
  376. package/web/assets/{requirementDiagram-JXO7QTGE-7oDcJ1_J.js → requirementDiagram-JXO7QTGE-BRcZvHs4.js} +1 -1
  377. package/web/assets/{sankeyDiagram-URQDO5SZ-LFJz53u5.js → sankeyDiagram-URQDO5SZ-1qEjlFIB.js} +1 -1
  378. package/web/assets/{sequenceDiagram-VS2MUI6T-FySeKCUy.js → sequenceDiagram-VS2MUI6T-PcSCuvrB.js} +3 -3
  379. package/web/assets/stateDiagram-7D4R322I-D6qYSV1E.js +1 -0
  380. package/web/assets/stateDiagram-v2-36443NZ5-Bg-ImOSX.js +1 -0
  381. package/web/assets/{timeline-definition-O6YCAMPW-Ds2CnVZK.js → timeline-definition-O6YCAMPW-QWkh01xw.js} +1 -1
  382. package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +1 -0
  383. package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +1 -0
  384. package/web/assets/{vennDiagram-MWXL3ELB-DUIEwXWp.js → vennDiagram-MWXL3ELB-ak4DfwuM.js} +3 -3
  385. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +1 -0
  386. package/web/assets/{wardleyDiagram-CUQ6CDDI-DEiFPQih.js → wardleyDiagram-CUQ6CDDI-CTzR4Loq.js} +1 -1
  387. package/web/assets/{xychartDiagram-N2JHSOCM-BUbayhST.js → xychartDiagram-N2JHSOCM-DA1BEaQz.js} +1 -1
  388. package/web/index.html +13 -15
  389. package/scripts/materialize-vendor-grammars.cjs +0 -97
  390. package/web/assets/architecture-7EHR7CIX-6QZW5X65-BETj2x4g.js +0 -1
  391. package/web/assets/architectureDiagram-UL44E2DR-D1EXI0zA.js +0 -36
  392. package/web/assets/chunk-2T2R6R2M-n6s9JZqv.js +0 -4
  393. package/web/assets/chunk-2UTLFMKG-CMBB1TMN.js +0 -1
  394. package/web/assets/chunk-4R4BOZG6-mKhL59ul.js +0 -159
  395. package/web/assets/chunk-6764PJDD-ChwMM2z4.js +0 -1
  396. package/web/assets/chunk-7J6CGLKN-DT-b53FT.js +0 -10
  397. package/web/assets/chunk-C62D2QBJ-CDAWj26E.js +0 -1
  398. package/web/assets/chunk-CEXFNPSA-D68Tk6ls.js +0 -1
  399. package/web/assets/chunk-CilyBKbf.js +0 -1
  400. package/web/assets/chunk-J5EP6P6S-DxWW0yvu.js +0 -1
  401. package/web/assets/chunk-KGYTTC2M-C6PHeuay.js +0 -1
  402. package/web/assets/chunk-RERM46MO-DQNbXtfw.js +0 -1
  403. package/web/assets/chunk-RKZBBQEN-BmTPLSyv.js +0 -1
  404. package/web/assets/chunk-RLI5ZMPA-DExu2DOK.js +0 -1
  405. package/web/assets/chunk-T5OCTHI4--9wWpVws.js +0 -1
  406. package/web/assets/chunk-UP6H54XL-DsKdC6jC.js +0 -1
  407. package/web/assets/chunk-UXSXWOXI-DR81EqLr.js +0 -1
  408. package/web/assets/classDiagram-KGZ6W3CR-Bv93af_b.js +0 -1
  409. package/web/assets/classDiagram-v2-72OJOZXJ-CLfEqHUa.js +0 -1
  410. package/web/assets/dagre-ND4H6XIP-DsIr9MOv.js +0 -4
  411. package/web/assets/diagram-3NCE3AQN-BqAtKUpW.js +0 -43
  412. package/web/assets/diagram-GF46GFSD-CaBG6n6o.js +0 -24
  413. package/web/assets/diagram-QXG6HAR7-CZ-O3rcV.js +0 -24
  414. package/web/assets/diagram-WEQXMOUZ-P4lSL4GH.js +0 -10
  415. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-B3myHUst.js +0 -1
  416. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DF3rtf4A.js +0 -1
  417. package/web/assets/gitGraphDiagram-S2ZK5IYY-CCwVLT__.js +0 -106
  418. package/web/assets/index-BKWA-m7o.css +0 -2
  419. package/web/assets/index-CG6q8eTs.js +0 -626
  420. package/web/assets/info-J43DQDTF-KCYPFFUO-R4XV_akJ.js +0 -1
  421. package/web/assets/infoDiagram-3YFTVSEB-DmLICZx1.js +0 -2
  422. package/web/assets/packet-YPE3B663-LP52Z2RK-CgQPdNZa.js +0 -1
  423. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BzWOwc_c.js +0 -1
  424. package/web/assets/radar-GUYGQ44K-RDLRG3WG-B7KG0FN7.js +0 -1
  425. package/web/assets/stateDiagram-7D4R322I-CB2nABwH.js +0 -1
  426. package/web/assets/stateDiagram-v2-36443NZ5-COBGd2RL.js +0 -1
  427. package/web/assets/treeView-BLDUP644-QA4HXRO3-CRSxEwLO.js +0 -1
  428. package/web/assets/treemap-LRROVOQU-LLAWBHMP-a0PfKoVn.js +0 -1
  429. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-BKQ6e5mC.js +0 -1
  430. /package/web/assets/{chunk-AQ6EADP3-CCFje6lL.js → chunk-AQ6EADP3-CZhslHi-.js} +0 -0
@@ -0,0 +1,719 @@
1
+ import { CallSiteFactAccumulator as FactAccumulator, finalizeChain } from './call-site-harvest.js';
2
+ /** Node types that own a nested CFG — their subtrees are opaque to harvesting. */
3
+ const NESTED_FUNCTION_TYPES = new Set([
4
+ 'function_declaration',
5
+ 'anonymous_function',
6
+ 'lambda_literal',
7
+ ]);
8
+ const COMMENT_TYPES = new Set(['line_comment', 'multiline_comment', 'shebang_line']);
9
+ export class KotlinHarvester {
10
+ fnNode;
11
+ bindings = [];
12
+ /** Single function-scope name → binding index (v1: no block scope). */
13
+ table = new Map();
14
+ synthetic = new Map();
15
+ fnId;
16
+ /** >0 while walking a conditionally-evaluated subexpression — defs become may-defs. */
17
+ conditionalDepth = 0;
18
+ /**
19
+ * `call_expression` node id → binding indices its single-target result is
20
+ * assigned to (`val x = f()` / `x = g()` ⇒ `[x]`). Populated just before the
21
+ * value walk reaches the call (see {@link registerResultDefs}) and consumed by
22
+ * {@link visitCall}. Mirrors the Go / Python / Dart harvesters' `resultDefTargets`.
23
+ */
24
+ resultDefTargets = new Map();
25
+ constructor(fnNode) {
26
+ this.fnNode = fnNode;
27
+ this.fnId = fnNode.id;
28
+ this.declareParams(fnNode);
29
+ const body = this.bodyOf(fnNode);
30
+ if (body)
31
+ this.prescan(body);
32
+ }
33
+ /** The completed binding table — pass to `CfgBuilder.finish`. */
34
+ bindingTable() {
35
+ return this.bindings;
36
+ }
37
+ /** The function/lambda body subtree to pre-scan (`statements` or `function_body`). */
38
+ bodyOf(fnNode) {
39
+ if (fnNode.type === 'lambda_literal') {
40
+ return fnNode.namedChildren.find((c) => c.type === 'statements');
41
+ }
42
+ return fnNode.namedChildren.find((c) => c.type === 'function_body');
43
+ }
44
+ // ── phase 1: declaration pre-scan ────────────────────────────────────────
45
+ declare(nameNode, kind) {
46
+ const name = nameNode.text;
47
+ if (!name || name === '_' || this.table.has(name))
48
+ return;
49
+ this.table.set(name, this.bindings.length);
50
+ this.bindings.push({
51
+ name,
52
+ declLine: nameNode.startPosition.row + 1,
53
+ declColumn: nameNode.startPosition.column,
54
+ kind,
55
+ });
56
+ }
57
+ /** Declare every parameter binder of a fn / anonymous fn / lambda. */
58
+ declareParams(fnNode) {
59
+ const params = fnNode.namedChildren.find((c) => c.type === 'function_value_parameters');
60
+ if (params) {
61
+ for (const p of params.namedChildren) {
62
+ if (p.type !== 'parameter')
63
+ continue;
64
+ const name = p.namedChildren.find((c) => c.type === 'simple_identifier');
65
+ if (name)
66
+ this.declare(name, 'param');
67
+ }
68
+ }
69
+ // Lambda params: `lambda_parameters` → `variable_declaration`(s).
70
+ const lambdaParams = fnNode.namedChildren.find((c) => c.type === 'lambda_parameters');
71
+ if (lambdaParams) {
72
+ for (const vd of lambdaParams.namedChildren) {
73
+ if (vd.type === 'variable_declaration')
74
+ this.declareVariableDeclaration(vd, 'param');
75
+ else if (vd.type === 'multi_variable_declaration') {
76
+ for (const inner of vd.namedChildren) {
77
+ if (inner.type === 'variable_declaration')
78
+ this.declareVariableDeclaration(inner, 'param');
79
+ }
80
+ }
81
+ }
82
+ }
83
+ }
84
+ /** Declare the `simple_identifier` of a `variable_declaration`. */
85
+ declareVariableDeclaration(vd, kind) {
86
+ const id = vd.namedChildren.find((c) => c.type === 'simple_identifier') ?? vd;
87
+ if (id.type === 'simple_identifier')
88
+ this.declare(id, kind);
89
+ }
90
+ /**
91
+ * Pre-scan the function body once, declaring every bound name. Recurses into
92
+ * compound expressions but NOT into nested function/lambda bodies (opaque).
93
+ */
94
+ prescan(node) {
95
+ const t = node.type;
96
+ if (NESTED_FUNCTION_TYPES.has(t) && node.id !== this.fnId)
97
+ return;
98
+ switch (t) {
99
+ case 'property_declaration':
100
+ this.declarePropertyPattern(node, 'let');
101
+ break;
102
+ case 'for_statement':
103
+ this.declareForPattern(node);
104
+ break;
105
+ case 'catch_block':
106
+ this.declareCatchParam(node);
107
+ break;
108
+ case 'when_subject':
109
+ this.declareWhenSubject(node);
110
+ break;
111
+ default:
112
+ break;
113
+ }
114
+ for (let i = 0; i < node.namedChildCount; i++) {
115
+ const c = node.namedChild(i);
116
+ if (c)
117
+ this.prescan(c);
118
+ }
119
+ }
120
+ /** Declare every binder of a `property_declaration`'s pattern (single or multi). */
121
+ declarePropertyPattern(node, kind) {
122
+ const single = node.namedChildren.find((c) => c.type === 'variable_declaration');
123
+ if (single) {
124
+ this.declareVariableDeclaration(single, kind);
125
+ return;
126
+ }
127
+ const multi = node.namedChildren.find((c) => c.type === 'multi_variable_declaration');
128
+ if (multi) {
129
+ for (const vd of multi.namedChildren) {
130
+ if (vd.type === 'variable_declaration')
131
+ this.declareVariableDeclaration(vd, kind);
132
+ }
133
+ }
134
+ }
135
+ /** Declare a `for` loop variable (`variable_declaration` / `multi_variable_declaration`). */
136
+ declareForPattern(node) {
137
+ const single = node.namedChildren.find((c) => c.type === 'variable_declaration');
138
+ if (single) {
139
+ this.declareVariableDeclaration(single, 'let');
140
+ return;
141
+ }
142
+ const multi = node.namedChildren.find((c) => c.type === 'multi_variable_declaration');
143
+ if (multi) {
144
+ for (const vd of multi.namedChildren) {
145
+ if (vd.type === 'variable_declaration')
146
+ this.declareVariableDeclaration(vd, 'let');
147
+ }
148
+ }
149
+ }
150
+ /** Declare a `catch (e: T)` error name. */
151
+ declareCatchParam(node) {
152
+ const id = node.namedChildren.find((c) => c.type === 'simple_identifier');
153
+ if (id)
154
+ this.declare(id, 'catch');
155
+ }
156
+ /** Declare a `when (val r = e)` subject binding. */
157
+ declareWhenSubject(node) {
158
+ const vd = node.namedChildren.find((c) => c.type === 'variable_declaration');
159
+ if (vd)
160
+ this.declareVariableDeclaration(vd, 'let');
161
+ }
162
+ // ── phase 2: per-statement fact extraction ───────────────────────────────
163
+ /** Def/use facts for one statement (or construct-header expression) node. */
164
+ facts(node) {
165
+ const acc = new FactAccumulator(node.startPosition.row + 1);
166
+ this.walkValue(node, acc);
167
+ return acc.finish();
168
+ }
169
+ /** Facts for an expression whose WHOLE evaluation is conditional (case tests). */
170
+ factsConditional(node) {
171
+ const acc = new FactAccumulator(node.startPosition.row + 1);
172
+ this.conditional(() => this.walkValue(node, acc));
173
+ return acc.finish();
174
+ }
175
+ /**
176
+ * Facts for a `for ( PAT in COLLECTION )` head: the loop pattern's leaves are
177
+ * defs, the iterated collection a use.
178
+ */
179
+ forHeadFacts(stmt) {
180
+ const acc = new FactAccumulator(stmt.startPosition.row + 1);
181
+ const collection = this.forCollection(stmt);
182
+ if (collection)
183
+ this.walkValue(collection, acc);
184
+ this.defForPattern(stmt, acc);
185
+ return acc.finish();
186
+ }
187
+ /** Facts for a `when` subject: a `val r = e` binds `r` (def); the expr's uses. */
188
+ whenSubjectFacts(subject) {
189
+ const acc = new FactAccumulator(subject.startPosition.row + 1);
190
+ const vd = subject.namedChildren.find((c) => c.type === 'variable_declaration');
191
+ // Walk the subject's value expression(s) for uses; bind the `val` name.
192
+ for (const c of subject.namedChildren) {
193
+ if (c.type === 'variable_declaration')
194
+ continue;
195
+ this.walkValue(c, acc);
196
+ }
197
+ if (vd)
198
+ this.defVariableDeclaration(vd, acc);
199
+ return acc.finish();
200
+ }
201
+ /**
202
+ * Def-ONLY facts for a value-position binding carrier (`val x = <branch>`,
203
+ * #2205): just the bound name's def, attached to the continuation block the
204
+ * branch arms rejoin. The branch subject + arm-value USES are already harvested
205
+ * onto the branch's own blocks (visitWhen / visitIf), so this must not re-walk
206
+ * them — only the `variable_declaration` leaves are defs here.
207
+ */
208
+ bindingDefFacts(stmt) {
209
+ const acc = new FactAccumulator(stmt.startPosition.row + 1);
210
+ this.defForPattern(stmt, acc);
211
+ return acc.defCount() ? acc.finish() : undefined;
212
+ }
213
+ /**
214
+ * Def-ONLY facts for a value-position assignment carrier (`x = when (k) {…}`,
215
+ * #2205): just the LHS target, attached to the continuation block the branch
216
+ * arms rejoin. The branch subject + arm-value USES are already harvested onto
217
+ * the branch's own blocks, so this must NOT re-walk the RHS — only a plain `=`
218
+ * to a simple-identifier lvalue defines (a member / index target is not a
219
+ * scalar def; a compound `+=` is not a value-branch carrier).
220
+ */
221
+ assignmentDefFacts(node) {
222
+ if (this.assignmentOperator(node) !== '=')
223
+ return undefined;
224
+ const acc = new FactAccumulator(node.startPosition.row + 1);
225
+ const lvalue = node.namedChildren.find((c) => c.type === 'directly_assignable_expression');
226
+ if (lvalue) {
227
+ const lv = this.unwrapAssignable(lvalue);
228
+ if (lv.type === 'simple_identifier')
229
+ this.def(lv, acc);
230
+ }
231
+ return acc.defCount() ? acc.finish() : undefined;
232
+ }
233
+ /** ENTRY-block facts for the parameters (defs only). */
234
+ paramFacts() {
235
+ const acc = new FactAccumulator(this.fnNode.startPosition.row + 1);
236
+ const params = this.fnNode.namedChildren.find((c) => c.type === 'function_value_parameters');
237
+ if (params) {
238
+ for (const p of params.namedChildren) {
239
+ if (p.type !== 'parameter')
240
+ continue;
241
+ const name = p.namedChildren.find((c) => c.type === 'simple_identifier');
242
+ if (name)
243
+ this.def(name, acc);
244
+ }
245
+ }
246
+ const lambdaParams = this.fnNode.namedChildren.find((c) => c.type === 'lambda_parameters');
247
+ if (lambdaParams) {
248
+ for (const vd of lambdaParams.namedChildren) {
249
+ if (vd.type === 'variable_declaration')
250
+ this.defVariableDeclaration(vd, acc);
251
+ else if (vd.type === 'multi_variable_declaration') {
252
+ for (const inner of vd.namedChildren) {
253
+ if (inner.type === 'variable_declaration')
254
+ this.defVariableDeclaration(inner, acc);
255
+ }
256
+ }
257
+ }
258
+ }
259
+ return acc.defCount() ? acc.finish() : undefined;
260
+ }
261
+ /** Def fact for a `catch (e: T)` error name — prepend to the handler entry block. */
262
+ catchParamFacts(catchBlock) {
263
+ const id = catchBlock.namedChildren.find((c) => c.type === 'simple_identifier');
264
+ if (!id)
265
+ return undefined;
266
+ const acc = new FactAccumulator(catchBlock.startPosition.row + 1);
267
+ this.def(id, acc);
268
+ return acc.defCount() ? acc.finish() : undefined;
269
+ }
270
+ resolve(nameNode) {
271
+ const name = nameNode.text;
272
+ const idx = this.table.get(name);
273
+ if (idx !== undefined)
274
+ return idx;
275
+ let syn = this.synthetic.get(name);
276
+ if (syn === undefined) {
277
+ syn = this.bindings.length;
278
+ this.synthetic.set(name, syn);
279
+ this.bindings.push({ name, declLine: 0, declColumn: 0, kind: 'module', synthetic: true });
280
+ }
281
+ return syn;
282
+ }
283
+ def(nameNode, acc) {
284
+ if (nameNode.text === '_')
285
+ return; // blank target defines nothing
286
+ if (this.conditionalDepth > 0)
287
+ acc.addMayDef(this.resolve(nameNode));
288
+ else
289
+ acc.addDef(this.resolve(nameNode));
290
+ }
291
+ use(nameNode, acc) {
292
+ if (nameNode.text === '_')
293
+ return;
294
+ acc.addUse(this.resolve(nameNode));
295
+ }
296
+ /** Run `fn` with defs demoted to may-defs (conditionally-evaluated context). */
297
+ conditional(fn) {
298
+ this.conditionalDepth++;
299
+ try {
300
+ fn();
301
+ }
302
+ finally {
303
+ this.conditionalDepth--;
304
+ }
305
+ }
306
+ /** Def the `simple_identifier` of a `variable_declaration`. */
307
+ defVariableDeclaration(vd, acc) {
308
+ const id = vd.namedChildren.find((c) => c.type === 'simple_identifier');
309
+ if (id)
310
+ this.def(id, acc);
311
+ }
312
+ /** Def every binder of a `for` loop pattern. */
313
+ defForPattern(stmt, acc) {
314
+ const single = stmt.namedChildren.find((c) => c.type === 'variable_declaration');
315
+ if (single) {
316
+ this.defVariableDeclaration(single, acc);
317
+ return;
318
+ }
319
+ const multi = stmt.namedChildren.find((c) => c.type === 'multi_variable_declaration');
320
+ if (multi) {
321
+ for (const vd of multi.namedChildren) {
322
+ if (vd.type === 'variable_declaration')
323
+ this.defVariableDeclaration(vd, acc);
324
+ }
325
+ }
326
+ }
327
+ /** The iterated collection of a `for_statement` — the named child after `in`. */
328
+ forCollection(stmt) {
329
+ let sawIn = false;
330
+ for (let i = 0; i < stmt.childCount; i++) {
331
+ const c = stmt.child(i);
332
+ if (!c)
333
+ continue;
334
+ if (c.type === 'in') {
335
+ sawIn = true;
336
+ continue;
337
+ }
338
+ if (c.type === ')')
339
+ return undefined;
340
+ if (sawIn && c.isNamed && !COMMENT_TYPES.has(c.type))
341
+ return c;
342
+ }
343
+ return undefined;
344
+ }
345
+ /** Value-position walk: collect uses; route def positions to the pattern handler. */
346
+ walkValue(node, acc) {
347
+ const t = node.type;
348
+ if (NESTED_FUNCTION_TYPES.has(t) && node.id !== this.fnId)
349
+ return; // opaque
350
+ switch (t) {
351
+ case 'simple_identifier':
352
+ this.use(node, acc);
353
+ return;
354
+ case 'property_declaration': {
355
+ // Walk the value for uses, then def each pattern binder.
356
+ const binder = node.namedChildren.find((c) => c.type === 'variable_declaration' || c.type === 'multi_variable_declaration');
357
+ const value = this.propertyValue(node);
358
+ // Register result-defs BEFORE the value walk so the call site (reached
359
+ // during the walk) carries them — single `variable_declaration` binder
360
+ // only (`val x = f()`); a `multi_variable_declaration` destructuring
361
+ // (`val (a, b) = p`) attaches nothing.
362
+ if (value && binder?.type === 'variable_declaration') {
363
+ const id = binder.namedChildren.find((c) => c.type === 'simple_identifier');
364
+ if (id)
365
+ this.registerResultDefs(value, [id]);
366
+ }
367
+ if (value)
368
+ this.walkValue(value, acc);
369
+ if (binder?.type === 'variable_declaration')
370
+ this.defVariableDeclaration(binder, acc);
371
+ else if (binder?.type === 'multi_variable_declaration') {
372
+ for (const vd of binder.namedChildren) {
373
+ if (vd.type === 'variable_declaration')
374
+ this.defVariableDeclaration(vd, acc);
375
+ }
376
+ }
377
+ return;
378
+ }
379
+ case 'assignment': {
380
+ const lvalue = node.namedChildren.find((c) => c.type === 'directly_assignable_expression');
381
+ const op = this.assignmentOperator(node);
382
+ const value = this.assignmentValue(node);
383
+ const scalar = lvalue ? this.unwrapAssignable(lvalue) : undefined;
384
+ // Plain `x = f(a)` attaches `resultDefs: [x]` (a compound `x += f(a)`
385
+ // does not — the prior value flows in too; a member/index lvalue is not
386
+ // a scalar def).
387
+ if (value && op === '=' && scalar?.type === 'simple_identifier') {
388
+ this.registerResultDefs(value, [scalar]);
389
+ }
390
+ if (value)
391
+ this.walkValue(value, acc);
392
+ if (lvalue) {
393
+ const lv = scalar ?? this.unwrapAssignable(lvalue);
394
+ if (lv.type === 'simple_identifier') {
395
+ this.def(lv, acc);
396
+ if (op !== '=')
397
+ this.use(lv, acc); // compound assign reads too
398
+ }
399
+ else {
400
+ // `this.x = …`, `a[i] = …` — root is a use only (not a scalar def).
401
+ this.walkValue(lv, acc);
402
+ }
403
+ }
404
+ return;
405
+ }
406
+ case 'postfix_expression':
407
+ case 'prefix_expression': {
408
+ // `x++` / `--x` — def AND use the operand when it is a plain identifier
409
+ // and the operator is an increment/decrement. Other pre/postfix forms
410
+ // (`-x`, `!x`, `x!!`, `x?`) are pure reads → walk the operand as a use.
411
+ const operand = node.namedChild(0);
412
+ if (operand?.type === 'simple_identifier' && this.isIncDec(node)) {
413
+ this.def(operand, acc);
414
+ this.use(operand, acc);
415
+ }
416
+ else if (operand) {
417
+ this.walkValue(operand, acc);
418
+ }
419
+ return;
420
+ }
421
+ case 'call_expression':
422
+ // #2227 follow-up: explicit case (previously default-descended) — same
423
+ // uses, plus a taint-site record. Kotlin has no `new` (constructor calls
424
+ // are plain `call_expression`s). Defs/uses stay byte-identical.
425
+ this.visitCall(node, acc);
426
+ return;
427
+ case 'navigation_expression': {
428
+ // `a.b` / `a?.b` — value read of the chain root only; the suffix name is
429
+ // not a scalar binding. Records the chain-root use (identical to the old
430
+ // descent) plus at most ONE member-read site (the innermost access),
431
+ // mirroring the Go / Python harvesters' value-position `walkChain`.
432
+ this.walkChain(node, acc, false);
433
+ return;
434
+ }
435
+ case 'conjunction_expression':
436
+ case 'disjunction_expression': {
437
+ // `a && b` / `a || b` — the right operand is conditionally evaluated.
438
+ const operands = node.namedChildren.filter((c) => !COMMENT_TYPES.has(c.type));
439
+ if (operands.length > 0)
440
+ this.walkValue(operands[0], acc);
441
+ for (let i = 1; i < operands.length; i++) {
442
+ const rhs = operands[i];
443
+ this.conditional(() => this.walkValue(rhs, acc));
444
+ }
445
+ return;
446
+ }
447
+ case 'elvis_expression': {
448
+ // `a ?: b` — the right operand only evaluates when the left is null.
449
+ const operands = node.namedChildren.filter((c) => !COMMENT_TYPES.has(c.type));
450
+ if (operands.length > 0)
451
+ this.walkValue(operands[0], acc);
452
+ for (let i = 1; i < operands.length; i++) {
453
+ const rhs = operands[i];
454
+ this.conditional(() => this.walkValue(rhs, acc));
455
+ }
456
+ return;
457
+ }
458
+ case 'when_subject':
459
+ case 'user_type':
460
+ case 'type_identifier':
461
+ case 'binding_pattern_kind':
462
+ // Binding keyword / type position — no scalar value uses.
463
+ return;
464
+ default:
465
+ for (let i = 0; i < node.namedChildCount; i++) {
466
+ const c = node.namedChild(i);
467
+ if (c)
468
+ this.walkValue(c, acc);
469
+ }
470
+ }
471
+ }
472
+ /** True iff `node` carries a `++` / `--` operator token (`x++` / `--x`). */
473
+ isIncDec(node) {
474
+ for (let i = 0; i < node.childCount; i++) {
475
+ const c = node.child(i);
476
+ if (c && !c.isNamed && (c.text === '++' || c.text === '--'))
477
+ return true;
478
+ }
479
+ return false;
480
+ }
481
+ /** The `= value` expression of a `property_declaration` (the child after `=`). */
482
+ propertyValue(node) {
483
+ let sawEq = false;
484
+ for (let i = 0; i < node.childCount; i++) {
485
+ const c = node.child(i);
486
+ if (!c)
487
+ continue;
488
+ if (c.type === '=') {
489
+ sawEq = true;
490
+ continue;
491
+ }
492
+ if (sawEq && c.isNamed && !COMMENT_TYPES.has(c.type))
493
+ return c;
494
+ }
495
+ return undefined;
496
+ }
497
+ /** The assignment operator text (`=` / `+=` / …) of an `assignment`. */
498
+ assignmentOperator(node) {
499
+ for (let i = 0; i < node.childCount; i++) {
500
+ const c = node.child(i);
501
+ if (c && !c.isNamed && /^[+\-*/%]?=$/.test(c.type))
502
+ return c.type;
503
+ }
504
+ return '=';
505
+ }
506
+ /** The right-hand value of an `assignment` (the named child after the operator). */
507
+ assignmentValue(node) {
508
+ let sawOp = false;
509
+ for (let i = 0; i < node.childCount; i++) {
510
+ const c = node.child(i);
511
+ if (!c)
512
+ continue;
513
+ if (!c.isNamed && /^[+\-*/%]?=$/.test(c.type)) {
514
+ sawOp = true;
515
+ continue;
516
+ }
517
+ if (sawOp && c.isNamed && !COMMENT_TYPES.has(c.type))
518
+ return c;
519
+ }
520
+ return undefined;
521
+ }
522
+ /** Strip a `directly_assignable_expression` wrapper around an lvalue. */
523
+ unwrapAssignable(node) {
524
+ let n = node;
525
+ let hops = 4;
526
+ while (n.type === 'directly_assignable_expression' && hops-- > 0) {
527
+ const inner = n.namedChild(0);
528
+ if (!inner)
529
+ break;
530
+ n = inner;
531
+ }
532
+ return n;
533
+ }
534
+ // ── taint-site harvest (#2227 follow-up) ─────────────────────────────────
535
+ /** Strip `parenthesized_expression` wrappers around a value (`(f())`). */
536
+ unwrapValue(node) {
537
+ let n = node;
538
+ let hops = 8;
539
+ while (n.type === 'parenthesized_expression' && hops-- > 0) {
540
+ const inner = n.namedChild(0);
541
+ if (!inner)
542
+ break;
543
+ n = inner;
544
+ }
545
+ return n;
546
+ }
547
+ /**
548
+ * When `value`'s root (after stripping parens) is a `call_expression`, remember
549
+ * that call site should carry `resultDefs` — the binding indices of `targets`
550
+ * (def-position identifiers). Consumed by {@link visitCall} once the value walk
551
+ * reaches the node. Single-target only (the caller restricts to a plain
552
+ * identifier binder); the blank target (`_`) binds nothing and is skipped.
553
+ */
554
+ registerResultDefs(value, targets) {
555
+ const root = this.unwrapValue(value);
556
+ if (root.type !== 'call_expression')
557
+ return;
558
+ const defs = [];
559
+ for (const target of targets) {
560
+ if (target.type !== 'simple_identifier' || target.text === '_')
561
+ continue;
562
+ defs.push(this.resolve(target));
563
+ }
564
+ if (defs.length > 0)
565
+ this.resultDefTargets.set(root.id, defs);
566
+ }
567
+ /**
568
+ * The callee node of a `call_expression` — the first named child that is NOT
569
+ * the trailing `call_suffix` (a bare `simple_identifier` for a free call, or a
570
+ * `navigation_expression` for a member/chained call).
571
+ */
572
+ calleeOf(call) {
573
+ for (let i = 0; i < call.namedChildCount; i++) {
574
+ const c = call.namedChild(i);
575
+ if (c && c.type !== 'call_suffix' && !COMMENT_TYPES.has(c.type))
576
+ return c;
577
+ }
578
+ return undefined;
579
+ }
580
+ /**
581
+ * Explicit `call_expression` handler. Records a call site (callee path,
582
+ * receiver, per-arg occurrence entries, result defs, spread marker) while
583
+ * reproducing EXACTLY the uses the old default descent recorded (callee chain
584
+ * root + arguments). Kotlin has no `new` — every site is `kind: 'call'`.
585
+ */
586
+ visitCall(node, acc) {
587
+ const calleeNode = this.calleeOf(node);
588
+ // `node` IS the `call_expression` — the SAME node the scope query anchors
589
+ // `@reference.call.free/.member` on (its `atRange`), so the resolved-id join
590
+ // lands by exact position (see file header ANCHOR ALIGNMENT).
591
+ const siteIdx = acc.openCallSite('call', [
592
+ node.startPosition.row + 1,
593
+ node.startPosition.column,
594
+ ]);
595
+ acc.pushFrame(siteIdx);
596
+ if (calleeNode) {
597
+ const callee = this.unwrapValue(calleeNode);
598
+ if (callee.type === 'simple_identifier') {
599
+ // A bare free call — the callee NAME is a statement-level use but NOT a
600
+ // value occurrence in any enclosing argument.
601
+ if (callee.text !== '_')
602
+ acc.addUseWithoutOccurrence(this.resolve(callee));
603
+ acc.setSiteCallee(siteIdx, callee.text);
604
+ }
605
+ else if (callee.type === 'navigation_expression') {
606
+ // skipFinalRead: the final `.name` IS the callee, carried by the path.
607
+ const chain = this.walkChain(callee, acc, true);
608
+ if (chain.path !== undefined)
609
+ acc.setSiteCallee(siteIdx, chain.path);
610
+ if (chain.rootIdx !== undefined)
611
+ acc.setSiteReceiver(siteIdx, chain.rootIdx);
612
+ }
613
+ else {
614
+ // Call-rooted chains (`f().g()`), indexing (`m[k]()`), parenthesized
615
+ // callables — the walk still records uses and nested sites; the callee
616
+ // path is not statically known.
617
+ this.walkValue(callee, acc);
618
+ }
619
+ }
620
+ const resultDefs = this.resultDefTargets.get(node.id);
621
+ if (resultDefs !== undefined)
622
+ acc.setSiteResultDefs(siteIdx, resultDefs);
623
+ const suffix = node.namedChildren.find((c) => c.type === 'call_suffix');
624
+ if (suffix)
625
+ this.walkArguments(suffix, siteIdx, acc);
626
+ acc.popFrame();
627
+ }
628
+ /**
629
+ * Walk a `call_suffix`'s `value_arguments`, tagging each positional / named /
630
+ * spread argument's occurrence position. A trailing `annotated_lambda` is a
631
+ * nested function body — opaque (its `lambda_literal` is excluded by
632
+ * {@link NESTED_FUNCTION_TYPES}), so it is not an argument occurrence here.
633
+ */
634
+ walkArguments(suffix, siteIdx, acc) {
635
+ const args = suffix.namedChildren.find((c) => c.type === 'value_arguments');
636
+ if (!args)
637
+ return;
638
+ let pos = 0;
639
+ for (let i = 0; i < args.namedChildCount; i++) {
640
+ const arg = args.namedChild(i);
641
+ if (!arg || arg.type !== 'value_argument')
642
+ continue;
643
+ acc.setFrameArg(pos);
644
+ const value = this.argumentValue(arg);
645
+ if (value?.type === 'spread_expression') {
646
+ // `f(*xs)` — a spread. Mark the first spread position so the matcher
647
+ // degrades soundly; the inner value still walks for occurrences.
648
+ acc.setSiteSpread(siteIdx, pos);
649
+ const inner = value.namedChild(0);
650
+ if (inner)
651
+ this.walkValue(inner, acc);
652
+ }
653
+ else if (value) {
654
+ this.walkValue(value, acc);
655
+ }
656
+ pos++;
657
+ }
658
+ }
659
+ /**
660
+ * The value expression of a `value_argument` — for a named argument
661
+ * (`name = value`) the leading `simple_identifier` name is dropped (it is a
662
+ * parameter name, not a use), and only the value after `=` is returned; a
663
+ * positional argument's value is its sole non-comment named child.
664
+ */
665
+ argumentValue(arg) {
666
+ // A named arg carries an anon `=` token; the value is the named child after
667
+ // it (skipping the leading `simple_identifier` name).
668
+ let sawEq = false;
669
+ for (let i = 0; i < arg.childCount; i++) {
670
+ const c = arg.child(i);
671
+ if (!c)
672
+ continue;
673
+ if (!c.isNamed && c.type === '=') {
674
+ sawEq = true;
675
+ continue;
676
+ }
677
+ if (sawEq && c.isNamed && !COMMENT_TYPES.has(c.type))
678
+ return c;
679
+ }
680
+ // Positional arg — the first non-comment named child.
681
+ for (let i = 0; i < arg.namedChildCount; i++) {
682
+ const c = arg.namedChild(i);
683
+ if (c && c.type !== 'annotation' && !COMMENT_TYPES.has(c.type))
684
+ return c;
685
+ }
686
+ return undefined;
687
+ }
688
+ /**
689
+ * `navigation_expression` chain walk shared by value position and callee
690
+ * position. Records the chain-root identifier as a use (identical to the old
691
+ * default descent) plus at most ONE member-read site — the INNERMOST access —
692
+ * when the root is an identifier; `skipFinalRead` suppresses it when that
693
+ * access is the callee (carried by the dotted path instead). Mirrors the Go /
694
+ * Python harvesters' `walkChain`.
695
+ */
696
+ walkChain(node, acc, skipFinalRead) {
697
+ const accesses = [];
698
+ let cur = this.unwrapValue(node);
699
+ for (;;) {
700
+ if (cur.type === 'navigation_expression') {
701
+ const suffix = cur.namedChildren.find((c) => c.type === 'navigation_suffix');
702
+ const name = suffix?.namedChildren.find((c) => c.type === 'simple_identifier');
703
+ accesses.unshift(name?.text ?? '');
704
+ const operand = cur.namedChild(0);
705
+ if (!operand)
706
+ break;
707
+ cur = this.unwrapValue(operand);
708
+ }
709
+ else {
710
+ break;
711
+ }
712
+ }
713
+ // The shared terminal: root-use record + innermost member-read + path-join.
714
+ return finalizeChain(acc, cur, accesses, skipFinalRead, (t) => t === 'simple_identifier', {
715
+ resolve: (n) => this.resolve(n),
716
+ walkRoot: (n) => this.walkValue(n, acc),
717
+ });
718
+ }
719
+ }