@singapore-editor/tree-sitter-x 0.28.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Max Brunsfeld
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,250 @@
1
+ # Tree-sitter-x for JavaScript
2
+
3
+ WASI bindings for [tree-sitter-x](https://github.com/ShaulLavo/tree-sitter-x), with shared text buffers and C extensions.
4
+
5
+ ## Setup
6
+
7
+ ```sh
8
+ npm install @singapore-editor/tree-sitter-x
9
+ ```
10
+
11
+ ```js
12
+ import { Parser, Language } from '@singapore-editor/tree-sitter-x';
13
+ await Parser.init();
14
+ ```
15
+
16
+ CommonJS is also supported:
17
+
18
+ ```js
19
+ const { Parser, Language } = require('@singapore-editor/tree-sitter-x');
20
+ Parser.init().then(() => {
21
+ const parser = new Parser();
22
+ });
23
+ ```
24
+
25
+ The package includes `web-tree-sitter.wasm`. Browser bundles must serve that asset alongside the runtime or pass its bytes to `Parser.init({ wasmBinary })`.
26
+
27
+ Import `@singapore-editor/tree-sitter-x/debug` for the build with debug symbols and assertions.
28
+
29
+ ### Basic Usage
30
+
31
+ First, create a parser:
32
+
33
+ ```js
34
+ const parser = new Parser();
35
+ ```
36
+
37
+ Then assign a language to the parser. Tree-sitter languages are packaged as individual `.wasm` files (more on this below):
38
+
39
+ ```js
40
+ const { Language } = require('@singapore-editor/tree-sitter-x');
41
+ const JavaScript = await Language.load('/path/to/tree-sitter-javascript.wasm');
42
+ parser.setLanguage(JavaScript);
43
+ ```
44
+
45
+ Now you can parse source code:
46
+
47
+ ```js
48
+ const sourceCode = 'let x = 1; console.log(x);';
49
+ const tree = parser.parse(sourceCode);
50
+ ```
51
+
52
+ and inspect the syntax tree.
53
+
54
+ ```javascript
55
+ console.log(tree.rootNode.toString());
56
+
57
+ // (program
58
+ // (lexical_declaration
59
+ // (variable_declarator (identifier) (number)))
60
+ // (expression_statement
61
+ // (call_expression
62
+ // (member_expression (identifier) (property_identifier))
63
+ // (arguments (identifier)))))
64
+
65
+ const callExpression = tree.rootNode.child(1).firstChild;
66
+ console.log(callExpression);
67
+
68
+ // { type: 'call_expression',
69
+ // startPosition: {row: 0, column: 16},
70
+ // endPosition: {row: 0, column: 30},
71
+ // startIndex: 0,
72
+ // endIndex: 30 }
73
+ ```
74
+
75
+ ### Editing
76
+
77
+ If your source code *changes*, you can update the syntax tree. This will take less time than the first parse.
78
+
79
+ ```javascript
80
+ // Replace 'let' with 'const'
81
+ const newSourceCode = 'const x = 1; console.log(x);';
82
+
83
+ tree.edit({
84
+ startIndex: 0,
85
+ oldEndIndex: 3,
86
+ newEndIndex: 5,
87
+ startPosition: {row: 0, column: 0},
88
+ oldEndPosition: {row: 0, column: 3},
89
+ newEndPosition: {row: 0, column: 5},
90
+ });
91
+
92
+ const newTree = parser.parse(newSourceCode, tree);
93
+ ```
94
+
95
+ ### Parsing Text From a Custom Data Structure
96
+
97
+ If your text is stored in a data structure other than a single string, you can parse it by supplying a callback to `parse`
98
+ instead of a string:
99
+
100
+ ```javascript
101
+ const sourceLines = [
102
+ 'let x = 1;',
103
+ 'console.log(x);'
104
+ ];
105
+
106
+ const tree = parser.parse((index, position) => {
107
+ let line = sourceLines[position.row];
108
+ if (line) return line.slice(position.column);
109
+ });
110
+ ```
111
+
112
+ ### Getting the `.wasm` language files
113
+
114
+ There are several options on how to get the `.wasm` files for the languages you want to parse.
115
+
116
+ #### From npmjs.com
117
+
118
+ The recommended way is to just install the package from npm. For example, to parse JavaScript, you can install the `tree-sitter-javascript`
119
+ package:
120
+
121
+ ```sh
122
+ npm install tree-sitter-javascript
123
+ ```
124
+
125
+ Then you can find the `.wasm` file in the `node_modules/tree-sitter-javascript` directory.
126
+
127
+ #### From GitHub
128
+
129
+ You can also download the `.wasm` files from GitHub releases, so long as the repository uses our reusable workflow to publish
130
+ them.
131
+ For example, you can download the JavaScript `.wasm` file from the tree-sitter-javascript [releases page][gh release js].
132
+
133
+ #### Generating `.wasm` files
134
+
135
+ You can also generate the `.wasm` file for your desired grammar. Shown below is an example of how to generate the `.wasm`
136
+ file for the JavaScript grammar.
137
+
138
+ > [!NOTE]
139
+ > Since v0.26.1, `tree-sitter build --wasm` uses [wasi-sdk][] and will automatically download it on first use.
140
+ > No additional tools need to be installed.
141
+
142
+ First install `tree-sitter-cli`, and the tree-sitter language for which to generate `.wasm`
143
+ (`tree-sitter-javascript` in this example):
144
+
145
+ ```sh
146
+ npm install --save-dev tree-sitter-cli tree-sitter-javascript
147
+ ```
148
+
149
+ Then just use tree-sitter cli tool to generate the `.wasm`.
150
+
151
+ ```sh
152
+ npx tree-sitter build --wasm node_modules/tree-sitter-javascript
153
+ ```
154
+
155
+ If everything is fine, file `tree-sitter-javascript.wasm` should be generated in current directory.
156
+
157
+ ### Wasm compatibility
158
+
159
+ `web-tree-sitter` supports the same parser ABI versions as the corresponding tree-sitter library:
160
+
161
+ | web-tree-sitter version | Min parser ABI version | Max parser ABI version |
162
+ |-------------------------|------------------------|------------------------|
163
+ | 0.24.x | 13 | 14 |
164
+ | >= 0.25.0 | 13 | 15 |
165
+
166
+ > [!WARNING]
167
+ > Some prebuilt `.wasm` files use an older dynamic-linking format that newer versions of `web-tree-sitter` cannot
168
+ > load, even if their parser ABI is supported. Rebuild these files using a current tree-sitter CLI.
169
+
170
+ ### Running .wasm in Node.js
171
+
172
+ Notice that executing `.wasm` files in Node.js is considerably slower than running [Node.js bindings][node bindings].
173
+ However, this could be useful for testing purposes:
174
+
175
+ ```javascript
176
+ const Parser = require('@singapore-editor/tree-sitter-x');
177
+
178
+ (async () => {
179
+ await Parser.init();
180
+ const parser = new Parser();
181
+ const Lang = await Parser.Language.load('tree-sitter-javascript.wasm');
182
+ parser.setLanguage(Lang);
183
+ const tree = parser.parse('let x = 1;');
184
+ console.log(tree.rootNode.toString());
185
+ })();
186
+ ```
187
+
188
+ ### Loading a pre-compiled WebAssembly module
189
+
190
+ Some environments, such as Cloudflare Workers and Vercel Edge Functions, import
191
+ `.wasm` files as `WebAssembly.Module` objects. You can pass those modules to `Language.loadSync`:
192
+
193
+ ```javascript
194
+ import treeSitterJavaScript from 'tree-sitter-javascript.wasm';
195
+ // treeSitterJavaScript is of type `WebAssembly.Module`
196
+ const JavaScript = Language.loadSync(treeSitterJavaScript);
197
+ parser.setLanguage(JavaScript);
198
+ ```
199
+
200
+ ### Running .wasm in browser
201
+
202
+ `web-tree-sitter` can run in the browser, but there are some common pitfalls.
203
+
204
+ #### Loading the .wasm file
205
+
206
+ `web-tree-sitter` needs to load the `tree-sitter.wasm` file. By default, it assumes that this file is available in the
207
+ same path as the JavaScript code. Therefore, if the code is being served from `http://localhost:3000/bundle.js`, then
208
+ the Wasm file should be at `http://localhost:3000/tree-sitter.wasm`.
209
+
210
+ For server side frameworks like NextJS, this can be tricky as pages are often served from a path such as
211
+ `http://localhost:3000/_next/static/chunks/pages/index.js`. The loader will therefore look for the Wasm file at
212
+ `http://localhost:3000/_next/static/chunks/pages/tree-sitter.wasm`. The solution is to pass a `locateFile` function in
213
+ the `moduleOptions` argument to `Parser.init()`:
214
+
215
+ ```javascript
216
+ await Parser.init({
217
+ locateFile(scriptName: string, scriptDirectory: string) {
218
+ return scriptName;
219
+ },
220
+ });
221
+ ```
222
+
223
+ `locateFile` takes in two parameters, `scriptName`, i.e. the Wasm file name, and `scriptDirectory`, i.e. the directory
224
+ where the loader expects the script to be. It returns the path where the loader will look for the Wasm file. In the NextJS
225
+ case, we want to return just the `scriptName` so that the loader will look at `http://localhost:3000/tree-sitter.wasm`
226
+ and not `http://localhost:3000/_next/static/chunks/pages/tree-sitter.wasm`.
227
+
228
+ `Parser.init` also accepts `wasmBinary`: the runtime's bytes or a compiled `WebAssembly.Module`, instead of fetching it.
229
+
230
+ #### "Can't resolve 'fs' in 'node_modules/web-tree-sitter"
231
+
232
+ Most bundlers will notice that the `web-tree-sitter.js` file is attempting to import `fs`, i.e. node's file system library.
233
+ Since this doesn't exist in the browser, the bundlers will get confused. For Webpack, you can fix this by adding the
234
+ following to your webpack config:
235
+
236
+ ```javascript
237
+ {
238
+ resolve: {
239
+ fallback: {
240
+ fs: false
241
+ }
242
+ }
243
+ }
244
+ ```
245
+
246
+ [gh release]: https://github.com/tree-sitter/tree-sitter/releases/latest
247
+ [gh release js]: https://github.com/tree-sitter/tree-sitter-javascript/releases/latest
248
+ [node bindings]: https://github.com/tree-sitter/node-tree-sitter
249
+ [npm module]: https://www.npmjs.com/package/@singapore-editor/tree-sitter-x
250
+ [wasi-sdk]: https://github.com/WebAssembly/wasi-sdk