@apple/tree-sitter-pkl 0.16.0 → 0.17.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 (58) hide show
  1. package/CHANGELOG.adoc +40 -0
  2. package/Cargo.lock +1 -1
  3. package/Cargo.toml +1 -1
  4. package/Package.swift +24 -0
  5. package/README.md +42 -0
  6. package/bindings/c/tree-sitter-pkl.h +16 -0
  7. package/bindings/swift/TreeSitterPkl/pkl.h +16 -0
  8. package/grammar.js +147 -63
  9. package/package.json +3 -4
  10. package/queries/highlights.scm +3 -8
  11. package/queries/injections.scm +3 -3
  12. package/src/grammar.json +750 -353
  13. package/src/node-types.json +1768 -1043
  14. package/src/parser.c +45772 -50670
  15. package/src/scanner.c +60 -28
  16. package/src/tree_sitter/alloc.h +54 -0
  17. package/src/tree_sitter/array.h +290 -0
  18. package/src/tree_sitter/parser.h +54 -13
  19. package/test/corpus/basic/annotation.txt +243 -0
  20. package/test/corpus/basic/comments.txt +41 -0
  21. package/test/corpus/basic/shebangComment.txt +15 -0
  22. package/test/corpus/basic/types.txt +232 -0
  23. package/test/corpus/class/constModifier.txt +24 -0
  24. package/test/corpus/class/fixedModifier.txt +24 -0
  25. package/test/corpus/expr/binary.txt +109 -0
  26. package/test/corpus/expr/functionLiteral.txt +23 -0
  27. package/test/corpus/expr/if.txt +15 -0
  28. package/test/corpus/expr/import.txt +20 -0
  29. package/test/corpus/expr/let.txt +17 -0
  30. package/test/corpus/expr/new.txt +36 -0
  31. package/test/corpus/expr/qualifiedAccess.txt +95 -0
  32. package/test/corpus/expr/read.txt +29 -0
  33. package/test/corpus/expr/throw.txt +14 -0
  34. package/test/corpus/expr/trace.txt +14 -0
  35. package/test/corpus/module/moduleHeader1.txt +23 -0
  36. package/test/corpus/module/moduleHeader2.txt +29 -0
  37. package/test/corpus/module/moduleHeader3.error.txt +23 -0
  38. package/test/corpus/module/moduleHeader4.txt +34 -0
  39. package/test/corpus/module/moduleHeader5.txt +16 -0
  40. package/test/corpus/module/moduleHeader6.txt +17 -0
  41. package/test/corpus/number/underscores.txt +99 -0
  42. package/test/corpus/object/objectAmendChain.txt +38 -0
  43. package/test/corpus/object/objectElementsWithParens.txt +51 -0
  44. package/test/corpus/object/objectGenerator.txt +53 -0
  45. package/test/corpus/object/objectMember.txt +129 -0
  46. package/test/corpus/object/objectMemberPredicate.txt +41 -0
  47. package/test/corpus/object/objectSpread.txt +51 -0
  48. package/test/corpus/object/objectWhenGenerator.txt +71 -0
  49. package/test/corpus/string/customStringDelimiters.txt +397 -0
  50. package/test/corpus/string/missingDelimiter.txt +28 -0
  51. package/test/corpus/string/multiline.txt +39 -0
  52. package/test/corpus/string/multilineInterpolation.txt +102 -0
  53. package/test/corpus/string/simple.txt +13 -0
  54. package/test/corpus/string/singleLineEscapes.txt +64 -0
  55. package/test/corpus/string/singleLineInterpolation.txt +94 -0
  56. package/test/corpus/string/stringWithTwoSlashes.txt +20 -0
  57. package/README.adoc +0 -61
  58. package/src/synctests.ts +0 -44
package/CHANGELOG.adoc ADDED
@@ -0,0 +1,40 @@
1
+ = Changelog
2
+
3
+ [[release-0.17.0]]
4
+ == 0.17.0 (2024-10-10)
5
+
6
+ === Breaking changes
7
+
8
+ * Give type nodes explicit names (e.g. `"unknown"` -> `unknownTypeNode`)
9
+ * Remove support for legacy syntax in for and when generators
10
+
11
+ === Additions
12
+
13
+ * Add support for Swift Package Manager
14
+ * Add support for C bindings
15
+ * Add doc comments to the parse tree
16
+ * Add `slStringLiteralPart` and `mlStringLiteralPart` to the parse tree
17
+ * Add field names to various nodes
18
+ * Add support for shebang comments
19
+
20
+ === Fixes
21
+
22
+ * Fix parsing of parenthesized expressions in object
23
+ elements
24
+ * Fix parsing of union types with default markers
25
+ * Add missing `else` in when generators
26
+ * Add missing module type
27
+ * Fix parsing of strings that start with two slashes
28
+
29
+ === Contributors ❤️
30
+
31
+ Thanks to all the contributors for this release!
32
+
33
+ * https://github.com/ObserverOfTime[@ObserverOfTime]
34
+ * https://github.com/jayadamsmorgan[jayadamsmorgan]
35
+ * https://github.com/thomaspurchas[@thomaspurchas]
36
+
37
+ [[release-0.16.0]]
38
+ == 0.16.0 (2024-02-02)
39
+
40
+ Initial release
package/Cargo.lock CHANGED
@@ -73,7 +73,7 @@ dependencies = [
73
73
 
74
74
  [[package]]
75
75
  name = "tree-sitter-pkl"
76
- version = "0.16.0"
76
+ version = "0.17.0"
77
77
  dependencies = [
78
78
  "cc",
79
79
  "tree-sitter",
package/Cargo.toml CHANGED
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  name = "tree-sitter-pkl"
3
3
  description = "Pkl grammar for the tree-sitter parsing library"
4
- version = "0.16.0"
4
+ version = "0.17.0"
5
5
  keywords = ["incremental", "parsing", "pkl"]
6
6
  categories = ["parsing", "text-editors"]
7
7
  repository = "https://github.com/apple/tree-sitter-pkl"
package/Package.swift ADDED
@@ -0,0 +1,24 @@
1
+ // swift-tools-version:5.9
2
+ import PackageDescription
3
+
4
+ let package = Package(
5
+ name: "TreeSitterPkl",
6
+ products: [
7
+ .library(name: "TreeSitterPkl", targets: ["TreeSitterPkl"]),
8
+ ],
9
+ dependencies: [],
10
+ targets: [
11
+ .target(name: "TreeSitterPkl",
12
+ path: ".",
13
+ sources: [
14
+ "src/parser.c",
15
+ "src/scanner.c",
16
+ ],
17
+ resources: [
18
+ .copy("queries"),
19
+ ],
20
+ publicHeadersPath: "bindings/swift",
21
+ cSettings: [.headerSearchPath("src")]
22
+ )
23
+ ]
24
+ )
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ A tree-sitter grammar for Pkl.
2
+
3
+ # install dependencies
4
+ $ npm install
5
+
6
+ # build parser
7
+ $ npm run build
8
+
9
+ # parse some code
10
+ $ ./node_modules/.bin/tree-sitter parse test.pkl
11
+
12
+ # Tests
13
+
14
+ Tree sitter comes with its own test framework. Files in `test/corpus/`
15
+ describe one test each. All tests in `test/corpus/` are performed by the
16
+ command
17
+
18
+ $ tree-sitter test
19
+
20
+ # Upgrading tree-sitter
21
+
22
+ Upgrading tree-sitter involves upgrading the NPM package.
23
+
24
+ 1. Run `npm update tree-sitter` to install the newer version of tree-sitter.
25
+ 2. Commit to main, and push.
26
+
27
+ # Releasing
28
+
29
+ 1. Run the build & test to make sure everything is up-to-date and passes (check 0 diff).
30
+ 2. Create a `Prepare 1.2.3 release` (with appropriate version number) commit where
31
+ - Versions are bumped in `package.json`, `Cargo.toml`
32
+ - Lockfiles are updated (`npm install`, `cargo check`)
33
+ - You have checked the previous release PR for any changes in process not described in this `README.adoc`; if any
34
+ - Adopt the changes accordingly
35
+ - Update this description to capture the changed process
36
+ 3. Merge into `main` & push
37
+ 4. Check that CI release succeeded ([release pipeline](https://app.circleci.com/pipelines/github/apple/tree-sitter-pkl))
38
+ 5. Check the publication is reachable, [on NPM](https://www.npmjs.com/package/@apple/tree-sitter-pkl)
39
+
40
+ # Resources
41
+ - [Tree-sitter docs](https://tree-sitter.github.io/tree-sitter/)
42
+ - [Guide to your first Tree-sitter grammar](https://gist.github.com/Aerijo/df27228d70c633e088b0591b8857eeef)
@@ -0,0 +1,16 @@
1
+ #ifndef TREE_SITTER_PKL_H
2
+ #define TREE_SITTER_PKL_H
3
+
4
+ typedef struct TSLanguage TSLanguage;
5
+
6
+ #ifdef __cplusplus
7
+ extern "C" {
8
+ #endif
9
+
10
+ const TSLanguage *tree_sitter_pkl();
11
+
12
+ #ifdef __cplusplus
13
+ }
14
+ #endif
15
+
16
+ #endif // TREE_SITTER_PKL_H
@@ -0,0 +1,16 @@
1
+ #ifndef TREE_SITTER_PKL_H
2
+ #define TREE_SITTER_PKL_H
3
+
4
+ typedef struct TSLanguage TSLanguage;
5
+
6
+ #ifdef __cplusplus
7
+ extern "C" {
8
+ #endif
9
+
10
+ extern TSLanguage *tree_sitter_pkl();
11
+
12
+ #ifdef __cplusplus
13
+ }
14
+ #endif
15
+
16
+ #endif // TREE_SITTER_PKL_H
package/grammar.js CHANGED
@@ -45,8 +45,8 @@ const PREC = {
45
45
 
46
46
  NULLABLE_TYPE: 5,
47
47
  FUN_TYPE: -5,
48
- UNION_TYPE: -6,
49
- DEFAULT_TYPE: -7,
48
+ UNION_DEFAULT_TYPE: -6,
49
+ UNION_TYPE: -7,
50
50
 
51
51
  VAR_OBJ_LITERAL: 2,
52
52
  OBJ_LITERAL: 1,
@@ -59,6 +59,7 @@ module.exports = grammar({
59
59
  name: 'pkl',
60
60
 
61
61
  externals: $ => [
62
+ $._sl_string_chars,
62
63
  $._sl1_string_chars,
63
64
  $._sl2_string_chars,
64
65
  $._sl3_string_chars,
@@ -72,46 +73,47 @@ module.exports = grammar({
72
73
  $._ml4_string_chars,
73
74
  $._ml5_string_chars,
74
75
  $._ml6_string_chars,
75
- $._open_square_bracket,
76
- $._open_entry_bracket,
76
+ // '[' without preceding newline or semicolon
77
+ $._open_subscript_bracket,
78
+ // '(' without preceding newline or semicolon
79
+ $._open_argument_paren,
77
80
  ],
78
81
 
79
82
  extras: $ => [
80
83
  $.lineComment,
81
- $.docComment,
82
84
  $.blockComment,
85
+ $.shebangComment,
83
86
  /[ \t\f\r\n;]/
84
87
  ],
85
88
 
86
89
  word: $ => $.identifier,
87
90
 
88
91
  conflicts: $ => [
89
- // in ANTLR we deal with these by not allowing a newline or semicolon before subscript
90
- [$.objectProperty, $.subscriptExpr],
91
- [$.objectMethod, $.subscriptExpr],
92
- [$.objectEntry, $.subscriptExpr],
93
- [$.objectPredicate, $.subscriptExpr],
94
-
95
92
  // these should be fixable in some other way (perhaps with prec)
96
- [$.propertyCallExpr, $.methodCallExpr],
97
- [$.variableExpr, $.methodCallExpr],
98
93
  [$.variableExpr, $.typedIdentifier],
99
94
 
100
95
  // not sure what this one is about
101
96
  [$.objectElement, $._expr],
102
97
 
103
98
  [$.qualifiedIdentifier],
104
- [$.type]
99
+ [$.declaredType]
105
100
  ],
106
101
 
107
102
  rules: {
108
103
  module: $ => seq(
104
+ optional($.shebangComment),
109
105
  optional($.moduleHeader),
110
106
  repeat(choice($.importClause, $.importGlobClause)),
111
107
  repeat($._moduleMember)
112
108
  ),
113
109
 
110
+ shebangComment: $ => seq(
111
+ "#!",
112
+ /.*/
113
+ ),
114
+
114
115
  moduleHeader: $ => seq(
116
+ optional($.docComment),
115
117
  repeat($.annotation),
116
118
  choice(
117
119
  seq($.moduleClause, optional($.extendsOrAmendsClause)),
@@ -150,6 +152,7 @@ module.exports = grammar({
150
152
  ),
151
153
 
152
154
  clazz: $ => seq(
155
+ optional($.docComment),
153
156
  repeat($.annotation),
154
157
  repeat($.modifier),
155
158
  "class",
@@ -172,6 +175,7 @@ module.exports = grammar({
172
175
  ),
173
176
 
174
177
  typeAlias: $ => seq(
178
+ optional($.docComment),
175
179
  repeat($.annotation),
176
180
  repeat($.modifier),
177
181
  "typealias",
@@ -182,6 +186,7 @@ module.exports = grammar({
182
186
  ),
183
187
 
184
188
  classProperty: $ => seq(
189
+ optional($.docComment),
185
190
  repeat($.annotation),
186
191
  repeat($.modifier),
187
192
  $.identifier,
@@ -198,6 +203,7 @@ module.exports = grammar({
198
203
  ),
199
204
 
200
205
  classMethod: $ => seq(
206
+ optional($.docComment),
201
207
  repeat($.annotation),
202
208
  $.methodHeader,
203
209
  optional(seq("=", $._expr))
@@ -252,11 +258,11 @@ module.exports = grammar({
252
258
  objectMethod: $ => seq($.methodHeader, "=", $._expr),
253
259
 
254
260
  objectEntry: $ => seq(
255
- $._open_entry_bracket,
256
- $._expr,
261
+ "[",
262
+ field("key", $._expr),
257
263
  "]",
258
264
  choice(
259
- seq("=", $._expr),
265
+ seq("=", field("valueExpr", $._expr)),
260
266
  repeat1($.objectBody)
261
267
  )
262
268
  ),
@@ -265,10 +271,10 @@ module.exports = grammar({
265
271
 
266
272
  objectPredicate: $ => seq(
267
273
  "[[",
268
- $._expr,
274
+ field("conditionExpr", $._expr),
269
275
  "]]",
270
276
  choice(
271
- seq("=", $._expr),
277
+ seq("=", field("valueExpr", $._expr)),
272
278
  repeat1($.objectBody)
273
279
  )
274
280
  ),
@@ -284,20 +290,20 @@ module.exports = grammar({
284
290
  "in",
285
291
  $._expr,
286
292
  ")",
287
- choice(
288
- $.objectBody,
289
- $._objectMember // deprecated in 0.15
290
- )
293
+ $.objectBody
291
294
  ),
292
295
 
293
296
  whenGenerator: $ => seq(
294
297
  "when",
295
298
  "(",
296
- $._expr,
299
+ field("conditionExpr", $._expr),
297
300
  ")",
298
- choice(
299
- $.objectBody,
300
- $._objectMember // deprecated in 0.15
301
+ field("thenBody", $.objectBody),
302
+ optional(
303
+ seq(
304
+ "else",
305
+ field("elseBody", $.objectBody)
306
+ )
301
307
  )
302
308
  ),
303
309
 
@@ -317,18 +323,35 @@ module.exports = grammar({
317
323
  typeAnnotation: $ => seq(":", $.type),
318
324
 
319
325
  type: $ => choice(
320
- "unknown",
321
- "nothing",
322
- $.stringConstant,
323
- seq($.qualifiedIdentifier, optional($.typeArgumentList)),
324
- seq("(", $.type, ")"),
325
- prec(PREC.NULLABLE_TYPE, seq($.type, "?")),
326
- seq($.type, "(", commaSep1($._expr), ")"),
327
- prec.left(PREC.UNION_TYPE, seq($.type, "|", $.type)),
328
- prec(PREC.DEFAULT_TYPE, seq("*", $.type)),
329
- prec(PREC.FUN_TYPE, seq("(", commaSep($.type), ")", "->", $.type))
326
+ alias("unknown", $.unknownType),
327
+ alias("nothing", $.nothingType),
328
+ alias("module", $.moduleType),
329
+ $.stringLiteralType,
330
+ $.declaredType,
331
+ $.parenthesizedType,
332
+ $.nullableType,
333
+ $.constrainedType,
334
+ $.unionType,
335
+ $.unionDefaultType,
336
+ $.functionLiteralType
330
337
  ),
331
338
 
339
+ stringLiteralType: $ => $.stringConstant,
340
+
341
+ declaredType: $ => seq($.qualifiedIdentifier, optional($.typeArgumentList)),
342
+
343
+ parenthesizedType: $ => seq("(", $.type, ")"),
344
+
345
+ nullableType: $ => prec(PREC.NULLABLE_TYPE, seq($.type, "?")),
346
+
347
+ constrainedType: $ => seq($.type, "(", commaSep1($._expr), ")"),
348
+
349
+ unionType: $ => prec.left(PREC.UNION_TYPE, seq($.type, "|", $.type)),
350
+
351
+ unionDefaultType: $ => prec(PREC.UNION_DEFAULT_TYPE, seq("*", $.type)),
352
+
353
+ functionLiteralType: $ => prec(PREC.FUN_TYPE, seq("(", commaSep($.type), ")", "->", $.type)),
354
+
332
355
  typeArgumentList: $ => seq(
333
356
  "<",
334
357
  commaSep1($.type),
@@ -353,7 +376,7 @@ module.exports = grammar({
353
376
  ),
354
377
 
355
378
  argumentList: $ => seq(
356
- '(',
379
+ alias($._open_argument_paren, '('),
357
380
  commaSep($._expr),
358
381
  ')'
359
382
  ),
@@ -450,7 +473,7 @@ module.exports = grammar({
450
473
  seq(
451
474
  '"',
452
475
  repeat(choice(
453
- token.immediate(/[^"\\\n\r]+/),
476
+ $.slStringLiteralPart,
454
477
  $.escapeSequence
455
478
  )),
456
479
  '"'
@@ -458,7 +481,7 @@ module.exports = grammar({
458
481
  seq(
459
482
  '#"',
460
483
  repeat(choice(
461
- $._sl1_string_chars,
484
+ alias($.slStringLiteralPart1, $.slStringLiteralPart),
462
485
  alias($.escapeSequence1, $.escapeSequence),
463
486
  )),
464
487
  '"#'
@@ -469,7 +492,7 @@ module.exports = grammar({
469
492
  seq(
470
493
  '"',
471
494
  repeat(choice(
472
- token.immediate(/[^"\\\n\r]+/),
495
+ $.slStringLiteralPart,
473
496
  $.escapeSequence,
474
497
  $.interpolationExpr,
475
498
  )),
@@ -478,7 +501,7 @@ module.exports = grammar({
478
501
  seq(
479
502
  '#"',
480
503
  repeat(choice(
481
- $._sl1_string_chars,
504
+ alias($.slStringLiteralPart1, $.slStringLiteralPart),
482
505
  alias($.escapeSequence1, $.escapeSequence),
483
506
  alias($.interpolationExpr1, $.interpolationExpr)
484
507
  )),
@@ -487,7 +510,7 @@ module.exports = grammar({
487
510
  seq(
488
511
  '##"',
489
512
  repeat(choice(
490
- $._sl2_string_chars,
513
+ alias($.slStringLiteralPart2, $.slStringLiteralPart),
491
514
  alias($.escapeSequence2, $.escapeSequence),
492
515
  alias($.interpolationExpr2, $.interpolationExpr)
493
516
  )),
@@ -496,7 +519,7 @@ module.exports = grammar({
496
519
  seq(
497
520
  '###"',
498
521
  repeat(choice(
499
- $._sl3_string_chars,
522
+ alias($.slStringLiteralPart3, $.slStringLiteralPart),
500
523
  alias($.escapeSequence3, $.escapeSequence),
501
524
  alias($.interpolationExpr3, $.interpolationExpr)
502
525
  )),
@@ -505,7 +528,7 @@ module.exports = grammar({
505
528
  seq(
506
529
  '####"',
507
530
  repeat(choice(
508
- $._sl4_string_chars,
531
+ alias($.slStringLiteralPart4, $.slStringLiteralPart),
509
532
  alias($.escapeSequence4, $.escapeSequence),
510
533
  alias($.interpolationExpr4, $.interpolationExpr)
511
534
  )),
@@ -514,7 +537,7 @@ module.exports = grammar({
514
537
  seq(
515
538
  '#####"',
516
539
  repeat(choice(
517
- $._sl5_string_chars,
540
+ alias($.slStringLiteralPart5, $.slStringLiteralPart),
518
541
  alias($.escapeSequence5, $.escapeSequence),
519
542
  alias($.interpolationExpr5, $.interpolationExpr)
520
543
  )),
@@ -523,7 +546,7 @@ module.exports = grammar({
523
546
  seq(
524
547
  '######"',
525
548
  repeat(choice(
526
- $._sl6_string_chars,
549
+ alias($.slStringLiteralPart6, $.slStringLiteralPart),
527
550
  alias($.escapeSequence6, $.escapeSequence),
528
551
  alias($.interpolationExpr6, $.interpolationExpr)
529
552
  )),
@@ -531,11 +554,25 @@ module.exports = grammar({
531
554
  ),
532
555
  ),
533
556
 
557
+ slStringLiteralPart: $ => $._sl_string_chars,
558
+
559
+ slStringLiteralPart1: $ => $._sl1_string_chars,
560
+
561
+ slStringLiteralPart2: $ => $._sl2_string_chars,
562
+
563
+ slStringLiteralPart3: $ => $._sl3_string_chars,
564
+
565
+ slStringLiteralPart4: $ => $._sl4_string_chars,
566
+
567
+ slStringLiteralPart5: $ => $._sl5_string_chars,
568
+
569
+ slStringLiteralPart6: $ => $._sl6_string_chars,
570
+
534
571
  mlStringLiteral: $ => choice(
535
572
  seq(
536
573
  '"""',
537
574
  repeat(choice(
538
- $._ml_string_chars,
575
+ $.mlStringLiteralPart,
539
576
  $.escapeSequence,
540
577
  $.interpolationExpr
541
578
  )),
@@ -544,7 +581,7 @@ module.exports = grammar({
544
581
  seq(
545
582
  '#"""',
546
583
  repeat(choice(
547
- $._ml1_string_chars,
584
+ alias($.mlStringLiteralPart1, $.mlStringLiteralPart),
548
585
  alias($.escapeSequence1, $.escapeSequence),
549
586
  alias($.interpolationExpr1, $.interpolationExpr)
550
587
  )),
@@ -553,7 +590,7 @@ module.exports = grammar({
553
590
  seq(
554
591
  '##"""',
555
592
  repeat(choice(
556
- $._ml2_string_chars,
593
+ alias($.mlStringLiteralPart2, $.mlStringLiteralPart),
557
594
  alias($.escapeSequence2, $.escapeSequence),
558
595
  alias($.interpolationExpr2, $.interpolationExpr)
559
596
  )),
@@ -562,7 +599,7 @@ module.exports = grammar({
562
599
  seq(
563
600
  '###"""',
564
601
  repeat(choice(
565
- $._ml3_string_chars,
602
+ alias($.mlStringLiteralPart3, $.mlStringLiteralPart),
566
603
  alias($.escapeSequence3, $.escapeSequence),
567
604
  alias($.interpolationExpr3, $.interpolationExpr)
568
605
  )),
@@ -571,7 +608,7 @@ module.exports = grammar({
571
608
  seq(
572
609
  '####"""',
573
610
  repeat(choice(
574
- $._ml4_string_chars,
611
+ alias($.mlStringLiteralPart4, $.mlStringLiteralPart),
575
612
  alias($.escapeSequence4, $.escapeSequence),
576
613
  alias($.interpolationExpr4, $.interpolationExpr)
577
614
  )),
@@ -580,7 +617,7 @@ module.exports = grammar({
580
617
  seq(
581
618
  '#####"""',
582
619
  repeat(choice(
583
- $._ml5_string_chars,
620
+ alias($.mlStringLiteralPart5, $.mlStringLiteralPart),
584
621
  alias($.escapeSequence5, $.escapeSequence),
585
622
  alias($.interpolationExpr5, $.interpolationExpr)
586
623
  )),
@@ -589,7 +626,7 @@ module.exports = grammar({
589
626
  seq(
590
627
  '######"""',
591
628
  repeat(choice(
592
- $._ml6_string_chars,
629
+ alias($.mlStringLiteralPart6, $.mlStringLiteralPart),
593
630
  alias($.escapeSequence6, $.escapeSequence),
594
631
  alias($.interpolationExpr6, $.interpolationExpr)
595
632
  )),
@@ -597,6 +634,20 @@ module.exports = grammar({
597
634
  ),
598
635
  ),
599
636
 
637
+ mlStringLiteralPart: $ => $._ml_string_chars,
638
+
639
+ mlStringLiteralPart1: $ => $._ml1_string_chars,
640
+
641
+ mlStringLiteralPart2: $ => $._ml2_string_chars,
642
+
643
+ mlStringLiteralPart3: $ => $._ml3_string_chars,
644
+
645
+ mlStringLiteralPart4: $ => $._ml4_string_chars,
646
+
647
+ mlStringLiteralPart5: $ => $._ml5_string_chars,
648
+
649
+ mlStringLiteralPart6: $ => $._ml6_string_chars,
650
+
600
651
  escapeSequence: $ => token.immediate(seq(
601
652
  '\\',
602
653
  choice(
@@ -671,11 +722,38 @@ module.exports = grammar({
671
722
 
672
723
  objectLiteral: $ => prec(PREC.OBJ_LITERAL, seq($._expr2, $.objectBody)),
673
724
 
674
- methodCallExpr: $ => seq(optional(seq(choice("super", $._expr), choice(".", "?."))), $.identifier, $.argumentList),
675
-
676
- propertyCallExpr: $ => seq(choice("super", $._expr), choice(".", "?."), $.identifier),
677
-
678
- subscriptExpr: $ => seq(choice("super", $._expr), $._open_square_bracket, $._expr, "]"),
725
+ methodCallExpr: $ => seq(
726
+ optional(
727
+ seq(
728
+ field("receiver", choice("super", $._expr)),
729
+ choice(".", "?.")
730
+ )
731
+ ),
732
+ $.identifier,
733
+ $.argumentList
734
+ ),
735
+
736
+ propertyCallExpr: $ => seq(
737
+ field("receiver", choice("super", $._expr)),
738
+ choice(".", "?."),
739
+ // allow newline as a possible token because tree-sitter otherwise doesn't handle error recovery correctly.
740
+ // E.g.
741
+ // This gets parsed as a single class property, where `bar.baz { foo = bar }` is the property's value
742
+ // ```
743
+ // foo = bar.
744
+ // baz { foo = bar }
745
+ // ```
746
+ //
747
+ // This gets parsed as two class properties; `foo = bar.typealias` and `Baz = String`
748
+ // ```
749
+ // foo = bar.
750
+ //
751
+ // typealias Baz = String
752
+ // ```
753
+ choice($.identifier, field("err", "\n"))
754
+ ),
755
+
756
+ subscriptExpr: $ => seq(field("receiver", choice("super", $._expr)), alias($._open_subscript_bracket, "["), $._expr, "]"),
679
757
 
680
758
  unaryExpr: $ => choice(
681
759
  prec.left(PREC.NEG, seq($._expr, '!!')),
@@ -687,7 +765,7 @@ module.exports = grammar({
687
765
  ['**', PREC.EXP],
688
766
  ['??', PREC.COALESCE]
689
767
  ].map(([operator, precedence]) =>
690
- prec.right(precedence, seq($._expr, operator, $._expr))
768
+ prec.right(precedence, seq($._expr, field('operator', operator), $._expr))
691
769
  )),
692
770
 
693
771
  binaryExpr: $ => choice(...[
@@ -707,7 +785,7 @@ module.exports = grammar({
707
785
  ['||', PREC.OR],
708
786
  ['|>', PREC.PIPE]
709
787
  ].map(([operator, precedence]) =>
710
- prec.left(precedence, seq($._expr, operator, $._expr))
788
+ prec.left(precedence, seq($._expr, field('operator', operator), $._expr))
711
789
  )),
712
790
 
713
791
  isExpr: $ => prec(PREC.IS, seq($._expr, "is", $.type)),
@@ -749,10 +827,16 @@ module.exports = grammar({
749
827
  return token(choice(seq(alpha, repeat(alpha_numeric)), /`[^`]*`/))
750
828
  },
751
829
 
752
- lineComment: $ => token(seq('//', /.*/)),
830
+ lineComment: $ => choice(
831
+ token(seq(/\/\/[^\/]/, /.*/)),
832
+ '//$',
833
+ ),
753
834
 
754
835
  // TODO
755
- docComment: $ => token(seq('///', /.*/)),
836
+ docComment: $ => seq(
837
+ token(seq('///', /.*/)),
838
+ repeat(token(seq('///', /.*/)))
839
+ ),
756
840
 
757
841
  blockComment: $ => token(seq(
758
842
  '/*',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apple/tree-sitter-pkl",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "Pkl grammar for node-tree-sitter",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,14 +27,13 @@
27
27
  "@types/glob": "^8.1.0",
28
28
  "@types/node": "^20.4.5",
29
29
  "node-gyp": "^9.1.0",
30
- "tree-sitter-cli": "^0.20.0",
31
- "ts-node": "^10.0.0",
30
+ "tree-sitter-cli": "^0.22.6",
32
31
  "typescript": "^4.9.0"
33
32
  },
34
33
  "scripts": {
35
34
  "build": "tree-sitter generate && node-gyp configure && node-gyp build",
35
+ "generate": "tree-sitter generate --no-bindings",
36
36
  "test": "tree-sitter test",
37
- "synctests": "ts-node src/synctests.ts",
38
37
  "getVersion": "node -p \"require('./package.json').version\""
39
38
  },
40
39
  "tree-sitter": [