@mrclrchtr/supi-tree-sitter 3.2.0 → 4.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 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/README.md +8 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +2 -4
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +0 -4
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/evidence-badge.ts +3 -2
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +0 -4
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/llm.ts +0 -10
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/path-utils.ts +19 -15
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +10 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +19 -29
- package/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +7 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/src/query-result.ts +42 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +15 -10
- package/node_modules/@mrclrchtr/supi-core/package.json +2 -4
- package/node_modules/@mrclrchtr/supi-core/src/api.ts +0 -4
- package/node_modules/@mrclrchtr/supi-core/src/evidence-badge.ts +3 -2
- package/node_modules/@mrclrchtr/supi-core/src/index.ts +0 -4
- package/node_modules/@mrclrchtr/supi-core/src/llm.ts +0 -10
- package/node_modules/@mrclrchtr/supi-core/src/path-utils.ts +19 -15
- package/package.json +4 -21
- package/resources/grammars/bash/tree-sitter-bash.wasm +0 -0
- package/resources/grammars/bash/tree-sitter-bash.wasm.json +2 -2
- package/resources/grammars/c/tree-sitter-c.wasm +0 -0
- package/resources/grammars/c/tree-sitter-c.wasm.json +2 -2
- package/resources/grammars/go/tree-sitter-go.wasm +0 -0
- package/resources/grammars/go/tree-sitter-go.wasm.json +2 -2
- package/resources/grammars/javascript/tree-sitter-javascript.wasm +0 -0
- package/resources/grammars/javascript/tree-sitter-javascript.wasm.json +2 -2
- package/resources/grammars/kotlin/tree-sitter-kotlin.wasm +0 -0
- package/resources/grammars/kotlin/tree-sitter-kotlin.wasm.json +2 -2
- package/resources/grammars/python/tree-sitter-python.wasm +0 -0
- package/resources/grammars/python/tree-sitter-python.wasm.json +2 -2
- package/resources/grammars/r/tree-sitter-r.wasm +0 -0
- package/resources/grammars/r/tree-sitter-r.wasm.json +2 -2
- package/resources/grammars/rust/tree-sitter-rust.wasm.json +1 -1
- package/resources/grammars/sql/tree-sitter-sql.wasm +0 -0
- package/resources/grammars/sql/tree-sitter-sql.wasm.json +3 -3
- package/scripts/generate-kotlin-wasm.mjs +6 -0
- package/scripts/generate-sql-wasm.mjs +18 -4
- package/scripts/vendor-wasm.mjs +17 -1
- package/src/api.ts +2 -0
- package/src/coordinates.ts +20 -41
- package/src/index.ts +2 -0
- package/src/language.ts +7 -0
- package/src/operation-support.ts +40 -0
- package/src/session/session.ts +9 -7
- package/src/tool/call-sites.ts +6 -1
- package/src/tool/callees.ts +76 -37
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +0 -31
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/substrate-types.ts +0 -11
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/types.ts +0 -2
- package/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +0 -31
- package/node_modules/@mrclrchtr/supi-core/src/substrate-types.ts +0 -11
- package/node_modules/@mrclrchtr/supi-core/src/types.ts +0 -2
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"source": {
|
|
3
3
|
"npmPackage": "tree-sitter-javascript",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.25.0"
|
|
5
5
|
},
|
|
6
|
-
"sha256": "
|
|
6
|
+
"sha256": "5fb488d0cabb4775a594bab85682de5ad6ce83c0d6ac997a9f82dd084d571240"
|
|
7
7
|
}
|
|
Binary file
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"releaseAsset": "https://github.com/fwcd/tree-sitter-kotlin/releases/download/0.3.8/tree-sitter-kotlin.wasm"
|
|
7
7
|
},
|
|
8
8
|
"generatedWith": {
|
|
9
|
-
"treeSitterCli": "0.
|
|
9
|
+
"treeSitterCli": "0.26.11"
|
|
10
10
|
},
|
|
11
|
-
"sha256": "
|
|
11
|
+
"sha256": "e08447e36ad5d86f39f91f13defce0636aea1490b8d65dafde6fa72649422061"
|
|
12
12
|
}
|
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"source": {
|
|
3
3
|
"npmPackage": "tree-sitter-python",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.25.0"
|
|
5
5
|
},
|
|
6
|
-
"sha256": "
|
|
6
|
+
"sha256": "16108b50df4ee9a30168794252ab55e7c93bfc5765d7fa0aa3e335752c515f47"
|
|
7
7
|
}
|
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"source": {
|
|
3
3
|
"npmPackage": "@davisvaughan/tree-sitter-r",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.0"
|
|
5
5
|
},
|
|
6
|
-
"sha256": "
|
|
6
|
+
"sha256": "a39d2e71bd39c29bb7f144a03f41d6d9f0099fede4110c696dc0715a62c9fbe1"
|
|
7
7
|
}
|
|
Binary file
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
"repository": "https://github.com/derekstride/tree-sitter-sql"
|
|
6
6
|
},
|
|
7
7
|
"generatedWith": {
|
|
8
|
-
"treeSitterCli": "0.
|
|
8
|
+
"treeSitterCli": "0.26.11"
|
|
9
9
|
},
|
|
10
|
-
"sha256": "
|
|
10
|
+
"sha256": "9b93a15dc3eade66df4347731f2687b939daf987c8382660d6118e863604ab09",
|
|
11
11
|
"trust": {
|
|
12
|
-
"note": "The @derekstride/tree-sitter-sql npm package is a devDependency only. It is never resolved at runtime
|
|
12
|
+
"note": "The @derekstride/tree-sitter-sql npm package is a devDependency only. It is never resolved at runtime; the vendored WASM above is the sole runtime artifact. This workspace explicitly disables the package's npx-based install script via pnpm allowBuilds. The WASM was built locally from the installed package source. See scripts/generate-sql-wasm.mjs for the rebuild procedure.",
|
|
13
13
|
"alternativesConsidered": [
|
|
14
14
|
"tree-sitter-sql (m-novikov, 2021, stale)",
|
|
15
15
|
"tree-sitter-sql-bigquery (BigQuery-specific)",
|
|
@@ -38,6 +38,7 @@ function expectedReleaseAsset(version) {
|
|
|
38
38
|
|
|
39
39
|
function assertKotlinWasmCurrent() {
|
|
40
40
|
const kotlinPackage = readPackage("tree-sitter-kotlin");
|
|
41
|
+
const cliPackage = readPackage("tree-sitter-cli");
|
|
41
42
|
const metadata = readMetadata();
|
|
42
43
|
const actualSha = sha256(wasmPath);
|
|
43
44
|
const errors = [];
|
|
@@ -55,6 +56,11 @@ function assertKotlinWasmCurrent() {
|
|
|
55
56
|
"metadata release asset URL does not match the installed tree-sitter-kotlin version",
|
|
56
57
|
);
|
|
57
58
|
}
|
|
59
|
+
if (metadata.generatedWith?.treeSitterCli !== cliPackage.json.version) {
|
|
60
|
+
errors.push(
|
|
61
|
+
`metadata pins tree-sitter-cli ${metadata.generatedWith?.treeSitterCli}, but installed CLI is ${cliPackage.json.version}`,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
58
64
|
if (metadata.sha256 !== actualSha) {
|
|
59
65
|
errors.push(`metadata sha256 ${metadata.sha256} does not match vendored file ${actualSha}`);
|
|
60
66
|
}
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Trust considerations:
|
|
10
10
|
* - The @derekstride/tree-sitter-sql install script uses "npx --yes", which
|
|
11
|
-
* some package managers flag as a supply-chain risk.
|
|
12
|
-
*
|
|
11
|
+
* some package managers flag as a supply-chain risk. This workspace disables
|
|
12
|
+
* that package's build script explicitly via pnpm `allowBuilds`.
|
|
13
13
|
* - The WASM is built locally from the installed package source (not downloaded
|
|
14
|
-
* from npm). The build uses tree-sitter-cli
|
|
14
|
+
* from npm). The build uses tree-sitter-cli with Emscripten/Docker.
|
|
15
15
|
* - Alternatives considered: tree-sitter-sql (m-novikov, stale since 2021),
|
|
16
16
|
* tree-sitter-sql-bigquery (dialect-specific), and dialect-specific grammars.
|
|
17
17
|
* derekstride/tree-sitter-sql is the most mature general-purpose SQL grammar.
|
|
@@ -55,6 +55,7 @@ function readMetadata() {
|
|
|
55
55
|
|
|
56
56
|
function assertSqlWasmCurrent() {
|
|
57
57
|
const sqlPackage = readPackage("@derekstride/tree-sitter-sql");
|
|
58
|
+
const cliPackage = readPackage("tree-sitter-cli");
|
|
58
59
|
const metadata = readMetadata();
|
|
59
60
|
const actualSha = sha256(wasmPath);
|
|
60
61
|
const errors = [];
|
|
@@ -67,6 +68,11 @@ function assertSqlWasmCurrent() {
|
|
|
67
68
|
`metadata pins @derekstride/tree-sitter-sql ${metadata.source?.version}, but installed package is ${sqlPackage.json.version}`,
|
|
68
69
|
);
|
|
69
70
|
}
|
|
71
|
+
if (metadata.generatedWith?.treeSitterCli !== cliPackage.json.version) {
|
|
72
|
+
errors.push(
|
|
73
|
+
`metadata pins tree-sitter-cli ${metadata.generatedWith?.treeSitterCli}, but installed CLI is ${cliPackage.json.version}`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
70
76
|
if (metadata.sha256 !== actualSha) {
|
|
71
77
|
errors.push(`metadata sha256 ${metadata.sha256} does not match vendored file ${actualSha}`);
|
|
72
78
|
}
|
|
@@ -92,7 +98,7 @@ function generateSqlWasm() {
|
|
|
92
98
|
try {
|
|
93
99
|
fs.cpSync(sqlPackage.dir, grammarDir, { recursive: true });
|
|
94
100
|
|
|
95
|
-
// tree-sitter-cli
|
|
101
|
+
// tree-sitter-cli requires a "tree-sitter" section in package.json
|
|
96
102
|
const grammarPackageJsonPath = path.join(grammarDir, "package.json");
|
|
97
103
|
const grammarPackageJson = JSON.parse(fs.readFileSync(grammarPackageJsonPath, "utf-8"));
|
|
98
104
|
grammarPackageJson["tree-sitter"] = [{ scope: "source.sql" }];
|
|
@@ -128,6 +134,14 @@ function generateSqlWasm() {
|
|
|
128
134
|
treeSitterCli: cliPackage.json.version,
|
|
129
135
|
},
|
|
130
136
|
sha256: checksum,
|
|
137
|
+
trust: {
|
|
138
|
+
note: "The @derekstride/tree-sitter-sql npm package is a devDependency only. It is never resolved at runtime; the vendored WASM above is the sole runtime artifact. This workspace explicitly disables the package's npx-based install script via pnpm allowBuilds. The WASM was built locally from the installed package source. See scripts/generate-sql-wasm.mjs for the rebuild procedure.",
|
|
139
|
+
alternativesConsidered: [
|
|
140
|
+
"tree-sitter-sql (m-novikov, 2021, stale)",
|
|
141
|
+
"tree-sitter-sql-bigquery (BigQuery-specific)",
|
|
142
|
+
"dialect-specific grammars (too narrow)",
|
|
143
|
+
],
|
|
144
|
+
},
|
|
131
145
|
};
|
|
132
146
|
fs.writeFileSync(metadataPath, `${JSON.stringify(metadata, null, 2)}\n`);
|
|
133
147
|
process.stdout.write(`Generated ${wasmPath}\n`);
|
package/scripts/vendor-wasm.mjs
CHANGED
|
@@ -108,8 +108,14 @@ function checkGrammar(grammarId, source) {
|
|
|
108
108
|
|
|
109
109
|
try {
|
|
110
110
|
const pkg = readPackage(source.npmPackage);
|
|
111
|
+
const sourceWasmPath = path.join(pkg.dir, source.wasmFile);
|
|
112
|
+
if (!fs.existsSync(sourceWasmPath)) {
|
|
113
|
+
errors.push(`${grammarId}: installed package is missing ${source.wasmFile}`);
|
|
114
|
+
return errors;
|
|
115
|
+
}
|
|
111
116
|
const metadata = JSON.parse(fs.readFileSync(metadataPath, "utf-8"));
|
|
112
117
|
const actualSha = sha256(wasmPath);
|
|
118
|
+
const sourceSha = sha256(sourceWasmPath);
|
|
113
119
|
|
|
114
120
|
if (metadata.source?.npmPackage !== source.npmPackage) {
|
|
115
121
|
errors.push(`${grammarId}: metadata source npmPackage mismatch`);
|
|
@@ -119,8 +125,18 @@ function checkGrammar(grammarId, source) {
|
|
|
119
125
|
`${grammarId}: metadata version ${metadata.source?.version} !== installed ${pkg.json.version}`,
|
|
120
126
|
);
|
|
121
127
|
}
|
|
128
|
+
if (actualSha !== sourceSha) {
|
|
129
|
+
errors.push(
|
|
130
|
+
`${grammarId}: vendored sha256 ${actualSha} !== installed package source ${sourceSha}`,
|
|
131
|
+
);
|
|
132
|
+
}
|
|
122
133
|
if (metadata.sha256 !== actualSha) {
|
|
123
|
-
errors.push(`${grammarId}: metadata sha256 ${metadata.sha256} !==
|
|
134
|
+
errors.push(`${grammarId}: metadata sha256 ${metadata.sha256} !== vendored ${actualSha}`);
|
|
135
|
+
}
|
|
136
|
+
if (metadata.sha256 !== sourceSha) {
|
|
137
|
+
errors.push(
|
|
138
|
+
`${grammarId}: metadata sha256 ${metadata.sha256} !== installed package source ${sourceSha}`,
|
|
139
|
+
);
|
|
124
140
|
}
|
|
125
141
|
} catch (err) {
|
|
126
142
|
errors.push(`${grammarId}: ${err.message}`);
|
package/src/api.ts
CHANGED
|
@@ -12,6 +12,8 @@ export {
|
|
|
12
12
|
isJsTsGrammar,
|
|
13
13
|
isSupportedFile,
|
|
14
14
|
} from "./language.ts";
|
|
15
|
+
export type { StructuralSearchOperation } from "./operation-support.ts";
|
|
16
|
+
export { getStructuralSearchSupportedExtensions } from "./operation-support.ts";
|
|
15
17
|
export { TreeSitterRuntime } from "./session/runtime.ts";
|
|
16
18
|
export type {
|
|
17
19
|
TsControllerState,
|
package/src/coordinates.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
// Coordinate conversion between public 1-based UTF-16 positions
|
|
2
|
-
// and Tree-sitter runtime
|
|
2
|
+
// and Tree-sitter runtime positions.
|
|
3
|
+
//
|
|
4
|
+
// web-tree-sitter's Parser.parse(string) uses JavaScript string columns
|
|
5
|
+
// (UTF-16 code unit offsets) for startPosition/endPosition. We convert
|
|
6
|
+
// 1-based user-facing positions to 0-based row/column and back without
|
|
7
|
+
// any byte-level encoding.
|
|
8
|
+
//
|
|
9
|
+
// This matches the column convention used by LSP and Monaco, so ranges
|
|
10
|
+
// are directly shareable between tree-sitter and LSP workflows.
|
|
3
11
|
|
|
4
12
|
import type { SourceRange } from "./types.ts";
|
|
5
13
|
|
|
6
|
-
const encoder = new TextEncoder();
|
|
7
|
-
|
|
8
14
|
/** Point in source: 1-based line and UTF-16 character. */
|
|
9
15
|
export interface PublicPoint {
|
|
10
16
|
line: number;
|
|
@@ -16,7 +22,8 @@ export interface PublicPoint {
|
|
|
16
22
|
* for Tree-sitter lookup.
|
|
17
23
|
*
|
|
18
24
|
* `character` is a UTF-16 code-unit column (editor/LSP convention).
|
|
19
|
-
*
|
|
25
|
+
* The column maps directly to JavaScript string code units — no byte
|
|
26
|
+
* conversion is needed for web-tree-sitter's string-parsing mode.
|
|
20
27
|
*/
|
|
21
28
|
export function publicToTreeSitter(
|
|
22
29
|
line: number,
|
|
@@ -25,32 +32,27 @@ export function publicToTreeSitter(
|
|
|
25
32
|
): { row: number; column: number } {
|
|
26
33
|
const row = line - 1;
|
|
27
34
|
const lines = splitSourceLines(source);
|
|
28
|
-
const lineText = row < lines.length ? lines[row] : "";
|
|
29
|
-
//
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
const textBefore = lineText.substring(0, charIndex);
|
|
33
|
-
const byteOffset = encoder.encode(textBefore).length;
|
|
34
|
-
return { row, column: byteOffset };
|
|
35
|
+
const lineText = row < lines.length ? (lines[row] ?? "") : "";
|
|
36
|
+
// Clamp column to the line length.
|
|
37
|
+
const column = Math.max(0, Math.min(character - 1, lineText.length));
|
|
38
|
+
return { row, column };
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
/**
|
|
38
42
|
* Convert a Tree-sitter (row, column) pair to a 1-based (line, character) pair.
|
|
39
43
|
*
|
|
40
|
-
* `column` is a
|
|
41
|
-
* code-unit index.
|
|
44
|
+
* `column` is a zero-based JavaScript string code unit offset within the line.
|
|
42
45
|
*/
|
|
43
46
|
export function treeSitterToPublic(row: number, column: number, source: string): PublicPoint {
|
|
47
|
+
// Clamp to EOL for positions right after the last character.
|
|
44
48
|
const lines = splitSourceLines(source);
|
|
45
|
-
const lineText = row < lines.length ? lines[row] : "";
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return { line: row + 1, character: charIndex + 1 };
|
|
49
|
+
const lineText = row < lines.length ? (lines[row] ?? "") : "";
|
|
50
|
+
const safeColumn = Math.max(0, Math.min(column, lineText.length));
|
|
51
|
+
return { line: row + 1, character: safeColumn + 1 };
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
/**
|
|
52
55
|
* Convert a Tree-sitter point {row, column} to a SourceRange-compatible point.
|
|
53
|
-
* Uses the source text for byte-to-UTF16 conversion.
|
|
54
56
|
*/
|
|
55
57
|
export function tsPointToPublic(
|
|
56
58
|
point: { row: number; column: number },
|
|
@@ -83,26 +85,3 @@ export function nodeToRange(
|
|
|
83
85
|
export function splitSourceLines(source: string): string[] {
|
|
84
86
|
return source.replace(/\r\n?/g, "\n").split("\n");
|
|
85
87
|
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Convert a byte offset within a line to a UTF-16 code unit index.
|
|
89
|
-
*/
|
|
90
|
-
function byteToUtf16Index(line: string, byteOffset: number): number {
|
|
91
|
-
let byteCount = 0;
|
|
92
|
-
for (let i = 0; i < line.length; i++) {
|
|
93
|
-
if (byteCount >= byteOffset) return i;
|
|
94
|
-
const char = line.charCodeAt(i);
|
|
95
|
-
// surrogate pair — 4 bytes in UTF-8, but 2 UTF-16 code units
|
|
96
|
-
if (char >= 0xd800 && char <= 0xdbff) {
|
|
97
|
-
byteCount += 4;
|
|
98
|
-
i++; // skip low surrogate
|
|
99
|
-
} else if (char > 0x7f) {
|
|
100
|
-
// Non-ASCII: 2-3 bytes in UTF-8
|
|
101
|
-
if (char <= 0x7ff) byteCount += 2;
|
|
102
|
-
else byteCount += 3;
|
|
103
|
-
} else {
|
|
104
|
-
byteCount += 1;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return line.length;
|
|
108
|
-
}
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,8 @@ export {
|
|
|
11
11
|
isJsTsGrammar,
|
|
12
12
|
isSupportedFile,
|
|
13
13
|
} from "./language.ts";
|
|
14
|
+
export type { StructuralSearchOperation } from "./operation-support.ts";
|
|
15
|
+
export { getStructuralSearchSupportedExtensions } from "./operation-support.ts";
|
|
14
16
|
// Provider implementation
|
|
15
17
|
export { createTreeSitterProvider } from "./provider/tree-sitter-provider.ts";
|
|
16
18
|
export { TreeSitterRuntime } from "./session/runtime.ts";
|
package/src/language.ts
CHANGED
|
@@ -61,6 +61,13 @@ export function getSupportedExtensions(): string[] {
|
|
|
61
61
|
return [...SUPPORTED_EXTENSIONS];
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
/** Internal registry snapshot used to derive operation-specific language support. */
|
|
65
|
+
export function getSupportedExtensionGrammarEntries(): Array<
|
|
66
|
+
readonly [SupportedExtension, GrammarId]
|
|
67
|
+
> {
|
|
68
|
+
return Object.entries(EXTENSION_GRAMMAR) as Array<readonly [SupportedExtension, GrammarId]>;
|
|
69
|
+
}
|
|
70
|
+
|
|
64
71
|
/** Get the file extension if it's supported, otherwise undefined. */
|
|
65
72
|
export function getSupportedExtension(filePath: string): SupportedExtension | undefined {
|
|
66
73
|
const ext = path.extname(filePath).toLowerCase();
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { getSupportedExtensionGrammarEntries, isJsTsGrammar } from "./language.ts";
|
|
2
|
+
import { supportsCallSitesGrammar } from "./tool/call-sites.ts";
|
|
3
|
+
import type { GrammarId, SupportedExtension } from "./types.ts";
|
|
4
|
+
|
|
5
|
+
/** Structural collection operations whose language support defines an AST Scan universe. */
|
|
6
|
+
const STRUCTURAL_SEARCH_OPERATIONS = ["outline", "imports", "exports", "call-sites"] as const;
|
|
7
|
+
|
|
8
|
+
/** One Tree-sitter structural collection operation used by code-aware search. */
|
|
9
|
+
export type StructuralSearchOperation = (typeof STRUCTURAL_SEARCH_OPERATIONS)[number];
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Return the file extensions that the concrete extractor supports for an operation.
|
|
13
|
+
*
|
|
14
|
+
* This is operation support, not general parser support. The result is derived from
|
|
15
|
+
* the same grammar predicates and query registry used by the extractors themselves.
|
|
16
|
+
*/
|
|
17
|
+
export function getStructuralSearchSupportedExtensions(
|
|
18
|
+
operation: StructuralSearchOperation,
|
|
19
|
+
): SupportedExtension[] {
|
|
20
|
+
return getSupportedExtensionGrammarEntries()
|
|
21
|
+
.filter(([, grammar]) => supportsGrammarOperation(grammar, operation))
|
|
22
|
+
.map(([extension]) => extension);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Return whether one grammar is supported by the requested structural operation. */
|
|
26
|
+
export function supportsGrammarOperation(
|
|
27
|
+
grammar: GrammarId,
|
|
28
|
+
operation: StructuralSearchOperation,
|
|
29
|
+
): boolean {
|
|
30
|
+
switch (operation) {
|
|
31
|
+
case "call-sites":
|
|
32
|
+
return supportsCallSitesGrammar(grammar);
|
|
33
|
+
case "outline":
|
|
34
|
+
case "imports":
|
|
35
|
+
case "exports":
|
|
36
|
+
return isJsTsGrammar(grammar);
|
|
37
|
+
default:
|
|
38
|
+
throw new TypeError(`Unsupported structural search operation: ${String(operation)}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/session/session.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Session factory — creates runtime-backed Tree-sitter services and owned sessions.
|
|
2
2
|
|
|
3
|
-
import { detectGrammar
|
|
3
|
+
import { detectGrammar } from "../language.ts";
|
|
4
|
+
import { supportsGrammarOperation } from "../operation-support.ts";
|
|
4
5
|
import {
|
|
5
6
|
extractCallSites,
|
|
6
7
|
extractExports,
|
|
@@ -45,15 +46,16 @@ export function createTreeSitterService(runtime: TreeSitterRuntime): TreeSitterS
|
|
|
45
46
|
},
|
|
46
47
|
|
|
47
48
|
async outline(file: string): Promise<TreeSitterResult<OutlineItem[]>> {
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
50
|
-
if (!isJsTsGrammar(parseResult.data.grammarId)) {
|
|
49
|
+
const grammarId = detectGrammar(file);
|
|
50
|
+
if (grammarId && !supportsGrammarOperation(grammarId, "outline")) {
|
|
51
51
|
return {
|
|
52
52
|
kind: "unsupported-language",
|
|
53
53
|
file,
|
|
54
|
-
message: `outline is not supported for ${
|
|
54
|
+
message: `outline is not supported for ${grammarId} files`,
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
+
const parseResult = await runtime.parseFile(file);
|
|
58
|
+
if (parseResult.kind !== "success") return parseResult;
|
|
57
59
|
const { tree, source } = parseResult.data;
|
|
58
60
|
try {
|
|
59
61
|
const items = extractOutline(tree.rootNode, source);
|
|
@@ -65,7 +67,7 @@ export function createTreeSitterService(runtime: TreeSitterRuntime): TreeSitterS
|
|
|
65
67
|
|
|
66
68
|
async imports(file: string): Promise<TreeSitterResult<ImportRecord[]>> {
|
|
67
69
|
const grammarId = detectGrammar(file);
|
|
68
|
-
if (grammarId && !
|
|
70
|
+
if (grammarId && !supportsGrammarOperation(grammarId, "imports")) {
|
|
69
71
|
return {
|
|
70
72
|
kind: "unsupported-language",
|
|
71
73
|
file,
|
|
@@ -77,7 +79,7 @@ export function createTreeSitterService(runtime: TreeSitterRuntime): TreeSitterS
|
|
|
77
79
|
|
|
78
80
|
async exports(file: string): Promise<TreeSitterResult<ExportRecord[]>> {
|
|
79
81
|
const grammarId = detectGrammar(file);
|
|
80
|
-
if (grammarId && !
|
|
82
|
+
if (grammarId && !supportsGrammarOperation(grammarId, "exports")) {
|
|
81
83
|
return {
|
|
82
84
|
kind: "unsupported-language",
|
|
83
85
|
file,
|
package/src/tool/call-sites.ts
CHANGED
|
@@ -30,10 +30,15 @@ const CALL_SITE_QUERIES: Partial<Record<GrammarId, string>> = {
|
|
|
30
30
|
kotlin:
|
|
31
31
|
"(call_expression . (simple_identifier) @call) (call_expression . (navigation_expression . (simple_identifier) @call))",
|
|
32
32
|
ruby: "(call method: (identifier) @call)",
|
|
33
|
-
bash: "(command name: (
|
|
33
|
+
bash: "(command name: (command_name) @call)",
|
|
34
34
|
r: "(call function: (identifier) @call)",
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
+
/** Return whether the call-site extractor has a query for one grammar. */
|
|
38
|
+
export function supportsCallSitesGrammar(grammarId: GrammarId): boolean {
|
|
39
|
+
return CALL_SITE_QUERIES[grammarId] !== undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
37
42
|
/**
|
|
38
43
|
* Extract all call-site callee expressions from a file.
|
|
39
44
|
*
|