tree-sitter-kdl 1.0.3 → 2.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.
Files changed (39) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -2
  3. package/binding.gyp +22 -6
  4. package/bindings/node/binding.cc +12 -23
  5. package/bindings/node/index.d.ts +60 -0
  6. package/bindings/node/index.js +33 -15
  7. package/grammar.js +193 -170
  8. package/package.json +48 -31
  9. package/prebuilds/darwin-arm64/tree-sitter-kdl.node +0 -0
  10. package/prebuilds/darwin-x64/tree-sitter-kdl.node +0 -0
  11. package/prebuilds/linux-arm64/tree-sitter-kdl.node +0 -0
  12. package/prebuilds/linux-x64/tree-sitter-kdl.node +0 -0
  13. package/prebuilds/win32-arm64/tree-sitter-kdl.node +0 -0
  14. package/prebuilds/win32-x64/tree-sitter-kdl.node +0 -0
  15. package/queries/highlights.scm +37 -17
  16. package/queries/indents.scm +1 -1
  17. package/queries/injections.scm +10 -0
  18. package/queries/locals.scm +3 -3
  19. package/src/grammar.json +744 -761
  20. package/src/node-types.json +271 -238
  21. package/src/parser.c +12895 -11901
  22. package/src/scanner.c +161 -53
  23. package/src/tree_sitter/alloc.h +54 -0
  24. package/src/tree_sitter/array.h +336 -0
  25. package/src/tree_sitter/parser.h +79 -17
  26. package/tree-sitter-kdl.wasm +0 -0
  27. package/tree-sitter.json +44 -0
  28. package/.eslintrc.js +0 -20
  29. package/.gitattributes +0 -7
  30. package/.github/workflows/ci.yml +0 -34
  31. package/.github/workflows/fuzz.yml +0 -21
  32. package/.github/workflows/lint.yml +0 -19
  33. package/.github/workflows/publish.yml +0 -51
  34. package/Cargo.toml +0 -27
  35. package/Package.swift +0 -38
  36. package/bindings/rust/README.md +0 -36
  37. package/bindings/rust/build.rs +0 -19
  38. package/bindings/rust/lib.rs +0 -68
  39. package/bindings/swift/kdl.h +0 -16
package/grammar.js CHANGED
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * @file KDL grammar for tree-sitter
3
- * @author Amaan Qureshi <amaanq12@gmail.com>
3
+ * @author Amaan Qureshi <contact@amaanq.com>
4
4
  * @license MIT
5
5
  * @see {@link https://kdl.dev|official website}
6
- * @see {@link https://github.com/kdl-org/kdl/blob/main/SPEC.md|official syntax spec}
6
+ * @see {@link https://github.com/kdl-org/kdl/blob/1.0.0/SPEC.md|KDL 1 syntax spec}
7
+ * @see {@link https://github.com/kdl-org/kdl/blob/2.0.0/SPEC.md|KDL 2 syntax spec}
7
8
  */
8
9
 
9
10
  // deno-lint-ignore-file no-control-regex
@@ -13,56 +14,75 @@
13
14
  /// <reference types="tree-sitter-cli/dsl" />
14
15
  // @ts-check
15
16
 
16
- const ANNOTATION_BUILTINS = [
17
- 'i8',
18
- 'i16',
19
- 'i32',
20
- 'i64',
21
- 'u8',
22
- 'u16',
23
- 'u32',
24
- 'u64',
25
- 'isize',
26
- 'usize',
27
- 'f32',
28
- 'f64',
29
- 'decimal64',
30
- 'decimal128',
31
- 'date-time',
32
- 'time',
33
- 'date',
34
- 'duration',
35
- 'decimal',
36
- 'currency',
37
- 'country-2',
38
- 'country-3',
39
- 'country-subdivision',
40
- 'email',
41
- 'idn-email',
42
- 'hostname',
43
- 'idn-hostname',
44
- 'ipv4',
45
- 'ipv6',
46
- 'url',
47
- 'url-reference',
48
- 'irl',
49
- 'iri-reference',
50
- 'url-template',
51
- 'uuid',
52
- 'regex',
53
- 'base64',
54
- ];
55
-
56
- module.exports = grammar({
17
+ const BOOLEAN_KEYWORDS = ['true', 'false', '#true', '#false'];
18
+ const NULL_KEYWORDS = ['null', '#null'];
19
+ const KEYWORD_NUMBERS = ['#inf', '#-inf', '#nan'];
20
+ const UNICODE_SPACES = '\\u0009\\u0020\\u00A0\\u1680\\u2000-\\u200A\\u202F\\u205F\\u3000';
21
+ const NEWLINES = '\\r\\n\\u0085\\u000B\\u000C\\u2028\\u2029';
22
+ const DISALLOWED_LITERAL =
23
+ '\\u0000-\\u0008\\u000E-\\u001F\\u007F\\u200E\\u200F\\u202A-\\u202E\\u2066-\\u2069\\uFEFF';
24
+ const IDENTIFIER_EXCLUSIONS = `${UNICODE_SPACES}${NEWLINES}${DISALLOWED_LITERAL}\\\\\\/(){};\\[\\]"=`;
25
+ const IDENTIFIER_CHAR = `[^${IDENTIFIER_EXCLUSIONS}]`;
26
+ const IDENTIFIER_START = `[^${IDENTIFIER_EXCLUSIONS}0-9+\\-]`;
27
+ const IDENTIFIER_START_AFTER_SIGN = `[^${IDENTIFIER_EXCLUSIONS}0-9]`;
28
+ const STRING_CHAR = `[^"\\\\${DISALLOWED_LITERAL}]`;
29
+ const SIGN = '[+-]';
30
+ // integer := digit (digit | '_')*
31
+ const DIGITS = '[0-9][0-9_]*';
32
+ // hex-unicode := hex-digit{1, 6} - surrogate - above-max-scalar
33
+ const HEX_CHARS = '0-9a-fA-F';
34
+ const HEX = `[${HEX_CHARS}]`;
35
+ const NON_SURROGATE_4 = `(?:[0-9a-cA-Ce-fE-F]${HEX}{3}|[dD][0-7]${HEX}{2})`;
36
+ const SCALAR_5 = `(?:[1-9a-fA-F]${HEX}{4}|0${NON_SURROGATE_4})`;
37
+ const SCALAR_6 = `(?:0${SCALAR_5}|10${HEX}{4})`;
38
+ const UNICODE_SCALAR_ESCAPE = new RegExp(
39
+ `u\\{(?:${HEX}{1,3}|${NON_SURROGATE_4}|${SCALAR_5}|${SCALAR_6})\\}`,
40
+ );
41
+
42
+ /**
43
+ * nodes := line-space* (node line-space*)*
44
+ *
45
+ * @param {GrammarSymbols<string>} $
46
+ * @returns {SeqRule}
47
+ */
48
+ function linespacedNodes($) {
49
+ return seq(
50
+ repeat($._linespace),
51
+ repeat(seq($.node, repeat($._linespace))),
52
+ );
53
+ }
54
+
55
+ /**
56
+ * (node-space* slashdash node-children)* (node-space* node-children)?
57
+ * (node-space* slashdash node-children)*
58
+ *
59
+ * Written with the trailing slashdashes nested inside the optional block, since
60
+ * the flat spelling cannot say which repeat owns them when the block is absent.
61
+ *
62
+ * @param {GrammarSymbols<string>} $
63
+ * @returns {SeqRule}
64
+ */
65
+ function childBlocks($) {
66
+ const commented = seq(repeat($._node_space), field('children', $.node_children_comment));
67
+ const block = seq(repeat($._node_space), field('children', $.node_children));
68
+ return seq(repeat(commented), optional(seq(block, repeat(commented))));
69
+ }
70
+
71
+ export default grammar({
57
72
  name: 'kdl',
58
73
 
59
74
  conflicts: $ => [
60
- [$.document],
61
- [$._node_space],
62
- [$.node_children],
75
+ [$.version, $._ws],
76
+ [$.identifier, $.value],
63
77
  ],
64
78
 
65
- externals: $ => [$._eof, $.multi_line_comment],
79
+ externals: $ => [
80
+ $._eof,
81
+ $.multi_line_comment,
82
+ $._raw_string_start,
83
+ $._raw_string_content,
84
+ $._raw_string_end,
85
+ ],
66
86
 
67
87
  extras: $ => [$.multi_line_comment],
68
88
 
@@ -70,171 +90,174 @@ module.exports = grammar({
70
90
 
71
91
  rules: {
72
92
  // nodes := linespace* (node nodes?)? linespace*
73
- document: $ =>
74
- seq(
75
- repeat($._linespace),
76
- optional(seq(
77
- $.node,
78
- repeat(seq(
79
- repeat($._linespace),
80
- $.node,
81
- )),
82
- )),
83
- repeat($._linespace),
84
- ),
93
+ document: $ => seq(optional($._bom), optional(field('version', $.version)), linespacedNodes($)),
94
+
95
+ version: $ => prec(2, seq(
96
+ '/-',
97
+ repeat($._unicode_space),
98
+ 'kdl-version',
99
+ repeat1($._unicode_space),
100
+ field('version', choice('1', '2')),
101
+ repeat($._unicode_space),
102
+ $._newline,
103
+ )),
85
104
 
86
105
  // node := ('/-' node-space*)? type? identifier (node-space+ node-prop-or-arg)* (node-space* node-children ws*)? node-space* node-terminator
87
- node: $ => prec(1,
106
+ node: $ => seq($._base_node, $._node_terminator),
107
+ _final_node: $ => seq(alias($._base_node, $.node), '}'),
108
+ _base_node: $ =>
88
109
  seq(
89
- alias(optional(seq('/-', repeat($._node_space))), $.node_comment),
90
- optional($.type),
91
- $.identifier,
92
- repeat(seq(repeat1($._node_space), $.node_field)),
93
- optional(seq(repeat($._node_space), field('children', $.node_children), repeat($._ws))),
110
+ optional($.node_comment),
111
+ optional(seq(field('type', $.type), repeat($._node_space))),
112
+ field('name', $.identifier),
113
+ repeat($.node_field),
114
+ childBlocks($),
94
115
  repeat($._node_space),
95
- $._node_terminator,
96
116
  ),
97
- ),
98
117
 
99
118
  // node-prop-or-arg (field) := ('/-' node-space*)? (prop | value)
100
- // _node_prop_or_arg: $ =>
101
- // seq(
102
- // alias(optional(seq('/-', repeat($._node_space))), $.node_prop_or_arg_slash_dash),
103
- // field('node_prop_or_arg', choice($.prop, $.value)),
104
- // ),
105
- node_field: $ => choice($._node_field_comment, $._node_field),
106
- _node_field_comment: $ => alias(seq('/-', repeat($._node_space), $._node_field), $.node_field_comment),
107
- _node_field: $ => choice($.prop, $.value),
119
+ node_field: $ => choice(
120
+ seq(repeat1($._node_space), $._node_field),
121
+ seq(repeat($._node_space), $.node_field_comment),
122
+ ),
123
+ node_comment: $ => seq('/-', repeat($._linespace)),
124
+ node_field_comment: $ => seq('/-', repeat($._linespace), $._node_field),
125
+ _node_field: $ => choice(field('property', $.prop), field('argument', $.value)),
108
126
  // node-children := ('/-' node-space*)? '{' nodes '}'
109
- node_children: $ =>
110
- seq(
111
- optional(seq(alias('/-', $.node_children_comment), repeat($._node_space))),
112
- '{',
113
- seq(
114
- repeat($._linespace),
115
- optional(seq($.node, repeat(seq(repeat($._linespace), $.node)))),
116
- repeat($._linespace),
117
- ),
118
- '}',
119
- ),
127
+ node_children_comment: $ => seq('/-', repeat($._linespace), $.node_children),
128
+ node_children: $ => seq(
129
+ '{',
130
+ repeat(choice($._linespace, $.node)),
131
+ choice('}', $._final_node),
132
+ ),
120
133
  // node-space := ws* escline ws* | ws+
121
- _node_space: $ =>
122
- choice(
123
- seq(repeat($._ws), $._escline, repeat($._ws)),
124
- repeat1($._ws),
125
- ),
134
+ _node_space: $ => choice($._ws, $._escline),
126
135
  // node-terminator := single-line-comment | newline | ';' | eof
127
136
  _node_terminator: $ =>
128
137
  choice($.single_line_comment, $._newline, ';', $._eof),
129
138
 
130
139
  // identifier := string | bare-identifier
131
140
  identifier: $ => choice($.string, $._bare_identifier),
141
+
132
142
  // bare-identifier := ((identifier-char - digit - sign) identifier-char* | sign ((identifier-char - digit) identifier-char*)?) - keyword
133
- _bare_identifier: $ =>
134
- choice(
135
- $._normal_bare_identifier,
136
- seq($._sign, optional(seq($.__identifier_char_no_digit, repeat($._identifier_char)))),
137
- ),
143
+ _bare_identifier: $ => choice($._normal_bare_identifier, $._signed_bare_identifier),
138
144
 
139
- // _normal_bare_identifier: $ => $.__identifier_char_no_digit_sign,
140
- _normal_bare_identifier: _ => token(
141
- seq(
142
- /[\u4E00-\u9FFF\p{L}\p{M}\p{N}\p{Emoji}_~!@#\$%\^&\*.:'\|\?&&[^\s\d\/(){}<>;\[\]=,"]]/,
143
- /[\u4E00-\u9FFF\p{L}\p{M}\p{N}\p{Emoji}\-_~!@#\$%\^&\*.:'\|\?+&&[^\s\/(){}<>;\[\]=,"]]*/,
144
- ),
145
- ),
146
- // identifier-char := unicode - linespace - [\/(){}<>;[]=,"]
147
- _identifier_char: _ => token(
148
- /[\u4E00-\u9FFF\p{L}\p{M}\p{N}\-_~!@#\$%\^&\*.:'\|\?+&&[^\s\/(){}<>;\[\]=,"]]/,
149
- ),
145
+ _normal_bare_identifier: _ =>
146
+ token(new RegExp(`${IDENTIFIER_START}${IDENTIFIER_CHAR}*`)),
150
147
 
151
- // can't start with a digit
152
- __identifier_char_no_digit: _ => token(
153
- /[\u4E00-\u9FFF\p{L}\p{M}\p{N}\-_~!@#\$%\^&\*.:'\|\?+&&[^\s\d\/(){}<>;\[\]=,"]]/,
154
- ),
148
+ _signed_bare_identifier: _ =>
149
+ token(new RegExp(`${SIGN}(?:${IDENTIFIER_START_AFTER_SIGN}${IDENTIFIER_CHAR}*)?`)),
155
150
 
156
- // can't start with a digit or sign
157
- __identifier_char_no_digit_sign: _ => token(
158
- /[\u4E00-\u9FFF\p{L}\p{M}\p{N}\-_~!@#\$%\^&\*.:'\|\?&&[^\s\d\+\-\/(){}<>;\[\]=,"]]/,
151
+ keyword: $ => choice($.boolean, ...NULL_KEYWORDS.map(value => token(prec(2, value)))),
152
+
153
+ prop: $ => seq(
154
+ field('key', $.identifier),
155
+ repeat($._node_space),
156
+ '=',
157
+ repeat($._node_space),
158
+ field('value', $.value),
159
159
  ),
160
160
 
161
- // keyword := boolean | 'null'
162
- keyword: $ => choice($.boolean, 'null'),
163
- // type annotations
164
- annotation_type: _ => choice(...ANNOTATION_BUILTINS),
165
- // prop := identifier '=' value
166
- prop: $ => seq($.identifier, '=', $.value),
167
161
  // value := type? (string | number | keyword)
168
- value: $ => seq(optional($.type), choice($.string, $.number, $.keyword)),
162
+ value: $ => seq(
163
+ optional(seq(field('type', $.type), repeat($._node_space))),
164
+ field('value', choice($.string, alias($._bare_identifier, $.string), $.number, $.keyword)),
165
+ ),
166
+
169
167
  // type := '(' identifier ')'
170
- type: $ => seq('(', choice($.identifier, $.annotation_type), ')'),
168
+ type: $ => seq(
169
+ '(',
170
+ repeat($._node_space),
171
+ field('name', $.identifier),
172
+ repeat($._node_space),
173
+ ')',
174
+ ),
171
175
 
172
176
  // String
173
- // string := raw-string | escaped-string
174
- string: $ => choice($._raw_string, $._escaped_string),
177
+ string: $ => choice($._raw_string, $.multi_line_string, $._escaped_string),
178
+ // raw-string := '#' raw-string-quotes '#' | '#' raw-string '#'
179
+ _raw_string: $ => seq(
180
+ $._raw_string_start,
181
+ optional(alias($._raw_string_content, $.string_fragment)),
182
+ $._raw_string_end,
183
+ ),
184
+ // quoted-string := '"""' newline (multi-line-string-body newline)?
185
+ // (unicode-space | ws-escape)* '"""'
186
+ multi_line_string: $ => seq(
187
+ $._multiline_open,
188
+ repeat(choice(
189
+ alias($._multiline_fragment, $.string_fragment),
190
+ $.escape,
191
+ $.escaped_whitespace,
192
+ )),
193
+ '"""',
194
+ ),
195
+ _multiline_open: _ => token(seq('"""', choice('\r\n', new RegExp(`[${NEWLINES}]`)))),
196
+ // multi-line-string-body := ('"' ^'"' | '""' ^'"' | string-character)*?
197
+ _multiline_fragment: _ =>
198
+ token.immediate(new RegExp(`(?:${STRING_CHAR}|"${STRING_CHAR}|""${STRING_CHAR})+`)),
175
199
  // escaped-string := '"' character* '"'
176
- _escaped_string: $ => seq('"', alias(repeat(choice($.escape, /[^"]/)), $.string_fragment), '"'),
200
+ _escaped_string: $ => seq(
201
+ '"',
202
+ repeat(choice(
203
+ alias($._string_fragment, $.string_fragment),
204
+ $.escape,
205
+ $.escaped_whitespace,
206
+ )),
207
+ '"',
208
+ ),
177
209
  // character := '\' escape | [^\"]
178
- _character: $ => choice($.escape, /[^"]/),
179
- // escape := ["\\/bfnrt] | 'u{' hex-digit{1, 6} '}'
180
- escape: _ =>
181
- token.immediate(/\\\\|\\"|\\\/|\\b|\\f|\\n|\\r|\\t|\\u\{[0-9a-fA-F]{1,6}\}/),
182
- // hex-digit := [0-9a-fA-F]
183
- _hex_digit: _ => /[0-9a-fA-F]/,
184
-
185
- // // raw-string := 'r' raw-string-hash
186
- // raw_string: $ => seq('r', $._raw_string_hash),
187
- // // raw-string-hash := '#' raw-string-hash '#' | raw-string-quotes
188
- // _raw_string_hash: $ => choice(seq('#', $._raw_string_hash, '#'), $._raw_string_quotes),
189
- // // raw-string-quotes := '"' .* '"'
190
- // _raw_string_quotes: _ => seq('"', /.*/, '"'),
191
- _raw_string: _ =>
192
- seq(
193
- choice(
194
- // raw-string-hash := '#' raw-string-hash '#' | raw-string-quotes
195
- // yes this isn't perfect but it works, ideally this should be handled in an external scanner
196
- seq(token.immediate(seq('r', repeat1('#'))), /[^#]*/, repeat1('#')),
197
- // raw-string-quotes := '"' . '"'
198
- seq(token.immediate(seq('r', '"')), /[^"]*/, '"'),
199
- ),
210
+ _string_fragment: _ => token.immediate(new RegExp(`${STRING_CHAR}+`)),
211
+ // escape := ["\\/bfnrts] | 'u{' hex-digit{1, 6} '}'
212
+ escape: _ => token.immediate(seq(
213
+ '\\',
214
+ choice(
215
+ '\\',
216
+ '"',
217
+ '/',
218
+ 'b',
219
+ 'f',
220
+ 'n',
221
+ 'r',
222
+ 't',
223
+ 's',
224
+ UNICODE_SCALAR_ESCAPE,
200
225
  ),
201
-
202
- // number := decimal | hex | octal | binary
203
- number: $ => choice($._decimal, $._hex, $._octal, $._binary),
226
+ )),
227
+ escaped_whitespace: _ => token.immediate(
228
+ /\\(?:\r\n|[\u0009\u0020\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000\r\n\u0085\u000B\u000C\u2028\u2029])+/,
229
+ ),
230
+ number: $ => choice($.keyword_number, $._decimal, $._hex, $._octal, $._binary),
204
231
 
205
232
  // decimal := sign? integer ('.' integer)? exponent?
206
233
  _decimal: $ =>
207
234
  seq(
208
- optional($._sign),
209
235
  $._integer,
210
- optional(seq('.', alias($._integer, $.decimal))),
236
+ optional(seq('.', alias($._fraction, $.decimal))),
211
237
  optional(alias($._exponent, $.exponent)),
212
238
  ),
213
239
 
214
- // exponent := ('e' | 'E') sign? integer
215
- _exponent: $ => seq(choice('e', 'E'), optional($._sign), $._integer),
216
240
  // integer := digit (digit | '_')*
217
- _integer: $ => seq($._digit, repeat(choice($._digit, '_'))),
218
- // digit := [0-9]
219
- _digit: _ => /[0-9]/,
220
- // sign := '+' | '-'
221
- _sign: _ => choice('+', '-'),
222
-
241
+ _integer: _ => token(new RegExp(`${SIGN}?${DIGITS}`)),
242
+ _fraction: _ => token.immediate(new RegExp(DIGITS)),
243
+ // exponent := ('e' | 'E') sign? integer
244
+ _exponent: _ => token.immediate(new RegExp(`[eE]${SIGN}?${DIGITS}`)),
223
245
  // hex := sign? '0x' hex-digit (hex-digit | '_')*
224
- _hex: $ => seq(optional($._sign), '0x', $._hex_digit, repeat(choice($._hex_digit, '_'))),
246
+ _hex: _ => token(new RegExp(`${SIGN}?0x${HEX}[${HEX_CHARS}_]*`)),
225
247
  // octal := sign? '0o' [0-7] [0-7_]*
226
- _octal: $ => seq(optional($._sign), '0o', /[0-7]/, repeat(choice(/[0-7]/, '_'))),
248
+ _octal: _ => token(new RegExp(`${SIGN}?0o[0-7][0-7_]*`)),
227
249
  // binary := sign? '0b' ('0' | '1') ('0' | '1' | '_')*
228
- _binary: $ => seq(optional($._sign), '0b', choice('0', '1'), repeat(choice('0', '1', '_'))),
250
+ _binary: _ => token(new RegExp(`${SIGN}?0b[01][01_]*`)),
251
+
252
+ keyword_number: _ => choice(...KEYWORD_NUMBERS.map(value => token(prec(2, value)))),
229
253
 
230
- // boolean := 'true' | 'false'
231
- boolean: _ => choice('true', 'false'),
254
+ boolean: _ => choice(...BOOLEAN_KEYWORDS.map(value => token(prec(2, value)))),
232
255
 
233
256
  // escline := '\\' ws* (single-line-comment | newline)
234
- _escline: $ => seq('\\', repeat($._ws), choice($.single_line_comment, $._newline)),
257
+ _escline: $ => seq('\\', repeat($._ws), choice($.single_line_comment, $._newline, $._eof)),
235
258
 
236
259
  // linespace := newline | ws | single-line-comment
237
- _linespace: $ => choice($._newline, $._ws, $.single_line_comment),
260
+ _linespace: $ => choice($._ws, $._escline, $._newline, $.single_line_comment),
238
261
 
239
262
  // newline := See Table (All line-break white_space)
240
263
  // Newline
@@ -251,10 +274,10 @@ module.exports = grammar({
251
274
  // │ PS Paragraph Separator U+2029 │
252
275
  // ╰──────────────────────────────────────────────────────────╯
253
276
  // Note that for the purpose of new lines, CRLF is considered a single newline.
254
- _newline: _ => choice(/\r'/, /\n/, /\r\n/, /\u0085/, /\u000C/, /\u2028/, /\u2029/),
277
+ _newline: _ => choice(/\r\n/, /\r/, /\n/, /\u0085/, /\u000B/, /\u000C/, /\u2028/, /\u2029/),
255
278
 
256
279
  // ws := bom | unicode-space | multi-line-comment
257
- _ws: $ => choice($._bom, $._unicode_space, $.multi_line_comment),
280
+ _ws: $ => choice($._unicode_space, $.multi_line_comment),
258
281
 
259
282
  // bom := '\u{FEFF}'
260
283
  _bom: _ => /\u{FEFF}/,
@@ -291,7 +314,7 @@ module.exports = grammar({
291
314
  single_line_comment: $ =>
292
315
  seq(
293
316
  '//',
294
- repeat(/[^\r\n\u0085\u000C\u2028\u2029]/),
317
+ repeat(/[^\r\n\u0085\u000B\u000C\u2028\u2029]/),
295
318
  choice($._newline, $._eof),
296
319
  ),
297
320
  },
package/package.json CHANGED
@@ -1,46 +1,63 @@
1
1
  {
2
2
  "name": "tree-sitter-kdl",
3
- "version": "1.0.3",
3
+ "version": "2.0.0",
4
4
  "description": "KDL grammar for tree-sitter",
5
+ "type": "module",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/amaanq/tree-sitter-kdl.git"
9
+ },
10
+ "license": "MIT",
11
+ "author": {
12
+ "name": "Amaan Qureshi",
13
+ "email": "contact@amaanq.com"
14
+ },
15
+ "contributors": [
16
+ "Andrew Hlynskyi <ahlincq@gmail.com>"
17
+ ],
5
18
  "main": "bindings/node",
19
+ "types": "bindings/node",
6
20
  "keywords": [
7
- "parser",
8
- "lexer",
21
+ "incremental",
22
+ "parsing",
23
+ "tree-sitter",
9
24
  "kdl"
10
25
  ],
11
- "author": "Amaan Qureshi <amaanq12@gmail.com>",
12
- "contributors": [
13
- "Andrew Hlynskyi <ahlincq@gmail.com>"
26
+ "files": [
27
+ "grammar.js",
28
+ "tree-sitter.json",
29
+ "binding.gyp",
30
+ "prebuilds/**",
31
+ "bindings/node/*",
32
+ "queries/*",
33
+ "src/**",
34
+ "*.wasm"
14
35
  ],
15
- "license": "MIT",
16
- "bugs": {
17
- "url": "https://github.com/amaanq/tree-sitter-kdl/issues"
18
- },
19
- "homepage": "https://github.com/amaanq/tree-sitter-kdl#readme",
20
36
  "dependencies": {
21
- "nan": "^2.17.0"
37
+ "node-addon-api": "^8.5.0",
38
+ "node-gyp-build": "^4.8.4"
22
39
  },
23
40
  "devDependencies": {
24
- "eslint": "^8.32.0",
25
- "eslint-config-google": "^0.14.0",
26
- "tree-sitter-cli": "^0.20.7"
41
+ "eslint": "^9.39.5",
42
+ "eslint-config-treesitter": "^1.0.2",
43
+ "prebuildify": "^6.0.1",
44
+ "tree-sitter": "^0.25.1",
45
+ "tree-sitter-cli": "^0.27.0"
27
46
  },
28
- "repository": "https://github.com/amaanq/tree-sitter-kdl",
29
- "scripts": {
30
- "build": "tree-sitter generate && node-gyp build",
31
- "test": "tree-sitter test && script/parse-examples",
32
- "parse": "tree-sitter parse",
33
- "test-windows": "tree-sitter test"
47
+ "peerDependencies": {
48
+ "tree-sitter": "^0.25.0"
34
49
  },
35
- "tree-sitter": [
36
- {
37
- "scope": "source.kdl",
38
- "file-types": [
39
- "kdl"
40
- ],
41
- "highlights": [
42
- "queries/highlights.scm"
43
- ]
50
+ "peerDependenciesMeta": {
51
+ "tree-sitter": {
52
+ "optional": true
44
53
  }
45
- ]
54
+ },
55
+ "scripts": {
56
+ "install": "node-gyp-build",
57
+ "lint": "eslint grammar.js",
58
+ "parse": "tree-sitter parse",
59
+ "prestart": "tree-sitter build --wasm",
60
+ "start": "tree-sitter playground",
61
+ "test": "tree-sitter test && script/parse-examples"
62
+ }
46
63
  }
@@ -1,40 +1,59 @@
1
- ; Types
1
+ ; Variables
2
2
 
3
- (node (identifier) @type)
3
+ (identifier) @variable
4
4
 
5
- (type) @type
5
+ ; Nodes
6
6
 
7
- (annotation_type) @type.builtin
7
+ (node name: (identifier) @tag)
8
+ (node name: (identifier (string) @tag))
8
9
 
9
- ; Properties
10
+ ; Types
10
11
 
11
- (prop (identifier) @property)
12
+ (type) @type
13
+ (type name: (identifier) @type)
14
+
15
+ ; Reserved type annotations are advisory in the spec, not syntax.
16
+ ((type name: (identifier) @type.builtin)
17
+ (#any-of? @type.builtin
18
+ "i8" "i16" "i32" "i64" "i128"
19
+ "u8" "u16" "u32" "u64" "u128"
20
+ "isize" "usize" "f32" "f64" "decimal64" "decimal128"
21
+ "date-time" "time" "date" "duration" "decimal" "currency"
22
+ "country-2" "country-3" "country-subdivision"
23
+ "email" "idn-email" "hostname" "idn-hostname"
24
+ "ipv4" "ipv6" "url" "url-reference" "irl" "irl-reference"
25
+ "url-template" "uuid" "regex" "base64" "base85"))
12
26
 
13
- ; Variables
27
+ ; Properties
14
28
 
15
- (identifier) @variable
29
+ (prop key: (identifier) @property)
16
30
 
17
31
  ; Operators
18
- [
19
- "="
20
- "+"
21
- "-"
22
- ] @operator
32
+
33
+ "=" @operator
23
34
 
24
35
  ; Literals
25
36
 
26
37
  (string) @string
27
38
 
39
+ (multi_line_string) @string
40
+
41
+ (string_fragment) @string
42
+
28
43
  (escape) @string.escape
29
44
 
45
+ (escaped_whitespace) @string.escape
46
+
30
47
  (number) @number
31
48
 
49
+ (keyword_number) @number
50
+
32
51
  (number (decimal) @float)
33
52
  (number (exponent) @float)
34
53
 
35
54
  (boolean) @boolean
36
55
 
37
- "null" @constant.builtin
56
+ [ "null" "#null" ] @constant.builtin
38
57
 
39
58
  ; Punctuation
40
59
 
@@ -51,8 +70,9 @@
51
70
  [
52
71
  (single_line_comment)
53
72
  (multi_line_comment)
73
+ (version)
54
74
  ] @comment @spell
55
75
 
56
- (node (node_comment) (#set! "priority" 105)) @comment
57
- (node (node_field (node_field_comment) (#set! "priority" 105)) @comment)
58
- (node_children (node_children_comment) (#set! "priority" 105)) @comment
76
+ (node_comment) @comment
77
+ (node_field_comment) @comment
78
+ (node_children_comment) @comment
@@ -1,4 +1,4 @@
1
- (node (node_children) @indent)
1
+ (node_children) @indent
2
2
 
3
3
  "}" @indent_end
4
4