@willbooster/tree-sitter-kotlin 1.3.1 → 1.4.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 CHANGED
@@ -1,12 +1,12 @@
1
1
  # @willbooster/tree-sitter-kotlin
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@willbooster/tree-sitter-kotlin.svg)](https://www.npmjs.com/package/@willbooster/tree-sitter-kotlin)
4
- [![crates.io](https://img.shields.io/crates/v/willbooster-tree-sitter-kotlin.svg)](https://crates.io/crates/willbooster-tree-sitter-kotlin)
5
4
  [![license](https://img.shields.io/npm/l/@willbooster/tree-sitter-kotlin.svg)](https://www.npmjs.com/package/@willbooster/tree-sitter-kotlin)
6
5
  [![Test](https://github.com/WillBooster/tree-sitter-kotlin/actions/workflows/test.yml/badge.svg)](https://github.com/WillBooster/tree-sitter-kotlin/actions/workflows/test.yml)
7
6
  [![Test rust](https://github.com/WillBooster/tree-sitter-kotlin/actions/workflows/test-rust.yml/badge.svg)](https://github.com/WillBooster/tree-sitter-kotlin/actions/workflows/test-rust.yml)
8
7
  [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
9
- [![wbfy](https://img.shields.io/badge/wbfy-20.23.2-1e90ff.svg)](https://github.com/WillBooster/shared/tree/main/packages/wbfy)
8
+ [![wbfy](https://img.shields.io/badge/wbfy-20.26.0-1e90ff.svg)](https://github.com/WillBooster/shared/tree/main/packages/wbfy)
9
+ [![crates.io](https://img.shields.io/crates/v/willbooster-tree-sitter-kotlin.svg)](https://crates.io/crates/willbooster-tree-sitter-kotlin)
10
10
 
11
11
  Kotlin grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter), forked from
12
12
  [tree-sitter-grammars/tree-sitter-kotlin](https://github.com/tree-sitter-grammars/tree-sitter-kotlin). We are grateful
@@ -16,11 +16,15 @@ This fork fixes parsing bugs and raises conformance with the Kotlin grammar.
16
16
 
17
17
  ## Usage
18
18
 
19
- The npm package ships `tree-sitter-kotlin.wasm` for [web-tree-sitter](https://www.npmjs.com/package/web-tree-sitter):
19
+ The npm package ships `tree-sitter-kotlin.wasm` for
20
+ [@willbooster/web-tree-sitter](https://www.npmjs.com/package/@willbooster/web-tree-sitter), which runs in Node.js, Bun,
21
+ browsers, and Cloudflare Workers.
22
+
23
+ In Node.js and Bun:
20
24
 
21
25
  ```js
22
26
  import { fileURLToPath } from 'node:url';
23
- import { Language, Parser } from 'web-tree-sitter';
27
+ import { Language, Parser } from '@willbooster/web-tree-sitter';
24
28
 
25
29
  await Parser.init();
26
30
  const parser = new Parser();
@@ -29,6 +33,31 @@ parser.setLanguage(await Language.load(wasmPath));
29
33
  const tree = parser.parse('fun main() = println("Hello")\n');
30
34
  ```
31
35
 
36
+ In browsers, load both `.wasm` files by URL. With Vite:
37
+
38
+ ```js
39
+ import { Language, Parser } from '@willbooster/web-tree-sitter';
40
+ import runtimeUrl from '@willbooster/web-tree-sitter/web-tree-sitter.wasm?url';
41
+ import kotlinUrl from '@willbooster/tree-sitter-kotlin/tree-sitter-kotlin.wasm?url';
42
+
43
+ await Parser.init({ locateFile: () => runtimeUrl });
44
+ const parser = new Parser();
45
+ parser.setLanguage(await Language.load(kotlinUrl));
46
+ ```
47
+
48
+ In Cloudflare Workers, which do not allow compiling Wasm at run time, import both `.wasm` files as modules (with or
49
+ without Node.js compatibility):
50
+
51
+ ```js
52
+ import { Language, Parser } from '@willbooster/web-tree-sitter';
53
+ import runtime from '@willbooster/web-tree-sitter/web-tree-sitter.wasm';
54
+ import kotlin from '@willbooster/tree-sitter-kotlin/tree-sitter-kotlin.wasm';
55
+
56
+ await Parser.init({ wasmModule: runtime });
57
+ const parser = new Parser();
58
+ parser.setLanguage(await Language.load(kotlin));
59
+ ```
60
+
32
61
  The package also ships the node types in `src/node-types.json`.
33
62
 
34
63
  In Rust, depend on the [crate](https://crates.io/crates/willbooster-tree-sitter-kotlin):
@@ -49,6 +78,7 @@ parser.set_language(&tree_sitter_kotlin::LANGUAGE.into())?;
49
78
  ```sh
50
79
  mise install
51
80
  bun install --frozen-lockfile
81
+ bun run test/ci-setup
52
82
  bun run build/ci
53
83
  bun run test
54
84
  script/parse-examples
@@ -67,7 +97,10 @@ cargo test
67
97
  it; review its diff before committing;
68
98
  - a performance check (`test/unit/performance.test.ts`) that recovering from an error on each of 10,000 lines takes
69
99
  linear time, since consumers parse files while they are being edited. It loads the Wasm build through
70
- web-tree-sitter, which `bun run build/ci` rebuilds after regenerating the parser.
100
+ @willbooster/web-tree-sitter, which `bun run build/ci` rebuilds after regenerating the parser;
101
+ - checks that the Wasm build parses Kotlin through @willbooster/web-tree-sitter in Chromium
102
+ (`test/unit/browser.test.ts`) and in Cloudflare Workers with and without
103
+ Node.js compatibility (`test/unit/workers.test.ts`).
71
104
 
72
105
  CI also runs these tests on Linux arm64 and macOS, where the Rust binding compiles the parser natively, and fuzzes the parser with libFuzzer and sanitizers
73
106
  (`.github/workflows/robustness.yml`).
package/grammar.js CHANGED
@@ -45,6 +45,7 @@ module.exports = grammar({
45
45
  [$._loop_prefix, $.annotated_expression],
46
46
  [$._loop_prefix, $.modifiers, $.type_modifiers, $.annotated_expression],
47
47
  [$._loop_prefix, $.labeled_expression],
48
+ [$._loop_prefix, $.type_modifiers, $.annotated_expression],
48
49
  [$.parameter_modifiers, $.type_modifiers],
49
50
  [$.function_modifier, $.type_modifiers],
50
51
  [$.function_modifier, $._reserved_identifier],
@@ -88,7 +89,7 @@ module.exports = grammar({
88
89
  '$',
89
90
  ],
90
91
 
91
- inline: ($) => [$._statements, $._identifier],
92
+ inline: ($) => [$._statements, $._identifier, $._control_structure_body],
92
93
 
93
94
  precedences: ($) => [
94
95
  [$.block, $.lambda_literal],
@@ -298,7 +299,7 @@ module.exports = grammar({
298
299
  'in',
299
300
  $.expression,
300
301
  ')',
301
- optional(field('body', choice($.block, $.statement)))
302
+ optional(field('body', $._control_structure_body))
302
303
  )
303
304
  ),
304
305
 
@@ -310,7 +311,7 @@ module.exports = grammar({
310
311
  '(',
311
312
  field('condition', $.expression),
312
313
  ')',
313
- optional(choice(field('body', choice($.block, $.statement)), ';'))
314
+ optional(choice(field('body', $._control_structure_body), ';'))
314
315
  )
315
316
  ),
316
317
 
@@ -319,7 +320,7 @@ module.exports = grammar({
319
320
  seq(
320
321
  optional($._loop_prefix),
321
322
  'do',
322
- optional(choice(field('body', choice($.block, $.statement)), ';')),
323
+ optional(choice(field('body', $._control_structure_body), ';')),
323
324
  'while',
324
325
  '(',
325
326
  field('condition', $.expression),
@@ -598,18 +599,23 @@ module.exports = grammar({
598
599
  field('condition', $.expression),
599
600
  ')',
600
601
  choice(
601
- field('consequence', choice($.block, $.expression, $.assignment)),
602
+ field('consequence', $._control_structure_body),
602
603
  ';',
603
604
  seq(
604
- optional(field('consequence', choice($.block, $.expression, $.assignment))),
605
+ optional(field('consequence', $._control_structure_body)),
605
606
  optional(';'),
606
607
  'else',
607
- choice(field('alternative', choice($.block, $.expression, $.assignment)), ';')
608
+ choice(field('alternative', $._control_structure_body), ';')
608
609
  )
609
610
  )
610
611
  )
611
612
  ),
612
613
 
614
+ // Unlike Kotlin's grammar, this excludes declarations, which the compiler rejects here anyway: allowing them
615
+ // lets declarations nest in every expression context and exceeds tree-sitter's limit of 65535 parse states.
616
+ _control_structure_body: ($) =>
617
+ choice($.block, $.expression, $.assignment, $.for_statement, $.while_statement, $.do_while_statement),
618
+
613
619
  parenthesized_expression: ($) => seq('(', $.expression, ')'),
614
620
 
615
621
  collection_literal: ($) => seq('[', commaSep1($.expression), optional(','), ']'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willbooster/tree-sitter-kotlin",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "description": "Kotlin grammar for tree-sitter",
5
5
  "keywords": [
6
6
  "incremental",
@@ -33,6 +33,7 @@
33
33
  "start": "tree-sitter playground",
34
34
  "test": "bun wb test",
35
35
  "test/ci": "bun wb test-on-ci",
36
+ "test/ci-setup": "playwright install --with-deps chromium",
36
37
  "typecheck": "bun wb typecheck",
37
38
  "verify": "bun wb verify",
38
39
  "verify-full": "bun wb verify --full"
@@ -41,25 +42,30 @@
41
42
  "@semantic-release/exec": "7.1.0",
42
43
  "@tsconfig/bun": "1.0.11",
43
44
  "@types/bun": "1.4.2",
45
+ "@vitest/browser-playwright": "5.0.1",
44
46
  "@willbooster/oxfmt-config": "1.2.2",
45
47
  "@willbooster/oxlint-config": "1.4.8",
46
- "@willbooster/wb": "22.8.0",
48
+ "@willbooster/wb": "22.11.5",
49
+ "@willbooster/web-tree-sitter": "1.0.0",
47
50
  "conventional-changelog-conventionalcommits": "10.4.0",
48
51
  "lefthook": "2.1.14",
49
- "oxfmt": "0.68.0",
50
- "oxlint": "1.83.0",
52
+ "oxfmt": "0.70.0",
53
+ "oxlint": "1.85.0",
51
54
  "oxlint-tsgolint": "7.0.2002",
55
+ "playwright": "1.63.0",
52
56
  "semantic-release": "25.0.9",
53
57
  "sort-package-json": "4.0.0",
54
58
  "tree-sitter-cli": "0.27.0",
55
59
  "typescript": "7.0.2",
56
- "web-tree-sitter": "0.27.0"
60
+ "vite": "8.3.0",
61
+ "vitest": "5.0.1",
62
+ "wrangler": "4.136.2"
57
63
  },
58
64
  "peerDependencies": {
59
- "web-tree-sitter": "^0.27.0"
65
+ "@willbooster/web-tree-sitter": "^1.0.0"
60
66
  },
61
67
  "peerDependenciesMeta": {
62
- "web-tree-sitter": {
68
+ "@willbooster/web-tree-sitter": {
63
69
  "optional": true
64
70
  }
65
71
  },
@@ -936,12 +936,28 @@
936
936
  "multiple": false,
937
937
  "required": false,
938
938
  "types": [
939
+ {
940
+ "type": "assignment",
941
+ "named": true
942
+ },
939
943
  {
940
944
  "type": "block",
941
945
  "named": true
942
946
  },
943
947
  {
944
- "type": "statement",
948
+ "type": "do_while_statement",
949
+ "named": true
950
+ },
951
+ {
952
+ "type": "expression",
953
+ "named": true
954
+ },
955
+ {
956
+ "type": "for_statement",
957
+ "named": true
958
+ },
959
+ {
960
+ "type": "while_statement",
945
961
  "named": true
946
962
  }
947
963
  ]
@@ -1079,12 +1095,28 @@
1079
1095
  "multiple": false,
1080
1096
  "required": false,
1081
1097
  "types": [
1098
+ {
1099
+ "type": "assignment",
1100
+ "named": true
1101
+ },
1082
1102
  {
1083
1103
  "type": "block",
1084
1104
  "named": true
1085
1105
  },
1086
1106
  {
1087
- "type": "statement",
1107
+ "type": "do_while_statement",
1108
+ "named": true
1109
+ },
1110
+ {
1111
+ "type": "expression",
1112
+ "named": true
1113
+ },
1114
+ {
1115
+ "type": "for_statement",
1116
+ "named": true
1117
+ },
1118
+ {
1119
+ "type": "while_statement",
1088
1120
  "named": true
1089
1121
  }
1090
1122
  ]
@@ -1295,9 +1327,21 @@
1295
1327
  "type": "block",
1296
1328
  "named": true
1297
1329
  },
1330
+ {
1331
+ "type": "do_while_statement",
1332
+ "named": true
1333
+ },
1298
1334
  {
1299
1335
  "type": "expression",
1300
1336
  "named": true
1337
+ },
1338
+ {
1339
+ "type": "for_statement",
1340
+ "named": true
1341
+ },
1342
+ {
1343
+ "type": "while_statement",
1344
+ "named": true
1301
1345
  }
1302
1346
  ]
1303
1347
  },
@@ -1323,9 +1367,21 @@
1323
1367
  "type": "block",
1324
1368
  "named": true
1325
1369
  },
1370
+ {
1371
+ "type": "do_while_statement",
1372
+ "named": true
1373
+ },
1326
1374
  {
1327
1375
  "type": "expression",
1328
1376
  "named": true
1377
+ },
1378
+ {
1379
+ "type": "for_statement",
1380
+ "named": true
1381
+ },
1382
+ {
1383
+ "type": "while_statement",
1384
+ "named": true
1329
1385
  }
1330
1386
  ]
1331
1387
  }
@@ -2605,12 +2661,28 @@
2605
2661
  "multiple": false,
2606
2662
  "required": false,
2607
2663
  "types": [
2664
+ {
2665
+ "type": "assignment",
2666
+ "named": true
2667
+ },
2608
2668
  {
2609
2669
  "type": "block",
2610
2670
  "named": true
2611
2671
  },
2612
2672
  {
2613
- "type": "statement",
2673
+ "type": "do_while_statement",
2674
+ "named": true
2675
+ },
2676
+ {
2677
+ "type": "expression",
2678
+ "named": true
2679
+ },
2680
+ {
2681
+ "type": "for_statement",
2682
+ "named": true
2683
+ },
2684
+ {
2685
+ "type": "while_statement",
2614
2686
  "named": true
2615
2687
  }
2616
2688
  ]
Binary file
package/tree-sitter.json CHANGED
@@ -13,7 +13,7 @@
13
13
  }
14
14
  ],
15
15
  "metadata": {
16
- "version": "1.3.1",
16
+ "version": "1.4.0",
17
17
  "license": "MIT",
18
18
  "description": "Kotlin grammar for tree-sitter",
19
19
  "authors": [