@lzehrung/codegraph 3.0.1 → 3.1.1

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 (684) hide show
  1. package/README.md +17 -17
  2. package/codegraph-skill/codegraph/SKILL.md +6 -2
  3. package/dist/agent/artifact.d.ts.map +1 -1
  4. package/dist/agent/artifact.js +4 -9
  5. package/dist/agent/artifact.js.map +1 -1
  6. package/dist/agent/call-hierarchy.d.ts +4 -2
  7. package/dist/agent/call-hierarchy.d.ts.map +1 -1
  8. package/dist/agent/call-hierarchy.js +20 -29
  9. package/dist/agent/call-hierarchy.js.map +1 -1
  10. package/dist/agent/explain.d.ts.map +1 -1
  11. package/dist/agent/explain.js +24 -18
  12. package/dist/agent/explain.js.map +1 -1
  13. package/dist/agent/explore.d.ts.map +1 -1
  14. package/dist/agent/explore.js +2 -11
  15. package/dist/agent/explore.js.map +1 -1
  16. package/dist/agent/file-view.d.ts.map +1 -1
  17. package/dist/agent/file-view.js +4 -12
  18. package/dist/agent/file-view.js.map +1 -1
  19. package/dist/agent/normalize.d.ts +0 -3
  20. package/dist/agent/normalize.d.ts.map +1 -1
  21. package/dist/agent/normalize.js +1 -7
  22. package/dist/agent/normalize.js.map +1 -1
  23. package/dist/agent/orient.d.ts.map +1 -1
  24. package/dist/agent/orient.js +2 -6
  25. package/dist/agent/orient.js.map +1 -1
  26. package/dist/agent/packet.d.ts.map +1 -1
  27. package/dist/agent/packet.js +2 -5
  28. package/dist/agent/packet.js.map +1 -1
  29. package/dist/agent/query-index/content.d.ts.map +1 -1
  30. package/dist/agent/query-index/content.js +2 -6
  31. package/dist/agent/query-index/content.js.map +1 -1
  32. package/dist/agent/query-index/update.d.ts.map +1 -1
  33. package/dist/agent/query-index/update.js +8 -45
  34. package/dist/agent/query-index/update.js.map +1 -1
  35. package/dist/agent/query-index/worker-pool.d.ts.map +1 -1
  36. package/dist/agent/query-index/worker-pool.js +2 -1
  37. package/dist/agent/query-index/worker-pool.js.map +1 -1
  38. package/dist/agent/refactor-plan.d.ts +2 -2
  39. package/dist/agent/refactor-plan.d.ts.map +1 -1
  40. package/dist/agent/refactor-plan.js +11 -57
  41. package/dist/agent/refactor-plan.js.map +1 -1
  42. package/dist/agent/rename-preview.d.ts.map +1 -1
  43. package/dist/agent/rename-preview.js +166 -23
  44. package/dist/agent/rename-preview.js.map +1 -1
  45. package/dist/agent/search.d.ts +13 -0
  46. package/dist/agent/search.d.ts.map +1 -1
  47. package/dist/agent/search.js +17 -26
  48. package/dist/agent/search.js.map +1 -1
  49. package/dist/agent/semantic-symbols.d.ts +1 -1
  50. package/dist/agent/semantic-symbols.d.ts.map +1 -1
  51. package/dist/agent/semantic-symbols.js +2 -5
  52. package/dist/agent/semantic-symbols.js.map +1 -1
  53. package/dist/agent/semantic.d.ts +5 -0
  54. package/dist/agent/semantic.d.ts.map +1 -1
  55. package/dist/agent/semantic.js +12 -1
  56. package/dist/agent/semantic.js.map +1 -1
  57. package/dist/agent/session.d.ts +9 -0
  58. package/dist/agent/session.d.ts.map +1 -1
  59. package/dist/agent/session.js +59 -41
  60. package/dist/agent/session.js.map +1 -1
  61. package/dist/agent/type-hierarchy.d.ts +4 -2
  62. package/dist/agent/type-hierarchy.d.ts.map +1 -1
  63. package/dist/agent/type-hierarchy.js +19 -31
  64. package/dist/agent/type-hierarchy.js.map +1 -1
  65. package/dist/agent/workspace-symbols.d.ts +1 -1
  66. package/dist/agent/workspace-symbols.d.ts.map +1 -1
  67. package/dist/agent/workspace-symbols.js +7 -15
  68. package/dist/agent/workspace-symbols.js.map +1 -1
  69. package/dist/analysis-summary.d.ts +1 -4
  70. package/dist/analysis-summary.d.ts.map +1 -1
  71. package/dist/analysis-summary.js +58 -19
  72. package/dist/analysis-summary.js.map +1 -1
  73. package/dist/bin/cli.js +41060 -27641
  74. package/dist/bin/query-index-worker.js +268 -241
  75. package/dist/bootstrap/tree-sitter-languages.d.ts +2 -0
  76. package/dist/bootstrap/tree-sitter-languages.d.ts.map +1 -1
  77. package/dist/bootstrap/tree-sitter-languages.js +6 -19
  78. package/dist/bootstrap/tree-sitter-languages.js.map +1 -1
  79. package/dist/chunking/chunk-matches.d.ts.map +1 -1
  80. package/dist/chunking/chunk-matches.js +6 -42
  81. package/dist/chunking/chunk-matches.js.map +1 -1
  82. package/dist/chunking/chunk-split.d.ts +7 -0
  83. package/dist/chunking/chunk-split.d.ts.map +1 -1
  84. package/dist/chunking/chunk-split.js +3 -3
  85. package/dist/chunking/chunk-split.js.map +1 -1
  86. package/dist/chunking/chunk-text-file.js +2 -30
  87. package/dist/chunking/chunk-text-file.js.map +1 -1
  88. package/dist/cli/affected.d.ts.map +1 -1
  89. package/dist/cli/affected.js +1 -9
  90. package/dist/cli/affected.js.map +1 -1
  91. package/dist/cli/call-hierarchy.js +3 -6
  92. package/dist/cli/call-hierarchy.js.map +1 -1
  93. package/dist/cli/chunk.d.ts.map +1 -1
  94. package/dist/cli/chunk.js +4 -11
  95. package/dist/cli/chunk.js.map +1 -1
  96. package/dist/cli/command-table.d.ts.map +1 -1
  97. package/dist/cli/command-table.js +7 -0
  98. package/dist/cli/command-table.js.map +1 -1
  99. package/dist/cli/context.d.ts +1 -0
  100. package/dist/cli/context.d.ts.map +1 -1
  101. package/dist/cli/context.js +1 -1
  102. package/dist/cli/context.js.map +1 -1
  103. package/dist/cli/doctor.d.ts.map +1 -1
  104. package/dist/cli/doctor.js +1 -11
  105. package/dist/cli/doctor.js.map +1 -1
  106. package/dist/cli/duplicates.d.ts +5 -0
  107. package/dist/cli/duplicates.d.ts.map +1 -1
  108. package/dist/cli/duplicates.js +15 -2
  109. package/dist/cli/duplicates.js.map +1 -1
  110. package/dist/cli/graph.d.ts +4 -12
  111. package/dist/cli/graph.d.ts.map +1 -1
  112. package/dist/cli/graph.js +17 -8
  113. package/dist/cli/graph.js.map +1 -1
  114. package/dist/cli/help.d.ts +4 -4
  115. package/dist/cli/help.d.ts.map +1 -1
  116. package/dist/cli/help.js +17 -9
  117. package/dist/cli/help.js.map +1 -1
  118. package/dist/cli/index.d.ts +2 -12
  119. package/dist/cli/index.d.ts.map +1 -1
  120. package/dist/cli/index.js +2 -5
  121. package/dist/cli/index.js.map +1 -1
  122. package/dist/cli/links.d.ts.map +1 -1
  123. package/dist/cli/links.js +4 -10
  124. package/dist/cli/links.js.map +1 -1
  125. package/dist/cli/mcp.d.ts.map +1 -1
  126. package/dist/cli/mcp.js +5 -0
  127. package/dist/cli/mcp.js.map +1 -1
  128. package/dist/cli/module-locals.d.ts +8 -0
  129. package/dist/cli/module-locals.d.ts.map +1 -0
  130. package/dist/cli/module-locals.js +9 -0
  131. package/dist/cli/module-locals.js.map +1 -0
  132. package/dist/cli/navigation.d.ts +2 -0
  133. package/dist/cli/navigation.d.ts.map +1 -1
  134. package/dist/cli/navigation.js +3 -5
  135. package/dist/cli/navigation.js.map +1 -1
  136. package/dist/cli/options.d.ts.map +1 -1
  137. package/dist/cli/options.js +6 -1
  138. package/dist/cli/options.js.map +1 -1
  139. package/dist/cli/pretty.d.ts +1 -0
  140. package/dist/cli/pretty.d.ts.map +1 -1
  141. package/dist/cli/pretty.js +6 -8
  142. package/dist/cli/pretty.js.map +1 -1
  143. package/dist/cli/progress.d.ts.map +1 -1
  144. package/dist/cli/progress.js +42 -16
  145. package/dist/cli/progress.js.map +1 -1
  146. package/dist/cli/refactor-plan.js +2 -5
  147. package/dist/cli/refactor-plan.js.map +1 -1
  148. package/dist/cli/rename-preview.js +2 -5
  149. package/dist/cli/rename-preview.js.map +1 -1
  150. package/dist/cli/review.d.ts +6 -16
  151. package/dist/cli/review.d.ts.map +1 -1
  152. package/dist/cli/review.js +2 -0
  153. package/dist/cli/review.js.map +1 -1
  154. package/dist/cli/server.d.ts.map +1 -1
  155. package/dist/cli/server.js +9 -10
  156. package/dist/cli/server.js.map +1 -1
  157. package/dist/cli/type-hierarchy.js +8 -8
  158. package/dist/cli/type-hierarchy.js.map +1 -1
  159. package/dist/cli/viewer.js +1 -1
  160. package/dist/cli/viewer.js.map +1 -1
  161. package/dist/document-links/asciidoc.d.ts.map +1 -1
  162. package/dist/document-links/asciidoc.js +4 -16
  163. package/dist/document-links/asciidoc.js.map +1 -1
  164. package/dist/document-links/check.d.ts.map +1 -1
  165. package/dist/document-links/check.js +1 -3
  166. package/dist/document-links/check.js.map +1 -1
  167. package/dist/document-links/html.d.ts.map +1 -1
  168. package/dist/document-links/html.js +6 -44
  169. package/dist/document-links/html.js.map +1 -1
  170. package/dist/document-links/markdown.d.ts.map +1 -1
  171. package/dist/document-links/markdown.js +4 -13
  172. package/dist/document-links/markdown.js.map +1 -1
  173. package/dist/document-links/rst.d.ts.map +1 -1
  174. package/dist/document-links/rst.js +7 -31
  175. package/dist/document-links/rst.js.map +1 -1
  176. package/dist/document-links/sfc.d.ts.map +1 -1
  177. package/dist/document-links/sfc.js +2 -5
  178. package/dist/document-links/sfc.js.map +1 -1
  179. package/dist/document-links/shared.d.ts +2 -0
  180. package/dist/document-links/shared.d.ts.map +1 -1
  181. package/dist/document-links/shared.js +13 -0
  182. package/dist/document-links/shared.js.map +1 -1
  183. package/dist/drift/artifact.d.ts.map +1 -1
  184. package/dist/drift/artifact.js +4 -27
  185. package/dist/drift/artifact.js.map +1 -1
  186. package/dist/drift/git.d.ts.map +1 -1
  187. package/dist/drift/git.js +10 -2
  188. package/dist/drift/git.js.map +1 -1
  189. package/dist/drift/graph-edges.d.ts +4 -0
  190. package/dist/drift/graph-edges.d.ts.map +1 -0
  191. package/dist/drift/graph-edges.js +15 -0
  192. package/dist/drift/graph-edges.js.map +1 -0
  193. package/dist/drift/snapshot.d.ts.map +1 -1
  194. package/dist/drift/snapshot.js +2 -17
  195. package/dist/drift/snapshot.js.map +1 -1
  196. package/dist/duplicates/candidates.d.ts +61 -0
  197. package/dist/duplicates/candidates.d.ts.map +1 -0
  198. package/dist/duplicates/candidates.js +873 -0
  199. package/dist/duplicates/candidates.js.map +1 -0
  200. package/dist/duplicates/progress.d.ts +17 -0
  201. package/dist/duplicates/progress.d.ts.map +1 -0
  202. package/dist/duplicates/progress.js +57 -0
  203. package/dist/duplicates/progress.js.map +1 -0
  204. package/dist/duplicates/scoring.d.ts +9 -40
  205. package/dist/duplicates/scoring.d.ts.map +1 -1
  206. package/dist/duplicates/scoring.js +34 -414
  207. package/dist/duplicates/scoring.js.map +1 -1
  208. package/dist/duplicates/types.d.ts +30 -1
  209. package/dist/duplicates/types.d.ts.map +1 -1
  210. package/dist/duplicates/unit-cache.d.ts +11 -1
  211. package/dist/duplicates/unit-cache.d.ts.map +1 -1
  212. package/dist/duplicates/unit-cache.js +20 -2
  213. package/dist/duplicates/unit-cache.js.map +1 -1
  214. package/dist/duplicates/units.d.ts +4 -2
  215. package/dist/duplicates/units.d.ts.map +1 -1
  216. package/dist/duplicates/units.js +47 -25
  217. package/dist/duplicates/units.js.map +1 -1
  218. package/dist/duplicates.d.ts +1 -0
  219. package/dist/duplicates.d.ts.map +1 -1
  220. package/dist/duplicates.js +116 -62
  221. package/dist/duplicates.js.map +1 -1
  222. package/dist/graph-builder.d.ts +1 -1
  223. package/dist/graph-builder.d.ts.map +1 -1
  224. package/dist/graph-builder.js +3 -2
  225. package/dist/graph-builder.js.map +1 -1
  226. package/dist/graph-edge-collector.d.ts +3 -1
  227. package/dist/graph-edge-collector.d.ts.map +1 -1
  228. package/dist/graph-edge-collector.js +38 -6
  229. package/dist/graph-edge-collector.js.map +1 -1
  230. package/dist/graphs/angularjs.d.ts.map +1 -1
  231. package/dist/graphs/angularjs.js +2 -9
  232. package/dist/graphs/angularjs.js.map +1 -1
  233. package/dist/graphs/edge-resolution.d.ts +4 -0
  234. package/dist/graphs/edge-resolution.d.ts.map +1 -1
  235. package/dist/graphs/edge-resolution.js +2 -0
  236. package/dist/graphs/edge-resolution.js.map +1 -1
  237. package/dist/graphs/external/manifests.d.ts.map +1 -1
  238. package/dist/graphs/external/manifests.js +1 -6
  239. package/dist/graphs/external/manifests.js.map +1 -1
  240. package/dist/graphs/specifiers.d.ts.map +1 -1
  241. package/dist/graphs/specifiers.js +47 -26
  242. package/dist/graphs/specifiers.js.map +1 -1
  243. package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts +2 -0
  244. package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts.map +1 -1
  245. package/dist/graphs/symbol-graph-detailed/edge-passes.js +9 -3
  246. package/dist/graphs/symbol-graph-detailed/edge-passes.js.map +1 -1
  247. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts +3 -3
  248. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts.map +1 -1
  249. package/dist/graphs/symbol-graph-detailed/receiver-calls.js +2 -26
  250. package/dist/graphs/symbol-graph-detailed/receiver-calls.js.map +1 -1
  251. package/dist/graphs/symbol-graph-detailed.d.ts.map +1 -1
  252. package/dist/graphs/symbol-graph-detailed.js +38 -1
  253. package/dist/graphs/symbol-graph-detailed.js.map +1 -1
  254. package/dist/impact/analyzer.d.ts.map +1 -1
  255. package/dist/impact/analyzer.js +23 -17
  256. package/dist/impact/analyzer.js.map +1 -1
  257. package/dist/impact/budgets.d.ts.map +1 -1
  258. package/dist/impact/budgets.js +3 -9
  259. package/dist/impact/budgets.js.map +1 -1
  260. package/dist/impact/call-compatibility.d.ts.map +1 -1
  261. package/dist/impact/call-compatibility.js +3 -12
  262. package/dist/impact/call-compatibility.js.map +1 -1
  263. package/dist/impact/context.d.ts +6 -0
  264. package/dist/impact/context.d.ts.map +1 -1
  265. package/dist/impact/context.js +2 -2
  266. package/dist/impact/context.js.map +1 -1
  267. package/dist/impact/direct.d.ts.map +1 -1
  268. package/dist/impact/direct.js +2 -6
  269. package/dist/impact/direct.js.map +1 -1
  270. package/dist/impact/map.d.ts +3 -1
  271. package/dist/impact/map.d.ts.map +1 -1
  272. package/dist/impact/map.js +12 -5
  273. package/dist/impact/map.js.map +1 -1
  274. package/dist/impact/providers/base.js +1 -1
  275. package/dist/impact/providers/base.js.map +1 -1
  276. package/dist/impact/reference-cache.d.ts.map +1 -1
  277. package/dist/impact/reference-cache.js +1 -24
  278. package/dist/impact/reference-cache.js.map +1 -1
  279. package/dist/impact/report-shared.d.ts +2 -1
  280. package/dist/impact/report-shared.d.ts.map +1 -1
  281. package/dist/impact/report-shared.js +10 -0
  282. package/dist/impact/report-shared.js.map +1 -1
  283. package/dist/impact/report-suggestions.d.ts.map +1 -1
  284. package/dist/impact/report-suggestions.js +2 -8
  285. package/dist/impact/report-suggestions.js.map +1 -1
  286. package/dist/impact/report.d.ts.map +1 -1
  287. package/dist/impact/report.js +2 -8
  288. package/dist/impact/report.js.map +1 -1
  289. package/dist/impact/streaming.d.ts.map +1 -1
  290. package/dist/impact/streaming.js +3 -8
  291. package/dist/impact/streaming.js.map +1 -1
  292. package/dist/indexer/build-cache/manifest.d.ts.map +1 -1
  293. package/dist/indexer/build-cache/manifest.js +10 -108
  294. package/dist/indexer/build-cache/manifest.js.map +1 -1
  295. package/dist/indexer/build-cache/module-cache.d.ts +6 -1
  296. package/dist/indexer/build-cache/module-cache.d.ts.map +1 -1
  297. package/dist/indexer/build-cache/module-cache.js +25 -2
  298. package/dist/indexer/build-cache/module-cache.js.map +1 -1
  299. package/dist/indexer/build-cache/options.d.ts +38 -1
  300. package/dist/indexer/build-cache/options.d.ts.map +1 -1
  301. package/dist/indexer/build-cache/options.js +38 -1
  302. package/dist/indexer/build-cache/options.js.map +1 -1
  303. package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
  304. package/dist/indexer/build-cache/project-snapshot.js +48 -99
  305. package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
  306. package/dist/indexer/build-cache/reports.d.ts +1 -0
  307. package/dist/indexer/build-cache/reports.d.ts.map +1 -1
  308. package/dist/indexer/build-cache/reports.js +10 -0
  309. package/dist/indexer/build-cache/reports.js.map +1 -1
  310. package/dist/indexer/build-index.d.ts +2 -0
  311. package/dist/indexer/build-index.d.ts.map +1 -1
  312. package/dist/indexer/build-index.js +187 -57
  313. package/dist/indexer/build-index.js.map +1 -1
  314. package/dist/indexer/build-workers.d.ts +7 -1
  315. package/dist/indexer/build-workers.d.ts.map +1 -1
  316. package/dist/indexer/build-workers.js +12 -0
  317. package/dist/indexer/build-workers.js.map +1 -1
  318. package/dist/indexer/call-hierarchy.d.ts.map +1 -1
  319. package/dist/indexer/call-hierarchy.js +5 -17
  320. package/dist/indexer/call-hierarchy.js.map +1 -1
  321. package/dist/indexer/compilation-units.d.ts +32 -20
  322. package/dist/indexer/compilation-units.d.ts.map +1 -1
  323. package/dist/indexer/compilation-units.js +139 -145
  324. package/dist/indexer/compilation-units.js.map +1 -1
  325. package/dist/indexer/cpp-callables.d.ts.map +1 -1
  326. package/dist/indexer/cpp-callables.js +2 -7
  327. package/dist/indexer/cpp-callables.js.map +1 -1
  328. package/dist/indexer/import-types.d.ts +5 -0
  329. package/dist/indexer/import-types.d.ts.map +1 -1
  330. package/dist/indexer/import-types.js.map +1 -1
  331. package/dist/indexer/imports/binding-ranges.d.ts +5 -12
  332. package/dist/indexer/imports/binding-ranges.d.ts.map +1 -1
  333. package/dist/indexer/imports/binding-ranges.js +13 -19
  334. package/dist/indexer/imports/binding-ranges.js.map +1 -1
  335. package/dist/indexer/imports/context.d.ts +6 -0
  336. package/dist/indexer/imports/context.d.ts.map +1 -1
  337. package/dist/indexer/imports/import-binding-tables.d.ts +28 -13
  338. package/dist/indexer/imports/import-binding-tables.d.ts.map +1 -1
  339. package/dist/indexer/imports/import-binding-tables.js +179 -178
  340. package/dist/indexer/imports/import-binding-tables.js.map +1 -1
  341. package/dist/indexer/imports/js-text-imports.d.ts +0 -1
  342. package/dist/indexer/imports/js-text-imports.d.ts.map +1 -1
  343. package/dist/indexer/imports/js-text-imports.js +0 -176
  344. package/dist/indexer/imports/js-text-imports.js.map +1 -1
  345. package/dist/indexer/imports/language-specific.d.ts.map +1 -1
  346. package/dist/indexer/imports/language-specific.js +4 -8
  347. package/dist/indexer/imports/language-specific.js.map +1 -1
  348. package/dist/indexer/imports/python.d.ts +0 -1
  349. package/dist/indexer/imports/python.d.ts.map +1 -1
  350. package/dist/indexer/imports/python.js +1 -29
  351. package/dist/indexer/imports/python.js.map +1 -1
  352. package/dist/indexer/imports/text-import-extractors.d.ts +2 -9
  353. package/dist/indexer/imports/text-import-extractors.d.ts.map +1 -1
  354. package/dist/indexer/imports/text-import-extractors.js +0 -284
  355. package/dist/indexer/imports/text-import-extractors.js.map +1 -1
  356. package/dist/indexer/imports.d.ts +15 -0
  357. package/dist/indexer/imports.d.ts.map +1 -1
  358. package/dist/indexer/imports.js +82 -44
  359. package/dist/indexer/imports.js.map +1 -1
  360. package/dist/indexer/incremental-plan.d.ts +0 -1
  361. package/dist/indexer/incremental-plan.d.ts.map +1 -1
  362. package/dist/indexer/incremental-plan.js +6 -12
  363. package/dist/indexer/incremental-plan.js.map +1 -1
  364. package/dist/indexer/name-lookup-policies/implicit-self.d.ts.map +1 -1
  365. package/dist/indexer/name-lookup-policies/implicit-self.js +25 -4
  366. package/dist/indexer/name-lookup-policies/implicit-self.js.map +1 -1
  367. package/dist/indexer/name-resolution-types.d.ts +5 -0
  368. package/dist/indexer/name-resolution-types.d.ts.map +1 -1
  369. package/dist/indexer/name-resolution.d.ts.map +1 -1
  370. package/dist/indexer/name-resolution.js +2 -0
  371. package/dist/indexer/name-resolution.js.map +1 -1
  372. package/dist/indexer/navigation-cpp.d.ts.map +1 -1
  373. package/dist/indexer/navigation-cpp.js +3 -5
  374. package/dist/indexer/navigation-cpp.js.map +1 -1
  375. package/dist/indexer/navigation-goto.d.ts +49 -3
  376. package/dist/indexer/navigation-goto.d.ts.map +1 -1
  377. package/dist/indexer/navigation-goto.js +500 -106
  378. package/dist/indexer/navigation-goto.js.map +1 -1
  379. package/dist/indexer/navigation-local.d.ts +7 -0
  380. package/dist/indexer/navigation-local.d.ts.map +1 -1
  381. package/dist/indexer/navigation-local.js +22 -2
  382. package/dist/indexer/navigation-local.js.map +1 -1
  383. package/dist/indexer/navigation-php.d.ts +0 -1
  384. package/dist/indexer/navigation-php.d.ts.map +1 -1
  385. package/dist/indexer/navigation-php.js +1 -7
  386. package/dist/indexer/navigation-php.js.map +1 -1
  387. package/dist/indexer/navigation-references.d.ts +1 -0
  388. package/dist/indexer/navigation-references.d.ts.map +1 -1
  389. package/dist/indexer/navigation-references.js +134 -23
  390. package/dist/indexer/navigation-references.js.map +1 -1
  391. package/dist/indexer/navigation-resolve.d.ts +22 -0
  392. package/dist/indexer/navigation-resolve.d.ts.map +1 -1
  393. package/dist/indexer/navigation-resolve.js +73 -8
  394. package/dist/indexer/navigation-resolve.js.map +1 -1
  395. package/dist/indexer/navigation.d.ts +4 -1
  396. package/dist/indexer/navigation.d.ts.map +1 -1
  397. package/dist/indexer/navigation.js +398 -95
  398. package/dist/indexer/navigation.js.map +1 -1
  399. package/dist/indexer/python-property-decorator.d.ts +11 -0
  400. package/dist/indexer/python-property-decorator.d.ts.map +1 -0
  401. package/dist/indexer/python-property-decorator.js +30 -0
  402. package/dist/indexer/python-property-decorator.js.map +1 -0
  403. package/dist/indexer/shared-owner-identity.d.ts +3 -1
  404. package/dist/indexer/shared-owner-identity.d.ts.map +1 -1
  405. package/dist/indexer/shared-owner-identity.js +40 -12
  406. package/dist/indexer/shared-owner-identity.js.map +1 -1
  407. package/dist/indexer/shared.d.ts +10 -0
  408. package/dist/indexer/shared.d.ts.map +1 -1
  409. package/dist/indexer/shared.js +8 -0
  410. package/dist/indexer/shared.js.map +1 -1
  411. package/dist/indexer/star-import-precedence.d.ts +5 -1
  412. package/dist/indexer/star-import-precedence.d.ts.map +1 -1
  413. package/dist/indexer/star-import-precedence.js +12 -19
  414. package/dist/indexer/star-import-precedence.js.map +1 -1
  415. package/dist/indexer/type-hierarchy.d.ts.map +1 -1
  416. package/dist/indexer/type-hierarchy.js +8 -9
  417. package/dist/indexer/type-hierarchy.js.map +1 -1
  418. package/dist/indexer/types.d.ts +49 -1
  419. package/dist/indexer/types.d.ts.map +1 -1
  420. package/dist/indexer/types.js.map +1 -1
  421. package/dist/indexer/workspace-symbols.d.ts.map +1 -1
  422. package/dist/indexer/workspace-symbols.js +3 -13
  423. package/dist/indexer/workspace-symbols.js.map +1 -1
  424. package/dist/installer/locks.d.ts +1 -0
  425. package/dist/installer/locks.d.ts.map +1 -1
  426. package/dist/installer/locks.js +4 -8
  427. package/dist/installer/locks.js.map +1 -1
  428. package/dist/installer/registry.d.ts.map +1 -1
  429. package/dist/installer/registry.js +9 -15
  430. package/dist/installer/registry.js.map +1 -1
  431. package/dist/languages/callable-arity.d.ts.map +1 -1
  432. package/dist/languages/callable-arity.js +1 -38
  433. package/dist/languages/callable-arity.js.map +1 -1
  434. package/dist/languages/definitions/csharp.d.ts.map +1 -1
  435. package/dist/languages/definitions/csharp.js +5 -13
  436. package/dist/languages/definitions/csharp.js.map +1 -1
  437. package/dist/languages/definitions/java.d.ts.map +1 -1
  438. package/dist/languages/definitions/java.js +4 -13
  439. package/dist/languages/definitions/java.js.map +1 -1
  440. package/dist/languages/definitions/kotlin.d.ts.map +1 -1
  441. package/dist/languages/definitions/kotlin.js +4 -8
  442. package/dist/languages/definitions/kotlin.js.map +1 -1
  443. package/dist/languages/definitions/python.d.ts.map +1 -1
  444. package/dist/languages/definitions/python.js +5 -3
  445. package/dist/languages/definitions/python.js.map +1 -1
  446. package/dist/languages/import-statement-parsers.d.ts +0 -30
  447. package/dist/languages/import-statement-parsers.d.ts.map +1 -1
  448. package/dist/languages/import-statement-parsers.js +1 -81
  449. package/dist/languages/import-statement-parsers.js.map +1 -1
  450. package/dist/languages/sfc.d.ts.map +1 -1
  451. package/dist/languages/sfc.js +8 -43
  452. package/dist/languages/sfc.js.map +1 -1
  453. package/dist/lifecycle/manifest.d.ts.map +1 -1
  454. package/dist/lifecycle/manifest.js +11 -29
  455. package/dist/lifecycle/manifest.js.map +1 -1
  456. package/dist/mcp/cancellation.d.ts +6 -0
  457. package/dist/mcp/cancellation.d.ts.map +1 -0
  458. package/dist/mcp/cancellation.js +11 -0
  459. package/dist/mcp/cancellation.js.map +1 -0
  460. package/dist/mcp/handlers.d.ts +54 -3
  461. package/dist/mcp/handlers.d.ts.map +1 -1
  462. package/dist/mcp/handlers.js +186 -42
  463. package/dist/mcp/handlers.js.map +1 -1
  464. package/dist/mcp/http-transport.d.ts.map +1 -1
  465. package/dist/mcp/http-transport.js +9 -2
  466. package/dist/mcp/http-transport.js.map +1 -1
  467. package/dist/mcp/index-readiness.d.ts +114 -0
  468. package/dist/mcp/index-readiness.d.ts.map +1 -0
  469. package/dist/mcp/index-readiness.js +264 -0
  470. package/dist/mcp/index-readiness.js.map +1 -0
  471. package/dist/mcp/project-watcher.d.ts +125 -0
  472. package/dist/mcp/project-watcher.d.ts.map +1 -0
  473. package/dist/mcp/project-watcher.js +643 -0
  474. package/dist/mcp/project-watcher.js.map +1 -0
  475. package/dist/mcp/protocol.d.ts.map +1 -1
  476. package/dist/mcp/protocol.js +23 -10
  477. package/dist/mcp/protocol.js.map +1 -1
  478. package/dist/mcp/server.d.ts +2 -0
  479. package/dist/mcp/server.d.ts.map +1 -1
  480. package/dist/mcp/server.js +11 -2
  481. package/dist/mcp/server.js.map +1 -1
  482. package/dist/mcp/stale-install.d.ts +13 -0
  483. package/dist/mcp/stale-install.d.ts.map +1 -0
  484. package/dist/mcp/stale-install.js +30 -0
  485. package/dist/mcp/stale-install.js.map +1 -0
  486. package/dist/native/byte-index.d.ts +1 -0
  487. package/dist/native/byte-index.d.ts.map +1 -1
  488. package/dist/native/byte-index.js +1 -1
  489. package/dist/native/byte-index.js.map +1 -1
  490. package/dist/native/contracts.d.ts +1 -0
  491. package/dist/native/contracts.d.ts.map +1 -1
  492. package/dist/native/native-backend-report.d.ts +2 -1
  493. package/dist/native/native-backend-report.d.ts.map +1 -1
  494. package/dist/native/native-backend-report.js +23 -0
  495. package/dist/native/native-backend-report.js.map +1 -1
  496. package/dist/native/tree-shape.d.ts +5 -7
  497. package/dist/native/tree-shape.d.ts.map +1 -1
  498. package/dist/native/tree-shape.js +11 -10
  499. package/dist/native/tree-shape.js.map +1 -1
  500. package/dist/presentation/bounds.d.ts +2 -0
  501. package/dist/presentation/bounds.d.ts.map +1 -1
  502. package/dist/presentation/bounds.js +8 -0
  503. package/dist/presentation/bounds.js.map +1 -1
  504. package/dist/review/candidates.d.ts.map +1 -1
  505. package/dist/review/candidates.js +4 -25
  506. package/dist/review/candidates.js.map +1 -1
  507. package/dist/review/deleted.js +1 -1
  508. package/dist/review/deleted.js.map +1 -1
  509. package/dist/review/report.d.ts.map +1 -1
  510. package/dist/review/report.js +4 -2
  511. package/dist/review/report.js.map +1 -1
  512. package/dist/review/summaries.d.ts.map +1 -1
  513. package/dist/review/summaries.js +14 -35
  514. package/dist/review/summaries.js.map +1 -1
  515. package/dist/review.d.ts +6 -0
  516. package/dist/review.d.ts.map +1 -1
  517. package/dist/review.js +5 -6
  518. package/dist/review.js.map +1 -1
  519. package/dist/scss/navigation.d.ts +13 -0
  520. package/dist/scss/navigation.d.ts.map +1 -0
  521. package/dist/scss/navigation.js +150 -0
  522. package/dist/scss/navigation.js.map +1 -0
  523. package/dist/scss/resolution.d.ts +190 -0
  524. package/dist/scss/resolution.d.ts.map +1 -0
  525. package/dist/scss/resolution.js +1802 -0
  526. package/dist/scss/resolution.js.map +1 -0
  527. package/dist/scss/syntax.d.ts +181 -0
  528. package/dist/scss/syntax.d.ts.map +1 -0
  529. package/dist/scss/syntax.js +1436 -0
  530. package/dist/scss/syntax.js.map +1 -0
  531. package/dist/sql/classify-sql-file.d.ts +7 -0
  532. package/dist/sql/classify-sql-file.d.ts.map +1 -1
  533. package/dist/sql/classify-sql-file.js +9 -0
  534. package/dist/sql/classify-sql-file.js.map +1 -1
  535. package/dist/sql/extract-facts.d.ts.map +1 -1
  536. package/dist/sql/extract-facts.js +517 -77
  537. package/dist/sql/extract-facts.js.map +1 -1
  538. package/dist/sql/lex.d.ts +100 -1
  539. package/dist/sql/lex.d.ts.map +1 -1
  540. package/dist/sql/lex.js +473 -11
  541. package/dist/sql/lex.js.map +1 -1
  542. package/dist/sql/lookup.d.ts +17 -0
  543. package/dist/sql/lookup.d.ts.map +1 -1
  544. package/dist/sql/lookup.js +21 -0
  545. package/dist/sql/lookup.js.map +1 -1
  546. package/dist/sql/navigation.d.ts +28 -1
  547. package/dist/sql/navigation.d.ts.map +1 -1
  548. package/dist/sql/navigation.js +474 -84
  549. package/dist/sql/navigation.js.map +1 -1
  550. package/dist/sql/object-mentions.d.ts +24 -0
  551. package/dist/sql/object-mentions.d.ts.map +1 -0
  552. package/dist/sql/object-mentions.js +233 -0
  553. package/dist/sql/object-mentions.js.map +1 -0
  554. package/dist/sql/review.d.ts +3 -0
  555. package/dist/sql/review.d.ts.map +1 -1
  556. package/dist/sql/review.js +15 -14
  557. package/dist/sql/review.js.map +1 -1
  558. package/dist/sql/routine-mentions.d.ts +61 -0
  559. package/dist/sql/routine-mentions.d.ts.map +1 -0
  560. package/dist/sql/routine-mentions.js +868 -0
  561. package/dist/sql/routine-mentions.js.map +1 -0
  562. package/dist/sql/source-graph.d.ts +18 -3
  563. package/dist/sql/source-graph.d.ts.map +1 -1
  564. package/dist/sql/source-graph.js +109 -32
  565. package/dist/sql/source-graph.js.map +1 -1
  566. package/dist/sqlite/raw-query-worker-pool.d.ts.map +1 -1
  567. package/dist/sqlite/raw-query-worker-pool.js +2 -0
  568. package/dist/sqlite/raw-query-worker-pool.js.map +1 -1
  569. package/dist/sqlite/types.d.ts +6 -5
  570. package/dist/sqlite/types.d.ts.map +1 -1
  571. package/dist/sqlite/write.d.ts.map +1 -1
  572. package/dist/sqlite/write.js.map +1 -1
  573. package/dist/sqlite-driver.d.ts +0 -1
  574. package/dist/sqlite-driver.d.ts.map +1 -1
  575. package/dist/sqlite-driver.js +0 -11
  576. package/dist/sqlite-driver.js.map +1 -1
  577. package/dist/terraform/navigation.d.ts.map +1 -1
  578. package/dist/terraform/navigation.js +1 -3
  579. package/dist/terraform/navigation.js.map +1 -1
  580. package/dist/terraform/syntax.d.ts.map +1 -1
  581. package/dist/terraform/syntax.js +1 -4
  582. package/dist/terraform/syntax.js.map +1 -1
  583. package/dist/types.d.ts +2 -0
  584. package/dist/types.d.ts.map +1 -1
  585. package/dist/util/ast.d.ts +5 -0
  586. package/dist/util/ast.d.ts.map +1 -1
  587. package/dist/util/ast.js +10 -0
  588. package/dist/util/ast.js.map +1 -1
  589. package/dist/util/atomic-file.d.ts +22 -0
  590. package/dist/util/atomic-file.d.ts.map +1 -0
  591. package/dist/util/atomic-file.js +106 -0
  592. package/dist/util/atomic-file.js.map +1 -0
  593. package/dist/util/collections.d.ts +5 -0
  594. package/dist/util/collections.d.ts.map +1 -1
  595. package/dist/util/collections.js +26 -0
  596. package/dist/util/collections.js.map +1 -1
  597. package/dist/util/concurrency.d.ts +8 -0
  598. package/dist/util/concurrency.d.ts.map +1 -1
  599. package/dist/util/concurrency.js +16 -0
  600. package/dist/util/concurrency.js.map +1 -1
  601. package/dist/util/confined-file.d.ts.map +1 -1
  602. package/dist/util/confined-file.js +1 -3
  603. package/dist/util/confined-file.js.map +1 -1
  604. package/dist/util/csharp-tree.d.ts +65 -0
  605. package/dist/util/csharp-tree.d.ts.map +1 -0
  606. package/dist/util/csharp-tree.js +266 -0
  607. package/dist/util/csharp-tree.js.map +1 -0
  608. package/dist/util/errors.d.ts +1 -0
  609. package/dist/util/errors.d.ts.map +1 -1
  610. package/dist/util/errors.js +3 -0
  611. package/dist/util/errors.js.map +1 -1
  612. package/dist/util/graph-edges.d.ts +2 -0
  613. package/dist/util/graph-edges.d.ts.map +1 -1
  614. package/dist/util/graph-edges.js +11 -0
  615. package/dist/util/graph-edges.js.map +1 -1
  616. package/dist/util/guards.d.ts +1 -0
  617. package/dist/util/guards.d.ts.map +1 -1
  618. package/dist/util/guards.js +6 -0
  619. package/dist/util/guards.js.map +1 -1
  620. package/dist/util/identifiers.d.ts +0 -24
  621. package/dist/util/identifiers.d.ts.map +1 -1
  622. package/dist/util/identifiers.js +0 -24
  623. package/dist/util/identifiers.js.map +1 -1
  624. package/dist/util/jvm-tree.d.ts +58 -0
  625. package/dist/util/jvm-tree.d.ts.map +1 -0
  626. package/dist/util/jvm-tree.js +153 -0
  627. package/dist/util/jvm-tree.js.map +1 -0
  628. package/dist/util/package-exports.d.ts +0 -22
  629. package/dist/util/package-exports.d.ts.map +1 -1
  630. package/dist/util/package-exports.js +25 -5
  631. package/dist/util/package-exports.js.map +1 -1
  632. package/dist/util/paths.d.ts +1 -0
  633. package/dist/util/paths.d.ts.map +1 -1
  634. package/dist/util/paths.js +10 -4
  635. package/dist/util/paths.js.map +1 -1
  636. package/dist/util/resolution/csharp.d.ts +20 -8
  637. package/dist/util/resolution/csharp.d.ts.map +1 -1
  638. package/dist/util/resolution/csharp.js +126 -127
  639. package/dist/util/resolution/csharp.js.map +1 -1
  640. package/dist/util/resolution/files.d.ts +6 -0
  641. package/dist/util/resolution/files.d.ts.map +1 -1
  642. package/dist/util/resolution/files.js +74 -21
  643. package/dist/util/resolution/files.js.map +1 -1
  644. package/dist/util/resolution/jvm.d.ts +21 -1
  645. package/dist/util/resolution/jvm.d.ts.map +1 -1
  646. package/dist/util/resolution/jvm.js +168 -100
  647. package/dist/util/resolution/jvm.js.map +1 -1
  648. package/dist/util/resolution/project-symbols.d.ts +1 -1
  649. package/dist/util/resolution/project-symbols.d.ts.map +1 -1
  650. package/dist/util/resolution/project-symbols.js.map +1 -1
  651. package/dist/util/resolution/specifier-targets.d.ts +4 -0
  652. package/dist/util/resolution/specifier-targets.d.ts.map +1 -1
  653. package/dist/util/resolution/specifier-targets.js +11 -3
  654. package/dist/util/resolution/specifier-targets.js.map +1 -1
  655. package/dist/util/resolution.d.ts.map +1 -1
  656. package/dist/util/resolution.js +21 -7
  657. package/dist/util/resolution.js.map +1 -1
  658. package/dist/util/syntax-tree.d.ts +16 -0
  659. package/dist/util/syntax-tree.d.ts.map +1 -0
  660. package/dist/util/syntax-tree.js +34 -0
  661. package/dist/util/syntax-tree.js.map +1 -0
  662. package/dist/util/text-scanning.d.ts +6 -0
  663. package/dist/util/text-scanning.d.ts.map +1 -0
  664. package/dist/util/text-scanning.js +35 -0
  665. package/dist/util/text-scanning.js.map +1 -0
  666. package/dist/util/trivia-tables.d.ts +13 -8
  667. package/dist/util/trivia-tables.d.ts.map +1 -1
  668. package/dist/util/trivia-tables.js +13 -72
  669. package/dist/util/trivia-tables.js.map +1 -1
  670. package/dist/util/trivia.d.ts +10 -3
  671. package/dist/util/trivia.d.ts.map +1 -1
  672. package/dist/util/trivia.js +209 -79
  673. package/dist/util/trivia.js.map +1 -1
  674. package/dist/util/windows-process-drain.d.ts.map +1 -1
  675. package/dist/util/windows-process-drain.js.map +1 -1
  676. package/dist/util/worker-threads.d.ts +16 -0
  677. package/dist/util/worker-threads.d.ts.map +1 -1
  678. package/dist/util/worker-threads.js +118 -0
  679. package/dist/util/worker-threads.js.map +1 -1
  680. package/dist/worker/native-worker-pool.d.ts.map +1 -1
  681. package/dist/worker/native-worker-pool.js +2 -1
  682. package/dist/worker/native-worker-pool.js.map +1 -1
  683. package/docs/mcp.md +82 -8
  684. package/package.json +7 -7
@@ -1,8 +1,10 @@
1
1
  import { collectLineStartOffsets } from "../util/lines.js";
2
2
  import { normalizePath } from "../util/paths.js";
3
3
  import { classifySqlFile } from "./classify-sql-file.js";
4
- import { createSqlObjectNameRegExp, maskSqlStringsAndComments, normalizeSqlObjectName, SQL_OBJECT_NAME_PATTERN, splitTopLevelCommaSeparated, sqlParenDepthAt, } from "./lex.js";
4
+ import { atForward, createSqlObjectNameRegExp, isBareSqlKeyword, maskSqlQuotedIdentifiers, maskSqlStringsAndComments, normalizeSqlObjectName, sqlObjectLookupKey, SQL_OBJECT_NAME_PATTERN, splitTopLevelCommaSeparated, sqlParenDepthAt, sqlMatchingParen as findMatchingParen, sqlQueryScopes, sqlSourceClauses, sqlTriviaBoundaries, } from "./lex.js";
5
5
  import { sqlObjectLookupKeys } from "./lookup.js";
6
+ import { SQL_ROUTINE_DEFINITION_RE } from "./routine-mentions.js";
7
+ import { skipWhitespace } from "../util/text-scanning.js";
6
8
  export { maskSqlStringsAndComments, normalizeSqlObjectName, sqlObjectBaseName } from "./lex.js";
7
9
  const OBJECT_NAME_RE = createSqlObjectNameRegExp("iy");
8
10
  const SQL_KEYWORDS = new Set([
@@ -71,20 +73,339 @@ function statementSlice(source, lineStarts, start, end) {
71
73
  endIndex,
72
74
  };
73
75
  }
74
- function splitSqlStatements(source) {
76
+ /** Words that can follow END in `END LOOP` or `END CASE`. Anything else is a plain END. */
77
+ const SQL_END_FOLLOWER = new Set(["case", "for", "if", "loop", "repeat", "while"]);
78
+ function readBareWord(text, index) {
79
+ if (!/[A-Za-z_]/.test(text[index] ?? ""))
80
+ return null;
81
+ let end = index + 1;
82
+ while (/[A-Za-z0-9_$]/.test(text[end] ?? ""))
83
+ end += 1;
84
+ return { word: text.slice(index, end).toLowerCase(), end };
85
+ }
86
+ /** A bare or quoted identifier: the optional label in `END LOOP label` or `END CASE label`. */
87
+ function identifierEnd(text, index) {
88
+ const open = text[index] ?? "";
89
+ if (open === '"' || open === "`" || open === "[") {
90
+ const close = open === "[" ? "]" : open;
91
+ let cursor = index + 1;
92
+ while (cursor < text.length) {
93
+ if ((text[cursor] ?? "") !== close) {
94
+ cursor += 1;
95
+ continue;
96
+ }
97
+ if ((text[cursor + 1] ?? "") === close) {
98
+ cursor += 2;
99
+ continue;
100
+ }
101
+ return cursor + 1;
102
+ }
103
+ return null;
104
+ }
105
+ if (!/[A-Za-z_]/.test(open))
106
+ return null;
107
+ let end = index + 1;
108
+ while (/[A-Za-z0-9_$]/.test(text[end] ?? ""))
109
+ end += 1;
110
+ return end;
111
+ }
112
+ /** `;`, or no further significant token, completes `END LOOP [label]` and `END CASE [label]`. */
113
+ function finishesCompound(text, index, trivia) {
114
+ const next = atForward(trivia, index);
115
+ return next >= text.length || (text[next] ?? "") === ";";
116
+ }
117
+ /** `GO` on its own line is a batch separator, not the label of an `END LOOP`. */
118
+ function isOwnLineGo(text, index) {
119
+ if (readBareWord(text, index)?.word !== "go")
120
+ return false;
121
+ let lineStart = index;
122
+ while (lineStart > 0 && (text[lineStart - 1] ?? "") !== "\n")
123
+ lineStart -= 1;
124
+ return /^[\t ]*go(?:[\t ]*(?:--[^\r\n]*)?)?(?:\r?\n|$)/i.test(text.slice(lineStart));
125
+ }
126
+ /**
127
+ * `END CASE` closes a CASE wherever it sits. `END IF|LOOP|WHILE|REPEAT|FOR` closes nothing
128
+ * only when the innermost frame is BEGIN or the stack is empty. An open CASE makes the same
129
+ * words the end of that expression: `END loop` is an alias, and `END FOR UPDATE` is a clause.
130
+ */
131
+ function compoundEndAction(keyword, innermost) {
132
+ if (keyword === "case")
133
+ return "case";
134
+ if (innermost === "case")
135
+ return "close";
136
+ return "noop";
137
+ }
138
+ /**
139
+ * `END CASE [label]` then `;` or the end of the text closes the innermost CASE. The same shape of
140
+ * `END IF|LOOP|WHILE|REPEAT|FOR [label]` closes nothing when the innermost frame is BEGIN or the
141
+ * stack is empty, and closes the CASE when that is the innermost frame. Any other END, including
142
+ * T-SQL `END IF @x` with no semicolon after IF, closes the innermost frame. The returned index
143
+ * stops before the semicolon so the statement scan can still split on it.
144
+ */
145
+ function classifyEnd(text, endWordEnd, trivia, innermost) {
146
+ const close = { action: "close", resume: endWordEnd };
147
+ const keywordAt = atForward(trivia, endWordEnd);
148
+ if (isOwnLineGo(text, keywordAt))
149
+ return close;
150
+ const keyword = readBareWord(text, keywordAt);
151
+ if (!keyword || !SQL_END_FOLLOWER.has(keyword.word))
152
+ return close;
153
+ if (!isBareSqlKeyword(text, keywordAt, keyword.end, trivia))
154
+ return close;
155
+ const action = compoundEndAction(keyword.word, innermost);
156
+ if (finishesCompound(text, keyword.end, trivia)) {
157
+ return { action, resume: keyword.end };
158
+ }
159
+ const labelAt = atForward(trivia, keyword.end);
160
+ if (isOwnLineGo(text, labelAt))
161
+ return close;
162
+ const labelEnd = identifierEnd(text, labelAt);
163
+ if (labelEnd === null || !finishesCompound(text, labelEnd, trivia))
164
+ return close;
165
+ return { action, resume: labelEnd };
166
+ }
167
+ function closeInnermostCase(stack) {
168
+ for (let index = stack.length - 1; index >= 0; index -= 1) {
169
+ if (stack[index] !== "case")
170
+ continue;
171
+ stack.length = index;
172
+ return;
173
+ }
174
+ }
175
+ /**
176
+ * Bare BEGIN and bare CASE open a frame. The bare-keyword check, using this scan's trivia
177
+ * table, leaves `t.case`, `@case`, a quoted name, and `CASE .5` as ordinary tokens.
178
+ */
179
+ function advanceSqlBlockWord(text, index, stack, trivia) {
180
+ const read = readBareWord(text, index);
181
+ if (!read)
182
+ return index + 1;
183
+ if (!isBareSqlKeyword(text, index, read.end, trivia))
184
+ return read.end;
185
+ if (read.word === "begin" || read.word === "case") {
186
+ stack.push(read.word);
187
+ return read.end;
188
+ }
189
+ if (read.word !== "end")
190
+ return read.end;
191
+ const classified = classifyEnd(text, read.end, trivia, stack[stack.length - 1]);
192
+ if (classified.action === "case")
193
+ closeInnermostCase(stack);
194
+ else if (classified.action === "close")
195
+ stack.pop();
196
+ return classified.resume;
197
+ }
198
+ /** MySQL allows one compound statement, with no BEGIN, as the body of a routine. */
199
+ const COMPOUND_BODY_WORDS = new Set(["case", "if", "loop", "repeat", "while"]);
200
+ /**
201
+ * Words that can sit between the parameter list and that body: `RETURNS integer`,
202
+ * `DETERMINISTIC`, `LANGUAGE SQL`, and the other MySQL characteristics.
203
+ */
204
+ const ROUTINE_CHARACTERISTICS = new Set([
205
+ "comment",
206
+ "contains",
207
+ "data",
208
+ "definer",
209
+ "deterministic",
210
+ "invoker",
211
+ "modifies",
212
+ "no",
213
+ "not",
214
+ "null",
215
+ "reads",
216
+ "security",
217
+ "sql",
218
+ ]);
219
+ /** A nested compound of the same keyword starts after one of these, or after a semicolon. */
220
+ const COMPOUND_NEST_WORDS = new Set(["begin", "do", "else", "elseif", "loop", "repeat", "then"]);
221
+ /** Words that mean the body is not a bare compound statement. */
222
+ const ROUTINE_BODY_STOP = new Set([
223
+ "as",
224
+ "begin",
225
+ "call",
226
+ "declare",
227
+ "delete",
228
+ "insert",
229
+ "perform",
230
+ "return",
231
+ "select",
232
+ "update",
233
+ ]);
234
+ /**
235
+ * When a CREATE PROCEDURE or FUNCTION has a parameter list and the next bare token, after
236
+ * characteristics, is IF, LOOP, REPEAT, WHILE, or CASE, `depth` counts that keyword only.
237
+ * `END` plus the same keyword closes one level. Null when this routine has no such body.
238
+ */
239
+ function scanRoutineCompound(code, trivia, start, end) {
240
+ let phase = "start";
241
+ let paramDepth = 0;
242
+ let typeDepth = 0;
243
+ let keyword = "";
244
+ let keywordEnd = -1;
245
+ let depth = 0;
246
+ let prevWord = "";
247
+ let prevWasSemi = false;
248
+ let index = start;
249
+ while (index < end) {
250
+ const char = code[index] ?? "";
251
+ if (char === "(") {
252
+ if (phase === "name" || phase === "after-name") {
253
+ phase = "params";
254
+ paramDepth = 1;
255
+ }
256
+ else if (phase === "params")
257
+ paramDepth += 1;
258
+ else if (phase === "type")
259
+ typeDepth += 1;
260
+ index += 1;
261
+ continue;
262
+ }
263
+ if (char === ")") {
264
+ if (phase === "params" && paramDepth > 0) {
265
+ paramDepth -= 1;
266
+ if (paramDepth === 0)
267
+ phase = "chars";
268
+ }
269
+ else if (phase === "type" && typeDepth > 0)
270
+ typeDepth -= 1;
271
+ index += 1;
272
+ continue;
273
+ }
274
+ if (char === ";") {
275
+ prevWasSemi = true;
276
+ prevWord = "";
277
+ index += 1;
278
+ continue;
279
+ }
280
+ if (char === "." && phase === "after-name") {
281
+ phase = "name";
282
+ index += 1;
283
+ continue;
284
+ }
285
+ if (!/[A-Za-z_]/.test(char)) {
286
+ index += 1;
287
+ continue;
288
+ }
289
+ const read = readBareWord(code, index);
290
+ if (!read) {
291
+ index += 1;
292
+ continue;
293
+ }
294
+ if (phase === "name") {
295
+ phase = "after-name";
296
+ index = read.end;
297
+ continue;
298
+ }
299
+ if (!isBareSqlKeyword(code, index, read.end, trivia)) {
300
+ index = read.end;
301
+ continue;
302
+ }
303
+ const word = read.word;
304
+ index = read.end;
305
+ if (phase === "params")
306
+ continue;
307
+ if (phase === "language") {
308
+ phase = "chars";
309
+ prevWord = word;
310
+ prevWasSemi = false;
311
+ continue;
312
+ }
313
+ if (phase === "type" && typeDepth > 0)
314
+ continue;
315
+ if (phase === "chars" || phase === "type") {
316
+ if (typeDepth === 0 && COMPOUND_BODY_WORDS.has(word)) {
317
+ keyword = word;
318
+ keywordEnd = index;
319
+ depth = 1;
320
+ phase = "body";
321
+ }
322
+ else if (word === "returns")
323
+ phase = "type";
324
+ else if (word === "language")
325
+ phase = "language";
326
+ else if (ROUTINE_CHARACTERISTICS.has(word))
327
+ phase = "chars";
328
+ else if (phase === "type" && !ROUTINE_BODY_STOP.has(word)) {
329
+ // A type word: integer, unsigned, varying, precision.
330
+ }
331
+ else
332
+ return null;
333
+ prevWord = word;
334
+ prevWasSemi = false;
335
+ continue;
336
+ }
337
+ if (phase === "body") {
338
+ if (word === "end") {
339
+ const followerAt = atForward(trivia, index);
340
+ const follower = followerAt < end ? readBareWord(code, followerAt) : null;
341
+ if (follower &&
342
+ follower.end <= end &&
343
+ follower.word === keyword &&
344
+ isBareSqlKeyword(code, followerAt, follower.end, trivia)) {
345
+ depth -= 1;
346
+ index = follower.end;
347
+ prevWord = follower.word;
348
+ prevWasSemi = false;
349
+ continue;
350
+ }
351
+ }
352
+ else if (word === keyword && (prevWasSemi || COMPOUND_NEST_WORDS.has(prevWord))) {
353
+ depth += 1;
354
+ }
355
+ prevWord = word;
356
+ prevWasSemi = false;
357
+ continue;
358
+ }
359
+ if (phase === "start")
360
+ phase = word === "create" ? "create" : "start";
361
+ else if (phase === "create") {
362
+ if (word === "or")
363
+ phase = "or";
364
+ else if (word === "procedure" || word === "function")
365
+ phase = "name";
366
+ else
367
+ return null;
368
+ }
369
+ else if (phase === "or")
370
+ phase = word === "replace" ? "replace" : "start";
371
+ else if (phase === "replace")
372
+ phase = word === "procedure" || word === "function" ? "name" : "start";
373
+ if (phase === "start" || phase === "after-name")
374
+ return null;
375
+ prevWord = word;
376
+ prevWasSemi = false;
377
+ }
378
+ if (phase !== "body" || keywordEnd < 0)
379
+ return null;
380
+ return { keywordEnd, depth };
381
+ }
382
+ /**
383
+ * Splits SQL text into statements. PostgreSQL and SQL Server let a block comment hold block comments,
384
+ * which `nestedComments` reads. Without it, a block comment ends at its first closing delimiter.
385
+ */
386
+ function scanSqlStatements(source, nestedComments) {
387
+ // Block keywords use trivia boundaries from this mask, so each look is one table read.
388
+ // A dash-dash inside a quote is already blank and cannot be read as a line comment.
389
+ const masked = maskSqlStringsAndComments(source, {
390
+ nestedBlockComments: nestedComments,
391
+ escapeStrings: true,
392
+ });
393
+ const code = maskSqlQuotedIdentifiers(masked);
394
+ const trivia = sqlTriviaBoundaries(masked);
75
395
  const statements = [];
76
396
  const lineStarts = lineStartsFor(source);
77
397
  let start = 0;
78
398
  let lineStart = 0;
79
399
  let i = 0;
80
400
  let lookingForStatementStart = true;
81
- let blockDepth = 0;
401
+ const openBlocks = [];
82
402
  let singleQuoted = false;
403
+ let escapeString = false;
83
404
  let doubleQuoted = false;
84
405
  let backtickQuoted = false;
85
406
  let bracketQuoted = false;
86
407
  let lineComment = false;
87
- let blockComment = false;
408
+ let commentDepth = 0;
88
409
  let dollarQuote = null;
89
410
  const pushStatement = (end, nextStart = end + 1) => {
90
411
  const statement = statementSlice(source, lineStarts, start, end);
@@ -110,11 +431,16 @@ function splitSqlStatements(source) {
110
431
  i += 1;
111
432
  continue;
112
433
  }
113
- if (blockComment) {
434
+ if (commentDepth) {
435
+ if (nestedComments && char === "/" && next === "*") {
436
+ commentDepth += 1;
437
+ i += 2;
438
+ continue;
439
+ }
114
440
  if (char === "*" && next === "/") {
115
- blockComment = false;
441
+ commentDepth -= 1;
116
442
  i += 2;
117
- if (lookingForStatementStart) {
443
+ if (!commentDepth && lookingForStatementStart) {
118
444
  start = i;
119
445
  }
120
446
  continue;
@@ -122,16 +448,11 @@ function splitSqlStatements(source) {
122
448
  i += 1;
123
449
  continue;
124
450
  }
125
- if (i === lineStart &&
126
- !blockDepth &&
127
- !singleQuoted &&
128
- !doubleQuoted &&
129
- !backtickQuoted &&
130
- !bracketQuoted &&
131
- !dollarQuote) {
451
+ if (i === lineStart && !singleQuoted && !doubleQuoted && !backtickQuoted && !bracketQuoted && !dollarQuote) {
132
452
  const batchSeparator = source.slice(i).match(/^[\t ]*GO(?:[\t ]*(?:--[^\r\n]*)?)?(?:\r?\n|$)/i);
133
453
  if (batchSeparator?.[0]) {
134
454
  const nextStart = i + batchSeparator[0].length;
455
+ openBlocks.length = 0;
135
456
  pushStatement(i, nextStart);
136
457
  i = nextStart;
137
458
  lineStart = nextStart;
@@ -150,7 +471,7 @@ function splitSqlStatements(source) {
150
471
  continue;
151
472
  }
152
473
  if (char === "/" && next === "*") {
153
- blockComment = true;
474
+ commentDepth = 1;
154
475
  i += 2;
155
476
  continue;
156
477
  }
@@ -167,12 +488,18 @@ function splitSqlStatements(source) {
167
488
  continue;
168
489
  }
169
490
  if (singleQuoted) {
491
+ if (escapeString && char === "\\" && next) {
492
+ i += 2;
493
+ continue;
494
+ }
170
495
  if (char === "'" && next === "'") {
171
496
  i += 2;
172
497
  continue;
173
498
  }
174
- if (char === "'")
499
+ if (char === "'") {
175
500
  singleQuoted = false;
501
+ escapeString = false;
502
+ }
176
503
  i += 1;
177
504
  continue;
178
505
  }
@@ -204,12 +531,14 @@ function splitSqlStatements(source) {
204
531
  continue;
205
532
  }
206
533
  if (char === "/" && next === "*") {
207
- blockComment = true;
534
+ commentDepth = 1;
208
535
  i += 2;
209
536
  continue;
210
537
  }
211
538
  if (char === "'") {
212
539
  singleQuoted = true;
540
+ // Only PostgreSQL E'...' strings give backslashes special meaning.
541
+ escapeString = /[eE]/.test(source[i - 1] ?? "") && !/[\w$]/.test(source[i - 2] ?? "");
213
542
  i += 1;
214
543
  continue;
215
544
  }
@@ -237,36 +566,33 @@ function splitSqlStatements(source) {
237
566
  }
238
567
  }
239
568
  if (/[A-Za-z_]/.test(char)) {
240
- let wordEnd = i + 1;
241
- while (/[A-Za-z0-9_$]/.test(source[wordEnd] ?? "")) {
242
- wordEnd += 1;
243
- }
244
- const word = source.slice(i, wordEnd).toLowerCase();
245
- if (word === "begin")
246
- blockDepth += 1;
247
- if (word === "end" && blockDepth)
248
- blockDepth -= 1;
249
- i = wordEnd;
569
+ i = advanceSqlBlockWord(masked, i, openBlocks, trivia);
250
570
  continue;
251
571
  }
252
- if (char === ";" && !blockDepth) {
253
- pushStatement(i);
572
+ // A compound routine body stays one statement until its own END keyword. BEGIN and CASE
573
+ // frames are unchanged, and a qualified name such as t.if is not that keyword.
574
+ if (char === ";" && openBlocks.length === 0) {
575
+ const compound = scanRoutineCompound(code, trivia, start, i);
576
+ if (!compound || compound.depth <= 0)
577
+ pushStatement(i);
254
578
  }
255
579
  i += 1;
256
580
  }
257
581
  const tail = statementSlice(source, lineStarts, start, source.length);
258
582
  if (tail)
259
583
  statements.push(tail);
260
- return statements;
584
+ return { statements, endsInBlockComment: commentDepth > 0 };
261
585
  }
262
- const SQL_OBJECT_MODIFIERS = new Set(["lateral", "only"]);
263
- function skipWhitespace(text, index) {
264
- let nextIndex = index;
265
- while (nextIndex < text.length && /\s/.test(text[nextIndex] ?? "")) {
266
- nextIndex += 1;
267
- }
268
- return nextIndex;
586
+ /**
587
+ * PostgreSQL and SQL Server nest block comments; MySQL, SQLite, and Oracle end one at its first closing
588
+ * delimiter, and the text does not say which it is. It reads as nested unless a comment then never
589
+ * closes, which no PostgreSQL or SQL Server text does. Such text reads the way MySQL does.
590
+ */
591
+ function splitSqlStatements(source) {
592
+ const nested = scanSqlStatements(source, true);
593
+ return nested.endsInBlockComment ? scanSqlStatements(source, false).statements : nested.statements;
269
594
  }
595
+ const SQL_OBJECT_MODIFIERS = new Set(["lateral", "only"]);
270
596
  function objectAt(text, index, skipModifiers = SQL_OBJECT_MODIFIERS) {
271
597
  let cursor = skipWhitespace(text, index);
272
598
  while (cursor < text.length) {
@@ -302,41 +628,38 @@ function collectObjectsAfterKeywords(text, keywords, opts) {
302
628
  }
303
629
  return Array.from(new Set(names));
304
630
  }
305
- function clauseEndIndex(text, start) {
306
- const rest = text.slice(start);
307
- const boundary = rest.search(/\b(?:where|group\s+by|order\s+by|having|limit|offset|returning|union|intersect|except|inner\s+join|left\s+join|right\s+join|full\s+join|cross\s+join|join)\b/i);
308
- return boundary < 0 ? text.length : start + boundary;
309
- }
310
- function collectCommaSeparatedObjectsAfterKeywords(text, keywords) {
631
+ function collectReadSources(text) {
632
+ const scan = maskSqlQuotedIdentifiers(text);
633
+ const trivia = sqlTriviaBoundaries(scan);
634
+ const scopes = sqlQueryScopes(scan, trivia);
311
635
  const names = [];
312
- const keywordPattern = keywords.map((keyword) => keyword.replace(/\s+/g, String.raw `\s+`)).join("|");
313
- const re = new RegExp(String.raw `\b(?:${keywordPattern})\s+`, "gi");
314
- for (const match of text.matchAll(re)) {
315
- if (sqlParenDepthAt(text, match.index ?? 0) > 0)
316
- continue;
317
- const start = (match.index ?? 0) + match[0].length;
318
- const clause = text.slice(start, clauseEndIndex(text, start));
319
- for (const part of splitTopLevelCommaSeparated(clause)) {
320
- const name = objectAt(part, 0);
321
- if (name && !SQL_KEYWORDS.has(name.toLowerCase()))
636
+ const fromNamesByScope = new Map();
637
+ const joins = [];
638
+ for (const clause of sqlSourceClauses(scan, trivia)) {
639
+ const scope = scopes.at(clause.start);
640
+ if (clause.kind === "from" || clause.kind === "using") {
641
+ for (const part of splitTopLevelCommaSeparated(text.slice(clause.end, clause.clauseEnd))) {
642
+ const name = objectAt(part, 0);
643
+ if (!name || SQL_KEYWORDS.has(name.toLowerCase()))
644
+ continue;
322
645
  names.push(name);
646
+ const inScope = fromNamesByScope.get(scope);
647
+ if (inScope)
648
+ inScope.push(name);
649
+ else
650
+ fromNamesByScope.set(scope, [name]);
651
+ }
323
652
  }
324
- }
325
- return Array.from(new Set(names));
326
- }
327
- function findMatchingParen(text, openIndex) {
328
- let depth = 0;
329
- for (let index = openIndex; index < text.length; index += 1) {
330
- const char = text[index];
331
- if (char === "(")
332
- depth += 1;
333
- if (char === ")") {
334
- depth -= 1;
335
- if (depth === 0)
336
- return index;
653
+ else if (clause.kind === "join") {
654
+ const name = objectAt(text, clause.end);
655
+ if (name && !SQL_KEYWORDS.has(name.toLowerCase()))
656
+ joins.push({ name, scope });
337
657
  }
338
658
  }
339
- return -1;
659
+ return {
660
+ names: Array.from(new Set(names)),
661
+ joins: joins.map((join) => ({ name: join.name, scopeFromNames: fromNamesByScope.get(join.scope) ?? [] })),
662
+ };
340
663
  }
341
664
  function collectCteReads(text) {
342
665
  const names = new Set();
@@ -378,7 +701,7 @@ function createDefinitionFact(text) {
378
701
  relatedObjectName: findObjectAfter(text, /\bon\s+/i),
379
702
  };
380
703
  }
381
- const routineName = findObjectAfter(text, /\bcreate\s+(?:or\s+replace\s+)?(?:function|procedure|trigger)\s+/i);
704
+ const routineName = findObjectAfter(text, SQL_ROUTINE_DEFINITION_RE);
382
705
  if (routineName)
383
706
  return { kind: "defines_routine", objectName: routineName, relatedObjectName: null };
384
707
  return null;
@@ -396,31 +719,148 @@ function extractCreateTableConstraintFacts(text, tableName) {
396
719
  function extractReadFacts(text) {
397
720
  const cteReads = collectCteReads(text);
398
721
  const isCteName = (name) => sqlObjectLookupKeys(name).some((key) => cteReads.names.has(key));
399
- const fromObjects = collectCommaSeparatedObjectsAfterKeywords(text, ["from", "using"]).filter((name) => !isCteName(name));
400
- const joinObjects = collectObjectsAfterKeywords(text, ["join", "inner join", "left join", "right join", "full join", "cross join"], { topLevelOnly: true }).filter((name) => !isCteName(name));
401
- const primaryRead = fromObjects[0] ?? null;
722
+ const sources = collectReadSources(text);
723
+ const fromObjects = sources.names.filter((name) => !isCteName(name));
402
724
  const facts = [...cteReads.facts];
725
+ const seenReads = new Set();
726
+ for (const fact of cteReads.facts) {
727
+ if (fact.kind === "reads_from" && fact.objectName)
728
+ seenReads.add(sqlObjectLookupKey(fact.objectName));
729
+ }
403
730
  for (const fromName of fromObjects) {
731
+ const key = sqlObjectLookupKey(fromName);
732
+ if (seenReads.has(key))
733
+ continue;
734
+ seenReads.add(key);
404
735
  facts.push({ kind: "reads_from", objectName: fromName, relatedObjectName: null });
405
736
  }
406
- for (const joinName of joinObjects) {
407
- facts.push({ kind: "joins", objectName: joinName, relatedObjectName: primaryRead });
737
+ const seenJoins = new Set();
738
+ const joinKey = (name, related) => {
739
+ const relatedKey = related === null ? "" : sqlObjectLookupKey(related);
740
+ return sqlObjectLookupKey(name) + ":" + relatedKey;
741
+ };
742
+ for (const fact of cteReads.facts) {
743
+ if (fact.kind === "joins" && fact.objectName) {
744
+ seenJoins.add(joinKey(fact.objectName, fact.relatedObjectName));
745
+ }
746
+ }
747
+ for (const join of sources.joins) {
748
+ if (isCteName(join.name))
749
+ continue;
750
+ const related = join.scopeFromNames.find((name) => !isCteName(name)) ?? null;
751
+ const key = joinKey(join.name, related);
752
+ if (seenJoins.has(key))
753
+ continue;
754
+ seenJoins.add(key);
755
+ facts.push({ kind: "joins", objectName: join.name, relatedObjectName: related });
408
756
  }
409
757
  return facts;
410
758
  }
759
+ /**
760
+ * The text between a routine body's BEGIN and its matching END. A BEGIN inside parentheses, as in
761
+ * a parameter named begin, is not the body. Bare CASE opens a frame and `END CASE` closes the
762
+ * innermost CASE. `END IF`, `END LOOP`, `END WHILE`, `END REPEAT`, and `END FOR` close nothing
763
+ * when the innermost frame is BEGIN, and close a CASE when that is the innermost frame. Any other
764
+ * END closes the innermost frame. A variable or qualified name such as `@case` or `t . case`
765
+ * is not a block keyword. Null when the statement has no such body. A dollar-quoted body is already
766
+ * blank, so only a BEGIN/END that the statement splitter kept as one statement is read.
767
+ */
768
+ function beginEndBody(text) {
769
+ const scan = maskSqlQuotedIdentifiers(text);
770
+ const trivia = sqlTriviaBoundaries(scan);
771
+ const stack = [];
772
+ let parenDepth = 0;
773
+ let cursor = 0;
774
+ let bodyStart = -1;
775
+ while (cursor < scan.length && bodyStart < 0) {
776
+ const code = scan.charCodeAt(cursor);
777
+ if (code === 40) {
778
+ parenDepth += 1;
779
+ cursor += 1;
780
+ continue;
781
+ }
782
+ if (code === 41) {
783
+ parenDepth = Math.max(0, parenDepth - 1);
784
+ cursor += 1;
785
+ continue;
786
+ }
787
+ if (!/[A-Za-z_]/.test(scan[cursor] ?? "")) {
788
+ cursor += 1;
789
+ continue;
790
+ }
791
+ const word = readBareWord(scan, cursor);
792
+ if (parenDepth === 0 && word?.word === "begin" && isBareSqlKeyword(scan, cursor, word.end, trivia)) {
793
+ bodyStart = word.end;
794
+ stack.push("begin");
795
+ cursor = word.end;
796
+ break;
797
+ }
798
+ cursor = word?.end ?? cursor + 1;
799
+ }
800
+ if (bodyStart < 0)
801
+ return null;
802
+ while (cursor < scan.length) {
803
+ if (/[A-Za-z_]/.test(scan[cursor] ?? "")) {
804
+ const atWord = cursor;
805
+ cursor = advanceSqlBlockWord(scan, cursor, stack, trivia);
806
+ if (stack.length === 0)
807
+ return text.slice(bodyStart, atWord);
808
+ continue;
809
+ }
810
+ cursor += 1;
811
+ }
812
+ return null;
813
+ }
814
+ /** Read facts of statements split out of a routine body. */
815
+ function readsOfStatements(body) {
816
+ const seen = new Set();
817
+ const facts = [];
818
+ for (const inner of splitSqlStatements(body)) {
819
+ for (const fact of extractReadFacts(inner.text)) {
820
+ const key = `${fact.kind}:${fact.objectName ?? ""}:${fact.relatedObjectName ?? ""}`;
821
+ if (seen.has(key))
822
+ continue;
823
+ seen.add(key);
824
+ facts.push(fact);
825
+ }
826
+ }
827
+ return facts;
828
+ }
829
+ /** Read facts of the statements inside a `BEGIN`/`END` body, split by the statement splitter. */
830
+ function readsInsideBeginEnd(masked) {
831
+ const body = beginEndBody(masked);
832
+ if (body === null)
833
+ return [];
834
+ return readsOfStatements(body);
835
+ }
836
+ /**
837
+ * Read facts inside a compound routine body the same way as a BEGIN/END body.
838
+ * Null when the routine body is not that single compound statement.
839
+ */
840
+ function readsInsideCompoundRoutine(masked) {
841
+ const code = maskSqlQuotedIdentifiers(masked);
842
+ const found = scanRoutineCompound(code, sqlTriviaBoundaries(masked), 0, code.length);
843
+ if (!found)
844
+ return null;
845
+ return readsOfStatements(masked.slice(found.keywordEnd));
846
+ }
411
847
  function withoutSelfRead(readFacts, objectName) {
412
848
  if (!objectName)
413
849
  return readFacts;
414
850
  return readFacts.filter((fact) => fact.objectName !== objectName);
415
851
  }
416
852
  function extractStatementFactDrafts(statementText) {
417
- const text = maskSqlStringsAndComments(statementText);
853
+ const text = maskSqlStringsAndComments(statementText, { escapeStrings: true });
418
854
  const definitionFact = createDefinitionFact(text);
419
855
  if (definitionFact) {
420
856
  const constraintFacts = definitionFact.kind === "defines_table" ? extractCreateTableConstraintFacts(text, definitionFact.objectName) : [];
421
- const readFacts = definitionFact.kind === "defines_view" || /\bas\s+select\b/i.test(text)
422
- ? withoutSelfRead(extractReadFacts(text), definitionFact.objectName)
423
- : [];
857
+ let readFacts = [];
858
+ if (definitionFact.kind === "defines_view" || /\bas\s+select\b/i.test(text)) {
859
+ readFacts = withoutSelfRead(extractReadFacts(text), definitionFact.objectName);
860
+ }
861
+ else if (definitionFact.kind === "defines_routine") {
862
+ readFacts = readsInsideCompoundRoutine(text) ?? readsInsideBeginEnd(text);
863
+ }
424
864
  return [definitionFact, ...constraintFacts, ...readFacts];
425
865
  }
426
866
  const renameSourceName = findObjectAfter(text, /\balter\s+table\s+(?:if\s+exists\s+)?/i);