@optave/codegraph 3.13.0 → 3.15.0

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 (458) hide show
  1. package/README.md +35 -34
  2. package/dist/ast-analysis/engine.d.ts.map +1 -1
  3. package/dist/ast-analysis/engine.js +38 -40
  4. package/dist/ast-analysis/engine.js.map +1 -1
  5. package/dist/ast-analysis/rules/b2.d.ts +7 -0
  6. package/dist/ast-analysis/rules/b2.d.ts.map +1 -0
  7. package/dist/ast-analysis/rules/b2.js +240 -0
  8. package/dist/ast-analysis/rules/b2.js.map +1 -0
  9. package/dist/ast-analysis/rules/b3.d.ts +6 -0
  10. package/dist/ast-analysis/rules/b3.d.ts.map +1 -0
  11. package/dist/ast-analysis/rules/b3.js +105 -0
  12. package/dist/ast-analysis/rules/b3.js.map +1 -0
  13. package/dist/ast-analysis/rules/b4.d.ts +9 -0
  14. package/dist/ast-analysis/rules/b4.d.ts.map +1 -0
  15. package/dist/ast-analysis/rules/b4.js +361 -0
  16. package/dist/ast-analysis/rules/b4.js.map +1 -0
  17. package/dist/ast-analysis/rules/b5.d.ts +4 -0
  18. package/dist/ast-analysis/rules/b5.d.ts.map +1 -0
  19. package/dist/ast-analysis/rules/b5.js +52 -0
  20. package/dist/ast-analysis/rules/b5.js.map +1 -0
  21. package/dist/ast-analysis/rules/c.d.ts +4 -0
  22. package/dist/ast-analysis/rules/c.d.ts.map +1 -0
  23. package/dist/ast-analysis/rules/c.js +143 -0
  24. package/dist/ast-analysis/rules/c.js.map +1 -0
  25. package/dist/ast-analysis/rules/index.d.ts.map +1 -1
  26. package/dist/ast-analysis/rules/index.js +34 -0
  27. package/dist/ast-analysis/rules/index.js.map +1 -1
  28. package/dist/ast-analysis/rules/javascript.d.ts.map +1 -1
  29. package/dist/ast-analysis/rules/javascript.js +3 -0
  30. package/dist/ast-analysis/rules/javascript.js.map +1 -1
  31. package/dist/ast-analysis/shared.d.ts.map +1 -1
  32. package/dist/ast-analysis/shared.js +2 -0
  33. package/dist/ast-analysis/shared.js.map +1 -1
  34. package/dist/ast-analysis/visitor-utils.d.ts +1 -0
  35. package/dist/ast-analysis/visitor-utils.d.ts.map +1 -1
  36. package/dist/ast-analysis/visitor-utils.js +5 -0
  37. package/dist/ast-analysis/visitor-utils.js.map +1 -1
  38. package/dist/ast-analysis/visitor.d.ts.map +1 -1
  39. package/dist/ast-analysis/visitor.js +60 -47
  40. package/dist/ast-analysis/visitor.js.map +1 -1
  41. package/dist/ast-analysis/visitors/cfg-visitor.d.ts.map +1 -1
  42. package/dist/ast-analysis/visitors/cfg-visitor.js +126 -76
  43. package/dist/ast-analysis/visitors/cfg-visitor.js.map +1 -1
  44. package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
  45. package/dist/ast-analysis/visitors/complexity-visitor.js +27 -15
  46. package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
  47. package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
  48. package/dist/ast-analysis/visitors/dataflow-visitor.js +54 -21
  49. package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
  50. package/dist/cli/commands/config.d.ts.map +1 -1
  51. package/dist/cli/commands/config.js +137 -134
  52. package/dist/cli/commands/config.js.map +1 -1
  53. package/dist/cli/commands/roles.d.ts.map +1 -1
  54. package/dist/cli/commands/roles.js +6 -1
  55. package/dist/cli/commands/roles.js.map +1 -1
  56. package/dist/db/better-sqlite3.d.ts +2 -1
  57. package/dist/db/better-sqlite3.d.ts.map +1 -1
  58. package/dist/db/better-sqlite3.js.map +1 -1
  59. package/dist/db/connection.d.ts +7 -1
  60. package/dist/db/connection.d.ts.map +1 -1
  61. package/dist/db/connection.js +20 -5
  62. package/dist/db/connection.js.map +1 -1
  63. package/dist/db/index.d.ts +1 -1
  64. package/dist/db/index.d.ts.map +1 -1
  65. package/dist/db/index.js +1 -1
  66. package/dist/db/index.js.map +1 -1
  67. package/dist/db/migrations.d.ts.map +1 -1
  68. package/dist/db/migrations.js +68 -0
  69. package/dist/db/migrations.js.map +1 -1
  70. package/dist/db/repository/build-stmts.d.ts.map +1 -1
  71. package/dist/db/repository/build-stmts.js +18 -0
  72. package/dist/db/repository/build-stmts.js.map +1 -1
  73. package/dist/db/repository/dataflow.d.ts +5 -0
  74. package/dist/db/repository/dataflow.d.ts.map +1 -1
  75. package/dist/db/repository/dataflow.js +14 -0
  76. package/dist/db/repository/dataflow.js.map +1 -1
  77. package/dist/db/repository/index.d.ts +1 -1
  78. package/dist/db/repository/index.d.ts.map +1 -1
  79. package/dist/db/repository/index.js +1 -1
  80. package/dist/db/repository/index.js.map +1 -1
  81. package/dist/db/repository/native-repository.d.ts.map +1 -1
  82. package/dist/db/repository/native-repository.js +47 -34
  83. package/dist/db/repository/native-repository.js.map +1 -1
  84. package/dist/domain/analysis/context.d.ts +2 -2
  85. package/dist/domain/analysis/dependencies.d.ts +2 -2
  86. package/dist/domain/analysis/diff-impact.d.ts +2 -2
  87. package/dist/domain/analysis/fn-impact.d.ts +3 -1
  88. package/dist/domain/analysis/fn-impact.d.ts.map +1 -1
  89. package/dist/domain/analysis/fn-impact.js +4 -0
  90. package/dist/domain/analysis/fn-impact.js.map +1 -1
  91. package/dist/domain/analysis/implementations.d.ts +2 -2
  92. package/dist/domain/analysis/module-map.d.ts.map +1 -1
  93. package/dist/domain/analysis/module-map.js +32 -5
  94. package/dist/domain/analysis/module-map.js.map +1 -1
  95. package/dist/domain/analysis/roles.d.ts +7 -1
  96. package/dist/domain/analysis/roles.d.ts.map +1 -1
  97. package/dist/domain/analysis/roles.js +16 -0
  98. package/dist/domain/analysis/roles.js.map +1 -1
  99. package/dist/domain/analysis/symbol-lookup.d.ts +4 -4
  100. package/dist/domain/graph/builder/call-resolver.d.ts +17 -5
  101. package/dist/domain/graph/builder/call-resolver.d.ts.map +1 -1
  102. package/dist/domain/graph/builder/call-resolver.js +85 -220
  103. package/dist/domain/graph/builder/call-resolver.js.map +1 -1
  104. package/dist/domain/graph/builder/context.d.ts +1 -0
  105. package/dist/domain/graph/builder/context.d.ts.map +1 -1
  106. package/dist/domain/graph/builder/context.js.map +1 -1
  107. package/dist/domain/graph/builder/helpers.d.ts +16 -1
  108. package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
  109. package/dist/domain/graph/builder/helpers.js +162 -72
  110. package/dist/domain/graph/builder/helpers.js.map +1 -1
  111. package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
  112. package/dist/domain/graph/builder/incremental.js +166 -97
  113. package/dist/domain/graph/builder/incremental.js.map +1 -1
  114. package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
  115. package/dist/domain/graph/builder/pipeline.js +10 -4
  116. package/dist/domain/graph/builder/pipeline.js.map +1 -1
  117. package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
  118. package/dist/domain/graph/builder/stages/build-edges.js +496 -250
  119. package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
  120. package/dist/domain/graph/builder/stages/collect-files.d.ts.map +1 -1
  121. package/dist/domain/graph/builder/stages/collect-files.js +10 -7
  122. package/dist/domain/graph/builder/stages/collect-files.js.map +1 -1
  123. package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
  124. package/dist/domain/graph/builder/stages/detect-changes.js +2 -1
  125. package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
  126. package/dist/domain/graph/builder/stages/native-orchestrator.d.ts.map +1 -1
  127. package/dist/domain/graph/builder/stages/native-orchestrator.js +895 -545
  128. package/dist/domain/graph/builder/stages/native-orchestrator.js.map +1 -1
  129. package/dist/domain/graph/resolver/points-to.d.ts.map +1 -1
  130. package/dist/domain/graph/resolver/points-to.js +105 -57
  131. package/dist/domain/graph/resolver/points-to.js.map +1 -1
  132. package/dist/domain/graph/resolver/strategy.d.ts +61 -0
  133. package/dist/domain/graph/resolver/strategy.d.ts.map +1 -0
  134. package/dist/domain/graph/resolver/strategy.js +222 -0
  135. package/dist/domain/graph/resolver/strategy.js.map +1 -0
  136. package/dist/domain/graph/watcher.d.ts.map +1 -1
  137. package/dist/domain/graph/watcher.js +16 -9
  138. package/dist/domain/graph/watcher.js.map +1 -1
  139. package/dist/domain/parser.d.ts +12 -0
  140. package/dist/domain/parser.d.ts.map +1 -1
  141. package/dist/domain/parser.js +12 -2
  142. package/dist/domain/parser.js.map +1 -1
  143. package/dist/domain/queries.d.ts +1 -1
  144. package/dist/domain/queries.d.ts.map +1 -1
  145. package/dist/domain/queries.js +1 -1
  146. package/dist/domain/queries.js.map +1 -1
  147. package/dist/domain/wasm-worker-entry.js +3 -0
  148. package/dist/domain/wasm-worker-entry.js.map +1 -1
  149. package/dist/domain/wasm-worker-pool.d.ts.map +1 -1
  150. package/dist/domain/wasm-worker-pool.js +24 -5
  151. package/dist/domain/wasm-worker-pool.js.map +1 -1
  152. package/dist/domain/wasm-worker-protocol.d.ts +7 -0
  153. package/dist/domain/wasm-worker-protocol.d.ts.map +1 -1
  154. package/dist/extractors/dart.js +48 -3
  155. package/dist/extractors/dart.js.map +1 -1
  156. package/dist/extractors/groovy.js +62 -3
  157. package/dist/extractors/groovy.js.map +1 -1
  158. package/dist/extractors/helpers.d.ts +4 -2
  159. package/dist/extractors/helpers.d.ts.map +1 -1
  160. package/dist/extractors/helpers.js +5 -1
  161. package/dist/extractors/helpers.js.map +1 -1
  162. package/dist/extractors/java.js +77 -1
  163. package/dist/extractors/java.js.map +1 -1
  164. package/dist/extractors/javascript.d.ts.map +1 -1
  165. package/dist/extractors/javascript.js +549 -163
  166. package/dist/extractors/javascript.js.map +1 -1
  167. package/dist/extractors/kotlin.js +58 -3
  168. package/dist/extractors/kotlin.js.map +1 -1
  169. package/dist/extractors/objc.js +25 -2
  170. package/dist/extractors/objc.js.map +1 -1
  171. package/dist/extractors/scala.js +62 -2
  172. package/dist/extractors/scala.js.map +1 -1
  173. package/dist/extractors/swift.js +52 -3
  174. package/dist/extractors/swift.js.map +1 -1
  175. package/dist/features/audit.js +26 -23
  176. package/dist/features/audit.js.map +1 -1
  177. package/dist/features/boundaries.d.ts.map +1 -1
  178. package/dist/features/boundaries.js +12 -9
  179. package/dist/features/boundaries.js.map +1 -1
  180. package/dist/features/cfg.d.ts.map +1 -1
  181. package/dist/features/cfg.js +25 -18
  182. package/dist/features/cfg.js.map +1 -1
  183. package/dist/features/check.d.ts.map +1 -1
  184. package/dist/features/check.js +18 -5
  185. package/dist/features/check.js.map +1 -1
  186. package/dist/features/communities.d.ts +4 -2
  187. package/dist/features/communities.d.ts.map +1 -1
  188. package/dist/features/communities.js +6 -4
  189. package/dist/features/communities.js.map +1 -1
  190. package/dist/features/dataflow.d.ts +60 -0
  191. package/dist/features/dataflow.d.ts.map +1 -1
  192. package/dist/features/dataflow.js +530 -6
  193. package/dist/features/dataflow.js.map +1 -1
  194. package/dist/features/manifesto.d.ts.map +1 -1
  195. package/dist/features/manifesto.js +59 -72
  196. package/dist/features/manifesto.js.map +1 -1
  197. package/dist/features/sequence.d.ts.map +1 -1
  198. package/dist/features/sequence.js +27 -22
  199. package/dist/features/sequence.js.map +1 -1
  200. package/dist/features/snapshot.d.ts.map +1 -1
  201. package/dist/features/snapshot.js +36 -28
  202. package/dist/features/snapshot.js.map +1 -1
  203. package/dist/features/structure.d.ts.map +1 -1
  204. package/dist/features/structure.js +150 -62
  205. package/dist/features/structure.js.map +1 -1
  206. package/dist/features/triage.d.ts.map +1 -1
  207. package/dist/features/triage.js +18 -11
  208. package/dist/features/triage.js.map +1 -1
  209. package/dist/graph/algorithms/bfs.d.ts +1 -1
  210. package/dist/graph/algorithms/bfs.d.ts.map +1 -1
  211. package/dist/graph/algorithms/bfs.js +14 -13
  212. package/dist/graph/algorithms/bfs.js.map +1 -1
  213. package/dist/graph/algorithms/tarjan.d.ts.map +1 -1
  214. package/dist/graph/algorithms/tarjan.js +5 -0
  215. package/dist/graph/algorithms/tarjan.js.map +1 -1
  216. package/dist/graph/builders/dependency.js +28 -22
  217. package/dist/graph/builders/dependency.js.map +1 -1
  218. package/dist/graph/classifiers/roles.d.ts +10 -1
  219. package/dist/graph/classifiers/roles.d.ts.map +1 -1
  220. package/dist/graph/classifiers/roles.js +60 -6
  221. package/dist/graph/classifiers/roles.js.map +1 -1
  222. package/dist/infrastructure/config.d.ts +10 -0
  223. package/dist/infrastructure/config.d.ts.map +1 -1
  224. package/dist/infrastructure/config.js +31 -3
  225. package/dist/infrastructure/config.js.map +1 -1
  226. package/dist/infrastructure/registry.d.ts +0 -7
  227. package/dist/infrastructure/registry.d.ts.map +1 -1
  228. package/dist/infrastructure/registry.js +29 -13
  229. package/dist/infrastructure/registry.js.map +1 -1
  230. package/dist/infrastructure/update-check.d.ts.map +1 -1
  231. package/dist/infrastructure/update-check.js +49 -31
  232. package/dist/infrastructure/update-check.js.map +1 -1
  233. package/dist/mcp/server.d.ts +2 -10
  234. package/dist/mcp/server.d.ts.map +1 -1
  235. package/dist/mcp/server.js.map +1 -1
  236. package/dist/mcp/tools/ast-query.d.ts +1 -1
  237. package/dist/mcp/tools/ast-query.d.ts.map +1 -1
  238. package/dist/mcp/tools/audit.d.ts +1 -1
  239. package/dist/mcp/tools/audit.d.ts.map +1 -1
  240. package/dist/mcp/tools/batch-query.d.ts +1 -1
  241. package/dist/mcp/tools/batch-query.d.ts.map +1 -1
  242. package/dist/mcp/tools/branch-compare.d.ts +1 -1
  243. package/dist/mcp/tools/branch-compare.d.ts.map +1 -1
  244. package/dist/mcp/tools/brief.d.ts +1 -1
  245. package/dist/mcp/tools/brief.d.ts.map +1 -1
  246. package/dist/mcp/tools/cfg.d.ts +1 -1
  247. package/dist/mcp/tools/cfg.d.ts.map +1 -1
  248. package/dist/mcp/tools/check.d.ts +1 -1
  249. package/dist/mcp/tools/check.d.ts.map +1 -1
  250. package/dist/mcp/tools/co-changes.d.ts +1 -1
  251. package/dist/mcp/tools/co-changes.d.ts.map +1 -1
  252. package/dist/mcp/tools/code-owners.d.ts +1 -1
  253. package/dist/mcp/tools/code-owners.d.ts.map +1 -1
  254. package/dist/mcp/tools/communities.d.ts +1 -1
  255. package/dist/mcp/tools/communities.d.ts.map +1 -1
  256. package/dist/mcp/tools/complexity.d.ts +1 -1
  257. package/dist/mcp/tools/complexity.d.ts.map +1 -1
  258. package/dist/mcp/tools/context.d.ts +1 -1
  259. package/dist/mcp/tools/context.d.ts.map +1 -1
  260. package/dist/mcp/tools/dataflow.d.ts +1 -1
  261. package/dist/mcp/tools/dataflow.d.ts.map +1 -1
  262. package/dist/mcp/tools/diff-impact.d.ts +1 -1
  263. package/dist/mcp/tools/diff-impact.d.ts.map +1 -1
  264. package/dist/mcp/tools/execution-flow.d.ts +1 -1
  265. package/dist/mcp/tools/execution-flow.d.ts.map +1 -1
  266. package/dist/mcp/tools/export-graph.d.ts +1 -1
  267. package/dist/mcp/tools/export-graph.d.ts.map +1 -1
  268. package/dist/mcp/tools/file-deps.d.ts +1 -1
  269. package/dist/mcp/tools/file-deps.d.ts.map +1 -1
  270. package/dist/mcp/tools/file-exports.d.ts +1 -1
  271. package/dist/mcp/tools/file-exports.d.ts.map +1 -1
  272. package/dist/mcp/tools/find-cycles.d.ts +1 -1
  273. package/dist/mcp/tools/find-cycles.d.ts.map +1 -1
  274. package/dist/mcp/tools/fn-impact.d.ts +1 -1
  275. package/dist/mcp/tools/fn-impact.d.ts.map +1 -1
  276. package/dist/mcp/tools/impact-analysis.d.ts +1 -1
  277. package/dist/mcp/tools/impact-analysis.d.ts.map +1 -1
  278. package/dist/mcp/tools/implementations.d.ts +1 -1
  279. package/dist/mcp/tools/implementations.d.ts.map +1 -1
  280. package/dist/mcp/tools/index.d.ts +2 -5
  281. package/dist/mcp/tools/index.d.ts.map +1 -1
  282. package/dist/mcp/tools/index.js.map +1 -1
  283. package/dist/mcp/tools/interfaces.d.ts +1 -1
  284. package/dist/mcp/tools/interfaces.d.ts.map +1 -1
  285. package/dist/mcp/tools/list-functions.d.ts +1 -1
  286. package/dist/mcp/tools/list-functions.d.ts.map +1 -1
  287. package/dist/mcp/tools/list-repos.d.ts +1 -1
  288. package/dist/mcp/tools/list-repos.d.ts.map +1 -1
  289. package/dist/mcp/tools/module-map.d.ts +1 -1
  290. package/dist/mcp/tools/module-map.d.ts.map +1 -1
  291. package/dist/mcp/tools/node-roles.d.ts +1 -1
  292. package/dist/mcp/tools/node-roles.d.ts.map +1 -1
  293. package/dist/mcp/tools/path.d.ts +1 -1
  294. package/dist/mcp/tools/path.d.ts.map +1 -1
  295. package/dist/mcp/tools/query.d.ts +1 -1
  296. package/dist/mcp/tools/query.d.ts.map +1 -1
  297. package/dist/mcp/tools/semantic-search.d.ts +1 -1
  298. package/dist/mcp/tools/semantic-search.d.ts.map +1 -1
  299. package/dist/mcp/tools/sequence.d.ts +1 -1
  300. package/dist/mcp/tools/sequence.d.ts.map +1 -1
  301. package/dist/mcp/tools/structure.d.ts +1 -1
  302. package/dist/mcp/tools/structure.d.ts.map +1 -1
  303. package/dist/mcp/tools/symbol-children.d.ts +1 -1
  304. package/dist/mcp/tools/symbol-children.d.ts.map +1 -1
  305. package/dist/mcp/tools/triage.d.ts +1 -1
  306. package/dist/mcp/tools/triage.d.ts.map +1 -1
  307. package/dist/mcp/tools/where.d.ts +1 -1
  308. package/dist/mcp/tools/where.d.ts.map +1 -1
  309. package/dist/mcp/types.d.ts +19 -0
  310. package/dist/mcp/types.d.ts.map +1 -0
  311. package/dist/mcp/types.js +6 -0
  312. package/dist/mcp/types.js.map +1 -0
  313. package/dist/presentation/queries-cli/index.d.ts +1 -1
  314. package/dist/presentation/queries-cli/index.d.ts.map +1 -1
  315. package/dist/presentation/queries-cli/index.js +1 -1
  316. package/dist/presentation/queries-cli/index.js.map +1 -1
  317. package/dist/presentation/queries-cli/overview.d.ts +1 -0
  318. package/dist/presentation/queries-cli/overview.d.ts.map +1 -1
  319. package/dist/presentation/queries-cli/overview.js +20 -1
  320. package/dist/presentation/queries-cli/overview.js.map +1 -1
  321. package/dist/presentation/queries-cli.d.ts +1 -1
  322. package/dist/presentation/queries-cli.d.ts.map +1 -1
  323. package/dist/presentation/queries-cli.js +1 -1
  324. package/dist/presentation/queries-cli.js.map +1 -1
  325. package/dist/presentation/viewer.d.ts.map +1 -1
  326. package/dist/presentation/viewer.js +45 -32
  327. package/dist/presentation/viewer.js.map +1 -1
  328. package/dist/shared/constants.d.ts +21 -0
  329. package/dist/shared/constants.d.ts.map +1 -1
  330. package/dist/shared/constants.js +25 -0
  331. package/dist/shared/constants.js.map +1 -1
  332. package/dist/shared/normalize.d.ts.map +1 -1
  333. package/dist/shared/normalize.js +12 -22
  334. package/dist/shared/normalize.js.map +1 -1
  335. package/dist/shared/paginate.d.ts +4 -17
  336. package/dist/shared/paginate.d.ts.map +1 -1
  337. package/dist/shared/paginate.js.map +1 -1
  338. package/dist/types.d.ts +76 -1
  339. package/dist/types.d.ts.map +1 -1
  340. package/grammars/tree-sitter-erlang.wasm +0 -0
  341. package/package.json +7 -7
  342. package/src/ast-analysis/engine.ts +43 -63
  343. package/src/ast-analysis/rules/b2.ts +263 -0
  344. package/src/ast-analysis/rules/b3.ts +127 -0
  345. package/src/ast-analysis/rules/b4.ts +378 -0
  346. package/src/ast-analysis/rules/b5.ts +65 -0
  347. package/src/ast-analysis/rules/c.ts +157 -0
  348. package/src/ast-analysis/rules/index.ts +34 -0
  349. package/src/ast-analysis/rules/javascript.ts +3 -0
  350. package/src/ast-analysis/shared.ts +2 -0
  351. package/src/ast-analysis/visitor-utils.ts +5 -0
  352. package/src/ast-analysis/visitor.ts +82 -52
  353. package/src/ast-analysis/visitors/cfg-visitor.ts +198 -84
  354. package/src/ast-analysis/visitors/complexity-visitor.ts +44 -16
  355. package/src/ast-analysis/visitors/dataflow-visitor.ts +68 -29
  356. package/src/cli/commands/config.ts +184 -184
  357. package/src/cli/commands/roles.ts +6 -1
  358. package/src/db/better-sqlite3.ts +5 -4
  359. package/src/db/connection.ts +23 -5
  360. package/src/db/index.ts +1 -0
  361. package/src/db/migrations.ts +68 -0
  362. package/src/db/repository/build-stmts.ts +30 -0
  363. package/src/db/repository/dataflow.ts +16 -0
  364. package/src/db/repository/index.ts +1 -1
  365. package/src/db/repository/native-repository.ts +56 -40
  366. package/src/domain/analysis/fn-impact.ts +4 -0
  367. package/src/domain/analysis/module-map.ts +38 -6
  368. package/src/domain/analysis/roles.ts +23 -0
  369. package/src/domain/graph/builder/call-resolver.ts +112 -232
  370. package/src/domain/graph/builder/context.ts +1 -0
  371. package/src/domain/graph/builder/helpers.ts +190 -72
  372. package/src/domain/graph/builder/incremental.ts +249 -120
  373. package/src/domain/graph/builder/pipeline.ts +11 -5
  374. package/src/domain/graph/builder/stages/build-edges.ts +696 -296
  375. package/src/domain/graph/builder/stages/collect-files.ts +12 -6
  376. package/src/domain/graph/builder/stages/detect-changes.ts +3 -1
  377. package/src/domain/graph/builder/stages/native-orchestrator.ts +1102 -590
  378. package/src/domain/graph/resolver/points-to.ts +182 -59
  379. package/src/domain/graph/resolver/strategy.ts +265 -0
  380. package/src/domain/graph/watcher.ts +19 -9
  381. package/src/domain/parser.ts +12 -2
  382. package/src/domain/queries.ts +1 -1
  383. package/src/domain/wasm-worker-entry.ts +3 -0
  384. package/src/domain/wasm-worker-pool.ts +28 -4
  385. package/src/domain/wasm-worker-protocol.ts +4 -0
  386. package/src/extractors/dart.ts +48 -3
  387. package/src/extractors/groovy.ts +62 -2
  388. package/src/extractors/helpers.ts +5 -2
  389. package/src/extractors/java.ts +80 -1
  390. package/src/extractors/javascript.ts +566 -161
  391. package/src/extractors/kotlin.ts +57 -3
  392. package/src/extractors/objc.ts +25 -1
  393. package/src/extractors/scala.ts +63 -1
  394. package/src/extractors/swift.ts +46 -3
  395. package/src/features/audit.ts +43 -34
  396. package/src/features/boundaries.ts +17 -9
  397. package/src/features/cfg.ts +31 -22
  398. package/src/features/check.ts +21 -5
  399. package/src/features/communities.ts +28 -19
  400. package/src/features/dataflow.ts +755 -6
  401. package/src/features/manifesto.ts +76 -75
  402. package/src/features/sequence.ts +29 -23
  403. package/src/features/snapshot.ts +36 -25
  404. package/src/features/structure.ts +185 -55
  405. package/src/features/triage.ts +28 -15
  406. package/src/graph/algorithms/bfs.ts +13 -12
  407. package/src/graph/algorithms/tarjan.ts +5 -0
  408. package/src/graph/builders/dependency.ts +35 -23
  409. package/src/graph/classifiers/roles.ts +74 -7
  410. package/src/infrastructure/config.ts +32 -3
  411. package/src/infrastructure/registry.ts +44 -20
  412. package/src/infrastructure/update-check.ts +55 -33
  413. package/src/mcp/server.ts +2 -8
  414. package/src/mcp/tools/ast-query.ts +1 -1
  415. package/src/mcp/tools/audit.ts +1 -1
  416. package/src/mcp/tools/batch-query.ts +1 -1
  417. package/src/mcp/tools/branch-compare.ts +1 -1
  418. package/src/mcp/tools/brief.ts +1 -1
  419. package/src/mcp/tools/cfg.ts +1 -1
  420. package/src/mcp/tools/check.ts +1 -1
  421. package/src/mcp/tools/co-changes.ts +1 -1
  422. package/src/mcp/tools/code-owners.ts +1 -1
  423. package/src/mcp/tools/communities.ts +1 -1
  424. package/src/mcp/tools/complexity.ts +1 -1
  425. package/src/mcp/tools/context.ts +1 -1
  426. package/src/mcp/tools/dataflow.ts +1 -1
  427. package/src/mcp/tools/diff-impact.ts +1 -1
  428. package/src/mcp/tools/execution-flow.ts +1 -1
  429. package/src/mcp/tools/export-graph.ts +1 -1
  430. package/src/mcp/tools/file-deps.ts +1 -1
  431. package/src/mcp/tools/file-exports.ts +1 -1
  432. package/src/mcp/tools/find-cycles.ts +1 -1
  433. package/src/mcp/tools/fn-impact.ts +1 -1
  434. package/src/mcp/tools/impact-analysis.ts +1 -1
  435. package/src/mcp/tools/implementations.ts +1 -1
  436. package/src/mcp/tools/index.ts +2 -5
  437. package/src/mcp/tools/interfaces.ts +1 -1
  438. package/src/mcp/tools/list-functions.ts +1 -1
  439. package/src/mcp/tools/list-repos.ts +1 -1
  440. package/src/mcp/tools/module-map.ts +1 -1
  441. package/src/mcp/tools/node-roles.ts +1 -1
  442. package/src/mcp/tools/path.ts +1 -1
  443. package/src/mcp/tools/query.ts +1 -1
  444. package/src/mcp/tools/semantic-search.ts +1 -1
  445. package/src/mcp/tools/sequence.ts +1 -1
  446. package/src/mcp/tools/structure.ts +1 -1
  447. package/src/mcp/tools/symbol-children.ts +1 -1
  448. package/src/mcp/tools/triage.ts +1 -1
  449. package/src/mcp/tools/where.ts +1 -1
  450. package/src/mcp/types.ts +21 -0
  451. package/src/presentation/queries-cli/index.ts +1 -1
  452. package/src/presentation/queries-cli/overview.ts +35 -1
  453. package/src/presentation/queries-cli.ts +1 -0
  454. package/src/presentation/viewer.ts +98 -87
  455. package/src/shared/constants.ts +26 -0
  456. package/src/shared/normalize.ts +13 -22
  457. package/src/shared/paginate.ts +4 -18
  458. package/src/types.ts +86 -1
@@ -0,0 +1,378 @@
1
+ import type { DataflowRulesConfig, TreeSitterNode } from '../../types.js';
2
+ import { makeDataflowRules } from '../shared.js';
3
+
4
+ // ─── Haskell ──────────────────────────────────────────────────────────────────
5
+ //
6
+ // Haskell `function` node: name via `childForFieldName('name')` (confirmed in extractor line 62).
7
+ // Params: `patterns` or `parameter` children of the function node (extractor line 81).
8
+ // No explicit return keyword — last expression is the return value. returnNode: null.
9
+ // apply: `childForFieldName('function')` for the called function (extractor line 264).
10
+ // No standard variable declarations or member access in the conventional sense.
11
+
12
+ function extractHaskellParamName(node: TreeSitterNode): string[] | null {
13
+ if (node.type === 'variable' || node.type === 'identifier') return [node.text];
14
+ if (node.type === 'wildcard') return ['_'];
15
+ // For pattern nodes, collect all variable bindings
16
+ if (node.type === 'patterns' || node.type === 'parameter') {
17
+ const names: string[] = [];
18
+ for (let i = 0; i < node.childCount; i++) {
19
+ const child = node.child(i);
20
+ if (!child) continue;
21
+ if (child.type === 'variable' || child.type === 'identifier') names.push(child.text);
22
+ }
23
+ return names.length > 0 ? names : null;
24
+ }
25
+ return null;
26
+ }
27
+
28
+ function getHaskellParamListNode(funcNode: TreeSitterNode): TreeSitterNode | null {
29
+ // Haskell params are positional children; find the `patterns` child if present
30
+ for (let i = 0; i < funcNode.childCount; i++) {
31
+ const child = funcNode.child(i);
32
+ if (child?.type === 'patterns') return child;
33
+ }
34
+ return null;
35
+ }
36
+
37
+ export const dataflowHaskell: DataflowRulesConfig = makeDataflowRules({
38
+ functionNodes: new Set(['function']),
39
+ nameField: 'name',
40
+
41
+ getParamListNode: getHaskellParamListNode,
42
+ paramWrapperTypes: new Set(['variable', 'identifier', 'wildcard', 'parameter']),
43
+ extractParamName: extractHaskellParamName,
44
+
45
+ returnNode: null, // Haskell: no explicit return; last expression is the result
46
+
47
+ callNode: 'apply',
48
+ callFunctionField: 'function',
49
+ // `apply` args don't have a single named 'arguments' field in tree-sitter-haskell.
50
+ });
51
+
52
+ // ─── OCaml ────────────────────────────────────────────────────────────────────
53
+ //
54
+ // OCaml functions are `value_definition` → `let_binding` nodes with parameter children.
55
+ // The extractor handles both `value_definition` (top-level) and standalone `let_binding`.
56
+ // Params: `parameter` or `value_pattern` children of let_binding (extractor line 139).
57
+ // No explicit return keyword — last expression is the result. returnNode: null.
58
+ // application_expression: first child is function node (extractor line 314).
59
+ // field_get_expression: `childForFieldName('field')` (extractor line 327).
60
+ // Variable declarations: `let_binding` with no params (extractor line 103-110).
61
+
62
+ function extractOCamlParamName(node: TreeSitterNode): string[] | null {
63
+ if (node.type === 'value_name' || node.type === 'identifier') return [node.text];
64
+ if (node.type === 'parameter' || node.type === 'value_pattern') {
65
+ // Pattern may be value_name or identifier
66
+ if (node.namedChildCount === 0) return [node.text];
67
+ for (const child of node.namedChildren) {
68
+ if (child.type === 'value_name' || child.type === 'identifier') return [child.text];
69
+ }
70
+ }
71
+ return null;
72
+ }
73
+
74
+ function getOCamlParamListNode(funcNode: TreeSitterNode): TreeSitterNode | null {
75
+ // For value_definition, params are inside let_binding children
76
+ if (funcNode.type === 'value_definition') {
77
+ for (let i = 0; i < funcNode.childCount; i++) {
78
+ const child = funcNode.child(i);
79
+ if (child?.type === 'let_binding') return child;
80
+ }
81
+ }
82
+ // For let_binding directly — return it as the "param list" (walker will iterate its children)
83
+ if (funcNode.type === 'let_binding') return funcNode;
84
+ return null;
85
+ }
86
+
87
+ export const dataflowOCaml: DataflowRulesConfig = makeDataflowRules({
88
+ functionNodes: new Set(['value_definition', 'let_binding']),
89
+ nameField: 'pattern',
90
+
91
+ getParamListNode: getOCamlParamListNode,
92
+ paramWrapperTypes: new Set(['parameter', 'value_pattern']),
93
+ extractParamName: extractOCamlParamName,
94
+
95
+ returnNode: null, // OCaml: no explicit return; last expression is the result
96
+
97
+ callNode: 'application_expression',
98
+ // application_expression: first child is function (no named 'function' field in tree-sitter-ocaml).
99
+ // Leave callFunctionField at default — will return null gracefully.
100
+
101
+ memberNode: 'field_get_expression',
102
+ memberPropertyField: 'field',
103
+ // field_get_expression object is first child, not a named field. Leave memberObjectField at default.
104
+ });
105
+
106
+ // ─── F# ───────────────────────────────────────────────────────────────────────
107
+ //
108
+ // F# functions: `function_declaration_left` is the LHS of a `let` binding (confirmed extractor).
109
+ // The name is a direct `identifier` child of `function_declaration_left` (extractor line 127).
110
+ // Params: `argument_patterns` child of `function_declaration_left` (extractor line 150).
111
+ // No explicit return keyword in F#. returnNode: null.
112
+ // application_expression: first child is function (extractor line 265).
113
+ // dot_expression: member access (extractor line 276).
114
+
115
+ function extractFSharpParamName(node: TreeSitterNode): string[] | null {
116
+ if (node.type === 'identifier') return [node.text];
117
+ // Collect all identifier descendants for pattern-destructured params
118
+ const names: string[] = [];
119
+ for (let i = 0; i < node.childCount; i++) {
120
+ const child = node.child(i);
121
+ if (child?.type === 'identifier') names.push(child.text);
122
+ }
123
+ return names.length > 0 ? names : null;
124
+ }
125
+
126
+ function getFSharpParamListNode(funcNode: TreeSitterNode): TreeSitterNode | null {
127
+ // function_declaration_left contains argument_patterns as a child
128
+ for (let i = 0; i < funcNode.childCount; i++) {
129
+ const child = funcNode.child(i);
130
+ if (child?.type === 'argument_patterns') return child;
131
+ }
132
+ return null;
133
+ }
134
+
135
+ export const dataflowFSharp: DataflowRulesConfig = makeDataflowRules({
136
+ functionNodes: new Set(['function_declaration_left']),
137
+ nameField: 'name',
138
+
139
+ getParamListNode: getFSharpParamListNode,
140
+ paramWrapperTypes: new Set(['identifier']),
141
+ extractParamName: extractFSharpParamName,
142
+
143
+ returnNode: null, // F#: no explicit return; last expression is the result
144
+
145
+ callNode: 'application_expression',
146
+ // application_expression: first child is function (no named 'function' field).
147
+
148
+ memberNode: 'dot_expression',
149
+ // dot_expression field names are not standard; leave memberObjectField/memberPropertyField at defaults.
150
+ });
151
+
152
+ // ─── Gleam ────────────────────────────────────────────────────────────────────
153
+ //
154
+ // Gleam `function` and `external_function`: name via `childForFieldName('name')` (extractor line 70).
155
+ // Params: `childForFieldName('parameters')` or findChild('function_parameters') (extractor line 221).
156
+ // Each param is `function_parameter` or `parameter` with `childForFieldName('name')` (extractor line 228).
157
+ // No explicit return keyword in Gleam. returnNode: null.
158
+ // function_call/call: `childForFieldName('function')` (extractor line 202).
159
+ // field_access/module_select: `childForFieldName('field')` / `childForFieldName('label')` (extractor line 207).
160
+
161
+ function extractGleamParamName(node: TreeSitterNode): string[] | null {
162
+ if (node.type === 'function_parameter' || node.type === 'parameter') {
163
+ const nameNode = node.childForFieldName('name');
164
+ if (nameNode) return [nameNode.text];
165
+ for (const child of node.namedChildren) {
166
+ if (child.type === 'identifier') return [child.text];
167
+ }
168
+ }
169
+ if (node.type === 'identifier') return [node.text];
170
+ return null;
171
+ }
172
+
173
+ export const dataflowGleam: DataflowRulesConfig = makeDataflowRules({
174
+ functionNodes: new Set(['function', 'external_function']),
175
+ nameField: 'name',
176
+
177
+ paramListField: 'parameters',
178
+ paramWrapperTypes: new Set(['function_parameter', 'parameter']),
179
+ extractParamName: extractGleamParamName,
180
+
181
+ returnNode: null, // Gleam: no explicit return; last expression is the result
182
+
183
+ callNodes: new Set(['function_call', 'call']),
184
+ callFunctionField: 'function',
185
+
186
+ memberNode: 'field_access',
187
+ memberObjectField: 'record',
188
+ memberPropertyField: 'field',
189
+ });
190
+
191
+ // ─── Elixir ───────────────────────────────────────────────────────────────────
192
+ //
193
+ // Elixir functions are `call` nodes where target is `def`/`defp` (confirmed extractor).
194
+ // The extractor emits the function definition from `handleDefFunction` which walks
195
+ // `call` nodes. The actual function body lives inside a `do_block`.
196
+ // Params: inside `call` → `arguments` → inner `call` → `arguments` (extractor line 181-196).
197
+ // No explicit return keyword in Elixir. returnNode: null.
198
+ // Regular call: `call` nodes with `target` identifier (extractor handleElixirCall).
199
+ // Dot call: `call` with `dot` target (extractor handleDotCall).
200
+ //
201
+ // For dataflow purposes: the function scope is a `call` node with `def`/`defp` target.
202
+ // This requires a custom nameExtractor to identify which calls are function definitions.
203
+ // The simplified approach: mark `call` as a function node but filter by target in nameExtractor.
204
+
205
+ function extractElixirFunctionName(node: TreeSitterNode): string | null {
206
+ if (node.type !== 'call') return null;
207
+ const target = node.childForFieldName('target');
208
+ if (target?.type !== 'identifier') return null;
209
+ if (target.text !== 'def' && target.text !== 'defp') return null;
210
+ // Extract the function name from arguments → first call → target identifier
211
+ const args =
212
+ node.childForFieldName('arguments') ??
213
+ (() => {
214
+ for (let i = 0; i < node.childCount; i++) {
215
+ const child = node.child(i);
216
+ if (child?.type === 'arguments') return child;
217
+ }
218
+ return null;
219
+ })();
220
+ if (!args) return null;
221
+ for (let i = 0; i < args.childCount; i++) {
222
+ const child = args.child(i);
223
+ if (!child) continue;
224
+ if (child.type === 'call') {
225
+ const fnTarget = child.childForFieldName('target');
226
+ if (fnTarget?.type === 'identifier') return fnTarget.text;
227
+ }
228
+ if (child.type === 'identifier') return child.text;
229
+ }
230
+ return null;
231
+ }
232
+
233
+ export const dataflowElixir: DataflowRulesConfig = makeDataflowRules({
234
+ functionNodes: new Set(['call']),
235
+ nameField: 'target',
236
+ nameExtractor: extractElixirFunctionName,
237
+
238
+ // Param list extraction is complex for Elixir (nested calls inside arguments).
239
+ // Leave at defaults — param list discovery will gracefully return null.
240
+
241
+ returnNode: null, // Elixir: no explicit return; last expression is the result
242
+
243
+ callNode: 'call',
244
+ // Elixir call nodes use 'target' for the function name, not 'function'.
245
+ // Leave callFunctionField at default 'function' — will return null gracefully.
246
+ // The primary value here is function scope marking.
247
+ });
248
+
249
+ // ─── Erlang ───────────────────────────────────────────────────────────────────
250
+ //
251
+ // Erlang `fun_decl` contains `function_clause` children.
252
+ // The extractor handles `fun_decl` by extracting from the first `function_clause`.
253
+ // function_clause: name via `childForFieldName('name')` or `findChild(node, 'atom')` (extractor line 151).
254
+ // Params: `childForFieldName('args')` or findChild('expr_args') (extractor line 179).
255
+ // Each arg in expr_args is a named child (pattern). arity preserved by param count.
256
+ // No explicit return keyword in Erlang. returnNode: null.
257
+ // call: first named child is function (extractor line 272).
258
+
259
+ function extractErlangParamName(node: TreeSitterNode): string[] | null {
260
+ // Erlang params are pattern nodes; var/atom get their text as name
261
+ if (node.type === 'var' || node.type === 'atom') return [node.text];
262
+ // For complex patterns, use a placeholder
263
+ return [`_${node.startPosition.row}`];
264
+ }
265
+
266
+ function getErlangParamListNode(funcNode: TreeSitterNode): TreeSitterNode | null {
267
+ // fun_decl: find first function_clause, then its expr_args
268
+ if (funcNode.type === 'fun_decl') {
269
+ for (let i = 0; i < funcNode.childCount; i++) {
270
+ const child = funcNode.child(i);
271
+ if (child?.type === 'function_clause') {
272
+ const args = child.childForFieldName('args');
273
+ if (args) return args;
274
+ for (let j = 0; j < child.childCount; j++) {
275
+ const argChild = child.child(j);
276
+ if (argChild?.type === 'expr_args') return argChild;
277
+ }
278
+ }
279
+ }
280
+ }
281
+ // function_clause directly: find expr_args
282
+ if (funcNode.type === 'function_clause') {
283
+ const args = funcNode.childForFieldName('args');
284
+ if (args) return args;
285
+ for (let i = 0; i < funcNode.childCount; i++) {
286
+ const child = funcNode.child(i);
287
+ if (child?.type === 'expr_args') return child;
288
+ }
289
+ }
290
+ return null;
291
+ }
292
+
293
+ export const dataflowErlang: DataflowRulesConfig = makeDataflowRules({
294
+ functionNodes: new Set(['fun_decl', 'function_clause']),
295
+ nameField: 'name',
296
+
297
+ getParamListNode: getErlangParamListNode,
298
+ extractParamName: extractErlangParamName,
299
+
300
+ returnNode: null, // Erlang: no explicit return; last expression is the result
301
+
302
+ callNode: 'call',
303
+ // Erlang call: first named child is function (atom or remote). No named 'function' field.
304
+ });
305
+
306
+ // ─── Clojure ──────────────────────────────────────────────────────────────────
307
+ //
308
+ // Clojure functions are `list_lit` nodes where first symbol is `defn`/`defn-`/`defmacro`.
309
+ // The extractor uses `findFirstSymbol` / `findSecondSymbol` helpers.
310
+ // The function name is the second symbol in the list.
311
+ // Params: first `vec_lit` child after the name (extractor extractClojureParams line 222).
312
+ // No explicit return keyword in Clojure. returnNode: null.
313
+ // Regular calls: `list_lit` nodes where first symbol is not a def form (extractor default case).
314
+ //
315
+ // nameExtractor must distinguish function-defining lists from call lists.
316
+
317
+ function extractClojureFunctionName(node: TreeSitterNode): string | null {
318
+ if (node.type !== 'list_lit') return null;
319
+ // Find first symbol — skip delimiters and metadata
320
+ let firstSym: TreeSitterNode | null = null;
321
+ let secondSym: TreeSitterNode | null = null;
322
+ let count = 0;
323
+ for (let i = 0; i < node.childCount; i++) {
324
+ const child = node.child(i);
325
+ if (!child) continue;
326
+ if ('()[]{}#'.includes(child.type) || child.type === 'meta_lit') continue;
327
+ if (child.type === 'sym_lit' || child.type === 'kwd_lit') {
328
+ count++;
329
+ if (count === 1) firstSym = child;
330
+ else if (count === 2) {
331
+ secondSym = child;
332
+ break;
333
+ }
334
+ }
335
+ }
336
+ if (!firstSym) return null;
337
+ const keyword = firstSym.text;
338
+ if (
339
+ keyword !== 'defn' &&
340
+ keyword !== 'defn-' &&
341
+ keyword !== 'defmacro' &&
342
+ keyword !== 'defmethod'
343
+ )
344
+ return null;
345
+ return secondSym ? secondSym.text : null;
346
+ }
347
+
348
+ function getClojureParamListNode(funcNode: TreeSitterNode): TreeSitterNode | null {
349
+ if (funcNode.type !== 'list_lit') return null;
350
+ // Find the first vec_lit child (the parameter vector)
351
+ for (let i = 0; i < funcNode.childCount; i++) {
352
+ const child = funcNode.child(i);
353
+ if (child?.type === 'vec_lit') return child;
354
+ }
355
+ return null;
356
+ }
357
+
358
+ function extractClojureParamName(node: TreeSitterNode): string[] | null {
359
+ if (node.type === 'sym_lit') return [node.text];
360
+ return null;
361
+ }
362
+
363
+ export const dataflowClojure: DataflowRulesConfig = makeDataflowRules({
364
+ functionNodes: new Set(['list_lit']),
365
+ nameField: 'name',
366
+ nameExtractor: extractClojureFunctionName,
367
+
368
+ getParamListNode: getClojureParamListNode,
369
+ paramWrapperTypes: new Set(['sym_lit']),
370
+ extractParamName: extractClojureParamName,
371
+
372
+ returnNode: null, // Clojure: no explicit return; last expression is the result
373
+
374
+ callNode: 'list_lit',
375
+ // Clojure calls are also list_lit nodes — first sym is the function name.
376
+ // The dataflow visitor will see these as calls (not function defs) since
377
+ // nameExtractor returns null for non-def forms.
378
+ });
@@ -0,0 +1,65 @@
1
+ import type { DataflowRulesConfig } from '../../types.js';
2
+ import { makeDataflowRules } from '../shared.js';
3
+
4
+ // ─── Zig ──────────────────────────────────────────────────────────────────────
5
+ //
6
+ // Zig function_declaration: name via `childForFieldName('name')` (confirmed in extractor line 68).
7
+ // Parameters: `childForFieldName('parameters')` (confirmed in extractor extractZigParams line 84).
8
+ // Each parameter is a `parameter` node; identifier child is the name (extractor line 89-90).
9
+ // return_statement: Zig has explicit return (confirmed in extractor + language spec).
10
+ // variable_declaration: name is first `identifier` child (extractor handleZigVariable line 99).
11
+ // call_expression: `childForFieldName('function')` (confirmed in extractor handleZigCallExpression line 209).
12
+ // field_expression/field_access: `childForFieldName('field')` or `childForFieldName('member')` (extractor line 215).
13
+ // member object: `childForFieldName('value')` or `funcNode.child(0)` (extractor line 216).
14
+
15
+ export const dataflowZig: DataflowRulesConfig = makeDataflowRules({
16
+ functionNodes: new Set(['function_declaration']),
17
+ nameField: 'name',
18
+
19
+ paramListField: 'parameters',
20
+ paramWrapperTypes: new Set(['parameter']),
21
+ // Zig parameter: identifier child for the name (extractZigParams uses findChild(param, 'identifier'))
22
+ paramIdentifier: 'identifier',
23
+
24
+ returnNode: 'return_statement',
25
+
26
+ varDeclaratorNode: 'variable_declaration',
27
+ varNameField: 'name',
28
+
29
+ callNode: 'call_expression',
30
+ callFunctionField: 'function',
31
+ callArgsField: 'arguments',
32
+
33
+ memberNode: 'field_expression',
34
+ memberObjectField: 'value',
35
+ memberPropertyField: 'field',
36
+ });
37
+
38
+ // ─── Solidity ─────────────────────────────────────────────────────────────────
39
+ //
40
+ // Solidity function_definition: name via `childForFieldName('name')` (confirmed in extractor line 232).
41
+ // Parameters: `childForFieldName('parameters')` or findChild('parameter_list') (extractor line 355-357).
42
+ // Each parameter is a `parameter` node (extractor uses extractSimpleParameters with paramTypes: ['parameter']).
43
+ // return_statement: Solidity has explicit return.
44
+ // call_expression / function_call: both confirmed in extractor walkSolidityNode line 71-72.
45
+ // call_expression handler: `childForFieldName('function')` or `childForFieldName('callee')` (extractor line 336).
46
+ // member_expression: `childForFieldName('property')` (extractor line 342), `childForFieldName('object')` (line 343).
47
+
48
+ export const dataflowSolidity: DataflowRulesConfig = makeDataflowRules({
49
+ functionNodes: new Set(['function_definition', 'modifier_definition']),
50
+ nameField: 'name',
51
+
52
+ paramListField: 'parameters',
53
+ paramWrapperTypes: new Set(['parameter']),
54
+ paramIdentifier: 'identifier',
55
+
56
+ returnNode: 'return_statement',
57
+
58
+ callNodes: new Set(['call_expression', 'function_call']),
59
+ callFunctionField: 'function',
60
+ callArgsField: 'arguments',
61
+
62
+ memberNode: 'member_expression',
63
+ memberObjectField: 'object',
64
+ memberPropertyField: 'property',
65
+ });
@@ -0,0 +1,157 @@
1
+ import type { DataflowRulesConfig, TreeSitterNode } from '../../types.js';
2
+ import { makeDataflowRules } from '../shared.js';
3
+
4
+ // ─── C/C++ function-name extraction ──────────────────────────────────────────
5
+ //
6
+ // C/C++ function_definition nests the name inside declarators:
7
+ // function_definition
8
+ // declarator: function_declarator
9
+ // declarator: identifier | pointer_declarator | qualified_identifier | ...
10
+ // parameters: parameter_list
11
+ //
12
+ // We unwrap through common decorator wrappers to reach the bare identifier.
13
+
14
+ const DECLARATOR_WRAPPERS = new Set([
15
+ 'pointer_declarator',
16
+ 'reference_declarator',
17
+ 'array_declarator',
18
+ 'parenthesized_declarator',
19
+ 'abstract_function_declarator',
20
+ ]);
21
+
22
+ function unwrapDeclarator(node: TreeSitterNode | null): TreeSitterNode | null {
23
+ let cur = node;
24
+ while (cur && DECLARATOR_WRAPPERS.has(cur.type)) {
25
+ cur = cur.childForFieldName('declarator');
26
+ }
27
+ return cur;
28
+ }
29
+
30
+ function extractCFunctionName(node: TreeSitterNode): string | null {
31
+ const decl = node.childForFieldName('declarator');
32
+ if (!decl) return null;
33
+
34
+ // For pointer/reference-returning functions (int *foo(), T &bar()), the direct
35
+ // child is a pointer_declarator or similar wrapper — unwrap one level first.
36
+ const unwrapped = DECLARATOR_WRAPPERS.has(decl.type)
37
+ ? decl.childForFieldName('declarator')
38
+ : decl;
39
+ const funcDecl = unwrapped?.type === 'function_declarator' ? unwrapped : null;
40
+ if (!funcDecl) return null;
41
+
42
+ const inner = funcDecl.childForFieldName('declarator');
43
+ const nameNode = unwrapDeclarator(inner);
44
+ if (!nameNode) return null;
45
+
46
+ // qualified_identifier (C++ method): extract the unqualified_identifier
47
+ if (nameNode.type === 'qualified_identifier') {
48
+ const unqual =
49
+ nameNode.childForFieldName('name') ??
50
+ nameNode.namedChildren[nameNode.namedChildren.length - 1] ??
51
+ null;
52
+ return unqual?.text ?? null;
53
+ }
54
+
55
+ return nameNode.type === 'identifier' || nameNode.type === 'field_identifier'
56
+ ? nameNode.text
57
+ : null;
58
+ }
59
+
60
+ // Traverse through pointer/reference/array wrappers to reach function_declarator.
61
+ function findFuncDeclarator(node: TreeSitterNode | null): TreeSitterNode | null {
62
+ if (!node) return null;
63
+ if (node.type === 'function_declarator') return node;
64
+ if (DECLARATOR_WRAPPERS.has(node.type)) {
65
+ return findFuncDeclarator(node.childForFieldName('declarator'));
66
+ }
67
+ return null;
68
+ }
69
+
70
+ // Navigate function_definition → (optional wrapper) → function_declarator → parameters.
71
+ // Needed because C/C++ params are on function_declarator, not directly on function_definition.
72
+ function getCParamListNode(funcNode: TreeSitterNode): TreeSitterNode | null {
73
+ const decl = funcNode.childForFieldName('declarator');
74
+ return findFuncDeclarator(decl)?.childForFieldName('parameters') ?? null;
75
+ }
76
+
77
+ function extractCParamName(node: TreeSitterNode): string[] | null {
78
+ if (node.type !== 'parameter_declaration') return null;
79
+ const decl = node.childForFieldName('declarator');
80
+ if (!decl) return null;
81
+
82
+ // Reference declarator (T& name, T&& name): tree-sitter-cpp uses no named
83
+ // 'declarator' field inside reference_declarator, so unwrapDeclarator would
84
+ // return null. Handle it first by taking the last named child.
85
+ if (decl.type === 'reference_declarator') {
86
+ const inner = decl.namedChild(decl.namedChildCount - 1);
87
+ if (inner?.type === 'identifier') return [inner.text];
88
+ return null;
89
+ }
90
+
91
+ const nameNode = unwrapDeclarator(decl);
92
+ if (!nameNode) return null;
93
+ if (nameNode.type === 'identifier') return [nameNode.text];
94
+ return null;
95
+ }
96
+
97
+ // ─── C Dataflow rules ─────────────────────────────────────────────────────────
98
+
99
+ export const dataflow: DataflowRulesConfig = makeDataflowRules({
100
+ functionNodes: new Set(['function_definition']),
101
+ nameField: 'declarator',
102
+ nameExtractor: extractCFunctionName,
103
+
104
+ paramListField: 'parameters',
105
+ getParamListNode: getCParamListNode,
106
+ paramIdentifier: 'identifier',
107
+ paramWrapperTypes: new Set(['parameter_declaration']),
108
+ extractParamName: extractCParamName,
109
+
110
+ returnNode: 'return_statement',
111
+
112
+ varDeclaratorNode: 'init_declarator',
113
+ varNameField: 'declarator',
114
+ varValueField: 'value',
115
+
116
+ assignmentNode: 'assignment_expression',
117
+ assignLeftField: 'left',
118
+ assignRightField: 'right',
119
+
120
+ callNode: 'call_expression',
121
+ callFunctionField: 'function',
122
+ callArgsField: 'arguments',
123
+
124
+ memberNode: 'field_expression',
125
+ memberObjectField: 'argument',
126
+ memberPropertyField: 'field',
127
+
128
+ expressionStmtNode: 'expression_statement',
129
+ mutatingMethods: new Set(),
130
+ });
131
+
132
+ // C++ extends C with additional function node types
133
+ export const dataflowCpp: DataflowRulesConfig = makeDataflowRules({
134
+ ...dataflow,
135
+ functionNodes: new Set([
136
+ 'function_definition',
137
+ // function_declaration is a forward declaration (no body) in tree-sitter-cpp;
138
+ // including it creates spurious param vertices from prototypes and can overwrite
139
+ // correct dataflow_summary rows with flows_to_return=0 when the declaration is
140
+ // processed after the definition.
141
+ ]),
142
+ // C++ call expressions can use :: scope resolution
143
+ mutatingMethods: new Set([
144
+ 'push_back',
145
+ 'push_front',
146
+ 'insert',
147
+ 'erase',
148
+ 'clear',
149
+ 'resize',
150
+ 'reserve',
151
+ 'emplace',
152
+ 'emplace_back',
153
+ 'emplace_front',
154
+ 'append',
155
+ 'assign',
156
+ ]),
157
+ });
@@ -4,6 +4,11 @@ import type {
4
4
  DataflowRulesConfig,
5
5
  HalsteadRules,
6
6
  } from '../../types.js';
7
+ import * as b2 from './b2.js';
8
+ import * as b3 from './b3.js';
9
+ import * as b4 from './b4.js';
10
+ import * as b5 from './b5.js';
11
+ import * as c from './c.js';
7
12
  import * as csharp from './csharp.js';
8
13
  import * as go from './go.js';
9
14
  import * as java from './java.js';
@@ -71,6 +76,35 @@ export const DATAFLOW_RULES: Map<string, DataflowRulesConfig> = new Map([
71
76
  ['csharp', csharp.dataflow],
72
77
  ['php', php.dataflow],
73
78
  ['ruby', ruby.dataflow],
79
+ // P5 Batch B1: C-family languages
80
+ ['c', c.dataflow],
81
+ ['cpp', c.dataflowCpp],
82
+ ['objc', c.dataflow], // ObjC C-compatible functions; ObjC methods TODO
83
+ ['cuda', c.dataflowCpp], // CUDA inherits C++ grammar
84
+ // P5 Batch B2: JVM/mobile languages
85
+ ['kotlin', b2.dataflowKotlin],
86
+ ['swift', b2.dataflowSwift],
87
+ ['scala', b2.dataflowScala],
88
+ ['dart', b2.dataflowDart],
89
+ ['groovy', b2.dataflowGroovy],
90
+ // P5 Batch B3: scripting/dynamic languages
91
+ ['lua', b3.dataflowLua],
92
+ ['r', b3.dataflowR],
93
+ ['julia', b3.dataflowJulia],
94
+ ['bash', b3.dataflowBash],
95
+ // P5 Batch B4: functional languages
96
+ ['haskell', b4.dataflowHaskell],
97
+ ['ocaml', b4.dataflowOCaml],
98
+ ['ocaml-interface', b4.dataflowOCaml],
99
+ ['fsharp', b4.dataflowFSharp],
100
+ ['fsharp-signature', b4.dataflowFSharp],
101
+ ['gleam', b4.dataflowGleam],
102
+ ['elixir', b4.dataflowElixir],
103
+ ['erlang', b4.dataflowErlang],
104
+ ['clojure', b4.dataflowClojure],
105
+ // P5 Batch B5: systems/blockchain languages
106
+ ['zig', b5.dataflowZig],
107
+ ['solidity', b5.dataflowSolidity],
74
108
  ]);
75
109
 
76
110
  // ─── AST Node Type Maps ──────────────────────────────────────────────────
@@ -212,6 +212,9 @@ export const dataflow: DataflowRulesConfig = makeDataflowRules({
212
212
  'arrow_function',
213
213
  'function_expression',
214
214
  'function',
215
+ // Generator functions — tree-sitter-javascript produces separate node types for these
216
+ 'generator_function_declaration',
217
+ 'generator_function',
215
218
  ]),
216
219
  varAssignedFnParent: 'variable_declarator',
217
220
  assignmentFnParent: 'assignment_expression',
@@ -80,12 +80,14 @@ export const DATAFLOW_DEFAULTS: DataflowRulesConfig = {
80
80
 
81
81
  // Function name extraction
82
82
  nameField: 'name',
83
+ nameExtractor: null, // override for languages with nested name structures (C/C++)
83
84
  varAssignedFnParent: null, // parent type for `const fn = ...` (JS only)
84
85
  assignmentFnParent: null, // parent type for `x = function...` (JS only)
85
86
  pairFnParent: null, // parent type for `{ key: function }` (JS only)
86
87
 
87
88
  // Parameters
88
89
  paramListField: 'parameters',
90
+ getParamListNode: null, // override for nested param lists (C/C++: function_definition→declarator→parameters)
89
91
  paramIdentifier: 'identifier',
90
92
  paramWrapperTypes: new Set(),
91
93
  defaultParamType: null,