@lzehrung/codegraph 3.0.1 → 3.1.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.
- package/README.md +17 -17
- package/codegraph-skill/codegraph/SKILL.md +3 -0
- package/dist/agent/artifact.d.ts.map +1 -1
- package/dist/agent/artifact.js +4 -9
- package/dist/agent/artifact.js.map +1 -1
- package/dist/agent/call-hierarchy.d.ts +4 -2
- package/dist/agent/call-hierarchy.d.ts.map +1 -1
- package/dist/agent/call-hierarchy.js +20 -29
- package/dist/agent/call-hierarchy.js.map +1 -1
- package/dist/agent/explain.d.ts.map +1 -1
- package/dist/agent/explain.js +12 -11
- package/dist/agent/explain.js.map +1 -1
- package/dist/agent/explore.d.ts.map +1 -1
- package/dist/agent/explore.js +2 -11
- package/dist/agent/explore.js.map +1 -1
- package/dist/agent/file-view.d.ts.map +1 -1
- package/dist/agent/file-view.js +4 -12
- package/dist/agent/file-view.js.map +1 -1
- package/dist/agent/normalize.d.ts +0 -3
- package/dist/agent/normalize.d.ts.map +1 -1
- package/dist/agent/normalize.js +1 -7
- package/dist/agent/normalize.js.map +1 -1
- package/dist/agent/orient.d.ts.map +1 -1
- package/dist/agent/orient.js +2 -6
- package/dist/agent/orient.js.map +1 -1
- package/dist/agent/packet.d.ts.map +1 -1
- package/dist/agent/packet.js +2 -5
- package/dist/agent/packet.js.map +1 -1
- package/dist/agent/query-index/content.d.ts.map +1 -1
- package/dist/agent/query-index/content.js +2 -6
- package/dist/agent/query-index/content.js.map +1 -1
- package/dist/agent/query-index/update.d.ts.map +1 -1
- package/dist/agent/query-index/update.js +8 -45
- package/dist/agent/query-index/update.js.map +1 -1
- package/dist/agent/query-index/worker-pool.d.ts.map +1 -1
- package/dist/agent/query-index/worker-pool.js +2 -1
- package/dist/agent/query-index/worker-pool.js.map +1 -1
- package/dist/agent/refactor-plan.d.ts +2 -2
- package/dist/agent/refactor-plan.d.ts.map +1 -1
- package/dist/agent/refactor-plan.js +11 -57
- package/dist/agent/refactor-plan.js.map +1 -1
- package/dist/agent/rename-preview.d.ts.map +1 -1
- package/dist/agent/rename-preview.js +166 -23
- package/dist/agent/rename-preview.js.map +1 -1
- package/dist/agent/search.d.ts.map +1 -1
- package/dist/agent/search.js +7 -22
- package/dist/agent/search.js.map +1 -1
- package/dist/agent/semantic-symbols.d.ts +1 -1
- package/dist/agent/semantic-symbols.d.ts.map +1 -1
- package/dist/agent/semantic-symbols.js +2 -5
- package/dist/agent/semantic-symbols.js.map +1 -1
- package/dist/agent/semantic.d.ts +5 -0
- package/dist/agent/semantic.d.ts.map +1 -1
- package/dist/agent/semantic.js +12 -1
- package/dist/agent/semantic.js.map +1 -1
- package/dist/agent/session.d.ts +9 -0
- package/dist/agent/session.d.ts.map +1 -1
- package/dist/agent/session.js +59 -41
- package/dist/agent/session.js.map +1 -1
- package/dist/agent/type-hierarchy.d.ts +4 -2
- package/dist/agent/type-hierarchy.d.ts.map +1 -1
- package/dist/agent/type-hierarchy.js +19 -31
- package/dist/agent/type-hierarchy.js.map +1 -1
- package/dist/agent/workspace-symbols.d.ts +1 -1
- package/dist/agent/workspace-symbols.d.ts.map +1 -1
- package/dist/agent/workspace-symbols.js +7 -15
- package/dist/agent/workspace-symbols.js.map +1 -1
- package/dist/analysis-summary.d.ts +1 -4
- package/dist/analysis-summary.d.ts.map +1 -1
- package/dist/analysis-summary.js +58 -19
- package/dist/analysis-summary.js.map +1 -1
- package/dist/bin/cli.js +35471 -23021
- package/dist/bin/query-index-worker.js +268 -241
- package/dist/bootstrap/tree-sitter-languages.d.ts +2 -0
- package/dist/bootstrap/tree-sitter-languages.d.ts.map +1 -1
- package/dist/bootstrap/tree-sitter-languages.js +6 -19
- package/dist/bootstrap/tree-sitter-languages.js.map +1 -1
- package/dist/chunking/chunk-matches.d.ts.map +1 -1
- package/dist/chunking/chunk-matches.js +6 -42
- package/dist/chunking/chunk-matches.js.map +1 -1
- package/dist/chunking/chunk-split.d.ts +7 -0
- package/dist/chunking/chunk-split.d.ts.map +1 -1
- package/dist/chunking/chunk-split.js +3 -3
- package/dist/chunking/chunk-split.js.map +1 -1
- package/dist/chunking/chunk-text-file.js +2 -30
- package/dist/chunking/chunk-text-file.js.map +1 -1
- package/dist/cli/affected.d.ts.map +1 -1
- package/dist/cli/affected.js +1 -9
- package/dist/cli/affected.js.map +1 -1
- package/dist/cli/call-hierarchy.js +3 -6
- package/dist/cli/call-hierarchy.js.map +1 -1
- package/dist/cli/chunk.d.ts.map +1 -1
- package/dist/cli/chunk.js +4 -11
- package/dist/cli/chunk.js.map +1 -1
- package/dist/cli/command-table.d.ts.map +1 -1
- package/dist/cli/command-table.js +3 -0
- package/dist/cli/command-table.js.map +1 -1
- package/dist/cli/context.d.ts +1 -0
- package/dist/cli/context.d.ts.map +1 -1
- package/dist/cli/context.js +1 -1
- package/dist/cli/context.js.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +1 -11
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/graph.d.ts +4 -12
- package/dist/cli/graph.d.ts.map +1 -1
- package/dist/cli/graph.js +17 -8
- package/dist/cli/graph.js.map +1 -1
- package/dist/cli/help.d.ts +3 -3
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +6 -4
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/index.d.ts +2 -12
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/links.d.ts.map +1 -1
- package/dist/cli/links.js +4 -10
- package/dist/cli/links.js.map +1 -1
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +1 -0
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/module-locals.d.ts +8 -0
- package/dist/cli/module-locals.d.ts.map +1 -0
- package/dist/cli/module-locals.js +9 -0
- package/dist/cli/module-locals.js.map +1 -0
- package/dist/cli/navigation.d.ts +2 -0
- package/dist/cli/navigation.d.ts.map +1 -1
- package/dist/cli/navigation.js +3 -5
- package/dist/cli/navigation.js.map +1 -1
- package/dist/cli/options.d.ts.map +1 -1
- package/dist/cli/options.js +2 -1
- package/dist/cli/options.js.map +1 -1
- package/dist/cli/pretty.d.ts +1 -0
- package/dist/cli/pretty.d.ts.map +1 -1
- package/dist/cli/pretty.js +6 -8
- package/dist/cli/pretty.js.map +1 -1
- package/dist/cli/refactor-plan.js +2 -5
- package/dist/cli/refactor-plan.js.map +1 -1
- package/dist/cli/rename-preview.js +2 -5
- package/dist/cli/rename-preview.js.map +1 -1
- package/dist/cli/review.d.ts +6 -16
- package/dist/cli/review.d.ts.map +1 -1
- package/dist/cli/review.js +2 -0
- package/dist/cli/review.js.map +1 -1
- package/dist/cli/server.d.ts.map +1 -1
- package/dist/cli/server.js +7 -10
- package/dist/cli/server.js.map +1 -1
- package/dist/cli/type-hierarchy.js +8 -8
- package/dist/cli/type-hierarchy.js.map +1 -1
- package/dist/document-links/asciidoc.d.ts.map +1 -1
- package/dist/document-links/asciidoc.js +4 -16
- package/dist/document-links/asciidoc.js.map +1 -1
- package/dist/document-links/check.d.ts.map +1 -1
- package/dist/document-links/check.js +1 -3
- package/dist/document-links/check.js.map +1 -1
- package/dist/document-links/html.d.ts.map +1 -1
- package/dist/document-links/html.js +6 -44
- package/dist/document-links/html.js.map +1 -1
- package/dist/document-links/markdown.d.ts.map +1 -1
- package/dist/document-links/markdown.js +4 -13
- package/dist/document-links/markdown.js.map +1 -1
- package/dist/document-links/rst.d.ts.map +1 -1
- package/dist/document-links/rst.js +7 -31
- package/dist/document-links/rst.js.map +1 -1
- package/dist/document-links/sfc.d.ts.map +1 -1
- package/dist/document-links/sfc.js +2 -5
- package/dist/document-links/sfc.js.map +1 -1
- package/dist/document-links/shared.d.ts +2 -0
- package/dist/document-links/shared.d.ts.map +1 -1
- package/dist/document-links/shared.js +13 -0
- package/dist/document-links/shared.js.map +1 -1
- package/dist/drift/artifact.d.ts.map +1 -1
- package/dist/drift/artifact.js +4 -27
- package/dist/drift/artifact.js.map +1 -1
- package/dist/drift/graph-edges.d.ts +4 -0
- package/dist/drift/graph-edges.d.ts.map +1 -0
- package/dist/drift/graph-edges.js +15 -0
- package/dist/drift/graph-edges.js.map +1 -0
- package/dist/drift/snapshot.d.ts.map +1 -1
- package/dist/drift/snapshot.js +2 -17
- package/dist/drift/snapshot.js.map +1 -1
- package/dist/duplicates/unit-cache.d.ts +11 -1
- package/dist/duplicates/unit-cache.d.ts.map +1 -1
- package/dist/duplicates/unit-cache.js +20 -2
- package/dist/duplicates/unit-cache.js.map +1 -1
- package/dist/duplicates/units.d.ts +2 -1
- package/dist/duplicates/units.d.ts.map +1 -1
- package/dist/duplicates/units.js +23 -22
- package/dist/duplicates/units.js.map +1 -1
- package/dist/graph-builder.d.ts +1 -1
- package/dist/graph-builder.d.ts.map +1 -1
- package/dist/graph-builder.js +3 -2
- package/dist/graph-builder.js.map +1 -1
- package/dist/graph-edge-collector.d.ts +3 -1
- package/dist/graph-edge-collector.d.ts.map +1 -1
- package/dist/graph-edge-collector.js +38 -6
- package/dist/graph-edge-collector.js.map +1 -1
- package/dist/graphs/angularjs.d.ts.map +1 -1
- package/dist/graphs/angularjs.js +2 -9
- package/dist/graphs/angularjs.js.map +1 -1
- package/dist/graphs/edge-resolution.d.ts +4 -0
- package/dist/graphs/edge-resolution.d.ts.map +1 -1
- package/dist/graphs/edge-resolution.js +2 -0
- package/dist/graphs/edge-resolution.js.map +1 -1
- package/dist/graphs/external/manifests.d.ts.map +1 -1
- package/dist/graphs/external/manifests.js +1 -6
- package/dist/graphs/external/manifests.js.map +1 -1
- package/dist/graphs/specifiers.d.ts.map +1 -1
- package/dist/graphs/specifiers.js +47 -26
- package/dist/graphs/specifiers.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts +2 -0
- package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed/edge-passes.js +9 -3
- package/dist/graphs/symbol-graph-detailed/edge-passes.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts +3 -3
- package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed/receiver-calls.js +2 -26
- package/dist/graphs/symbol-graph-detailed/receiver-calls.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed.js +38 -1
- package/dist/graphs/symbol-graph-detailed.js.map +1 -1
- package/dist/impact/analyzer.d.ts.map +1 -1
- package/dist/impact/analyzer.js +23 -17
- package/dist/impact/analyzer.js.map +1 -1
- package/dist/impact/budgets.d.ts.map +1 -1
- package/dist/impact/budgets.js +3 -9
- package/dist/impact/budgets.js.map +1 -1
- package/dist/impact/call-compatibility.d.ts.map +1 -1
- package/dist/impact/call-compatibility.js +3 -12
- package/dist/impact/call-compatibility.js.map +1 -1
- package/dist/impact/context.d.ts +6 -0
- package/dist/impact/context.d.ts.map +1 -1
- package/dist/impact/context.js +2 -2
- package/dist/impact/context.js.map +1 -1
- package/dist/impact/direct.d.ts.map +1 -1
- package/dist/impact/direct.js +2 -6
- package/dist/impact/direct.js.map +1 -1
- package/dist/impact/map.d.ts +3 -1
- package/dist/impact/map.d.ts.map +1 -1
- package/dist/impact/map.js +12 -5
- package/dist/impact/map.js.map +1 -1
- package/dist/impact/reference-cache.d.ts.map +1 -1
- package/dist/impact/reference-cache.js +1 -24
- package/dist/impact/reference-cache.js.map +1 -1
- package/dist/impact/report-shared.d.ts +2 -1
- package/dist/impact/report-shared.d.ts.map +1 -1
- package/dist/impact/report-shared.js +10 -0
- package/dist/impact/report-shared.js.map +1 -1
- package/dist/impact/report-suggestions.d.ts.map +1 -1
- package/dist/impact/report-suggestions.js +2 -8
- package/dist/impact/report-suggestions.js.map +1 -1
- package/dist/impact/report.d.ts.map +1 -1
- package/dist/impact/report.js +2 -8
- package/dist/impact/report.js.map +1 -1
- package/dist/impact/streaming.d.ts.map +1 -1
- package/dist/impact/streaming.js +3 -8
- package/dist/impact/streaming.js.map +1 -1
- package/dist/indexer/build-cache/manifest.d.ts.map +1 -1
- package/dist/indexer/build-cache/manifest.js +10 -108
- package/dist/indexer/build-cache/manifest.js.map +1 -1
- package/dist/indexer/build-cache/module-cache.d.ts +6 -1
- package/dist/indexer/build-cache/module-cache.d.ts.map +1 -1
- package/dist/indexer/build-cache/module-cache.js +25 -2
- package/dist/indexer/build-cache/module-cache.js.map +1 -1
- package/dist/indexer/build-cache/options.d.ts +38 -1
- package/dist/indexer/build-cache/options.d.ts.map +1 -1
- package/dist/indexer/build-cache/options.js +38 -1
- package/dist/indexer/build-cache/options.js.map +1 -1
- package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
- package/dist/indexer/build-cache/project-snapshot.js +48 -99
- package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
- package/dist/indexer/build-cache/reports.d.ts +1 -0
- package/dist/indexer/build-cache/reports.d.ts.map +1 -1
- package/dist/indexer/build-cache/reports.js +10 -0
- package/dist/indexer/build-cache/reports.js.map +1 -1
- package/dist/indexer/build-index.d.ts +2 -0
- package/dist/indexer/build-index.d.ts.map +1 -1
- package/dist/indexer/build-index.js +187 -57
- package/dist/indexer/build-index.js.map +1 -1
- package/dist/indexer/build-workers.d.ts +7 -1
- package/dist/indexer/build-workers.d.ts.map +1 -1
- package/dist/indexer/build-workers.js +12 -0
- package/dist/indexer/build-workers.js.map +1 -1
- package/dist/indexer/call-hierarchy.d.ts.map +1 -1
- package/dist/indexer/call-hierarchy.js +5 -17
- package/dist/indexer/call-hierarchy.js.map +1 -1
- package/dist/indexer/compilation-units.d.ts +32 -20
- package/dist/indexer/compilation-units.d.ts.map +1 -1
- package/dist/indexer/compilation-units.js +139 -145
- package/dist/indexer/compilation-units.js.map +1 -1
- package/dist/indexer/cpp-callables.d.ts.map +1 -1
- package/dist/indexer/cpp-callables.js +2 -7
- package/dist/indexer/cpp-callables.js.map +1 -1
- package/dist/indexer/import-types.d.ts +5 -0
- package/dist/indexer/import-types.d.ts.map +1 -1
- package/dist/indexer/import-types.js.map +1 -1
- package/dist/indexer/imports/binding-ranges.d.ts +5 -12
- package/dist/indexer/imports/binding-ranges.d.ts.map +1 -1
- package/dist/indexer/imports/binding-ranges.js +13 -19
- package/dist/indexer/imports/binding-ranges.js.map +1 -1
- package/dist/indexer/imports/context.d.ts +6 -0
- package/dist/indexer/imports/context.d.ts.map +1 -1
- package/dist/indexer/imports/import-binding-tables.d.ts +28 -13
- package/dist/indexer/imports/import-binding-tables.d.ts.map +1 -1
- package/dist/indexer/imports/import-binding-tables.js +179 -178
- package/dist/indexer/imports/import-binding-tables.js.map +1 -1
- package/dist/indexer/imports/js-text-imports.d.ts +0 -1
- package/dist/indexer/imports/js-text-imports.d.ts.map +1 -1
- package/dist/indexer/imports/js-text-imports.js +0 -176
- package/dist/indexer/imports/js-text-imports.js.map +1 -1
- package/dist/indexer/imports/language-specific.d.ts.map +1 -1
- package/dist/indexer/imports/language-specific.js +4 -8
- package/dist/indexer/imports/language-specific.js.map +1 -1
- package/dist/indexer/imports/python.d.ts +0 -1
- package/dist/indexer/imports/python.d.ts.map +1 -1
- package/dist/indexer/imports/python.js +1 -29
- package/dist/indexer/imports/python.js.map +1 -1
- package/dist/indexer/imports/text-import-extractors.d.ts +2 -9
- package/dist/indexer/imports/text-import-extractors.d.ts.map +1 -1
- package/dist/indexer/imports/text-import-extractors.js +0 -284
- package/dist/indexer/imports/text-import-extractors.js.map +1 -1
- package/dist/indexer/imports.d.ts +15 -0
- package/dist/indexer/imports.d.ts.map +1 -1
- package/dist/indexer/imports.js +82 -44
- package/dist/indexer/imports.js.map +1 -1
- package/dist/indexer/incremental-plan.d.ts +0 -1
- package/dist/indexer/incremental-plan.d.ts.map +1 -1
- package/dist/indexer/incremental-plan.js +6 -12
- package/dist/indexer/incremental-plan.js.map +1 -1
- package/dist/indexer/name-lookup-policies/implicit-self.d.ts.map +1 -1
- package/dist/indexer/name-lookup-policies/implicit-self.js +25 -4
- package/dist/indexer/name-lookup-policies/implicit-self.js.map +1 -1
- package/dist/indexer/name-resolution-types.d.ts +5 -0
- package/dist/indexer/name-resolution-types.d.ts.map +1 -1
- package/dist/indexer/name-resolution.d.ts.map +1 -1
- package/dist/indexer/name-resolution.js +2 -0
- package/dist/indexer/name-resolution.js.map +1 -1
- package/dist/indexer/navigation-cpp.d.ts.map +1 -1
- package/dist/indexer/navigation-cpp.js +3 -5
- package/dist/indexer/navigation-cpp.js.map +1 -1
- package/dist/indexer/navigation-goto.d.ts +49 -3
- package/dist/indexer/navigation-goto.d.ts.map +1 -1
- package/dist/indexer/navigation-goto.js +500 -106
- package/dist/indexer/navigation-goto.js.map +1 -1
- package/dist/indexer/navigation-local.d.ts +7 -0
- package/dist/indexer/navigation-local.d.ts.map +1 -1
- package/dist/indexer/navigation-local.js +22 -2
- package/dist/indexer/navigation-local.js.map +1 -1
- package/dist/indexer/navigation-php.d.ts +0 -1
- package/dist/indexer/navigation-php.d.ts.map +1 -1
- package/dist/indexer/navigation-php.js +1 -7
- package/dist/indexer/navigation-php.js.map +1 -1
- package/dist/indexer/navigation-references.d.ts +1 -0
- package/dist/indexer/navigation-references.d.ts.map +1 -1
- package/dist/indexer/navigation-references.js +134 -23
- package/dist/indexer/navigation-references.js.map +1 -1
- package/dist/indexer/navigation-resolve.d.ts +22 -0
- package/dist/indexer/navigation-resolve.d.ts.map +1 -1
- package/dist/indexer/navigation-resolve.js +73 -8
- package/dist/indexer/navigation-resolve.js.map +1 -1
- package/dist/indexer/navigation.d.ts +4 -1
- package/dist/indexer/navigation.d.ts.map +1 -1
- package/dist/indexer/navigation.js +398 -95
- package/dist/indexer/navigation.js.map +1 -1
- package/dist/indexer/python-property-decorator.d.ts +11 -0
- package/dist/indexer/python-property-decorator.d.ts.map +1 -0
- package/dist/indexer/python-property-decorator.js +30 -0
- package/dist/indexer/python-property-decorator.js.map +1 -0
- package/dist/indexer/shared-owner-identity.d.ts +3 -1
- package/dist/indexer/shared-owner-identity.d.ts.map +1 -1
- package/dist/indexer/shared-owner-identity.js +40 -12
- package/dist/indexer/shared-owner-identity.js.map +1 -1
- package/dist/indexer/shared.d.ts +10 -0
- package/dist/indexer/shared.d.ts.map +1 -1
- package/dist/indexer/shared.js +8 -0
- package/dist/indexer/shared.js.map +1 -1
- package/dist/indexer/star-import-precedence.d.ts +5 -1
- package/dist/indexer/star-import-precedence.d.ts.map +1 -1
- package/dist/indexer/star-import-precedence.js +12 -19
- package/dist/indexer/star-import-precedence.js.map +1 -1
- package/dist/indexer/type-hierarchy.d.ts.map +1 -1
- package/dist/indexer/type-hierarchy.js +8 -9
- package/dist/indexer/type-hierarchy.js.map +1 -1
- package/dist/indexer/types.d.ts +49 -1
- package/dist/indexer/types.d.ts.map +1 -1
- package/dist/indexer/types.js.map +1 -1
- package/dist/indexer/workspace-symbols.d.ts.map +1 -1
- package/dist/indexer/workspace-symbols.js +3 -13
- package/dist/indexer/workspace-symbols.js.map +1 -1
- package/dist/installer/locks.d.ts +1 -0
- package/dist/installer/locks.d.ts.map +1 -1
- package/dist/installer/locks.js +4 -8
- package/dist/installer/locks.js.map +1 -1
- package/dist/installer/registry.d.ts.map +1 -1
- package/dist/installer/registry.js +9 -15
- package/dist/installer/registry.js.map +1 -1
- package/dist/languages/callable-arity.d.ts.map +1 -1
- package/dist/languages/callable-arity.js +1 -38
- package/dist/languages/callable-arity.js.map +1 -1
- package/dist/languages/definitions/csharp.d.ts.map +1 -1
- package/dist/languages/definitions/csharp.js +5 -13
- package/dist/languages/definitions/csharp.js.map +1 -1
- package/dist/languages/definitions/java.d.ts.map +1 -1
- package/dist/languages/definitions/java.js +4 -13
- package/dist/languages/definitions/java.js.map +1 -1
- package/dist/languages/definitions/kotlin.d.ts.map +1 -1
- package/dist/languages/definitions/kotlin.js +4 -8
- package/dist/languages/definitions/kotlin.js.map +1 -1
- package/dist/languages/definitions/python.d.ts.map +1 -1
- package/dist/languages/definitions/python.js +5 -3
- package/dist/languages/definitions/python.js.map +1 -1
- package/dist/languages/import-statement-parsers.d.ts +0 -30
- package/dist/languages/import-statement-parsers.d.ts.map +1 -1
- package/dist/languages/import-statement-parsers.js +1 -81
- package/dist/languages/import-statement-parsers.js.map +1 -1
- package/dist/languages/sfc.d.ts.map +1 -1
- package/dist/languages/sfc.js +8 -43
- package/dist/languages/sfc.js.map +1 -1
- package/dist/lifecycle/manifest.d.ts.map +1 -1
- package/dist/lifecycle/manifest.js +11 -29
- package/dist/lifecycle/manifest.js.map +1 -1
- package/dist/mcp/handlers.d.ts +21 -0
- package/dist/mcp/handlers.d.ts.map +1 -1
- package/dist/mcp/handlers.js +66 -20
- package/dist/mcp/handlers.js.map +1 -1
- package/dist/mcp/http-transport.d.ts.map +1 -1
- package/dist/mcp/http-transport.js +5 -1
- package/dist/mcp/http-transport.js.map +1 -1
- package/dist/mcp/project-watcher.d.ts +125 -0
- package/dist/mcp/project-watcher.d.ts.map +1 -0
- package/dist/mcp/project-watcher.js +643 -0
- package/dist/mcp/project-watcher.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +5 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/native/byte-index.d.ts +1 -0
- package/dist/native/byte-index.d.ts.map +1 -1
- package/dist/native/byte-index.js +1 -1
- package/dist/native/byte-index.js.map +1 -1
- package/dist/native/contracts.d.ts +1 -0
- package/dist/native/contracts.d.ts.map +1 -1
- package/dist/native/native-backend-report.d.ts +2 -1
- package/dist/native/native-backend-report.d.ts.map +1 -1
- package/dist/native/native-backend-report.js +23 -0
- package/dist/native/native-backend-report.js.map +1 -1
- package/dist/native/tree-shape.d.ts +5 -7
- package/dist/native/tree-shape.d.ts.map +1 -1
- package/dist/native/tree-shape.js +11 -10
- package/dist/native/tree-shape.js.map +1 -1
- package/dist/presentation/bounds.d.ts +2 -0
- package/dist/presentation/bounds.d.ts.map +1 -1
- package/dist/presentation/bounds.js +8 -0
- package/dist/presentation/bounds.js.map +1 -1
- package/dist/review/candidates.d.ts.map +1 -1
- package/dist/review/candidates.js +4 -25
- package/dist/review/candidates.js.map +1 -1
- package/dist/review/report.d.ts.map +1 -1
- package/dist/review/report.js +4 -2
- package/dist/review/report.js.map +1 -1
- package/dist/review/summaries.d.ts.map +1 -1
- package/dist/review/summaries.js +14 -35
- package/dist/review/summaries.js.map +1 -1
- package/dist/review.d.ts.map +1 -1
- package/dist/review.js +4 -5
- package/dist/review.js.map +1 -1
- package/dist/scss/navigation.d.ts +13 -0
- package/dist/scss/navigation.d.ts.map +1 -0
- package/dist/scss/navigation.js +150 -0
- package/dist/scss/navigation.js.map +1 -0
- package/dist/scss/resolution.d.ts +190 -0
- package/dist/scss/resolution.d.ts.map +1 -0
- package/dist/scss/resolution.js +1802 -0
- package/dist/scss/resolution.js.map +1 -0
- package/dist/scss/syntax.d.ts +181 -0
- package/dist/scss/syntax.d.ts.map +1 -0
- package/dist/scss/syntax.js +1436 -0
- package/dist/scss/syntax.js.map +1 -0
- package/dist/sql/classify-sql-file.d.ts +7 -0
- package/dist/sql/classify-sql-file.d.ts.map +1 -1
- package/dist/sql/classify-sql-file.js +9 -0
- package/dist/sql/classify-sql-file.js.map +1 -1
- package/dist/sql/extract-facts.d.ts.map +1 -1
- package/dist/sql/extract-facts.js +517 -77
- package/dist/sql/extract-facts.js.map +1 -1
- package/dist/sql/lex.d.ts +100 -1
- package/dist/sql/lex.d.ts.map +1 -1
- package/dist/sql/lex.js +473 -11
- package/dist/sql/lex.js.map +1 -1
- package/dist/sql/lookup.d.ts +17 -0
- package/dist/sql/lookup.d.ts.map +1 -1
- package/dist/sql/lookup.js +21 -0
- package/dist/sql/lookup.js.map +1 -1
- package/dist/sql/navigation.d.ts +28 -1
- package/dist/sql/navigation.d.ts.map +1 -1
- package/dist/sql/navigation.js +474 -84
- package/dist/sql/navigation.js.map +1 -1
- package/dist/sql/object-mentions.d.ts +24 -0
- package/dist/sql/object-mentions.d.ts.map +1 -0
- package/dist/sql/object-mentions.js +233 -0
- package/dist/sql/object-mentions.js.map +1 -0
- package/dist/sql/review.d.ts +3 -0
- package/dist/sql/review.d.ts.map +1 -1
- package/dist/sql/review.js +15 -14
- package/dist/sql/review.js.map +1 -1
- package/dist/sql/routine-mentions.d.ts +61 -0
- package/dist/sql/routine-mentions.d.ts.map +1 -0
- package/dist/sql/routine-mentions.js +868 -0
- package/dist/sql/routine-mentions.js.map +1 -0
- package/dist/sql/source-graph.d.ts +18 -3
- package/dist/sql/source-graph.d.ts.map +1 -1
- package/dist/sql/source-graph.js +109 -32
- package/dist/sql/source-graph.js.map +1 -1
- package/dist/sqlite/raw-query-worker-pool.d.ts.map +1 -1
- package/dist/sqlite/raw-query-worker-pool.js +2 -0
- package/dist/sqlite/raw-query-worker-pool.js.map +1 -1
- package/dist/sqlite/types.d.ts +6 -5
- package/dist/sqlite/types.d.ts.map +1 -1
- package/dist/sqlite/write.d.ts.map +1 -1
- package/dist/sqlite/write.js.map +1 -1
- package/dist/sqlite-driver.d.ts +0 -1
- package/dist/sqlite-driver.d.ts.map +1 -1
- package/dist/sqlite-driver.js +0 -11
- package/dist/sqlite-driver.js.map +1 -1
- package/dist/terraform/navigation.d.ts.map +1 -1
- package/dist/terraform/navigation.js +1 -3
- package/dist/terraform/navigation.js.map +1 -1
- package/dist/terraform/syntax.d.ts.map +1 -1
- package/dist/terraform/syntax.js +1 -4
- package/dist/terraform/syntax.js.map +1 -1
- package/dist/util/ast.d.ts +5 -0
- package/dist/util/ast.d.ts.map +1 -1
- package/dist/util/ast.js +10 -0
- package/dist/util/ast.js.map +1 -1
- package/dist/util/atomic-file.d.ts +22 -0
- package/dist/util/atomic-file.d.ts.map +1 -0
- package/dist/util/atomic-file.js +106 -0
- package/dist/util/atomic-file.js.map +1 -0
- package/dist/util/collections.d.ts +5 -0
- package/dist/util/collections.d.ts.map +1 -1
- package/dist/util/collections.js +26 -0
- package/dist/util/collections.js.map +1 -1
- package/dist/util/concurrency.d.ts +1 -0
- package/dist/util/concurrency.d.ts.map +1 -1
- package/dist/util/concurrency.js +5 -0
- package/dist/util/concurrency.js.map +1 -1
- package/dist/util/confined-file.d.ts.map +1 -1
- package/dist/util/confined-file.js +1 -3
- package/dist/util/confined-file.js.map +1 -1
- package/dist/util/csharp-tree.d.ts +65 -0
- package/dist/util/csharp-tree.d.ts.map +1 -0
- package/dist/util/csharp-tree.js +266 -0
- package/dist/util/csharp-tree.js.map +1 -0
- package/dist/util/errors.d.ts +1 -0
- package/dist/util/errors.d.ts.map +1 -1
- package/dist/util/errors.js +3 -0
- package/dist/util/errors.js.map +1 -1
- package/dist/util/graph-edges.d.ts +2 -0
- package/dist/util/graph-edges.d.ts.map +1 -1
- package/dist/util/graph-edges.js +11 -0
- package/dist/util/graph-edges.js.map +1 -1
- package/dist/util/guards.d.ts +1 -0
- package/dist/util/guards.d.ts.map +1 -1
- package/dist/util/guards.js +6 -0
- package/dist/util/guards.js.map +1 -1
- package/dist/util/identifiers.d.ts +0 -24
- package/dist/util/identifiers.d.ts.map +1 -1
- package/dist/util/identifiers.js +0 -24
- package/dist/util/identifiers.js.map +1 -1
- package/dist/util/jvm-tree.d.ts +58 -0
- package/dist/util/jvm-tree.d.ts.map +1 -0
- package/dist/util/jvm-tree.js +153 -0
- package/dist/util/jvm-tree.js.map +1 -0
- package/dist/util/package-exports.d.ts +0 -22
- package/dist/util/package-exports.d.ts.map +1 -1
- package/dist/util/package-exports.js +25 -5
- package/dist/util/package-exports.js.map +1 -1
- package/dist/util/paths.d.ts +1 -0
- package/dist/util/paths.d.ts.map +1 -1
- package/dist/util/paths.js +10 -4
- package/dist/util/paths.js.map +1 -1
- package/dist/util/resolution/csharp.d.ts +20 -8
- package/dist/util/resolution/csharp.d.ts.map +1 -1
- package/dist/util/resolution/csharp.js +126 -127
- package/dist/util/resolution/csharp.js.map +1 -1
- package/dist/util/resolution/files.d.ts +6 -0
- package/dist/util/resolution/files.d.ts.map +1 -1
- package/dist/util/resolution/files.js +74 -21
- package/dist/util/resolution/files.js.map +1 -1
- package/dist/util/resolution/jvm.d.ts +21 -1
- package/dist/util/resolution/jvm.d.ts.map +1 -1
- package/dist/util/resolution/jvm.js +168 -100
- package/dist/util/resolution/jvm.js.map +1 -1
- package/dist/util/resolution/project-symbols.d.ts +1 -1
- package/dist/util/resolution/project-symbols.d.ts.map +1 -1
- package/dist/util/resolution/project-symbols.js.map +1 -1
- package/dist/util/resolution/specifier-targets.d.ts +4 -0
- package/dist/util/resolution/specifier-targets.d.ts.map +1 -1
- package/dist/util/resolution/specifier-targets.js +11 -3
- package/dist/util/resolution/specifier-targets.js.map +1 -1
- package/dist/util/resolution.d.ts.map +1 -1
- package/dist/util/resolution.js +21 -7
- package/dist/util/resolution.js.map +1 -1
- package/dist/util/syntax-tree.d.ts +16 -0
- package/dist/util/syntax-tree.d.ts.map +1 -0
- package/dist/util/syntax-tree.js +34 -0
- package/dist/util/syntax-tree.js.map +1 -0
- package/dist/util/text-scanning.d.ts +6 -0
- package/dist/util/text-scanning.d.ts.map +1 -0
- package/dist/util/text-scanning.js +35 -0
- package/dist/util/text-scanning.js.map +1 -0
- package/dist/util/trivia-tables.d.ts +13 -8
- package/dist/util/trivia-tables.d.ts.map +1 -1
- package/dist/util/trivia-tables.js +13 -72
- package/dist/util/trivia-tables.js.map +1 -1
- package/dist/util/trivia.d.ts +10 -3
- package/dist/util/trivia.d.ts.map +1 -1
- package/dist/util/trivia.js +209 -79
- package/dist/util/trivia.js.map +1 -1
- package/dist/util/windows-process-drain.d.ts.map +1 -1
- package/dist/util/windows-process-drain.js.map +1 -1
- package/dist/util/worker-threads.d.ts +16 -0
- package/dist/util/worker-threads.d.ts.map +1 -1
- package/dist/util/worker-threads.js +118 -0
- package/dist/util/worker-threads.js.map +1 -1
- package/dist/worker/native-worker-pool.d.ts.map +1 -1
- package/dist/worker/native-worker-pool.js +2 -1
- package/dist/worker/native-worker-pool.js.map +1 -1
- package/docs/mcp.md +27 -2
- 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
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
434
|
+
if (commentDepth) {
|
|
435
|
+
if (nestedComments && char === "/" && next === "*") {
|
|
436
|
+
commentDepth += 1;
|
|
437
|
+
i += 2;
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
114
440
|
if (char === "*" && next === "/") {
|
|
115
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
253
|
-
|
|
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
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
|
306
|
-
const
|
|
307
|
-
const
|
|
308
|
-
|
|
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
|
|
313
|
-
const
|
|
314
|
-
for (const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
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
|
-
|
|
326
|
-
|
|
327
|
-
|
|
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
|
|
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,
|
|
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
|
|
400
|
-
const
|
|
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
|
-
|
|
407
|
-
|
|
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
|
-
|
|
422
|
-
|
|
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);
|