@ast-grep/ast-grep-wasm 0.40.5
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 +107 -0
- package/ast_grep_wasm.d.ts +244 -0
- package/ast_grep_wasm.js +1531 -0
- package/ast_grep_wasm_bg.wasm +0 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# @ast-grep/wasm
|
|
2
|
+
|
|
3
|
+
WebAssembly build of [ast-grep](https://ast-grep.github.io/) for use in browsers and Node.js.
|
|
4
|
+
|
|
5
|
+
This package provides the same API as [`@ast-grep/napi`](https://www.npmjs.com/package/@ast-grep/napi) but runs in any JavaScript environment that supports WebAssembly, including browsers, Deno, and edge runtimes.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
yarn add @ast-grep/wasm web-tree-sitter
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`web-tree-sitter` is a required peer dependency.
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { initializeTreeSitter, setupParser, parse, kind } from '@ast-grep/wasm'
|
|
19
|
+
|
|
20
|
+
// 1. Initialize the tree-sitter WASM runtime (once)
|
|
21
|
+
await initializeTreeSitter()
|
|
22
|
+
|
|
23
|
+
// 2. Load a language parser WASM binary
|
|
24
|
+
await setupParser('javascript', '/path/to/tree-sitter-javascript.wasm')
|
|
25
|
+
|
|
26
|
+
// 3. Parse and search code
|
|
27
|
+
const sg = parse('javascript', 'console.log("hello world")')
|
|
28
|
+
const node = sg.root().find('console.log($ARG)')
|
|
29
|
+
console.log(node.getMatch('ARG').text()) // "hello world"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Pattern Matching
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
// By pattern string
|
|
36
|
+
sg.root().find('console.log($$$ARGS)')
|
|
37
|
+
|
|
38
|
+
// By kind number
|
|
39
|
+
const k = kind('javascript', 'call_expression')
|
|
40
|
+
sg.root().find(k)
|
|
41
|
+
|
|
42
|
+
// By rule config (same as YAML rules)
|
|
43
|
+
sg.root().find({
|
|
44
|
+
rule: { pattern: 'console.log($A)' },
|
|
45
|
+
constraints: { A: { kind: 'string' } },
|
|
46
|
+
})
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Code Rewriting
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
const match = sg.root().find('console.log($A)')
|
|
53
|
+
const edit = match.replace('console.error($A)')
|
|
54
|
+
const newCode = sg.root().commitEdits([edit])
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Supported Languages
|
|
58
|
+
|
|
59
|
+
bash, c, cpp, csharp, css, elixir, go, haskell, html, java, javascript, json, kotlin, lua, nix, php, python, ruby, rust, scala, swift, tsx, typescript, yaml
|
|
60
|
+
|
|
61
|
+
## API Reference
|
|
62
|
+
|
|
63
|
+
See the full [ast-grep API documentation](https://ast-grep.github.io/reference/api.html).
|
|
64
|
+
|
|
65
|
+
## Building from Source
|
|
66
|
+
|
|
67
|
+
Requires [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/).
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# For browser (ES module)
|
|
71
|
+
yarn build
|
|
72
|
+
|
|
73
|
+
# For Node.js (CommonJS)
|
|
74
|
+
yarn build:nodejs
|
|
75
|
+
|
|
76
|
+
# For bundlers
|
|
77
|
+
yarn build:bundler
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Testing
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
yarn install
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Rust WASM tests
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
yarn test
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
> **Note:** `wasm-pack test --node` runs the test harness from a temporary directory.
|
|
93
|
+
> The `test` script sets `NODE_PATH=$PWD/node_modules` so that `web-tree-sitter` and
|
|
94
|
+
> parser WASM files can be resolved. If you run `wasm-pack test --node` directly,
|
|
95
|
+
> set `NODE_PATH` yourself:
|
|
96
|
+
>
|
|
97
|
+
> ```bash
|
|
98
|
+
> NODE_PATH=$PWD/node_modules wasm-pack test --node
|
|
99
|
+
> ```
|
|
100
|
+
|
|
101
|
+
### JavaScript tests
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
yarn test:js
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
This builds the WASM package for Node.js and runs AVA tests against it.
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
export class Pos {
|
|
5
|
+
private constructor();
|
|
6
|
+
free(): void;
|
|
7
|
+
[Symbol.dispose](): void;
|
|
8
|
+
/**
|
|
9
|
+
* line number starting from 0
|
|
10
|
+
*/
|
|
11
|
+
line: number;
|
|
12
|
+
/**
|
|
13
|
+
* column number starting from 0
|
|
14
|
+
*/
|
|
15
|
+
column: number;
|
|
16
|
+
/**
|
|
17
|
+
* character offset of the position
|
|
18
|
+
*/
|
|
19
|
+
index: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class Range {
|
|
23
|
+
private constructor();
|
|
24
|
+
free(): void;
|
|
25
|
+
[Symbol.dispose](): void;
|
|
26
|
+
/**
|
|
27
|
+
* starting position of the range
|
|
28
|
+
*/
|
|
29
|
+
start: Pos;
|
|
30
|
+
/**
|
|
31
|
+
* ending position of the range
|
|
32
|
+
*/
|
|
33
|
+
end: Pos;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class SgNode {
|
|
37
|
+
private constructor();
|
|
38
|
+
free(): void;
|
|
39
|
+
[Symbol.dispose](): void;
|
|
40
|
+
range(): Range;
|
|
41
|
+
isLeaf(): boolean;
|
|
42
|
+
isNamed(): boolean;
|
|
43
|
+
isNamedLeaf(): boolean;
|
|
44
|
+
kind(): string;
|
|
45
|
+
is(kind: string): boolean;
|
|
46
|
+
text(): string;
|
|
47
|
+
id(): number;
|
|
48
|
+
matches(m: any): boolean;
|
|
49
|
+
inside(m: any): boolean;
|
|
50
|
+
has(m: any): boolean;
|
|
51
|
+
precedes(m: any): boolean;
|
|
52
|
+
follows(m: any): boolean;
|
|
53
|
+
getMatch(m: string): SgNode | undefined;
|
|
54
|
+
getMultipleMatches(m: string): SgNode[];
|
|
55
|
+
getTransformed(m: string): string | undefined;
|
|
56
|
+
children_nodes(): SgNode[];
|
|
57
|
+
parent_node(): SgNode | undefined;
|
|
58
|
+
child(nth: number): SgNode | undefined;
|
|
59
|
+
ancestors(): SgNode[];
|
|
60
|
+
next_node(): SgNode | undefined;
|
|
61
|
+
nextAll(): SgNode[];
|
|
62
|
+
prev(): SgNode | undefined;
|
|
63
|
+
prevAll(): SgNode[];
|
|
64
|
+
find(matcher: any): SgNode | undefined;
|
|
65
|
+
findAll(matcher: any): SgNode[];
|
|
66
|
+
field(name: string): SgNode | undefined;
|
|
67
|
+
fieldChildren(name: string): SgNode[];
|
|
68
|
+
replace(text: string): WasmEdit;
|
|
69
|
+
commitEdits(edits: any): string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export class SgRoot {
|
|
73
|
+
private constructor();
|
|
74
|
+
free(): void;
|
|
75
|
+
[Symbol.dispose](): void;
|
|
76
|
+
/**
|
|
77
|
+
* Returns the root SgNode of the ast-grep instance.
|
|
78
|
+
*/
|
|
79
|
+
root(): SgNode;
|
|
80
|
+
/**
|
|
81
|
+
* Returns the path of the file if it is discovered by ast-grep's `findInFiles`.
|
|
82
|
+
* Returns `"anonymous"` if the instance is created by `parse`.
|
|
83
|
+
*/
|
|
84
|
+
filename(): string;
|
|
85
|
+
/**
|
|
86
|
+
* This method is mainly for debugging tree parsing result.
|
|
87
|
+
*/
|
|
88
|
+
getInnerTree(): any;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export class WasmEdit {
|
|
92
|
+
private constructor();
|
|
93
|
+
free(): void;
|
|
94
|
+
[Symbol.dispose](): void;
|
|
95
|
+
/**
|
|
96
|
+
* The start position of the edit (character offset)
|
|
97
|
+
*/
|
|
98
|
+
start_pos: number;
|
|
99
|
+
/**
|
|
100
|
+
* The end position of the edit (character offset)
|
|
101
|
+
*/
|
|
102
|
+
end_pos: number;
|
|
103
|
+
/**
|
|
104
|
+
* The text to be inserted
|
|
105
|
+
*/
|
|
106
|
+
inserted_text: string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Dump a pattern's internal structure for inspection.
|
|
111
|
+
* `selector` is an optional kind name for contextual patterns.
|
|
112
|
+
* `strictness` is one of: "cst", "smart", "ast", "relaxed", "signature", "template".
|
|
113
|
+
* Returns a tree structure showing how ast-grep parses the pattern, including source positions.
|
|
114
|
+
*/
|
|
115
|
+
export function dumpPattern(lang: string, pattern_str: string, selector?: string | null, strictness?: string | null): any;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Initialize the tree-sitter WASM runtime.
|
|
119
|
+
* Must be called before any other function.
|
|
120
|
+
*/
|
|
121
|
+
export function initializeTreeSitter(): Promise<void>;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Get the `kind` number from its string name.
|
|
125
|
+
*/
|
|
126
|
+
export function kind(lang: string, kind_name: string): number;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Parse a string to an ast-grep instance.
|
|
130
|
+
*/
|
|
131
|
+
export function parse(lang: string, src: string): SgRoot;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Compile a string to ast-grep Pattern config.
|
|
135
|
+
*/
|
|
136
|
+
export function pattern(lang: string, pattern_str: string): any;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Register dynamic languages for parsing.
|
|
140
|
+
* `langs` is a Map of language name to its registration config
|
|
141
|
+
* (with `libraryPath` and optional `expandoChar`).
|
|
142
|
+
* Can be called multiple times; existing languages are updated.
|
|
143
|
+
*/
|
|
144
|
+
export function registerDynamicLanguage(langs: any): Promise<void>;
|
|
145
|
+
|
|
146
|
+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
147
|
+
|
|
148
|
+
export interface InitOutput {
|
|
149
|
+
readonly memory: WebAssembly.Memory;
|
|
150
|
+
readonly __wbg_wasmedit_free: (a: number, b: number) => void;
|
|
151
|
+
readonly __wbg_get_wasmedit_start_pos: (a: number) => number;
|
|
152
|
+
readonly __wbg_set_wasmedit_start_pos: (a: number, b: number) => void;
|
|
153
|
+
readonly __wbg_get_wasmedit_end_pos: (a: number) => number;
|
|
154
|
+
readonly __wbg_set_wasmedit_end_pos: (a: number, b: number) => void;
|
|
155
|
+
readonly __wbg_get_wasmedit_inserted_text: (a: number) => [number, number];
|
|
156
|
+
readonly __wbg_set_wasmedit_inserted_text: (a: number, b: number, c: number) => void;
|
|
157
|
+
readonly __wbg_pos_free: (a: number, b: number) => void;
|
|
158
|
+
readonly __wbg_get_pos_line: (a: number) => number;
|
|
159
|
+
readonly __wbg_set_pos_line: (a: number, b: number) => void;
|
|
160
|
+
readonly __wbg_get_pos_column: (a: number) => number;
|
|
161
|
+
readonly __wbg_set_pos_column: (a: number, b: number) => void;
|
|
162
|
+
readonly __wbg_get_pos_index: (a: number) => number;
|
|
163
|
+
readonly __wbg_set_pos_index: (a: number, b: number) => void;
|
|
164
|
+
readonly __wbg_range_free: (a: number, b: number) => void;
|
|
165
|
+
readonly __wbg_get_range_start: (a: number) => number;
|
|
166
|
+
readonly __wbg_set_range_start: (a: number, b: number) => void;
|
|
167
|
+
readonly __wbg_get_range_end: (a: number) => number;
|
|
168
|
+
readonly __wbg_set_range_end: (a: number, b: number) => void;
|
|
169
|
+
readonly __wbg_sgroot_free: (a: number, b: number) => void;
|
|
170
|
+
readonly sgroot_root: (a: number) => number;
|
|
171
|
+
readonly sgroot_filename: (a: number) => [number, number];
|
|
172
|
+
readonly sgroot_getInnerTree: (a: number) => any;
|
|
173
|
+
readonly __wbg_sgnode_free: (a: number, b: number) => void;
|
|
174
|
+
readonly sgnode_range: (a: number) => number;
|
|
175
|
+
readonly sgnode_isLeaf: (a: number) => number;
|
|
176
|
+
readonly sgnode_isNamed: (a: number) => number;
|
|
177
|
+
readonly sgnode_isNamedLeaf: (a: number) => number;
|
|
178
|
+
readonly sgnode_kind: (a: number) => [number, number];
|
|
179
|
+
readonly sgnode_is: (a: number, b: number, c: number) => number;
|
|
180
|
+
readonly sgnode_text: (a: number) => [number, number];
|
|
181
|
+
readonly sgnode_id: (a: number) => number;
|
|
182
|
+
readonly sgnode_matches: (a: number, b: any) => [number, number, number];
|
|
183
|
+
readonly sgnode_inside: (a: number, b: any) => [number, number, number];
|
|
184
|
+
readonly sgnode_has: (a: number, b: any) => [number, number, number];
|
|
185
|
+
readonly sgnode_precedes: (a: number, b: any) => [number, number, number];
|
|
186
|
+
readonly sgnode_follows: (a: number, b: any) => [number, number, number];
|
|
187
|
+
readonly sgnode_getMatch: (a: number, b: number, c: number) => number;
|
|
188
|
+
readonly sgnode_getMultipleMatches: (a: number, b: number, c: number) => [number, number];
|
|
189
|
+
readonly sgnode_getTransformed: (a: number, b: number, c: number) => [number, number];
|
|
190
|
+
readonly sgnode_children_nodes: (a: number) => [number, number];
|
|
191
|
+
readonly sgnode_parent_node: (a: number) => number;
|
|
192
|
+
readonly sgnode_child: (a: number, b: number) => number;
|
|
193
|
+
readonly sgnode_ancestors: (a: number) => [number, number];
|
|
194
|
+
readonly sgnode_next_node: (a: number) => number;
|
|
195
|
+
readonly sgnode_nextAll: (a: number) => [number, number];
|
|
196
|
+
readonly sgnode_prev: (a: number) => number;
|
|
197
|
+
readonly sgnode_prevAll: (a: number) => [number, number];
|
|
198
|
+
readonly sgnode_find: (a: number, b: any) => [number, number, number];
|
|
199
|
+
readonly sgnode_findAll: (a: number, b: any) => [number, number, number, number];
|
|
200
|
+
readonly sgnode_field: (a: number, b: number, c: number) => number;
|
|
201
|
+
readonly sgnode_fieldChildren: (a: number, b: number, c: number) => [number, number];
|
|
202
|
+
readonly sgnode_replace: (a: number, b: number, c: number) => number;
|
|
203
|
+
readonly sgnode_commitEdits: (a: number, b: any) => [number, number, number, number];
|
|
204
|
+
readonly initializeTreeSitter: () => any;
|
|
205
|
+
readonly registerDynamicLanguage: (a: any) => any;
|
|
206
|
+
readonly parse: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
207
|
+
readonly kind: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
208
|
+
readonly pattern: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
209
|
+
readonly dumpPattern: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => [number, number, number];
|
|
210
|
+
readonly wasm_bindgen__convert__closures_____invoke__hf6abb6e10d012239: (a: number, b: number, c: any) => void;
|
|
211
|
+
readonly wasm_bindgen__closure__destroy__hfe03ac61b9e9de77: (a: number, b: number) => void;
|
|
212
|
+
readonly wasm_bindgen__convert__closures_____invoke__h626c386f4a0f1908: (a: number, b: number, c: any, d: any) => void;
|
|
213
|
+
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
214
|
+
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
215
|
+
readonly __wbindgen_exn_store: (a: number) => void;
|
|
216
|
+
readonly __externref_table_alloc: () => number;
|
|
217
|
+
readonly __wbindgen_externrefs: WebAssembly.Table;
|
|
218
|
+
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
219
|
+
readonly __externref_table_dealloc: (a: number) => void;
|
|
220
|
+
readonly __externref_drop_slice: (a: number, b: number) => void;
|
|
221
|
+
readonly __wbindgen_start: () => void;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
228
|
+
* a precompiled `WebAssembly.Module`.
|
|
229
|
+
*
|
|
230
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
231
|
+
*
|
|
232
|
+
* @returns {InitOutput}
|
|
233
|
+
*/
|
|
234
|
+
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
238
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
239
|
+
*
|
|
240
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
241
|
+
*
|
|
242
|
+
* @returns {Promise<InitOutput>}
|
|
243
|
+
*/
|
|
244
|
+
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|