@mrclrchtr/supi-code-intelligence 4.10.0 → 6.0.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 +4 -3
- package/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
- package/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
- package/node_modules/@mrclrchtr/supi-core/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-core/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
- package/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
- package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -6
- package/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
- package/node_modules/@mrclrchtr/supi-lsp/README.md +111 -5
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -6
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
- package/node_modules/@mrclrchtr/supi-lsp/package.json +7 -6
- package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +22 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +245 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-capabilities.ts +78 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-collection.ts +171 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +413 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +15 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-publication.ts +214 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-pull.ts +62 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +690 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-request.ts +9 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +97 -16
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-waiters.ts +206 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +448 -298
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +70 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +231 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-file-state.ts +25 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +529 -119
- package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +161 -33
- package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +12 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +5 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/config/defaults.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +3 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-extends.ts +68 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-path.ts +8 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-scope.ts +176 -24
- package/node_modules/@mrclrchtr/supi-lsp/src/debug-telemetry.ts +45 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +42 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/workspace-sentinels.ts +46 -10
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-client-state.ts +79 -9
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +17 -7
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +350 -26
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-symbol.ts +5 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +586 -96
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-refactor-provider.ts +130 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +45 -329
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +57 -120
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-edit-normalizer.ts +320 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-symbol-mapper.ts +207 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/readiness.ts +72 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +151 -26
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +42 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +92 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +165 -118
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-transition-debug.ts +49 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/workspace-lsp-runtime.ts +102 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +17 -7
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -6
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/LICENSE +21 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/README.md +258 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/babel.cjs +257 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/jiti.cjs +1 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-cli.mjs +34 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-hooks.mjs +124 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-native.mjs +121 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.d.mts +1 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.mjs +4 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-static.mjs +23 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.cjs +30 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.cts +8 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.mts +8 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.mjs +29 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/types.d.ts +420 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/package.json +146 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +6 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +0 -9
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +0 -8
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +16 -12
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +65 -87
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +47 -95
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-timing.ts +147 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client-lifecycle.ts +39 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client.ts +561 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-message-size.ts +24 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-protocol.ts +452 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +4 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +12 -4
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/exports.ts +4 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/imports.ts +4 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/node-at.ts +5 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +33 -12
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/blocking-test-bootstrap.mjs +34 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/bootstrap.mjs +8 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store-helpers.ts +23 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store.ts +400 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/request-control.ts +48 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-parser-helpers.ts +24 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-query-helpers.ts +43 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime.ts +421 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/service.ts +116 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/worker-main.ts +201 -0
- package/package.json +5 -5
- package/src/analysis/health/diagnostics.ts +221 -77
- package/src/analysis/health/file-scope.ts +184 -0
- package/src/analysis/health/recovery.ts +14 -3
- package/src/analysis/provider.ts +58 -0
- package/src/analysis/readiness.ts +34 -9
- package/src/analysis/refactor/apply.ts +45 -1
- package/src/analysis/refactor/mutation-authority.ts +143 -0
- package/src/analysis/relations/callees.ts +9 -1
- package/src/analysis/relations/types.ts +5 -2
- package/src/analysis/search/ast-scan-timing.ts +9 -2
- package/src/analysis/search/ast-scan.ts +5 -2
- package/src/analysis/search/deadline.ts +2 -2
- package/src/analysis/search/pattern-analysis.ts +54 -33
- package/src/analysis/search/pattern.ts +18 -3
- package/src/analysis/target/anchored.ts +20 -11
- package/src/analysis/target/file.ts +18 -11
- package/src/analysis/target/identity.ts +19 -3
- package/src/analysis/target/symbol.ts +36 -15
- package/src/api.ts +4 -0
- package/src/config.ts +35 -1
- package/src/diagnostics/evidence.ts +51 -0
- package/src/extension.ts +57 -14
- package/src/overview/overview-data.ts +9 -2
- package/src/overview/overview.ts +49 -30
- package/src/overview/types.ts +2 -0
- package/src/session/capability-adapter.ts +12 -3
- package/src/session/find-types.ts +2 -2
- package/src/session/find-workflow.ts +20 -9
- package/src/session/graph/collect.ts +18 -2
- package/src/session/graph-workflow.ts +19 -12
- package/src/session/health-refresh.ts +175 -0
- package/src/session/health-types.ts +43 -15
- package/src/session/health-workflow.ts +69 -54
- package/src/session/input/workflows.ts +2 -2
- package/src/session/inspect/collect.ts +20 -3
- package/src/session/inspect-workflow.ts +12 -6
- package/src/session/orientation/collect.ts +12 -3
- package/src/session/orientation/context-facts.ts +3 -1
- package/src/session/orientation/context-sections.ts +20 -7
- package/src/session/orientation/gather.ts +17 -11
- package/src/session/orientation-types.ts +4 -1
- package/src/session/orientation-workflow.ts +23 -10
- package/src/session/refactor-plans.ts +2 -0
- package/src/session/refactor-workflow.ts +61 -15
- package/src/session/session.ts +29 -2
- package/src/session/target-workflow.ts +54 -23
- package/src/session/workflow-control.ts +7 -3
- package/src/substrate/lsp/lifecycle.ts +26 -46
- package/src/substrate/lsp/maintenance.ts +284 -28
- package/src/substrate/lsp/recovery.ts +11 -5
- package/src/substrate/lsp/state.ts +2 -2
- package/src/substrate/workspace-provider-host.ts +25 -3
- package/src/tool/{find → code_find}/execute.ts +2 -16
- package/src/tool/code_find/guidance.ts +8 -0
- package/src/tool/{find → code_find}/render.ts +21 -4
- package/src/tool/{result/find.ts → code_find/result.ts} +78 -9
- package/src/tool/code_find/spec.ts +37 -0
- package/src/tool/code_find/tui.ts +41 -0
- package/src/tool/code_graph/execute.ts +24 -0
- package/src/tool/code_graph/guidance.ts +6 -0
- package/src/tool/{graph → code_graph}/markdown.ts +1 -1
- package/src/tool/{result/graph.ts → code_graph/result.ts} +111 -3
- package/src/tool/code_graph/spec.ts +39 -0
- package/src/tool/code_graph/tui.ts +117 -0
- package/src/tool/{health → code_health}/execute.ts +2 -13
- package/src/tool/code_health/guidance.ts +8 -0
- package/src/tool/{health → code_health}/markdown.ts +119 -27
- package/src/tool/code_health/refresh-status.ts +105 -0
- package/src/tool/{result/health.ts → code_health/result.ts} +80 -3
- package/src/tool/code_health/spec.ts +41 -0
- package/src/tool/{health → code_health}/tui.ts +95 -98
- package/src/tool/{inspect → code_inspect}/execute.ts +2 -16
- package/src/tool/code_inspect/guidance.ts +6 -0
- package/src/tool/{inspect → code_inspect}/markdown.ts +1 -1
- package/src/tool/{result/inspect.ts → code_inspect/result.ts} +143 -2
- package/src/tool/code_inspect/spec.ts +25 -0
- package/src/tool/code_inspect/tui.ts +44 -0
- package/src/tool/code_orientation/execute.ts +25 -0
- package/src/tool/code_orientation/guidance.ts +9 -0
- package/src/tool/{orientation → code_orientation}/markdown.ts +1 -1
- package/src/tool/code_orientation/result.ts +248 -0
- package/src/tool/code_orientation/spec.ts +25 -0
- package/src/tool/{orientation → code_orientation}/tui.ts +51 -35
- package/src/tool/code_refactor_apply/execute.ts +17 -0
- package/src/tool/code_refactor_apply/guidance.ts +5 -0
- package/src/tool/{refactor-apply/execute.ts → code_refactor_apply/result.ts} +8 -11
- package/src/tool/code_refactor_apply/spec.ts +26 -0
- package/src/tool/code_refactor_apply/tui.ts +73 -0
- package/src/tool/code_refactor_plan/execute.ts +27 -0
- package/src/tool/code_refactor_plan/guidance.ts +8 -0
- package/src/tool/{refactor-plan/execute.ts → code_refactor_plan/result.ts} +13 -22
- package/src/tool/code_refactor_plan/spec.ts +25 -0
- package/src/tool/code_refactor_plan/tui.ts +54 -0
- package/src/tool/code_resolve/execute.ts +19 -0
- package/src/tool/code_resolve/guidance.ts +8 -0
- package/src/tool/{resolve → code_resolve}/markdown.ts +1 -1
- package/src/tool/{result/resolve.ts → code_resolve/result.ts} +79 -29
- package/src/tool/code_resolve/spec.ts +25 -0
- package/src/tool/code_resolve/tui.ts +60 -0
- package/src/tool/guidance.ts +71 -52
- package/src/tool/infra/truncate.ts +40 -0
- package/src/tool/infra/workflow-control.ts +8 -0
- package/src/tool/{refactor-plan/markdown.ts → refactor-markdown.ts} +4 -7
- package/src/tool/register.ts +105 -88
- package/src/tool/result/display.ts +107 -0
- package/src/tool/result/errors.ts +20 -17
- package/src/tool/result/refactor.ts +37 -8
- package/src/tool/result/types.ts +20 -0
- package/src/tool/schemas.ts +26 -157
- package/src/tool/specs.ts +40 -126
- package/src/types/execution.ts +18 -5
- package/src/types/index.ts +8 -1
- package/src/ui/status-command.ts +5 -3
- package/src/ui/status-overlay.ts +4 -0
- package/src/ui/tui/common.ts +108 -10
- package/src/ui/tui/display.ts +48 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime.ts +0 -351
- package/src/tool/find/tui.ts +0 -39
- package/src/tool/graph/execute.ts +0 -62
- package/src/tool/graph/tui.ts +0 -104
- package/src/tool/inspect/tui.ts +0 -36
- package/src/tool/orientation/execute.ts +0 -62
- package/src/tool/refactor-apply/tui.ts +0 -55
- package/src/tool/refactor-plan/tui.ts +0 -41
- package/src/tool/resolve/execute.ts +0 -36
- package/src/tool/resolve/tui.ts +0 -42
- package/src/tool/result/orientation.ts +0 -132
- /package/src/tool/{find → code_find}/ast-kinds.ts +0 -0
- /package/src/tool/{find → code_find}/markdown.ts +0 -0
- /package/src/tool/{find → code_find}/modes.ts +0 -0
- /package/src/tool/{health → code_health}/semantic-state.ts +0 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
// biome-ignore-all lint/style/noExcessiveLinesPerFile: raw parser and query ownership stays in one Worker-only module
|
|
2
|
+
// Tree-sitter runtime — parser management, parse, and query services.
|
|
3
|
+
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { resolveToolPath } from "@mrclrchtr/supi-core/path";
|
|
6
|
+
import type { Language, Parser, Tree } from "web-tree-sitter";
|
|
7
|
+
import { detectGrammar, resolveGrammarWasmPath } from "../language.ts";
|
|
8
|
+
import {
|
|
9
|
+
finishStructuralTiming,
|
|
10
|
+
type ParseTimingPhase,
|
|
11
|
+
type QueryTimingPhase,
|
|
12
|
+
type StructuralTimingEvent,
|
|
13
|
+
startStructuralTiming,
|
|
14
|
+
} from "../session/structural-timing.ts";
|
|
15
|
+
import type { GrammarId, QueryCapture, TreeSitterResult } from "../types.ts";
|
|
16
|
+
import {
|
|
17
|
+
ParsedFileReadError,
|
|
18
|
+
ParsedFileStore,
|
|
19
|
+
type StructuralCacheObservation,
|
|
20
|
+
} from "./parsed-file-store.ts";
|
|
21
|
+
import {
|
|
22
|
+
isStructuralRequestInterrupted,
|
|
23
|
+
isStructuralRequestInterruption,
|
|
24
|
+
type StructuralRequestControl,
|
|
25
|
+
throwIfStructuralRequestInterrupted,
|
|
26
|
+
} from "./request-control.ts";
|
|
27
|
+
import { resetInterruptedParser } from "./runtime-parser-helpers.ts";
|
|
28
|
+
import {
|
|
29
|
+
collectQueryCaptures,
|
|
30
|
+
formatRuntimeError,
|
|
31
|
+
validateQueryString,
|
|
32
|
+
} from "./runtime-query-helpers.ts";
|
|
33
|
+
|
|
34
|
+
interface ParserEntry {
|
|
35
|
+
parser: Parser;
|
|
36
|
+
language: Language;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const QUERY_PARSED_FILE = Symbol("query-parsed-file");
|
|
40
|
+
|
|
41
|
+
interface ParsedQueryInput {
|
|
42
|
+
readonly grammarId: GrammarId;
|
|
43
|
+
readonly tree: Tree;
|
|
44
|
+
readonly source: string;
|
|
45
|
+
readonly queryString: string;
|
|
46
|
+
readonly control?: StructuralRequestControl;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Session-scoped Tree-sitter runtime.
|
|
51
|
+
*
|
|
52
|
+
* A runtime owns the expensive `web-tree-sitter` initialization and parser
|
|
53
|
+
* instances for one pi working directory. Call `dispose()` when the session is
|
|
54
|
+
* torn down so WASM parser resources are released.
|
|
55
|
+
*/
|
|
56
|
+
export class TreeSitterRuntime {
|
|
57
|
+
private parserModule: typeof import("web-tree-sitter") | undefined;
|
|
58
|
+
private parsers = new Map<GrammarId, ParserEntry>();
|
|
59
|
+
private parsedFiles = new ParsedFileStore();
|
|
60
|
+
private parserPromises = new Map<GrammarId, Promise<ParserEntry>>();
|
|
61
|
+
private initPromise: Promise<typeof import("web-tree-sitter")> | undefined;
|
|
62
|
+
private initializing = false;
|
|
63
|
+
private disposed = false;
|
|
64
|
+
|
|
65
|
+
/** Create a runtime that resolves relative file paths from `cwd`. */
|
|
66
|
+
constructor(
|
|
67
|
+
private cwd: string,
|
|
68
|
+
private onTiming?: (event: StructuralTimingEvent) => void,
|
|
69
|
+
) {}
|
|
70
|
+
|
|
71
|
+
/** Ensure web-tree-sitter Parser is initialized. */
|
|
72
|
+
private async ensureParserInit(): Promise<typeof import("web-tree-sitter")> {
|
|
73
|
+
this.assertActive();
|
|
74
|
+
if (this.parserModule) return this.parserModule;
|
|
75
|
+
if (this.initializing && this.initPromise) return this.initPromise;
|
|
76
|
+
|
|
77
|
+
this.initializing = true;
|
|
78
|
+
this.initPromise = (async () => {
|
|
79
|
+
const mod = await import("web-tree-sitter");
|
|
80
|
+
await mod.Parser.init();
|
|
81
|
+
this.assertActive();
|
|
82
|
+
this.parserModule = mod;
|
|
83
|
+
return mod;
|
|
84
|
+
})();
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
return await this.initPromise;
|
|
88
|
+
} catch (err: unknown) {
|
|
89
|
+
// Allow retry on next call
|
|
90
|
+
this.initPromise = undefined;
|
|
91
|
+
this.initializing = false;
|
|
92
|
+
throw new Error("Failed to initialize web-tree-sitter", { cause: err });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Get or create a parser entry for a grammar.
|
|
98
|
+
*
|
|
99
|
+
* Concurrent first-use calls for the same grammar share one initialization
|
|
100
|
+
* promise. Failed initialization is not cached, so a later request can retry.
|
|
101
|
+
*/
|
|
102
|
+
async ensureGrammarParser(grammarId: GrammarId): Promise<ParserEntry> {
|
|
103
|
+
this.assertActive();
|
|
104
|
+
const existing = this.parsers.get(grammarId);
|
|
105
|
+
if (existing) return existing;
|
|
106
|
+
|
|
107
|
+
const pending = this.parserPromises.get(grammarId);
|
|
108
|
+
if (pending) return pending;
|
|
109
|
+
|
|
110
|
+
const promise = this.createGrammarParser(grammarId);
|
|
111
|
+
this.parserPromises.set(grammarId, promise);
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
return await promise;
|
|
115
|
+
} finally {
|
|
116
|
+
if (this.parserPromises.get(grammarId) === promise) {
|
|
117
|
+
this.parserPromises.delete(grammarId);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private async createGrammarParser(grammarId: GrammarId): Promise<ParserEntry> {
|
|
123
|
+
const mod = await this.ensureParserInit();
|
|
124
|
+
const wasmPath = resolveGrammarWasmPath(grammarId);
|
|
125
|
+
|
|
126
|
+
const language = await mod.Language.load(wasmPath);
|
|
127
|
+
const parser = new mod.Parser();
|
|
128
|
+
try {
|
|
129
|
+
parser.setLanguage(language);
|
|
130
|
+
} catch (err) {
|
|
131
|
+
deleteWasmResource(parser);
|
|
132
|
+
throw err;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (this.disposed) {
|
|
136
|
+
deleteWasmResource(parser);
|
|
137
|
+
throw new Error("Tree-sitter runtime has been disposed");
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const entry = { parser, language };
|
|
141
|
+
this.parsers.set(grammarId, entry);
|
|
142
|
+
return entry;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Read and parse a file.
|
|
147
|
+
*
|
|
148
|
+
* The returned tree is an owned shallow copy. The caller must delete it.
|
|
149
|
+
* Canonical cached trees never leave the parsed-file store.
|
|
150
|
+
*/
|
|
151
|
+
async parseFile(
|
|
152
|
+
filePath: string,
|
|
153
|
+
control?: StructuralRequestControl,
|
|
154
|
+
): Promise<
|
|
155
|
+
TreeSitterResult<{
|
|
156
|
+
tree: Tree;
|
|
157
|
+
source: string;
|
|
158
|
+
resolvedPath: string;
|
|
159
|
+
grammarId: GrammarId;
|
|
160
|
+
}>
|
|
161
|
+
> {
|
|
162
|
+
const resolvedPath = resolveToolPath(this.cwd, filePath);
|
|
163
|
+
const grammarId = detectGrammar(filePath);
|
|
164
|
+
if (!grammarId) {
|
|
165
|
+
return {
|
|
166
|
+
kind: "unsupported-language",
|
|
167
|
+
file: filePath,
|
|
168
|
+
message: `No Tree-sitter grammar configured for ${path.extname(filePath) || "this file type"}`,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const timer = startStructuralTiming(control?.operationId, this.onTiming);
|
|
173
|
+
const parserState = this.parsers.has(grammarId)
|
|
174
|
+
? "reused"
|
|
175
|
+
: this.parserPromises.has(grammarId)
|
|
176
|
+
? "initializing"
|
|
177
|
+
: "cold";
|
|
178
|
+
let finalPhase: ParseTimingPhase = "file-read";
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
const parsed = await this.parsedFiles.acquireParsedFile({
|
|
182
|
+
resolvedPath,
|
|
183
|
+
grammarId,
|
|
184
|
+
control,
|
|
185
|
+
onPhase: (phase) => {
|
|
186
|
+
timer.mark(phase);
|
|
187
|
+
finalPhase = phase === "file-read" ? "content-hash" : "cache-lookup";
|
|
188
|
+
},
|
|
189
|
+
parse: async (source) => {
|
|
190
|
+
finalPhase = "parser-setup";
|
|
191
|
+
let entry = await this.ensureGrammarParser(grammarId);
|
|
192
|
+
this.assertActive();
|
|
193
|
+
throwIfStructuralRequestInterrupted(control);
|
|
194
|
+
if (this.parsers.get(grammarId) !== entry) {
|
|
195
|
+
entry = await this.ensureGrammarParser(grammarId);
|
|
196
|
+
this.assertActive();
|
|
197
|
+
throwIfStructuralRequestInterrupted(control);
|
|
198
|
+
}
|
|
199
|
+
timer.mark("parser-setup");
|
|
200
|
+
finalPhase = "parse";
|
|
201
|
+
const tree = entry.parser.parse(source, undefined, {
|
|
202
|
+
progressCallback: () => isStructuralRequestInterrupted(control),
|
|
203
|
+
});
|
|
204
|
+
if (!tree) {
|
|
205
|
+
resetInterruptedParser(this.parsers, grammarId, entry);
|
|
206
|
+
throwIfStructuralRequestInterrupted(control);
|
|
207
|
+
throw new Error("Tree-sitter parser did not produce a tree");
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
throwIfStructuralRequestInterrupted(control);
|
|
211
|
+
return tree;
|
|
212
|
+
} catch (error) {
|
|
213
|
+
tree.delete();
|
|
214
|
+
throw error;
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
finishStructuralTiming(timer, {
|
|
219
|
+
operation: "parse",
|
|
220
|
+
grammar: grammarId,
|
|
221
|
+
parserState,
|
|
222
|
+
outcome: "completed",
|
|
223
|
+
cache: parsed.cache,
|
|
224
|
+
finalPhase,
|
|
225
|
+
});
|
|
226
|
+
return {
|
|
227
|
+
kind: "success",
|
|
228
|
+
data: {
|
|
229
|
+
tree: parsed.tree,
|
|
230
|
+
source: parsed.source,
|
|
231
|
+
resolvedPath: parsed.resolvedPath,
|
|
232
|
+
grammarId: parsed.grammarId,
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
} catch (err: unknown) {
|
|
236
|
+
if (isStructuralRequestInterruption(err, control)) {
|
|
237
|
+
finishStructuralTiming(timer, {
|
|
238
|
+
operation: "parse",
|
|
239
|
+
grammar: grammarId,
|
|
240
|
+
parserState,
|
|
241
|
+
outcome: control?.signal?.aborted ? "cancelled" : "timeout",
|
|
242
|
+
finalPhase,
|
|
243
|
+
});
|
|
244
|
+
throw err;
|
|
245
|
+
}
|
|
246
|
+
if (err instanceof ParsedFileReadError) {
|
|
247
|
+
finishStructuralTiming(timer, {
|
|
248
|
+
operation: "parse",
|
|
249
|
+
grammar: grammarId,
|
|
250
|
+
parserState,
|
|
251
|
+
outcome: "file-access-error",
|
|
252
|
+
finalPhase: "file-read",
|
|
253
|
+
});
|
|
254
|
+
return { kind: "file-access-error", file: filePath, message: err.message };
|
|
255
|
+
}
|
|
256
|
+
finishStructuralTiming(timer, {
|
|
257
|
+
operation: "parse",
|
|
258
|
+
grammar: grammarId,
|
|
259
|
+
parserState,
|
|
260
|
+
outcome: "runtime-error",
|
|
261
|
+
finalPhase,
|
|
262
|
+
});
|
|
263
|
+
return {
|
|
264
|
+
kind: "runtime-error",
|
|
265
|
+
message: formatRuntimeError(err, "Parser initialization failed"),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** Execute a Tree-sitter query against a file. */
|
|
271
|
+
async queryFile(
|
|
272
|
+
filePath: string,
|
|
273
|
+
queryString: string,
|
|
274
|
+
control?: StructuralRequestControl,
|
|
275
|
+
): Promise<TreeSitterResult<QueryCapture[]>> {
|
|
276
|
+
const validation = validateQueryString(queryString);
|
|
277
|
+
if (validation) return validation;
|
|
278
|
+
|
|
279
|
+
const parseResult = await this.parseFile(filePath, control);
|
|
280
|
+
if (parseResult.kind !== "success") return parseResult;
|
|
281
|
+
|
|
282
|
+
const { grammarId, tree, source } = parseResult.data;
|
|
283
|
+
try {
|
|
284
|
+
return await this[QUERY_PARSED_FILE]({ grammarId, tree, source, queryString, control });
|
|
285
|
+
} finally {
|
|
286
|
+
tree.delete();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** Execute a query against one caller-owned parsed tree without parsing again. */
|
|
291
|
+
async [QUERY_PARSED_FILE](input: ParsedQueryInput): Promise<TreeSitterResult<QueryCapture[]>> {
|
|
292
|
+
const { grammarId, tree, source, queryString, control } = input;
|
|
293
|
+
const validation = validateQueryString(queryString);
|
|
294
|
+
if (validation) return validation;
|
|
295
|
+
|
|
296
|
+
const timer = startStructuralTiming(control?.operationId, this.onTiming);
|
|
297
|
+
let phase: QueryTimingPhase = "query-compilation";
|
|
298
|
+
let compilationStarted = false;
|
|
299
|
+
let cache: StructuralCacheObservation = {
|
|
300
|
+
state: "miss",
|
|
301
|
+
retained: false,
|
|
302
|
+
evictionCount: 0,
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
try {
|
|
306
|
+
let entry = await this.ensureGrammarParser(grammarId);
|
|
307
|
+
this.assertActive();
|
|
308
|
+
throwIfStructuralRequestInterrupted(control);
|
|
309
|
+
if (this.parsers.get(grammarId) !== entry) {
|
|
310
|
+
entry = await this.ensureGrammarParser(grammarId);
|
|
311
|
+
this.assertActive();
|
|
312
|
+
throwIfStructuralRequestInterrupted(control);
|
|
313
|
+
}
|
|
314
|
+
const mod = await this.ensureParserInit();
|
|
315
|
+
this.assertActive();
|
|
316
|
+
throwIfStructuralRequestInterrupted(control);
|
|
317
|
+
compilationStarted = true;
|
|
318
|
+
const execution = this.parsedFiles.withQuery(grammarId, queryString, {
|
|
319
|
+
control,
|
|
320
|
+
compile: () => {
|
|
321
|
+
const query = new mod.Query(entry.language, queryString);
|
|
322
|
+
timer.mark("query-compilation");
|
|
323
|
+
phase = "query-execution";
|
|
324
|
+
return query;
|
|
325
|
+
},
|
|
326
|
+
execute: (query, observation) => {
|
|
327
|
+
cache = observation;
|
|
328
|
+
if (observation.state === "hit") {
|
|
329
|
+
timer.mark("query-cache");
|
|
330
|
+
phase = "query-execution";
|
|
331
|
+
}
|
|
332
|
+
const matches = query.matches(tree.rootNode, {
|
|
333
|
+
progressCallback: () => isStructuralRequestInterrupted(control),
|
|
334
|
+
});
|
|
335
|
+
throwIfStructuralRequestInterrupted(control);
|
|
336
|
+
return collectQueryCaptures(matches, source);
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
finishStructuralTiming(timer, {
|
|
340
|
+
operation: "query",
|
|
341
|
+
grammar: grammarId,
|
|
342
|
+
outcome: "completed",
|
|
343
|
+
captureCount: execution.data.length,
|
|
344
|
+
cache: execution.cache,
|
|
345
|
+
finalPhase: "query-execution",
|
|
346
|
+
});
|
|
347
|
+
return { kind: "success", data: execution.data };
|
|
348
|
+
} catch (err: unknown) {
|
|
349
|
+
if (isStructuralRequestInterruption(err, control)) {
|
|
350
|
+
finishStructuralTiming(timer, {
|
|
351
|
+
operation: "query",
|
|
352
|
+
grammar: grammarId,
|
|
353
|
+
outcome: control?.signal?.aborted ? "cancelled" : "timeout",
|
|
354
|
+
captureCount: 0,
|
|
355
|
+
cache,
|
|
356
|
+
finalPhase: phase,
|
|
357
|
+
});
|
|
358
|
+
throw err;
|
|
359
|
+
}
|
|
360
|
+
const validationError = compilationStarted && phase === "query-compilation";
|
|
361
|
+
finishStructuralTiming(timer, {
|
|
362
|
+
operation: "query",
|
|
363
|
+
grammar: grammarId,
|
|
364
|
+
outcome: validationError ? "validation-error" : "runtime-error",
|
|
365
|
+
captureCount: 0,
|
|
366
|
+
cache,
|
|
367
|
+
finalPhase: phase,
|
|
368
|
+
});
|
|
369
|
+
return validationError
|
|
370
|
+
? { kind: "validation-error", message: `Invalid query: ${formatRuntimeError(err)}` }
|
|
371
|
+
: { kind: "runtime-error", message: formatRuntimeError(err, "Query execution failed") };
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/** Get the grammar ID for a file, or undefined if unsupported. */
|
|
376
|
+
getGrammarId(filePath: string): GrammarId | undefined {
|
|
377
|
+
return detectGrammar(filePath);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/** Resolve a file path from cwd. */
|
|
381
|
+
resolvePath(filePath: string): string {
|
|
382
|
+
return resolveToolPath(this.cwd, filePath);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/** Dispose all held tree, query, and parser resources. */
|
|
386
|
+
dispose(): void {
|
|
387
|
+
if (this.disposed) return;
|
|
388
|
+
this.disposed = true;
|
|
389
|
+
this.parsedFiles.dispose();
|
|
390
|
+
for (const [, entry] of this.parsers) {
|
|
391
|
+
deleteWasmResource(entry.parser);
|
|
392
|
+
}
|
|
393
|
+
this.parsers.clear();
|
|
394
|
+
this.parserPromises.clear();
|
|
395
|
+
this.parserModule = undefined;
|
|
396
|
+
this.initPromise = undefined;
|
|
397
|
+
this.initializing = false;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
private assertActive(): void {
|
|
401
|
+
if (this.disposed) {
|
|
402
|
+
throw new Error("Tree-sitter runtime has been disposed");
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/** Package-internal query execution for consumers that already own a parsed tree. */
|
|
408
|
+
export function queryParsedFile(
|
|
409
|
+
runtime: TreeSitterRuntime,
|
|
410
|
+
input: ParsedQueryInput,
|
|
411
|
+
): Promise<TreeSitterResult<QueryCapture[]>> {
|
|
412
|
+
return runtime[QUERY_PARSED_FILE](input);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function deleteWasmResource(resource: { delete(): void }): void {
|
|
416
|
+
try {
|
|
417
|
+
resource.delete();
|
|
418
|
+
} catch {
|
|
419
|
+
// Continue cleanup so one failed release does not retain other resources.
|
|
420
|
+
}
|
|
421
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { detectGrammar } from "../language.ts";
|
|
2
|
+
import { supportsGrammarOperation } from "../operation-support.ts";
|
|
3
|
+
import type { StructuralWorkerOperation } from "../session/structural-worker-protocol.ts";
|
|
4
|
+
import {
|
|
5
|
+
extractCallSites,
|
|
6
|
+
extractExports,
|
|
7
|
+
extractImports,
|
|
8
|
+
extractOutline,
|
|
9
|
+
lookupCalleesAt,
|
|
10
|
+
lookupNodeAt,
|
|
11
|
+
} from "../tool/structure.ts";
|
|
12
|
+
import type { TreeSitterResult } from "../types.ts";
|
|
13
|
+
import {
|
|
14
|
+
type StructuralRequestControl,
|
|
15
|
+
throwIfStructuralRequestInterrupted,
|
|
16
|
+
} from "./request-control.ts";
|
|
17
|
+
import type { TreeSitterRuntime } from "./runtime.ts";
|
|
18
|
+
|
|
19
|
+
/** Execute parser-backed operations in the Structural Worker. */
|
|
20
|
+
export class StructuralWorkerService {
|
|
21
|
+
constructor(private readonly runtime: TreeSitterRuntime) {}
|
|
22
|
+
|
|
23
|
+
async execute(
|
|
24
|
+
input: StructuralWorkerOperation,
|
|
25
|
+
control: StructuralRequestControl,
|
|
26
|
+
): Promise<TreeSitterResult<unknown>> {
|
|
27
|
+
throwIfStructuralRequestInterrupted(control);
|
|
28
|
+
switch (input.operation) {
|
|
29
|
+
case "canParse":
|
|
30
|
+
return this.#canParse(input.file, control);
|
|
31
|
+
case "query":
|
|
32
|
+
return this.runtime.queryFile(input.file, input.query, control);
|
|
33
|
+
case "outline":
|
|
34
|
+
return this.#outline(input.file, control);
|
|
35
|
+
case "imports":
|
|
36
|
+
return this.#imports(input.file, control);
|
|
37
|
+
case "exports":
|
|
38
|
+
return this.#exports(input.file, control);
|
|
39
|
+
case "nodeAt":
|
|
40
|
+
return lookupNodeAt(this.runtime, input.file, input.line, input.character, control);
|
|
41
|
+
case "calleesAt":
|
|
42
|
+
return lookupCalleesAt(
|
|
43
|
+
this.runtime,
|
|
44
|
+
input.file,
|
|
45
|
+
input.line,
|
|
46
|
+
input.character,
|
|
47
|
+
input.depth,
|
|
48
|
+
control,
|
|
49
|
+
);
|
|
50
|
+
case "callSites":
|
|
51
|
+
return extractCallSites(this.runtime, input.file, control);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async #canParse(
|
|
56
|
+
file: string,
|
|
57
|
+
control: StructuralRequestControl,
|
|
58
|
+
): Promise<TreeSitterResult<{ file: string; language: string }>> {
|
|
59
|
+
const result = await this.runtime.parseFile(file, control);
|
|
60
|
+
if (result.kind !== "success") return result;
|
|
61
|
+
const { resolvedPath, grammarId, tree } = result.data;
|
|
62
|
+
try {
|
|
63
|
+
return { kind: "success", data: { file: resolvedPath, language: grammarId } };
|
|
64
|
+
} finally {
|
|
65
|
+
tree.delete();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async #outline(
|
|
70
|
+
file: string,
|
|
71
|
+
control: StructuralRequestControl,
|
|
72
|
+
): Promise<TreeSitterResult<unknown>> {
|
|
73
|
+
const unsupported = unsupportedOperation(file, "outline");
|
|
74
|
+
if (unsupported) return unsupported;
|
|
75
|
+
const result = await this.runtime.parseFile(file, control);
|
|
76
|
+
if (result.kind !== "success") return result;
|
|
77
|
+
try {
|
|
78
|
+
throwIfStructuralRequestInterrupted(control);
|
|
79
|
+
return {
|
|
80
|
+
kind: "success",
|
|
81
|
+
data: extractOutline(result.data.tree.rootNode, result.data.source),
|
|
82
|
+
};
|
|
83
|
+
} finally {
|
|
84
|
+
result.data.tree.delete();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async #imports(
|
|
89
|
+
file: string,
|
|
90
|
+
control: StructuralRequestControl,
|
|
91
|
+
): Promise<TreeSitterResult<unknown>> {
|
|
92
|
+
const unsupported = unsupportedOperation(file, "imports");
|
|
93
|
+
return unsupported ?? extractImports(this.runtime, file, control);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async #exports(
|
|
97
|
+
file: string,
|
|
98
|
+
control: StructuralRequestControl,
|
|
99
|
+
): Promise<TreeSitterResult<unknown>> {
|
|
100
|
+
const unsupported = unsupportedOperation(file, "exports");
|
|
101
|
+
return unsupported ?? extractExports(this.runtime, file, control);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function unsupportedOperation(
|
|
106
|
+
file: string,
|
|
107
|
+
operation: "outline" | "imports" | "exports",
|
|
108
|
+
): TreeSitterResult<never> | null {
|
|
109
|
+
const grammarId = detectGrammar(file);
|
|
110
|
+
if (!grammarId || supportsGrammarOperation(grammarId, operation)) return null;
|
|
111
|
+
return {
|
|
112
|
+
kind: "unsupported-language",
|
|
113
|
+
file,
|
|
114
|
+
message: `${operation} is not supported for ${grammarId} files`,
|
|
115
|
+
};
|
|
116
|
+
}
|