@mrclrchtr/supi-code-intelligence 6.0.1 → 6.2.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 +2 -2
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +5 -0
- package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/debug-identity.ts +11 -0
- package/node_modules/@mrclrchtr/supi-core/src/debug.ts +5 -0
- package/node_modules/@mrclrchtr/supi-lsp/README.md +26 -4
- 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/capability/types.ts +5 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-identity.ts +11 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug.ts +5 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-jsonrpc/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.colorProvider.d.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.d.ts +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/lib/common/protocol.fileOperations.d.ts +9 -9
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-protocol/package.json +3 -3
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/lib/esm/main.d.ts +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/lib/esm/main.js +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/lib/umd/main.d.ts +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/lib/umd/main.js +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/vscode-languageserver-types/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/package.json +4 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +14 -7
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-capabilities.ts +0 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-publication.ts +6 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +2 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +5 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +2 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +23 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +40 -18
- package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +164 -30
- package/node_modules/@mrclrchtr/supi-lsp/src/config/lsp-settings.ts +9 -87
- package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +8 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-scope.ts +4 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/config/types.ts +1 -29
- package/node_modules/@mrclrchtr/supi-lsp/src/debug-telemetry.ts +7 -21
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostic-severity.ts +6 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostic-summary.ts +11 -14
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +0 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/stale-diagnostics.ts +0 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/workspace-sentinels.ts +29 -49
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-client-state.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +4 -8
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-helpers.ts +1 -9
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +12 -6
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +9 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-symbol.ts +26 -41
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +849 -117
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +6 -4
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-symbol-mapper.ts +59 -28
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +27 -19
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +10 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +26 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registration.ts +0 -17
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +118 -27
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-transition-debug.ts +7 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/session/scanner.ts +24 -21
- package/node_modules/@mrclrchtr/supi-lsp/src/session/workspace-lsp-runtime.ts +33 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/summary.ts +19 -40
- package/node_modules/@mrclrchtr/supi-lsp/src/utils.ts +13 -19
- package/node_modules/@mrclrchtr/supi-lsp/src/workspace-path-policy.ts +287 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +6 -18
- 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/capability/types.ts +5 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-identity.ts +11 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug.ts +5 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -5
- package/node_modules/@mrclrchtr/supi-tree-sitter/resources/grammars/kotlin/tree-sitter-kotlin.wasm.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/resources/grammars/sql/tree-sitter-sql.wasm.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +1 -11
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/coordinates.ts +19 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/language.ts +5 -23
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/operation-support.ts +3 -21
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +5 -9
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +10 -20
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +7 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client.ts +9 -5
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-protocol.ts +134 -9
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-name.ts +96 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +11 -12
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +39 -56
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/exports.ts +9 -7
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/js-binding-pattern.ts +26 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/node-at.ts +2 -21
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-html-sql.ts +144 -12
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline.ts +50 -37
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/scope.ts +138 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +0 -7
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store.ts +1 -14
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime.ts +0 -10
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/service.ts +6 -8
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/worker-main.ts +34 -10
- package/package.json +5 -5
- package/src/analysis/capability/capability-warnings.ts +4 -22
- package/src/analysis/health/recovery.ts +4 -0
- package/src/analysis/health/server-status.ts +64 -0
- package/src/analysis/health/signals.ts +1 -0
- package/src/analysis/provider.ts +2 -1
- package/src/analysis/search/ast-scan-timing.ts +4 -2
- package/src/analysis/search/ast-scan.ts +1 -1
- package/src/analysis/target/symbol.ts +28 -16
- package/src/analysis/target/types.ts +1 -0
- package/src/api.ts +1 -0
- package/src/extension.ts +4 -2
- package/src/session/find-workflow.ts +5 -12
- package/src/session/health-refresh.ts +30 -4
- package/src/session/health-types.ts +27 -2
- package/src/session/health-workflow.ts +5 -1
- package/src/session/input/health-refactor.ts +16 -14
- package/src/session/refactor-types.ts +14 -1
- package/src/session/refactor-workflow.ts +21 -16
- package/src/session/semantic-demand.ts +36 -0
- package/src/session/target-workflow.ts +9 -12
- package/src/substrate/lsp/lifecycle.ts +0 -3
- package/src/substrate/lsp/maintenance.ts +4 -5
- package/src/substrate/lsp/settings.ts +6 -9
- package/src/substrate/lsp/state.ts +0 -2
- package/src/substrate/workspace-provider-host.ts +2 -2
- package/src/tool/code_health/file-scope-markdown.ts +43 -0
- package/src/tool/code_health/guidance.ts +2 -2
- package/src/tool/code_health/markdown.ts +81 -69
- package/src/tool/code_health/refresh-outcome.ts +46 -0
- package/src/tool/code_health/refresh-status.ts +166 -23
- package/src/tool/code_health/result.ts +15 -5
- package/src/tool/code_health/spec.ts +2 -1
- package/src/tool/code_health/tui.ts +42 -8
- package/src/tool/code_refactor_apply/guidance.ts +3 -2
- package/src/tool/code_refactor_plan/guidance.ts +1 -1
- package/src/tool/register.ts +5 -2
- package/src/tool/result/errors.ts +1 -0
- package/src/tool/result/types.ts +6 -0
- package/src/tool/schemas.ts +21 -11
- package/src/ui/footer.ts +7 -5
- package/src/ui/status-command.ts +31 -0
- package/src/ui/status-overlay.ts +69 -23
- package/node_modules/@mrclrchtr/supi-lsp/src/config/server-actions.ts +0 -59
- package/node_modules/@mrclrchtr/supi-lsp/src/pattern-matcher.ts +0 -24
- package/node_modules/@mrclrchtr/supi-tree-sitter/scripts/generate-kotlin-wasm.mjs +0 -132
- package/node_modules/@mrclrchtr/supi-tree-sitter/scripts/generate-sql-wasm.mjs +0 -158
- package/node_modules/@mrclrchtr/supi-tree-sitter/scripts/vendor-wasm.mjs +0 -167
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +0 -42
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-registration.ts +0 -37
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/service-registry.ts +0 -30
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/structure.ts +0 -8
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { GrammarId } from "../types.ts";
|
|
2
|
+
|
|
3
|
+
/** Normalize one grammar node that represents a call callee. */
|
|
4
|
+
export function normalizeCallName(text: string, grammarId: GrammarId, nodeType: string): string {
|
|
5
|
+
const normalized = text.trim().replace(/\s+/g, " ");
|
|
6
|
+
switch (grammarId) {
|
|
7
|
+
case "java":
|
|
8
|
+
return nodeType === "method_invocation"
|
|
9
|
+
? stripFinalInvocationArguments(normalized)
|
|
10
|
+
: normalized;
|
|
11
|
+
case "kotlin":
|
|
12
|
+
return nodeType === "call_expression" ? stripKotlinCallSuffix(normalized) : normalized;
|
|
13
|
+
case "ruby":
|
|
14
|
+
return nodeType === "call" ? stripRubyCallSuffix(normalized) : normalized;
|
|
15
|
+
default:
|
|
16
|
+
return normalized;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function stripKotlinCallSuffix(text: string): string {
|
|
21
|
+
const lambda = topLevelIndex(text, "{");
|
|
22
|
+
const withoutLambda = lambda >= 0 ? text.slice(0, lambda).trim() : text;
|
|
23
|
+
return stripFinalInvocationArguments(withoutLambda);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function stripRubyCallSuffix(text: string): string {
|
|
27
|
+
const block = topLevelKeywordIndex(text, "do");
|
|
28
|
+
const withoutBlock = block >= 0 ? text.slice(0, block).trim() : text;
|
|
29
|
+
const bracedBlock = topLevelIndex(withoutBlock, "{");
|
|
30
|
+
const withoutSuffix = bracedBlock >= 0 ? withoutBlock.slice(0, bracedBlock).trim() : withoutBlock;
|
|
31
|
+
const withoutArguments = stripFinalInvocationArguments(withoutSuffix);
|
|
32
|
+
const whitespace = topLevelWhitespaceIndex(withoutArguments);
|
|
33
|
+
return whitespace >= 0 ? withoutArguments.slice(0, whitespace).trim() : withoutArguments;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function stripFinalInvocationArguments(text: string): string {
|
|
37
|
+
if (!text.endsWith(")")) return text;
|
|
38
|
+
const openingIndex = findLastTopLevelOpening(text);
|
|
39
|
+
return openingIndex >= 0 ? text.slice(0, openingIndex).trim() : text;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function findLastTopLevelOpening(text: string): number {
|
|
43
|
+
let openingIndex = -1;
|
|
44
|
+
scanTopLevel(text, (character, index, depth) => {
|
|
45
|
+
if (character === "(" && depth === 0) openingIndex = index;
|
|
46
|
+
return false;
|
|
47
|
+
});
|
|
48
|
+
return openingIndex;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function topLevelKeywordIndex(text: string, keyword: string): number {
|
|
52
|
+
const marker = ` ${keyword}`;
|
|
53
|
+
const index = topLevelIndex(text, marker);
|
|
54
|
+
return index >= 0 ? index + 1 : -1;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function topLevelIndex(text: string, marker: string): number {
|
|
58
|
+
return scanTopLevel(
|
|
59
|
+
text,
|
|
60
|
+
(_character, index, depth) => depth === 0 && text.startsWith(marker, index),
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function topLevelWhitespaceIndex(text: string): number {
|
|
65
|
+
return scanTopLevel(text, (character, _index, depth) => depth === 0 && /\s/.test(character));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function scanTopLevel(
|
|
69
|
+
text: string,
|
|
70
|
+
visit: (character: string, index: number, depth: number) => boolean,
|
|
71
|
+
): number {
|
|
72
|
+
let depth = 0;
|
|
73
|
+
let quote: string | null = null;
|
|
74
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
75
|
+
const character = text[index] ?? "";
|
|
76
|
+
if (quote !== null) {
|
|
77
|
+
if (character === quote && text[index - 1] !== "\\") quote = null;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (character === '"' || character === "'") {
|
|
81
|
+
quote = character;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (visit(character, index, depth)) return index;
|
|
85
|
+
depth = updateDepth(character, depth);
|
|
86
|
+
}
|
|
87
|
+
return -1;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function updateDepth(character: string, depth: number): number {
|
|
91
|
+
if (character === "(" || character === "[" || character === "{") return depth + 1;
|
|
92
|
+
if (character === ")" || character === "]" || character === "}") {
|
|
93
|
+
return Math.max(0, depth - 1);
|
|
94
|
+
}
|
|
95
|
+
return depth;
|
|
96
|
+
}
|
|
@@ -4,6 +4,7 @@ import type { CodeRequestControl } from "@mrclrchtr/supi-code-runtime/api";
|
|
|
4
4
|
import { detectGrammar } from "../language.ts";
|
|
5
5
|
import type { CallSiteMatch, GrammarId, TreeSitterResult } from "../types.ts";
|
|
6
6
|
import type { TreeSitterRuntime } from "../worker/runtime.ts";
|
|
7
|
+
import { normalizeCallName } from "./call-name.ts";
|
|
7
8
|
|
|
8
9
|
// ── Per-grammar call-site queries ─────────────────────────────────────
|
|
9
10
|
|
|
@@ -21,18 +22,16 @@ const CALL_SITE_QUERIES: Partial<Record<GrammarId, string>> = {
|
|
|
21
22
|
javascript: JS_TS_CALL_SITE_QUERY,
|
|
22
23
|
typescript: JS_TS_CALL_SITE_QUERY,
|
|
23
24
|
tsx: JS_TS_CALL_SITE_QUERY,
|
|
24
|
-
python:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"(call_expression . (simple_identifier) @call) (call_expression . (navigation_expression . (simple_identifier) @call))",
|
|
33
|
-
ruby: "(call method: (identifier) @call)",
|
|
25
|
+
python: "(call function: (_) @call)",
|
|
26
|
+
rust: "(call_expression function: (_) @call) (macro_invocation macro: (_) @call)",
|
|
27
|
+
go: "(call_expression function: (_) @call)",
|
|
28
|
+
c: "(call_expression function: (_) @call)",
|
|
29
|
+
cpp: "(call_expression function: (_) @call)",
|
|
30
|
+
java: "(method_invocation) @call (object_creation_expression type: (_) @call)",
|
|
31
|
+
kotlin: "(call_expression) @call",
|
|
32
|
+
ruby: "(call) @call",
|
|
34
33
|
bash: "(command name: (command_name) @call)",
|
|
35
|
-
r: "(call function: (
|
|
34
|
+
r: "(call function: (_) @call)",
|
|
36
35
|
};
|
|
37
36
|
|
|
38
37
|
/** Return whether the call-site extractor has a query for one grammar. */
|
|
@@ -78,7 +77,7 @@ export async function extractCallSites(
|
|
|
78
77
|
|
|
79
78
|
for (const capture of captures) {
|
|
80
79
|
// Normalize: trim whitespace and collapse internal whitespace to single space
|
|
81
|
-
const name = capture.text
|
|
80
|
+
const name = normalizeCallName(capture.text, grammarId, capture.nodeType);
|
|
82
81
|
if (name.length === 0) continue;
|
|
83
82
|
|
|
84
83
|
// Deduplicate by name + line
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// Structural callee extraction — enclosing-scope lookup with per-language queries.
|
|
2
2
|
|
|
3
3
|
import type { CodeRequestControl } from "@mrclrchtr/supi-code-runtime/api";
|
|
4
|
+
import { validatePublicPositionBounds } from "../coordinates.ts";
|
|
4
5
|
import { detectGrammar } from "../language.ts";
|
|
5
6
|
import type { GrammarId, SourceRange, TreeSitterResult } from "../types.ts";
|
|
6
7
|
import { queryParsedFile, type TreeSitterRuntime } from "../worker/runtime.ts";
|
|
8
|
+
import { normalizeCallName } from "./call-name.ts";
|
|
9
|
+
import { extractScopeName } from "./scope.ts";
|
|
7
10
|
|
|
8
11
|
/** Result shape returned by lookupCalleesAt. */
|
|
9
12
|
export interface CalleesAtResult {
|
|
@@ -25,13 +28,13 @@ const CALLEE_QUERIES: Partial<Record<GrammarId, string>> = {
|
|
|
25
28
|
typescript: "(call_expression function: (_) @callee) (new_expression constructor: (_) @callee)",
|
|
26
29
|
tsx: "(call_expression function: (_) @callee) (new_expression constructor: (_) @callee)",
|
|
27
30
|
python: "(call function: (_) @callee)",
|
|
28
|
-
rust: "(call_expression function: (_) @callee) (macro_invocation) @callee",
|
|
31
|
+
rust: "(call_expression function: (_) @callee) (macro_invocation macro: (_) @callee)",
|
|
29
32
|
go: "(call_expression function: (_) @callee)",
|
|
30
33
|
c: "(call_expression function: (_) @callee)",
|
|
31
34
|
cpp: "(call_expression function: (_) @callee)",
|
|
32
|
-
java: "(method_invocation
|
|
33
|
-
kotlin: "(call_expression
|
|
34
|
-
ruby: "(call
|
|
35
|
+
java: "(method_invocation) @callee (object_creation_expression type: (_) @callee)",
|
|
36
|
+
kotlin: "(call_expression) @callee",
|
|
37
|
+
ruby: "(call) @callee",
|
|
35
38
|
bash: "(command . (_) @callee)",
|
|
36
39
|
r: "(call function: (_) @callee)",
|
|
37
40
|
};
|
|
@@ -57,63 +60,22 @@ const ENCLOSING_SCOPE_TYPES: Record<GrammarId, ReadonlySet<string>> = {
|
|
|
57
60
|
"arrow_function",
|
|
58
61
|
"function_expression",
|
|
59
62
|
]),
|
|
60
|
-
python: new Set(["function_definition"]),
|
|
61
|
-
rust: new Set(["function_item"]),
|
|
62
|
-
go: new Set(["function_declaration"]),
|
|
63
|
+
python: new Set(["function_definition", "lambda"]),
|
|
64
|
+
rust: new Set(["function_item", "closure_expression"]),
|
|
65
|
+
go: new Set(["function_declaration", "method_declaration", "func_literal"]),
|
|
63
66
|
c: new Set(["function_definition"]),
|
|
64
|
-
cpp: new Set(["function_definition"]),
|
|
65
|
-
java: new Set(["method_declaration"]),
|
|
66
|
-
kotlin: new Set(["function_declaration"]),
|
|
67
|
-
ruby: new Set(["method"]),
|
|
67
|
+
cpp: new Set(["function_definition", "lambda_expression"]),
|
|
68
|
+
java: new Set(["method_declaration", "constructor_declaration", "lambda_expression"]),
|
|
69
|
+
kotlin: new Set(["function_declaration", "lambda_literal", "anonymous_function"]),
|
|
70
|
+
ruby: new Set(["method", "block", "do_block", "lambda"]),
|
|
68
71
|
bash: new Set(["function_definition"]),
|
|
69
72
|
r: new Set(["function_definition"]),
|
|
70
73
|
html: new Set(),
|
|
71
74
|
sql: new Set(),
|
|
72
75
|
};
|
|
73
76
|
|
|
74
|
-
// ── Name extraction from enclosing scope text ─────────────────────────
|
|
75
|
-
|
|
76
|
-
/** Extract a best-effort name from an enclosing scope node's source text. */
|
|
77
|
-
function extractScopeName(_type: string, text: string): string {
|
|
78
|
-
// JS/TS/Go/Rust: `function foo` or `fn foo` or `def foo`
|
|
79
|
-
// Python: `def foo`
|
|
80
|
-
const firstLine = text.split("\n")[0] ?? text;
|
|
81
|
-
const match = firstLine.match(/(?:function|fn|func|def|method)\s+(\w+)/);
|
|
82
|
-
if (match?.[1]) return match[1];
|
|
83
|
-
|
|
84
|
-
// Ruby: `def foo`
|
|
85
|
-
const rubyMatch = firstLine.match(/def\s+(\w+)/);
|
|
86
|
-
if (rubyMatch?.[1]) return rubyMatch[1];
|
|
87
|
-
|
|
88
|
-
// Bash: `foo()`
|
|
89
|
-
const bashMatch = firstLine.match(/^(\w+)\s*\(\)/);
|
|
90
|
-
if (bashMatch?.[1]) return bashMatch[1];
|
|
91
|
-
|
|
92
|
-
// Kotlin/Java: `fun foo` or `fun Foo.bar()` — extract the last name part
|
|
93
|
-
const kotlinMatch = firstLine.match(/fun\s+(?:[\w.]+\.)?(\w+)/);
|
|
94
|
-
if (kotlinMatch?.[1]) return kotlinMatch[1];
|
|
95
|
-
|
|
96
|
-
// C++: type name(params) { — heuristic: first word before `(`
|
|
97
|
-
const cLikeMatch = firstLine.match(
|
|
98
|
-
/(\w+)\s*\([^)]*\)\s*(?:const\s*)?(?:override\s*)?(?:final\s*)?[{;]/,
|
|
99
|
-
);
|
|
100
|
-
if (cLikeMatch?.[1]) return cLikeMatch[1];
|
|
101
|
-
|
|
102
|
-
return "anonymous";
|
|
103
|
-
}
|
|
104
|
-
|
|
105
77
|
// ── Main entrypoint ──────────────────────────────────────────────────
|
|
106
78
|
|
|
107
|
-
/**
|
|
108
|
-
* Extract direct structural callee calls for a file at the given position.
|
|
109
|
-
*
|
|
110
|
-
* 1. Parses the file with the Tree-sitter runtime.
|
|
111
|
-
* 2. Finds the enclosing function/method/callback scope at the position.
|
|
112
|
-
* 3. Runs a grammar-specific callee query.
|
|
113
|
-
* 4. Filters to captures within that enclosing scope.
|
|
114
|
-
* 5. Excludes nested function/method/callback scopes that do not contain the anchor.
|
|
115
|
-
* 6. Deduplicates by name.
|
|
116
|
-
*/
|
|
117
79
|
/** Validate that coordinates are usable and grammar is supported. */
|
|
118
80
|
function validateCalleeInput(
|
|
119
81
|
filePath: string,
|
|
@@ -168,6 +130,16 @@ function findEnclosingScope(
|
|
|
168
130
|
return null;
|
|
169
131
|
}
|
|
170
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Extract direct structural callee calls for a file at the given position.
|
|
135
|
+
*
|
|
136
|
+
* 1. Parses the file with the Tree-sitter runtime.
|
|
137
|
+
* 2. Finds the enclosing function/method/callback scope at the position.
|
|
138
|
+
* 3. Runs a grammar-specific callee query.
|
|
139
|
+
* 4. Filters to captures within that enclosing scope.
|
|
140
|
+
* 5. Excludes nested function/method/callback scopes that do not contain the anchor.
|
|
141
|
+
* 6. Deduplicates by name.
|
|
142
|
+
*/
|
|
171
143
|
// biome-ignore lint/complexity/useMaxParams: provider function needs runtime + coordinates + depth
|
|
172
144
|
export async function lookupCalleesAt(
|
|
173
145
|
runtime: TreeSitterRuntime,
|
|
@@ -189,6 +161,9 @@ export async function lookupCalleesAt(
|
|
|
189
161
|
const { tree, source } = parseResult.data;
|
|
190
162
|
|
|
191
163
|
try {
|
|
164
|
+
const boundsError = validatePublicPositionBounds(line, character, source);
|
|
165
|
+
if (boundsError) return boundsError;
|
|
166
|
+
|
|
192
167
|
const scopes = ENCLOSING_SCOPE_TYPES[grammarId];
|
|
193
168
|
const tsPoint = { row: line - 1, column: character - 1 };
|
|
194
169
|
const node = tree.rootNode.descendantForPosition(tsPoint);
|
|
@@ -230,10 +205,17 @@ export async function lookupCalleesAt(
|
|
|
230
205
|
};
|
|
231
206
|
}
|
|
232
207
|
|
|
233
|
-
const callees = filterCalleeCaptures(
|
|
208
|
+
const callees = filterCalleeCaptures(
|
|
209
|
+
queryResult.data,
|
|
210
|
+
grammarId,
|
|
211
|
+
enclosingNode,
|
|
212
|
+
scopes,
|
|
213
|
+
tsPoint,
|
|
214
|
+
depth,
|
|
215
|
+
);
|
|
234
216
|
|
|
235
217
|
const enclosingRange = nodeToSourceRange(enclosingNode);
|
|
236
|
-
const scopeName = extractScopeName(enclosingNode
|
|
218
|
+
const scopeName = extractScopeName(enclosingNode);
|
|
237
219
|
|
|
238
220
|
return {
|
|
239
221
|
kind: "success",
|
|
@@ -329,7 +311,8 @@ function containsPoint(
|
|
|
329
311
|
// biome-ignore lint/complexity/useMaxParams: filtering needs captures + node context + depth
|
|
330
312
|
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: filtering combines scope containment, column-aware inner-scope exclusion, and dedup in one cohesive pass
|
|
331
313
|
function filterCalleeCaptures(
|
|
332
|
-
captures: Array<{ range: SourceRange; text: string }>,
|
|
314
|
+
captures: Array<{ nodeType: string; range: SourceRange; text: string }>,
|
|
315
|
+
grammarId: GrammarId,
|
|
333
316
|
// biome-ignore lint/suspicious/noExplicitAny: tree-sitter SyntaxNode is complex
|
|
334
317
|
enclosingNode: any,
|
|
335
318
|
scopeTypes: ReadonlySet<string>,
|
|
@@ -382,7 +365,7 @@ function filterCalleeCaptures(
|
|
|
382
365
|
if (isInInner) continue;
|
|
383
366
|
}
|
|
384
367
|
|
|
385
|
-
const name = capture.text
|
|
368
|
+
const name = normalizeCallName(capture.text, grammarId, capture.nodeType);
|
|
386
369
|
if (name.length === 0 || seen.has(name)) continue;
|
|
387
370
|
seen.add(name);
|
|
388
371
|
|
|
@@ -5,6 +5,7 @@ import { nodeToRange } from "../coordinates.ts";
|
|
|
5
5
|
import type { SyntaxNodeLike } from "../syntax-node.ts";
|
|
6
6
|
import type { ExportRecord, TreeSitterResult } from "../types.ts";
|
|
7
7
|
import type { TreeSitterRuntime } from "../worker/runtime.ts";
|
|
8
|
+
import { extractBindingIdentifiers } from "./js-binding-pattern.ts";
|
|
8
9
|
|
|
9
10
|
/** Extract export records from a supported file. */
|
|
10
11
|
export async function extractExports(
|
|
@@ -120,13 +121,9 @@ function extractLexicalDeclarationExports(
|
|
|
120
121
|
): void {
|
|
121
122
|
for (const child of decl.children) {
|
|
122
123
|
if (child.type !== "variable_declarator") continue;
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
exports.push({
|
|
126
|
-
name: nameNode.text,
|
|
127
|
-
kind: "variable",
|
|
128
|
-
range: nodeToRange(child, source),
|
|
129
|
-
});
|
|
124
|
+
const names = extractBindingIdentifiers(child.childForFieldName("name"));
|
|
125
|
+
const range = nodeToRange(child, source);
|
|
126
|
+
for (const name of names) exports.push({ name, kind: "variable", range });
|
|
130
127
|
}
|
|
131
128
|
}
|
|
132
129
|
|
|
@@ -139,6 +136,11 @@ function extractAmbientDeclarationExport(
|
|
|
139
136
|
const nested = decl.children.find((child) => child.type !== "declare" && child.type !== ";");
|
|
140
137
|
if (!nested) return;
|
|
141
138
|
|
|
139
|
+
if (nested.type === "lexical_declaration") {
|
|
140
|
+
extractLexicalDeclarationExports(nested, source, exports);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
142
144
|
const name = getDeclarationName(nested);
|
|
143
145
|
if (!name) return;
|
|
144
146
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SyntaxNodeLike } from "../syntax-node.ts";
|
|
2
|
+
|
|
3
|
+
/** Extract every identifier bound by one JavaScript or TypeScript pattern. */
|
|
4
|
+
export function extractBindingIdentifiers(pattern: SyntaxNodeLike | null): string[] {
|
|
5
|
+
if (!pattern) return [];
|
|
6
|
+
|
|
7
|
+
switch (pattern.type) {
|
|
8
|
+
case "identifier":
|
|
9
|
+
return [pattern.text];
|
|
10
|
+
case "shorthand_property_identifier_pattern":
|
|
11
|
+
return [pattern.text];
|
|
12
|
+
case "pair_pattern":
|
|
13
|
+
case "pair":
|
|
14
|
+
return extractBindingIdentifiers(pattern.childForFieldName("value"));
|
|
15
|
+
case "object_assignment_pattern":
|
|
16
|
+
case "assignment_pattern":
|
|
17
|
+
return extractBindingIdentifiers(pattern.childForFieldName("left"));
|
|
18
|
+
case "rest_pattern":
|
|
19
|
+
return pattern.children.flatMap((child) => extractBindingIdentifiers(child));
|
|
20
|
+
case "object_pattern":
|
|
21
|
+
case "array_pattern":
|
|
22
|
+
return pattern.children.flatMap((child) => extractBindingIdentifiers(child));
|
|
23
|
+
default:
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Node-at-position lookup.
|
|
2
2
|
|
|
3
3
|
import type { CodeRequestControl } from "@mrclrchtr/supi-code-runtime/api";
|
|
4
|
-
import { nodeToRange, publicToTreeSitter,
|
|
4
|
+
import { nodeToRange, publicToTreeSitter, validatePublicPositionBounds } from "../coordinates.ts";
|
|
5
5
|
import type { NodeAtResult, SourceRange, TreeSitterResult } from "../types.ts";
|
|
6
6
|
import type { TreeSitterRuntime } from "../worker/runtime.ts";
|
|
7
7
|
|
|
@@ -28,7 +28,7 @@ export async function lookupNodeAt(
|
|
|
28
28
|
const { tree, source } = parseResult.data;
|
|
29
29
|
|
|
30
30
|
try {
|
|
31
|
-
const boundsError =
|
|
31
|
+
const boundsError = validatePublicPositionBounds(line, character, source);
|
|
32
32
|
if (boundsError) return boundsError;
|
|
33
33
|
|
|
34
34
|
const tsPoint = publicToTreeSitter(line, character, source);
|
|
@@ -52,25 +52,6 @@ export async function lookupNodeAt(
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
/** Validate that a requested public position exists in the source text. */
|
|
56
|
-
function validateBounds(
|
|
57
|
-
line: number,
|
|
58
|
-
character: number,
|
|
59
|
-
source: string,
|
|
60
|
-
): TreeSitterResult<NodeAtResult> | null {
|
|
61
|
-
const lines = splitSourceLines(source);
|
|
62
|
-
if (line > lines.length) {
|
|
63
|
-
return { kind: "validation-error", message: "line is beyond end of file" };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const lineText = lines[line - 1] ?? "";
|
|
67
|
-
if (character > lineText.length + 1) {
|
|
68
|
-
return { kind: "validation-error", message: "character is beyond end of line" };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
55
|
function collectAncestry(
|
|
75
56
|
node: {
|
|
76
57
|
type: string;
|
|
@@ -80,7 +80,7 @@ function sqlType(node: SyntaxNodeLike, source: string): OutlineItem | null {
|
|
|
80
80
|
? enumElements.children
|
|
81
81
|
.filter((child) => child.type === "literal")
|
|
82
82
|
.map((child) => ({
|
|
83
|
-
name:
|
|
83
|
+
name: sqlStringLiteralValue(child.text),
|
|
84
84
|
kind: "enum-member",
|
|
85
85
|
range: nodeToRange(child, source),
|
|
86
86
|
}))
|
|
@@ -112,10 +112,12 @@ function sqlColumns(node: SyntaxNodeLike, source: string): OutlineItem[] {
|
|
|
112
112
|
function sqlInlineConstraints(node: SyntaxNodeLike, source: string): OutlineItem[] {
|
|
113
113
|
const marker = node.children.findIndex((child) => child.type === "keyword_constraint");
|
|
114
114
|
if (marker < 0) return [];
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
const nameNode = node.children
|
|
116
|
+
.slice(marker + 1)
|
|
117
|
+
.find((child) => child.type === "literal" || child.type === "identifier");
|
|
118
|
+
const name = readSqlNameAfterKeyword(node.text, "CONSTRAINT");
|
|
119
|
+
if (!name || !nameNode) return [];
|
|
120
|
+
return [{ name, kind: "constraint", range: nodeToRange(nameNode, source) }];
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
function sqlSchemaChildren(node: SyntaxNodeLike, source: string): OutlineItem[] {
|
|
@@ -139,21 +141,29 @@ function sqlItem(
|
|
|
139
141
|
}
|
|
140
142
|
|
|
141
143
|
function sqlMember(node: SyntaxNodeLike, kind: string, source: string): OutlineItem | null {
|
|
144
|
+
const textName =
|
|
145
|
+
kind === "constraint"
|
|
146
|
+
? readSqlNameAfterKeyword(node.text, "CONSTRAINT")
|
|
147
|
+
: readSqlIdentifier(node.text);
|
|
142
148
|
const name = node.childForFieldName("name") ?? directChild(node, "identifier");
|
|
143
|
-
|
|
149
|
+
const value = textName ?? (name ? normalizeSqlIdentifierLike(name.text) : null);
|
|
150
|
+
return value ? { name: value, kind, range: nodeToRange(node, source) } : null;
|
|
144
151
|
}
|
|
145
152
|
|
|
146
153
|
function sqlDeclarationName(node: SyntaxNodeLike): string | null {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
154
|
+
const keyword = SQL_DECLARATION_KEYWORDS[node.type];
|
|
155
|
+
if (keyword) {
|
|
156
|
+
const name = readSqlNameAfterKeyword(node.text, keyword);
|
|
157
|
+
if (name) return name;
|
|
150
158
|
}
|
|
159
|
+
|
|
151
160
|
const reference = directChild(node, "object_reference");
|
|
152
161
|
if (reference) {
|
|
153
162
|
const name = reference.childForFieldName("name") ?? lastDirectChild(reference, "identifier");
|
|
154
|
-
if (name) return name.text;
|
|
163
|
+
if (name) return normalizeSqlIdentifierLike(name.text);
|
|
155
164
|
}
|
|
156
|
-
|
|
165
|
+
const name = directChild(node, "identifier");
|
|
166
|
+
return name ? normalizeSqlIdentifierLike(name.text) : null;
|
|
157
167
|
}
|
|
158
168
|
|
|
159
169
|
function directChild(node: SyntaxNodeLike, type: string): SyntaxNodeLike | null {
|
|
@@ -168,12 +178,119 @@ function lastDirectChild(node: SyntaxNodeLike, type: string): SyntaxNodeLike | n
|
|
|
168
178
|
return null;
|
|
169
179
|
}
|
|
170
180
|
|
|
171
|
-
function
|
|
181
|
+
function normalizeSqlIdentifierLike(value: string): string {
|
|
182
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
183
|
+
return value.slice(1, -1).replaceAll('""', '"');
|
|
184
|
+
}
|
|
185
|
+
if (value.startsWith("'") && value.endsWith("'")) {
|
|
186
|
+
return sqlStringLiteralValue(value);
|
|
187
|
+
}
|
|
188
|
+
return value;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function sqlStringLiteralValue(value: string): string {
|
|
172
192
|
return value.startsWith("'") && value.endsWith("'")
|
|
173
193
|
? value.slice(1, -1).replaceAll("''", "'")
|
|
174
194
|
: value;
|
|
175
195
|
}
|
|
176
196
|
|
|
197
|
+
function readSqlNameAfterKeyword(text: string, keyword: string): string | null {
|
|
198
|
+
const marker = findSqlKeyword(text, keyword);
|
|
199
|
+
if (marker < 0) return null;
|
|
200
|
+
let position = skipSqlSpace(text, marker + keyword.length);
|
|
201
|
+
for (const optional of ["CONCURRENTLY", "IF", "NOT", "EXISTS"]) {
|
|
202
|
+
if (readSqlWord(text, position) === optional) {
|
|
203
|
+
position = skipSqlSpace(text, position + optional.length);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const name = readSqlQualifiedIdentifier(text, position);
|
|
207
|
+
return name ? normalizeSqlIdentifierLike(name) : null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function readSqlIdentifier(text: string): string | null {
|
|
211
|
+
const name = readSqlQualifiedIdentifier(text, 0);
|
|
212
|
+
return name ? normalizeSqlIdentifierLike(name) : null;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function readSqlQualifiedIdentifier(text: string, start: number): string | null {
|
|
216
|
+
let position = skipSqlSpace(text, start);
|
|
217
|
+
let last: string | null = null;
|
|
218
|
+
while (position < text.length) {
|
|
219
|
+
const token = readSqlIdentifierToken(text, position);
|
|
220
|
+
if (!token) break;
|
|
221
|
+
last = token.value;
|
|
222
|
+
position = skipSqlSpace(text, token.end);
|
|
223
|
+
if (text[position] !== ".") break;
|
|
224
|
+
position = skipSqlSpace(text, position + 1);
|
|
225
|
+
}
|
|
226
|
+
return last;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function readSqlIdentifierToken(
|
|
230
|
+
text: string,
|
|
231
|
+
start: number,
|
|
232
|
+
): { value: string; end: number } | null {
|
|
233
|
+
if (text[start] === '"' || text[start] === "'") {
|
|
234
|
+
const quote = text[start];
|
|
235
|
+
let position = start + 1;
|
|
236
|
+
while (position < text.length) {
|
|
237
|
+
if (text[position] !== quote) {
|
|
238
|
+
position += 1;
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
if (text[position + 1] === quote) {
|
|
242
|
+
position += 2;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
position += 1;
|
|
246
|
+
return { value: text.slice(start, position), end: position };
|
|
247
|
+
}
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
let position = start;
|
|
252
|
+
while (position < text.length && !/[\s(;.,]/.test(text[position] ?? "")) position += 1;
|
|
253
|
+
return position > start ? { value: text.slice(start, position), end: position } : null;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: quoted SQL names need a small lexical scan before keyword recovery
|
|
257
|
+
function findSqlKeyword(text: string, keyword: string): number {
|
|
258
|
+
const upper = text.toUpperCase();
|
|
259
|
+
let quote: '"' | "'" | null = null;
|
|
260
|
+
for (let position = 0; position < text.length; position += 1) {
|
|
261
|
+
const character = text[position];
|
|
262
|
+
if (quote !== null) {
|
|
263
|
+
if (character === quote && text[position + 1] === quote) {
|
|
264
|
+
position += 1;
|
|
265
|
+
} else if (character === quote) {
|
|
266
|
+
quote = null;
|
|
267
|
+
}
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
if (character === '"' || character === "'") {
|
|
271
|
+
quote = character;
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (!upper.startsWith(keyword, position)) continue;
|
|
275
|
+
const before = upper[position - 1] ?? " ";
|
|
276
|
+
const after = upper[position + keyword.length] ?? " ";
|
|
277
|
+
if (!/[A-Z0-9_]/.test(before) && !/[A-Z0-9_]/.test(after)) return position;
|
|
278
|
+
}
|
|
279
|
+
return -1;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function readSqlWord(text: string, start: number): string | null {
|
|
283
|
+
const end = text.slice(start).search(/\s/);
|
|
284
|
+
const wordEnd = end < 0 ? text.length : start + end;
|
|
285
|
+
return wordEnd > start ? text.slice(start, wordEnd).toUpperCase() : null;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function skipSqlSpace(text: string, start: number): number {
|
|
289
|
+
let position = start;
|
|
290
|
+
while (/\s/.test(text[position] ?? "")) position += 1;
|
|
291
|
+
return position;
|
|
292
|
+
}
|
|
293
|
+
|
|
177
294
|
function one(item: OutlineItem | null): OutlineItem[] {
|
|
178
295
|
return item ? [item] : [];
|
|
179
296
|
}
|
|
@@ -184,3 +301,18 @@ const HTML_ELEMENT_TYPES = new Set([
|
|
|
184
301
|
"self_closing_tag",
|
|
185
302
|
"style_element",
|
|
186
303
|
]);
|
|
304
|
+
|
|
305
|
+
const SQL_DECLARATION_KEYWORDS: Record<string, string> = {
|
|
306
|
+
create_schema: "SCHEMA",
|
|
307
|
+
create_type: "TYPE",
|
|
308
|
+
create_table: "TABLE",
|
|
309
|
+
create_view: "VIEW",
|
|
310
|
+
create_materialized_view: "VIEW",
|
|
311
|
+
create_index: "INDEX",
|
|
312
|
+
create_sequence: "SEQUENCE",
|
|
313
|
+
create_function: "FUNCTION",
|
|
314
|
+
create_trigger: "TRIGGER",
|
|
315
|
+
create_database: "DATABASE",
|
|
316
|
+
create_role: "ROLE",
|
|
317
|
+
create_extension: "EXTENSION",
|
|
318
|
+
};
|