@willbooster/tree-sitter-kotlin 1.6.2 → 1.6.4

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/grammar.js CHANGED
@@ -68,10 +68,12 @@ module.exports = grammar({
68
68
  [$.member_modifier, $._reserved_identifier],
69
69
 
70
70
  [$.context_parameters, $._reserved_identifier],
71
- [$.modifiers, $.function_type],
71
+ [$._modifier_context_parameters, $._reserved_identifier],
72
+ [$.context_parameters, $._modifier_context_parameters, $._reserved_identifier],
73
+ [$._context_entry, $._modifier_context_parameters],
74
+ [$._modifier_context_parameters],
72
75
  [$.secondary_constructor, $._reserved_identifier],
73
76
  [$.enum_entry, $.modifiers],
74
- [$.modifiers, $.anonymous_function],
75
77
  [$.qualified_identifier],
76
78
  [$.constructor_invocation, $._unescaped_annotation],
77
79
  [$.nullable_type],
@@ -111,6 +113,14 @@ module.exports = grammar({
111
113
  $._delegation_end,
112
114
  // the `)` that ends a call's arguments (see `value_arguments`)
113
115
  $._arguments_end,
116
+ // empty: they tell the scanner when a statement list or the member list of a class body opens in braces, and when
117
+ // either closes (see `frames` in the scanner)
118
+ $._open_statements,
119
+ $._open_members,
120
+ $._close_braces,
121
+ $._top_level_statement_end,
122
+ // empty: it ends a context list of types among modifiers, except directly in a statement list (see `modifiers`)
123
+ $._context_end,
114
124
  ],
115
125
 
116
126
  inline: ($) => [$._statements, $._identifier, $._control_structure_body],
@@ -170,7 +180,9 @@ module.exports = grammar({
170
180
  repeat($.file_annotation),
171
181
  optional($.package_header),
172
182
  repeat($.import),
173
- repeat(seq($.statement, $._semi))
183
+ // The scanner clears its brace frames after each top-level statement, so that a brace that error recovery
184
+ // consumed affects no later statement.
185
+ repeat(seq($.statement, $._semi, $._top_level_statement_end))
174
186
  ),
175
187
 
176
188
  file_annotation: ($) =>
@@ -344,7 +356,7 @@ module.exports = grammar({
344
356
 
345
357
  function_body: ($) => choice($.block, seq('=', $.expression)),
346
358
 
347
- block: ($) => seq('{', optional($._statements), '}'),
359
+ block: ($) => seq('{', $._open_statements, optional($._statements), '}', $._close_braces),
348
360
 
349
361
  for_statement: ($) =>
350
362
  prec.right(
@@ -388,7 +400,8 @@ module.exports = grammar({
388
400
 
389
401
  _loop_prefix: ($) => prec.dynamic(1, repeat1(choice($.annotation, $.label))),
390
402
 
391
- class_body: ($) => seq('{', repeat(seq($.class_member_declaration, $._class_member_semi)), '}'),
403
+ class_body: ($) =>
404
+ seq('{', $._open_members, repeat(seq($.class_member_declaration, $._class_member_semi)), '}', $._close_braces),
392
405
 
393
406
  class_member_declaration: ($) =>
394
407
  choice($.declaration, $.companion_object, $.anonymous_initializer, $.secondary_constructor),
@@ -398,9 +411,11 @@ module.exports = grammar({
398
411
  enum_class_body: ($) =>
399
412
  seq(
400
413
  '{',
414
+ $._open_members,
401
415
  optionalCommaSep1($.enum_entry),
402
416
  optional(seq(';', repeat(seq($.class_member_declaration, $._class_member_semi)))),
403
- '}'
417
+ '}',
418
+ $._close_braces
404
419
  ),
405
420
 
406
421
  // Only annotations can modify an enum entry, and with the full modifier list a `context` after an annotation would
@@ -413,10 +428,7 @@ module.exports = grammar({
413
428
  optional($.class_body)
414
429
  ),
415
430
 
416
- // Whether a call takes a trailing lambda depends on the token after its arguments, which the lookahead of the
417
- // scanned `)` reaches, so an edit there makes incremental parsing reparse the call instead of reusing a call without
418
- // the lambda.
419
- value_arguments: ($) => seq('(', optionalCommaSep1($.value_argument), alias($._arguments_end, ')')),
431
+ value_arguments: ($) => valueArguments($, '('),
420
432
 
421
433
  value_argument: ($) => seq(optional(seq($._identifier, '=')), optional('*'), $.expression),
422
434
 
@@ -443,7 +455,7 @@ module.exports = grammar({
443
455
  $.inheritance_modifier,
444
456
  $.parameter_modifier,
445
457
  $.platform_modifier,
446
- $.context_parameters
458
+ alias($._modifier_context_parameters, $.context_parameters)
447
459
  )
448
460
  )
449
461
  )
@@ -480,7 +492,15 @@ module.exports = grammar({
480
492
  use_site_target: () =>
481
493
  seq(choice('field', 'property', 'get', 'set', 'receiver', 'param', 'setparam', 'delegate'), ':'),
482
494
 
483
- _unescaped_annotation: ($) => choice($.constructor_invocation, $.type),
495
+ // As in Kotlin, a `(` right after an annotation's name always starts its arguments; lexing it as a separate immediate
496
+ // token keeps an annotated parenthesized expression from being read there. After whitespace, Kotlin's reading
497
+ // depends on the context, so both readings remain.
498
+ _unescaped_annotation: ($) =>
499
+ choice($.constructor_invocation, alias($._annotation_invocation, $.constructor_invocation), $.type),
500
+
501
+ _annotation_invocation: ($) => seq($.type, alias($._annotation_arguments, $.value_arguments)),
502
+
503
+ _annotation_arguments: ($) => valueArguments($, alias(token.immediate('('), '(')),
484
504
 
485
505
  type: ($) =>
486
506
  choice($.user_type, $.nullable_type, $.function_type, $.non_nullable_type, $.parenthesized_type, 'dynamic'),
@@ -513,13 +533,27 @@ module.exports = grammar({
513
533
  ),
514
534
 
515
535
  // Context parameters (`context(scope: Scope)`, Kotlin 2.2) and the older context receivers (`context(Scope)`).
516
- context_parameters: ($) =>
536
+ context_parameters: ($) => seq('context', '(', commaSep1($._context_entry), optional(','), ')'),
537
+
538
+ _context_entry: ($) => choice(seq(optional($.parameter_modifiers), $.parameter), $.type),
539
+
540
+ // Directly in a statement list, Kotlin reads `context(…)` with only types as a call, e.g. before a local declaration
541
+ // on the next line, so the scanner ends such a list among modifiers only elsewhere. A list with a named parameter
542
+ // cannot be a call.
543
+ _modifier_context_parameters: ($) =>
517
544
  seq(
518
545
  'context',
519
546
  '(',
520
- commaSep1(choice(seq(optional($.parameter_modifiers), $.parameter), $.type)),
521
- optional(','),
522
- ')'
547
+ choice(
548
+ seq(commaSep1($.type), optional(','), ')', $._context_end),
549
+ seq(
550
+ repeat(seq($.type, ',')),
551
+ seq(optional($.parameter_modifiers), $.parameter),
552
+ repeat(seq(',', $._context_entry)),
553
+ optional(','),
554
+ ')'
555
+ )
556
+ )
523
557
  ),
524
558
 
525
559
  function_type_parameters: ($) => seq('(', optionalCommaSep1(choice($.parameter, $.type)), ')'),
@@ -657,7 +691,14 @@ module.exports = grammar({
657
691
  annotated_lambda: ($) => seq(repeat($.annotation), optional($.label), $.lambda_literal),
658
692
 
659
693
  lambda_literal: ($) =>
660
- seq('{', optional(seq(optional($.lambda_parameters), '->')), optionalSep1($.statement, $._semi), '}'),
694
+ seq(
695
+ '{',
696
+ $._open_statements,
697
+ optional(seq(optional($.lambda_parameters), '->')),
698
+ optionalSep1($.statement, $._semi),
699
+ '}',
700
+ $._close_braces
701
+ ),
661
702
 
662
703
  lambda_parameters: ($) => seq(commaSep1($._lambda_parameter), optional(',')),
663
704
 
@@ -719,7 +760,8 @@ module.exports = grammar({
719
760
 
720
761
  collection_literal: ($) => seq('[', optionalCommaSep1($.expression), ']'),
721
762
 
722
- when_expression: ($) => seq('when', optional($.when_subject), '{', repeat($.when_entry), '}'),
763
+ when_expression: ($) =>
764
+ seq('when', optional($.when_subject), '{', $._open_statements, repeat($.when_entry), '}', $._close_braces),
723
765
 
724
766
  when_subject: ($) =>
725
767
  seq('(', optional(seq(repeat($.annotation), 'val', $.variable_declaration, '=')), $.expression, ')'),
@@ -964,3 +1006,17 @@ function commaSep1(rule) {
964
1006
  function optionalCommaSep1(rule) {
965
1007
  return optional(seq(rule, repeat(seq(',', rule)), optional(',')));
966
1008
  }
1009
+
1010
+ /**
1011
+ * Creates the arguments of a call or an annotation. Whether a call takes a trailing lambda depends on the token after
1012
+ * its arguments, which the lookahead of the scanned `)` reaches, so an edit there makes incremental parsing reparse the
1013
+ * call instead of reusing a call without the lambda.
1014
+ *
1015
+ * @param {GrammarSymbols<string>} $
1016
+ * @param {RuleOrLiteral} open
1017
+ *
1018
+ * @returns {SeqRule}
1019
+ */
1020
+ function valueArguments($, open) {
1021
+ return seq(open, optionalCommaSep1($.value_argument), alias($._arguments_end, ')'));
1022
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willbooster/tree-sitter-kotlin",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "description": "Kotlin grammar for tree-sitter",
5
5
  "keywords": [
6
6
  "incremental",
Binary file
package/tree-sitter.json CHANGED
@@ -13,7 +13,7 @@
13
13
  }
14
14
  ],
15
15
  "metadata": {
16
- "version": "1.6.2",
16
+ "version": "1.6.4",
17
17
  "license": "MIT",
18
18
  "description": "Kotlin grammar for tree-sitter",
19
19
  "authors": [