gitnexus 1.6.8-rc.8 → 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 (439) 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 +23 -2
  135. package/dist/core/ingestion/languages/c-cpp.js +17 -5
  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 +8 -1
  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 +44 -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/clone-safety.d.ts +109 -0
  238. package/dist/core/ingestion/workers/clone-safety.js +465 -0
  239. package/dist/core/ingestion/workers/parse-worker.d.ts +23 -0
  240. package/dist/core/ingestion/workers/parse-worker.js +81 -53
  241. package/dist/core/ingestion/workers/post-result.d.ts +22 -0
  242. package/dist/core/ingestion/workers/post-result.js +87 -0
  243. package/dist/core/ingestion/workers/result-merge.d.ts +20 -0
  244. package/dist/core/ingestion/workers/result-merge.js +43 -0
  245. package/dist/core/ingestion/workers/worker-pool.d.ts +15 -40
  246. package/dist/core/ingestion/workers/worker-pool.js +43 -16
  247. package/dist/core/lbug/csv-generator.d.ts +51 -3
  248. package/dist/core/lbug/csv-generator.js +369 -255
  249. package/dist/core/lbug/lbug-adapter.d.ts +58 -18
  250. package/dist/core/lbug/lbug-adapter.js +346 -84
  251. package/dist/core/lbug/lbug-config.d.ts +19 -0
  252. package/dist/core/lbug/lbug-config.js +29 -0
  253. package/dist/core/lbug/pdg-emit-sink.d.ts +127 -0
  254. package/dist/core/lbug/pdg-emit-sink.js +358 -0
  255. package/dist/core/lbug/pool-adapter.d.ts +35 -0
  256. package/dist/core/lbug/pool-adapter.js +90 -1
  257. package/dist/core/lbug/rel-pair-routing.d.ts +54 -0
  258. package/dist/core/lbug/rel-pair-routing.js +140 -0
  259. package/dist/core/lbug/schema.d.ts +2 -2
  260. package/dist/core/lbug/schema.js +3 -0
  261. package/dist/core/logger.d.ts +0 -5
  262. package/dist/core/run-analyze.d.ts +96 -0
  263. package/dist/core/run-analyze.js +207 -3
  264. package/dist/core/tree-sitter/parser-loader.js +5 -4
  265. package/dist/core/tree-sitter/safe-parse.d.ts +0 -5
  266. package/dist/core/tree-sitter/vendored-grammars.d.ts +39 -0
  267. package/dist/core/tree-sitter/vendored-grammars.js +57 -0
  268. package/dist/core/wiki/generator.js +3 -1
  269. package/dist/core/wiki/graph-queries.d.ts +6 -0
  270. package/dist/core/wiki/graph-queries.js +9 -1
  271. package/dist/mcp/http-transport.d.ts +134 -0
  272. package/dist/mcp/http-transport.js +503 -0
  273. package/dist/mcp/local/local-backend.d.ts +110 -24
  274. package/dist/mcp/local/local-backend.js +1225 -19
  275. package/dist/mcp/local/pdg-impact.d.ts +384 -0
  276. package/dist/mcp/local/pdg-impact.js +1972 -0
  277. package/dist/mcp/resources.js +13 -1
  278. package/dist/mcp/tools.d.ts +12 -0
  279. package/dist/mcp/tools.js +214 -7
  280. package/dist/server/analyze-launch.d.ts +29 -0
  281. package/dist/server/analyze-launch.js +137 -0
  282. package/dist/server/analyze-upload.d.ts +33 -0
  283. package/dist/server/analyze-upload.js +123 -0
  284. package/dist/server/analyze-worker-ipc.d.ts +58 -0
  285. package/dist/server/analyze-worker-ipc.js +16 -0
  286. package/dist/server/analyze-worker.d.ts +17 -1
  287. package/dist/server/analyze-worker.js +7 -1
  288. package/dist/server/api.d.ts +17 -0
  289. package/dist/server/api.js +132 -168
  290. package/dist/server/git-clone.d.ts +43 -2
  291. package/dist/server/git-clone.js +211 -16
  292. package/dist/server/mcp-http.d.ts +5 -6
  293. package/dist/server/mcp-http.js +9 -82
  294. package/dist/server/middleware.d.ts +40 -0
  295. package/dist/server/middleware.js +92 -0
  296. package/dist/server/private-ip.d.ts +1 -0
  297. package/dist/server/private-ip.js +15 -0
  298. package/dist/server/upload-ingest.d.ts +56 -0
  299. package/dist/server/upload-ingest.js +276 -0
  300. package/dist/server/upload-paths.d.ts +37 -0
  301. package/dist/server/upload-paths.js +57 -0
  302. package/dist/server/upload-sweep.d.ts +20 -0
  303. package/dist/server/upload-sweep.js +57 -0
  304. package/dist/storage/git.js +5 -8
  305. package/dist/storage/parse-cache.d.ts +22 -1
  306. package/dist/storage/parse-cache.js +44 -10
  307. package/dist/storage/repo-manager.d.ts +121 -10
  308. package/dist/storage/repo-manager.js +43 -5
  309. package/dist/types/pipeline.d.ts +9 -0
  310. package/hooks/antigravity/gitnexus-antigravity-hook.cjs +110 -10
  311. package/hooks/claude/gitnexus-hook.cjs +110 -13
  312. package/hooks/claude/hook-db-lock-probe.cjs +513 -26
  313. package/package.json +8 -2
  314. package/scripts/assert-publish-grammar-coverage.cjs +31 -0
  315. package/scripts/build-tree-sitter-grammars.cjs +16 -10
  316. package/scripts/cross-platform-tests.ts +1 -0
  317. package/skills/gitnexus-debugging.md +16 -4
  318. package/skills/gitnexus-exploring.md +3 -3
  319. package/skills/gitnexus-guide.md +33 -0
  320. package/skills/gitnexus-pdg-query.md +89 -0
  321. package/skills/gitnexus-refactoring.md +1 -1
  322. package/skills/gitnexus-taint-analysis.md +178 -0
  323. package/vendor/tree-sitter-c/package.json +1 -1
  324. package/vendor/tree-sitter-dart/package.json +1 -1
  325. package/vendor/tree-sitter-kotlin/package.json +1 -1
  326. package/vendor/tree-sitter-proto/package.json +1 -1
  327. package/vendor/tree-sitter-swift/package.json +1 -1
  328. package/web/assets/{agent-CKPMqImC.js → agent-D3Xd7zZE.js} +123 -123
  329. package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +1 -0
  330. package/web/assets/architectureDiagram-UL44E2DR-ChH9xW-N.js +36 -0
  331. package/web/assets/{blockDiagram-7IZFK4PR-B4niSLvR.js → blockDiagram-7IZFK4PR-BkWhpzWB.js} +1 -1
  332. package/web/assets/{c4Diagram-Y2BXMSZH-DIzEXalR.js → c4Diagram-Y2BXMSZH-DtBvpzWD.js} +1 -1
  333. package/web/assets/{chunk-3SSMPTDK-BzGeeheI.js → chunk-3SSMPTDK-B4_etUhr.js} +2 -2
  334. package/web/assets/{chunk-5IMINLNL-CnTLsXIV.js → chunk-5IMINLNL-DOdTeQri.js} +1 -1
  335. package/web/assets/{chunk-5VCL7Z4A-w1BCx98Z.js → chunk-5VCL7Z4A-CQ-2dYWj.js} +1 -1
  336. package/web/assets/chunk-6764PJDD-DpIS7hxD.js +1 -0
  337. package/web/assets/{chunk-67TQ5CYL-CChC2cAv.js → chunk-67TQ5CYL-4sNPJU1q.js} +3 -3
  338. package/web/assets/{chunk-7W6UQGC5-CgFyfZ6k.js → chunk-7W6UQGC5-KyEG0HQg.js} +1 -1
  339. package/web/assets/{chunk-AZZRMDJM-5E9ARdDQ.js → chunk-AZZRMDJM-y-xJBuMz.js} +1 -1
  340. package/web/assets/{chunk-INKRHTLW-ELpfuk9h.js → chunk-INKRHTLW-Nu4ri9P-.js} +1 -1
  341. package/web/assets/{chunk-JQRUD6KW-Dcq_Qnyy.js → chunk-JQRUD6KW-Dbva2Z17.js} +1 -1
  342. package/web/assets/{chunk-KGFNY3KK-W-VR57xb.js → chunk-KGFNY3KK-JGMJvKCK.js} +1 -1
  343. package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +161 -0
  344. package/web/assets/{chunk-KNLZD3CH-BuZBOcso.js → chunk-KNLZD3CH-BGlP6X9R.js} +1 -1
  345. package/web/assets/{chunk-KRXBNO2N-DH2NPM7I.js → chunk-KRXBNO2N-BW5o0KUN.js} +1 -1
  346. package/web/assets/{chunk-LCXTWHL2-Dfmux4m1.js → chunk-LCXTWHL2-zoomRtWX.js} +1 -1
  347. package/web/assets/{chunk-LII3EMHJ-3X33tCpU.js → chunk-LII3EMHJ-D-jm-dLa.js} +1 -1
  348. package/web/assets/{chunk-QA3QBVWF-D5Ha3GgB.js → chunk-QA3QBVWF-BgRW3SXd.js} +1 -1
  349. package/web/assets/{chunk-RG4AUYOV-CAkzcoRj.js → chunk-RG4AUYOV-DD0B2N2B.js} +1 -1
  350. package/web/assets/{chunk-T2UQINTJ-kGYG7ppP.js → chunk-T2UQINTJ-DSBqkzH7.js} +1 -1
  351. package/web/assets/chunk-T5OCTHI4-DdZvN-9i.js +1 -0
  352. package/web/assets/{chunk-UY5QBCOK-Du-c56gs.js → chunk-UY5QBCOK-DyF0vyGd.js} +1 -1
  353. package/web/assets/{chunk-W44A43WB-lrCpuupA.js → chunk-W44A43WB-JqMLIpR0.js} +1 -1
  354. package/web/assets/{chunk-ZXARS5L4-CSZRiyOf.js → chunk-ZXARS5L4-CxN8oiwI.js} +1 -1
  355. package/web/assets/classDiagram-KGZ6W3CR-DJm9BgF-.js +1 -0
  356. package/web/assets/classDiagram-v2-72OJOZXJ-DJm9BgF-.js +1 -0
  357. package/web/assets/{context-builder-_HS0v2ma.js → context-builder-BHiFUA8O.js} +10 -2
  358. package/web/assets/{cose-bilkent-UX7MHV2Q-BHv2bbtl.js → cose-bilkent-UX7MHV2Q-D71wNYRJ.js} +1 -1
  359. package/web/assets/dagre-ND4H6XIP-BIkxmhcu.js +4 -0
  360. package/web/assets/diagram-3NCE3AQN-BTa6iH0T.js +43 -0
  361. package/web/assets/diagram-GF46GFSD-DZDV0vBj.js +24 -0
  362. package/web/assets/{diagram-HNR7UZ2L-fUWreZzx.js → diagram-HNR7UZ2L-DFCfd5LI.js} +2 -2
  363. package/web/assets/diagram-QXG6HAR7-BzM--Jj0.js +24 -0
  364. package/web/assets/diagram-WEQXMOUZ-DFFwz0k4.js +10 -0
  365. package/web/assets/{erDiagram-L5TCEMPS-QN2eEP1e.js → erDiagram-L5TCEMPS-CfHMJJqo.js} +1 -1
  366. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +1 -0
  367. package/web/assets/{flowDiagram-H6V6AXG4-CXbXImlN.js → flowDiagram-H6V6AXG4-Be805QiJ.js} +3 -3
  368. package/web/assets/{ganttDiagram-JCBTUEKG-BHQssTz6.js → ganttDiagram-JCBTUEKG-D3iL2Aet.js} +1 -1
  369. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +1 -0
  370. package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +106 -0
  371. package/web/assets/index-BvYev1UJ.js +635 -0
  372. package/web/assets/index-_lgn7hs5.css +2 -0
  373. package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +1 -0
  374. package/web/assets/infoDiagram-3YFTVSEB-Y7BKSoke.js +2 -0
  375. package/web/assets/{ishikawaDiagram-BNXS4ZKH-6LKOvBfp.js → ishikawaDiagram-BNXS4ZKH-CT4SHFuI.js} +1 -1
  376. package/web/assets/{journeyDiagram-M6C3CM3L-DNPYCpvq.js → journeyDiagram-M6C3CM3L-CvArszLo.js} +1 -1
  377. package/web/assets/{kanban-definition-75IXJCU3-DgDi9oJT.js → kanban-definition-75IXJCU3-C6yDxr7N.js} +3 -3
  378. package/web/assets/{katex-K3KEBU37-CrVLz8l7.js → katex-K3KEBU37-CTc5BslQ.js} +1 -1
  379. package/web/assets/{mindmap-definition-2TDM6QVE-CwR5sBB-.js → mindmap-definition-2TDM6QVE-BOc2WEne.js} +1 -1
  380. package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +1 -0
  381. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +1 -0
  382. package/web/assets/{pieDiagram-CU6KROY3-By8g6f6B.js → pieDiagram-CU6KROY3-Cvc0f_Pd.js} +1 -1
  383. package/web/assets/{quadrantDiagram-VICAPDV7-bAm6Hi_5.js → quadrantDiagram-VICAPDV7-yXSZ2lLz.js} +1 -1
  384. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +1 -0
  385. package/web/assets/{requirementDiagram-JXO7QTGE-7oDcJ1_J.js → requirementDiagram-JXO7QTGE-BRcZvHs4.js} +1 -1
  386. package/web/assets/{sankeyDiagram-URQDO5SZ-LFJz53u5.js → sankeyDiagram-URQDO5SZ-1qEjlFIB.js} +1 -1
  387. package/web/assets/{sequenceDiagram-VS2MUI6T-FySeKCUy.js → sequenceDiagram-VS2MUI6T-PcSCuvrB.js} +3 -3
  388. package/web/assets/stateDiagram-7D4R322I-D6qYSV1E.js +1 -0
  389. package/web/assets/stateDiagram-v2-36443NZ5-Bg-ImOSX.js +1 -0
  390. package/web/assets/{timeline-definition-O6YCAMPW-Ds2CnVZK.js → timeline-definition-O6YCAMPW-QWkh01xw.js} +1 -1
  391. package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +1 -0
  392. package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +1 -0
  393. package/web/assets/{vennDiagram-MWXL3ELB-DUIEwXWp.js → vennDiagram-MWXL3ELB-ak4DfwuM.js} +3 -3
  394. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +1 -0
  395. package/web/assets/{wardleyDiagram-CUQ6CDDI-DEiFPQih.js → wardleyDiagram-CUQ6CDDI-CTzR4Loq.js} +1 -1
  396. package/web/assets/{xychartDiagram-N2JHSOCM-BUbayhST.js → xychartDiagram-N2JHSOCM-DA1BEaQz.js} +1 -1
  397. package/web/index.html +13 -15
  398. package/scripts/materialize-vendor-grammars.cjs +0 -97
  399. package/web/assets/architecture-7EHR7CIX-6QZW5X65-BETj2x4g.js +0 -1
  400. package/web/assets/architectureDiagram-UL44E2DR-D1EXI0zA.js +0 -36
  401. package/web/assets/chunk-2T2R6R2M-n6s9JZqv.js +0 -4
  402. package/web/assets/chunk-2UTLFMKG-CMBB1TMN.js +0 -1
  403. package/web/assets/chunk-4R4BOZG6-mKhL59ul.js +0 -159
  404. package/web/assets/chunk-6764PJDD-ChwMM2z4.js +0 -1
  405. package/web/assets/chunk-7J6CGLKN-DT-b53FT.js +0 -10
  406. package/web/assets/chunk-C62D2QBJ-CDAWj26E.js +0 -1
  407. package/web/assets/chunk-CEXFNPSA-D68Tk6ls.js +0 -1
  408. package/web/assets/chunk-CilyBKbf.js +0 -1
  409. package/web/assets/chunk-J5EP6P6S-DxWW0yvu.js +0 -1
  410. package/web/assets/chunk-KGYTTC2M-C6PHeuay.js +0 -1
  411. package/web/assets/chunk-RERM46MO-DQNbXtfw.js +0 -1
  412. package/web/assets/chunk-RKZBBQEN-BmTPLSyv.js +0 -1
  413. package/web/assets/chunk-RLI5ZMPA-DExu2DOK.js +0 -1
  414. package/web/assets/chunk-T5OCTHI4--9wWpVws.js +0 -1
  415. package/web/assets/chunk-UP6H54XL-DsKdC6jC.js +0 -1
  416. package/web/assets/chunk-UXSXWOXI-DR81EqLr.js +0 -1
  417. package/web/assets/classDiagram-KGZ6W3CR-Bv93af_b.js +0 -1
  418. package/web/assets/classDiagram-v2-72OJOZXJ-CLfEqHUa.js +0 -1
  419. package/web/assets/dagre-ND4H6XIP-DsIr9MOv.js +0 -4
  420. package/web/assets/diagram-3NCE3AQN-BqAtKUpW.js +0 -43
  421. package/web/assets/diagram-GF46GFSD-CaBG6n6o.js +0 -24
  422. package/web/assets/diagram-QXG6HAR7-CZ-O3rcV.js +0 -24
  423. package/web/assets/diagram-WEQXMOUZ-P4lSL4GH.js +0 -10
  424. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-B3myHUst.js +0 -1
  425. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DF3rtf4A.js +0 -1
  426. package/web/assets/gitGraphDiagram-S2ZK5IYY-CCwVLT__.js +0 -106
  427. package/web/assets/index-BKWA-m7o.css +0 -2
  428. package/web/assets/index-CG6q8eTs.js +0 -626
  429. package/web/assets/info-J43DQDTF-KCYPFFUO-R4XV_akJ.js +0 -1
  430. package/web/assets/infoDiagram-3YFTVSEB-DmLICZx1.js +0 -2
  431. package/web/assets/packet-YPE3B663-LP52Z2RK-CgQPdNZa.js +0 -1
  432. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BzWOwc_c.js +0 -1
  433. package/web/assets/radar-GUYGQ44K-RDLRG3WG-B7KG0FN7.js +0 -1
  434. package/web/assets/stateDiagram-7D4R322I-CB2nABwH.js +0 -1
  435. package/web/assets/stateDiagram-v2-36443NZ5-COBGd2RL.js +0 -1
  436. package/web/assets/treeView-BLDUP644-QA4HXRO3-CRSxEwLO.js +0 -1
  437. package/web/assets/treemap-LRROVOQU-LLAWBHMP-a0PfKoVn.js +0 -1
  438. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-BKQ6e5mC.js +0 -1
  439. /package/web/assets/{chunk-AQ6EADP3-CCFje6lL.js → chunk-AQ6EADP3-CZhslHi-.js} +0 -0
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Control dependence (#2085 M5 U3) — Ferrante, Ottenstein & Warren §3.1.1
3
+ * semantics. A block `dependent` is control-dependent on a branch block
4
+ * `controller` when `controller` decides whether `dependent` executes: formally,
5
+ * there is a CFG edge `controller → B` such that `dependent` post-dominates `B`
6
+ * but does NOT strictly post-dominate `controller`.
7
+ *
8
+ * Construction — the reverse-CFG dominance-frontier formulation (Cytron,
9
+ * Ferrante, Rosen, Wegman & Zadeck 1991): control dependence IS the dominance
10
+ * frontier of the reverse CFG, so `A ∈ PDF(X)` (the post-dominance frontier)
11
+ * ⟺ `X` is control-dependent on `A`. The PDF is computed bottom-up over the
12
+ * post-dom tree (`PDF_local` from a node's CFG predecessors + `PDF_up` from its
13
+ * post-dom-tree children) in O(N + E + output) — each up-step is charged to a
14
+ * distinct emitted edge, NOT re-walked per CFG edge as the original §3.1.1
15
+ * up-walk did (which was Θ(N²) on a deep post-dom chain). The two formulations
16
+ * enumerate the IDENTICAL full `(controller, dependent, label)` set (verified
17
+ * byte-identical on 3203 CFGs + ~1M-case differential fuzz); LLVM, Joern and WALA
18
+ * use the reverse-DF form. (Only the rare TRUNCATED prefix — when a function
19
+ * exceeds `maxEdges` — differs from the old prefix: it is now a sorted
20
+ * deterministic prefix rather than CFG-edge-iteration order. Both are valid,
21
+ * deterministic subsets; the full untruncated output is unchanged.)
22
+ * The branch SENSE ('T' | 'F') of the controlling edge becomes the edge label
23
+ * (KTD4 / KTD3 — it rides the persisted relation's `reason` column).
24
+ *
25
+ * PURE AND DETERMINISTIC (mirrors post-dominators.ts / reaching-defs.ts): no
26
+ * graph, no logger, importable outside the worker; output is deduped per
27
+ * (controller, dependent, label) and sorted, so snapshot tests and
28
+ * content-derived edge ids are stable. The loop header legitimately appears as
29
+ * control-dependent on ITSELF (`controller === dependent`) — the loop predicate
30
+ * gates its own re-execution; this is standard PDG behavior, not a bug.
31
+ */
32
+ import { computePostDominators, NO_IPDOM } from './post-dominators.js';
33
+ function buildArmSenses(cfg) {
34
+ const n = cfg.blocks.length;
35
+ const senses = Array.from({ length: n }, () => ({
36
+ hasTrueArm: false,
37
+ hasFalseArm: false,
38
+ }));
39
+ for (const e of cfg.edges) {
40
+ if (e.from < 0 || e.from >= n)
41
+ continue;
42
+ if (e.kind === 'cond-true' || e.kind === 'switch-case')
43
+ senses[e.from].hasTrueArm = true;
44
+ else if (e.kind === 'cond-false')
45
+ senses[e.from].hasFalseArm = true;
46
+ }
47
+ return senses;
48
+ }
49
+ /**
50
+ * The CDG label ('T'|'F') for a control-dependence edge, given the controlling
51
+ * block's arm senses. An explicitly-sensed edge is taken at face value; an
52
+ * ambiguous fall-through edge (`seq`/`loop-back`/`fallthrough`/jump) is the
53
+ * COMPLEMENT of the controller's explicit sibling arm. Per-case `switch` value
54
+ * labels are deferred to #2086 — every `switch-case` is 'T' in M5.
55
+ */
56
+ function labelFor(kind, controller) {
57
+ if (kind === 'cond-true' || kind === 'switch-case')
58
+ return 'T';
59
+ if (kind === 'cond-false')
60
+ return 'F';
61
+ // Ambiguous structural kind: take the complement of the controller's explicit
62
+ // arm. A block with a true arm reaches here via its false fall-through; a
63
+ // do/while bottom-test (false arm = cond-false) reaches here via its true
64
+ // loop-back. With neither explicit arm (a degenerate / exit-unreachable
65
+ // region — see #2188 F2, where the dependence itself is unsound) the sense is
66
+ // indeterminate; default 'F' since fall-through is the common case.
67
+ if (controller.hasTrueArm)
68
+ return 'F';
69
+ if (controller.hasFalseArm)
70
+ return 'T';
71
+ return 'F';
72
+ }
73
+ /**
74
+ * Compute control-dependence edges for one function's CFG. `postDom` may be
75
+ * supplied to reuse an already-built tree; otherwise it is computed. See the
76
+ * module doc for the purity/determinism contract.
77
+ */
78
+ export function computeControlDependence(cfg, postDom,
79
+ // Output-size ceiling, mirroring computeReachingDefs' `maxFacts` (#2188 review).
80
+ // The reverse-DF set is the bounded (controller, dependent, label) dependence
81
+ // relation, so peak working set ≈ output here (no pre-dedup spike like the old
82
+ // up-walk) — this caps the final edge COUNT, not transient memory. `0` ⇒
83
+ // unbounded. On overflow `edges` is a deterministic SORTED prefix and
84
+ // `truncated` is set — never a silent drop. (The sorted prefix is the prefix
85
+ // CONTENTS may differ from the old up-walk's CFG-edge-iteration prefix at the
86
+ // cap boundary; the FULL untruncated set is byte-identical — see the module doc.)
87
+ maxEdges = 0) {
88
+ const tree = postDom ?? computePostDominators(cfg);
89
+ const { ipdom } = tree;
90
+ const n = cfg.blocks.length;
91
+ const armSenses = buildArmSenses(cfg);
92
+ const cap = maxEdges > 0 ? maxEdges : Infinity;
93
+ // Reverse-CFG post-dominance frontier (Cytron, Ferrante, Rosen, Wegman,
94
+ // Zadeck 1991): control dependence IS the dominance frontier of the reverse
95
+ // CFG. `A ∈ PDF(X)` ⟺ X is control-dependent on A, so emit (controller=A,
96
+ // dependent=X). Computing the PDF bottom-up over the post-dom tree charges
97
+ // each up-step to a DISTINCT emitted entry — O(N+E+output) — instead of the
98
+ // old Ferrante up-walk that re-climbs the ipdom chain per CFG edge (Θ(N²) on
99
+ // a deep post-dom chain). Output is the identical (controller, dependent,
100
+ // label) set (verified byte-identical on 3203 CFGs across all languages +
101
+ // fuzz) and 1-2 orders of magnitude faster. LLVM (ReverseIDFCalculator),
102
+ // Joern (CdgPass) and WALA use the same formulation.
103
+ const children = Array.from({ length: n }, () => []);
104
+ const inEdges = Array.from({ length: n }, () => []);
105
+ for (let b = 0; b < n; b++) {
106
+ const ip = ipdom[b];
107
+ if (ip !== NO_IPDOM && ip >= 0 && ip < n)
108
+ children[ip].push(b);
109
+ }
110
+ for (const e of cfg.edges) {
111
+ if (e.from < 0 || e.from >= n || e.to < 0 || e.to >= n)
112
+ continue;
113
+ inEdges[e.to].push({ from: e.from, kind: e.kind });
114
+ }
115
+ // Post-dom-tree post-order (children before parents). Iterative — the post-dom
116
+ // forest can itself be chain-deep. Roots are the NO_IPDOM nodes (EXIT, plus
117
+ // any exit-unreachable region per #2188 F2). The reverse of a root-first DFS
118
+ // visits every parent AFTER all its descendants.
119
+ const dfs = [];
120
+ for (let r = 0; r < n; r++)
121
+ if (ipdom[r] === NO_IPDOM)
122
+ dfs.push(r);
123
+ const preorder = [];
124
+ while (dfs.length) {
125
+ const x = dfs.pop();
126
+ preorder.push(x);
127
+ for (const c of children[x])
128
+ dfs.push(c);
129
+ }
130
+ const order = preorder.reverse();
131
+ // PDF[X]: controller A → the label SET with which A controls X. A set (not one
132
+ // label) because a controller can reach X via opposite-sense arms (goto-
133
+ // cycles) — the old (a, cur, label) dedup kept both rows.
134
+ const pdf = Array.from({ length: n }, () => new Map());
135
+ const add = (x, a, label) => {
136
+ const set = pdf[x].get(a);
137
+ if (set)
138
+ set.add(label);
139
+ else
140
+ pdf[x].set(a, new Set([label]));
141
+ };
142
+ for (const x of order) {
143
+ // PDF_local: a CFG-predecessor A of X that X does not (immediately) post-
144
+ // dominate. `A !== X && ipdom[A] !== X` is exactly the production
145
+ // `!postDominates(X, A)` for one edge A→X (postDominates(X,A) ⟺ ipdom[A]===X),
146
+ // and it excludes self-edges + NO_IPDOM regions. Sense is read from the
147
+ // CONTROLLER's arms (seq/loop-back fall-through false arms would otherwise
148
+ // mislabel as 'T' — #2188 F1).
149
+ for (const { from: a, kind } of inEdges[x]) {
150
+ if (a !== x && ipdom[a] !== x)
151
+ add(x, a, labelFor(kind, armSenses[a]));
152
+ }
153
+ // PDF_up: inherit each post-dom child's frontier controller (with its label
154
+ // set) when X does not post-dominate it.
155
+ for (const z of children[x]) {
156
+ for (const [a, labels] of pdf[z]) {
157
+ if (ipdom[a] !== x)
158
+ for (const l of labels)
159
+ add(x, a, l);
160
+ }
161
+ }
162
+ }
163
+ const out = [];
164
+ for (const x of order) {
165
+ for (const [a, labels] of pdf[x]) {
166
+ for (const label of labels)
167
+ out.push({ controllerBlock: a, dependentBlock: x, label });
168
+ }
169
+ }
170
+ out.sort((x, y) => x.controllerBlock - y.controllerBlock ||
171
+ x.dependentBlock - y.dependentBlock ||
172
+ (x.label < y.label ? -1 : x.label > y.label ? 1 : 0));
173
+ // `maxEdges` is a heap-safety backstop applied to the SORTED set (the DF makes
174
+ // overflow far rarer than the old per-edge walk). Deterministic prefix, never
175
+ // a silent drop; mirrors computeReachingDefs' `truncated`.
176
+ let truncated = false;
177
+ if (cap !== Infinity && out.length > cap) {
178
+ truncated = true;
179
+ out.length = cap;
180
+ }
181
+ return { edges: out, truncated };
182
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * ControlFlowContext (issue #2081 M1; finalizer frames added by #2082 M2 U2).
3
+ *
4
+ * Resolves the targets of `break`/`continue` (plain and labeled) as the visitor
5
+ * descends through loops and switches. Loops and switches push a target frame
6
+ * on entry and pop it on exit; a labeled statement attaches its label to the
7
+ * frame of the construct it labels, so `break outer` / `continue outer` resolve
8
+ * against the right enclosing loop/switch rather than the nearest one.
9
+ *
10
+ * M2 adds FINALIZER frames, interleaved on the SAME stack as loop/switch frames
11
+ * — interleaving is load-bearing: a jump must route through exactly the
12
+ * `finally` bodies lexically BETWEEN it and its target (target-relative
13
+ * threading). A `break` whose loop lives entirely inside the `try` crosses no
14
+ * finally and must keep its direct edge; re-routing it anyway would force the
15
+ * only path to the in-try continuation through the finally, letting a finally
16
+ * redefinition falsely KILL in-loop definitions for the downstream
17
+ * reaching-defs pass (a taint false negative). A parallel stack cannot express
18
+ * that between-ness, which is why the frames live here.
19
+ */
20
+ import type { CfgBuilder } from './cfg-builder.js';
21
+ import type { CfgEdgeKind } from './types.js';
22
+ /** A `finally` whose body any crossing jump must route through. */
23
+ export interface FinalizerFrame {
24
+ readonly kind: 'finalizer';
25
+ /** Entry block of the finally body. */
26
+ readonly entry: number;
27
+ /**
28
+ * Completion legs registered by jumps that crossed this finally: once the
29
+ * owning try pops the frame, it wires `finally-exits → to` with `kind` for
30
+ * each entry. Mutated by the jump handlers via {@link ControlFlowContext}.
31
+ */
32
+ readonly pending: {
33
+ to: number;
34
+ kind: CfgEdgeKind;
35
+ }[];
36
+ }
37
+ /** A resolved jump: its ultimate target + the finallys it crosses (inner→outer). */
38
+ export interface JumpResolution {
39
+ readonly target: number;
40
+ readonly finalizers: readonly FinalizerFrame[];
41
+ }
42
+ export declare class ControlFlowContext {
43
+ private readonly stack;
44
+ pushLoop(continueTo: number, breakTo: number, labels?: readonly string[]): void;
45
+ pushSwitch(breakTo: number, labels?: readonly string[]): void;
46
+ /** Push a labeled non-loop statement's break-target frame. */
47
+ pushLabeledBlock(breakTo: number, labels: readonly string[]): void;
48
+ /**
49
+ * Push a finalizer frame and return it — the owning `visitTry` keeps the
50
+ * reference to wire {@link FinalizerFrame.pending} after popping it.
51
+ */
52
+ pushFinalizer(entry: number): FinalizerFrame;
53
+ pop(): void;
54
+ /**
55
+ * Resolve a `break`: the nearest enclosing loop/switch frame (or, with a
56
+ * label, the nearest frame carrying that label) plus every finalizer frame
57
+ * stacked ABOVE it — i.e. exactly the finallys the jump crosses, innermost
58
+ * first. Returns `undefined` if there is no valid target (malformed input or
59
+ * an unmodeled label) — the caller falls back to its conservative routing and
60
+ * threads nothing.
61
+ */
62
+ resolveBreak(label?: string): JumpResolution | undefined;
63
+ /** Resolve a `continue`: like {@link resolveBreak} but only loop frames match. */
64
+ resolveContinue(label?: string): JumpResolution | undefined;
65
+ /**
66
+ * Resolve a Java `yield e` (switch-EXPRESSION arm exit): the nearest enclosing
67
+ * SWITCH frame's exit, threading the finalizers stacked above it. Unlike a
68
+ * `break`, a `yield` ALWAYS targets the switch — never an intervening loop — so
69
+ * it cannot match a loop frame (a `yield` inside a loop inside a switch arm
70
+ * still exits the whole switch). Returns `undefined` when there is no enclosing
71
+ * switch (malformed input); the caller falls back to its conservative routing.
72
+ */
73
+ resolveYield(): JumpResolution | undefined;
74
+ /** Every active finalizer, innermost first — what a `return` must cross. */
75
+ finalizersForReturn(): readonly FinalizerFrame[];
76
+ /**
77
+ * Target block for a `break` (no finalizer info) — see {@link resolveBreak}.
78
+ * Prefer `resolveBreak` + {@link wireJumpThroughFinalizers} in visitors: a
79
+ * target-only lookup silently loses finalizer threading (the M2 soundness
80
+ * fix). Kept for target-shape assertions in tests.
81
+ */
82
+ breakTarget(label?: string): number | undefined;
83
+ /** Target block for a `continue` — same caveat as {@link breakTarget}. */
84
+ continueTarget(label?: string): number | undefined;
85
+ private resolve;
86
+ }
87
+ /**
88
+ * Wire a jump from `from` to `target`, routing through the finallys it
89
+ * crosses (innermost first). The first leg keeps the bare jump `kind`
90
+ * (preserving the "kind ⟹ source-block terminator" invariant in types.ts);
91
+ * each finally's completion leg is registered as pending on its frame with the
92
+ * matching `finally-*` kind and wired by the owning try via
93
+ * {@link drainFinalizerPending} once the finally's exits are known.
94
+ *
95
+ * Language-agnostic on purpose (#2082 M2): the threading protocol encodes
96
+ * three subtle invariants every future language visitor needs identically —
97
+ * keeping it here means a new visitor cannot drift on any of them.
98
+ */
99
+ export declare function wireJumpThroughFinalizers(builder: CfgBuilder, from: number, finalizers: readonly FinalizerFrame[], target: number, kind: 'return' | 'break' | 'continue'): void;
100
+ /**
101
+ * Wire a popped finalizer frame's pending completion legs from the finally's
102
+ * exit blocks. A finally that itself always jumps (`finally { return 2; }`)
103
+ * has no exits — its pending legs wire nowhere, matching JS's
104
+ * finally-override semantics.
105
+ */
106
+ export declare function drainFinalizerPending(builder: CfgBuilder, frame: FinalizerFrame, finallyExits: readonly number[]): void;
@@ -0,0 +1,124 @@
1
+ export class ControlFlowContext {
2
+ stack = [];
3
+ pushLoop(continueTo, breakTo, labels = []) {
4
+ this.stack.push({ kind: 'loop', continueTo, breakTo, labels });
5
+ }
6
+ pushSwitch(breakTo, labels = []) {
7
+ this.stack.push({ kind: 'switch', breakTo, labels });
8
+ }
9
+ /** Push a labeled non-loop statement's break-target frame. */
10
+ pushLabeledBlock(breakTo, labels) {
11
+ this.stack.push({ kind: 'block', breakTo, labels });
12
+ }
13
+ /**
14
+ * Push a finalizer frame and return it — the owning `visitTry` keeps the
15
+ * reference to wire {@link FinalizerFrame.pending} after popping it.
16
+ */
17
+ pushFinalizer(entry) {
18
+ const frame = { kind: 'finalizer', entry, pending: [] };
19
+ this.stack.push(frame);
20
+ return frame;
21
+ }
22
+ pop() {
23
+ this.stack.pop();
24
+ }
25
+ /**
26
+ * Resolve a `break`: the nearest enclosing loop/switch frame (or, with a
27
+ * label, the nearest frame carrying that label) plus every finalizer frame
28
+ * stacked ABOVE it — i.e. exactly the finallys the jump crosses, innermost
29
+ * first. Returns `undefined` if there is no valid target (malformed input or
30
+ * an unmodeled label) — the caller falls back to its conservative routing and
31
+ * threads nothing.
32
+ */
33
+ resolveBreak(label) {
34
+ return this.resolve((f) => label === undefined
35
+ ? f.kind !== 'block' // an unlabeled break never targets a labeled block
36
+ : f.labels.includes(label));
37
+ }
38
+ /** Resolve a `continue`: like {@link resolveBreak} but only loop frames match. */
39
+ resolveContinue(label) {
40
+ return this.resolve((f) => f.kind === 'loop' && (label === undefined || f.labels.includes(label)), (f) => f.continueTo);
41
+ }
42
+ /**
43
+ * Resolve a Java `yield e` (switch-EXPRESSION arm exit): the nearest enclosing
44
+ * SWITCH frame's exit, threading the finalizers stacked above it. Unlike a
45
+ * `break`, a `yield` ALWAYS targets the switch — never an intervening loop — so
46
+ * it cannot match a loop frame (a `yield` inside a loop inside a switch arm
47
+ * still exits the whole switch). Returns `undefined` when there is no enclosing
48
+ * switch (malformed input); the caller falls back to its conservative routing.
49
+ */
50
+ resolveYield() {
51
+ return this.resolve((f) => f.kind === 'switch');
52
+ }
53
+ /** Every active finalizer, innermost first — what a `return` must cross. */
54
+ finalizersForReturn() {
55
+ const fins = [];
56
+ for (let i = this.stack.length - 1; i >= 0; i--) {
57
+ const f = this.stack[i];
58
+ if (f.kind === 'finalizer')
59
+ fins.push(f);
60
+ }
61
+ return fins;
62
+ }
63
+ /**
64
+ * Target block for a `break` (no finalizer info) — see {@link resolveBreak}.
65
+ * Prefer `resolveBreak` + {@link wireJumpThroughFinalizers} in visitors: a
66
+ * target-only lookup silently loses finalizer threading (the M2 soundness
67
+ * fix). Kept for target-shape assertions in tests.
68
+ */
69
+ breakTarget(label) {
70
+ return this.resolveBreak(label)?.target;
71
+ }
72
+ /** Target block for a `continue` — same caveat as {@link breakTarget}. */
73
+ continueTarget(label) {
74
+ return this.resolveContinue(label)?.target;
75
+ }
76
+ resolve(matches, targetOf = (f) => f.breakTo) {
77
+ const crossed = [];
78
+ for (let i = this.stack.length - 1; i >= 0; i--) {
79
+ const f = this.stack[i];
80
+ if (f.kind === 'finalizer') {
81
+ crossed.push(f);
82
+ continue;
83
+ }
84
+ if (matches(f))
85
+ return { target: targetOf(f), finalizers: crossed };
86
+ }
87
+ return undefined;
88
+ }
89
+ }
90
+ /**
91
+ * Wire a jump from `from` to `target`, routing through the finallys it
92
+ * crosses (innermost first). The first leg keeps the bare jump `kind`
93
+ * (preserving the "kind ⟹ source-block terminator" invariant in types.ts);
94
+ * each finally's completion leg is registered as pending on its frame with the
95
+ * matching `finally-*` kind and wired by the owning try via
96
+ * {@link drainFinalizerPending} once the finally's exits are known.
97
+ *
98
+ * Language-agnostic on purpose (#2082 M2): the threading protocol encodes
99
+ * three subtle invariants every future language visitor needs identically —
100
+ * keeping it here means a new visitor cannot drift on any of them.
101
+ */
102
+ export function wireJumpThroughFinalizers(builder, from, finalizers, target, kind) {
103
+ if (finalizers.length === 0) {
104
+ builder.edge(from, target, kind);
105
+ return;
106
+ }
107
+ const completionKind = `finally-${kind}`;
108
+ builder.edge(from, finalizers[0].entry, kind);
109
+ for (let i = 0; i < finalizers.length; i++) {
110
+ const to = i + 1 < finalizers.length ? finalizers[i + 1].entry : target;
111
+ finalizers[i].pending.push({ to, kind: completionKind });
112
+ }
113
+ }
114
+ /**
115
+ * Wire a popped finalizer frame's pending completion legs from the finally's
116
+ * exit blocks. A finally that itself always jumps (`finally { return 2; }`)
117
+ * has no exits — its pending legs wire nowhere, matching JS's
118
+ * finally-override semantics.
119
+ */
120
+ export function drainFinalizerPending(builder, frame, finallyExits) {
121
+ for (const p of frame.pending) {
122
+ builder.connect(finallyExits, p.to, p.kind);
123
+ }
124
+ }