@willbooster/tree-sitter-ruby 2.0.8 → 2.0.10

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
@@ -9,6 +9,7 @@ const PREC = {
9
9
  AND: -2,
10
10
  OR: -2,
11
11
  NOT: 5,
12
+ PATTERN: 6,
12
13
  DEFINED: 10,
13
14
  ALIAS: 11,
14
15
  ASSIGN: 15,
@@ -82,20 +83,127 @@ module.exports = grammar({
82
83
  $._element_reference_bracket,
83
84
  $._short_interpolation,
84
85
  $._line_comment,
86
+ $._block_comment,
85
87
  $._uninterpreted,
88
+ $._not_parenthesized,
86
89
  ],
87
90
 
88
91
  extras: ($) => [$.comment, $.heredoc_body, /\s/, /\\\r?\n/],
89
92
 
90
93
  word: ($) => $.identifier,
91
94
 
95
+ reserved: { global: () => [], variables: () => ['in', 'ensure', 'rescue', 'else'], methodNames: () => [] },
96
+
92
97
  conflicts: ($) => [
98
+ [$._command_not_operand_expression, $._chained_test_pattern, $._negated_chained_test_pattern],
99
+ [
100
+ $._command_not_operand_expression,
101
+ $._chained_test_pattern,
102
+ $._negated_chained_test_pattern,
103
+ $._yield_test_pattern,
104
+ ],
105
+ [$._command_value, $._ordinary_rhs_expression],
106
+ [$._command_value, $._yield_value, $._ordinary_rhs_expression],
107
+ [$._expression, $._test_pattern_not_operand_expression, $._yield_pattern_not_operand_expression],
108
+ [$._command_value, $._command_not_operand_expression, $._yield_value],
109
+ [$._yield_value, $._ordinary_rhs_expression],
110
+ [$._yield_argument_expression, $._yield_assignment_rhs],
111
+ [$._command_value, $._test_pattern_not_operand_expression],
112
+ [$._test_pattern_not_operand_expression, $._yield_pattern_not_operand_expression],
113
+ [$._expression, $._yield_pattern_not_operand_expression],
114
+ [$._command_not_operand_expression, $._yield_value],
115
+ [$._command_not_operand_expression, $._chained_match_pattern, $._yield_value],
116
+ [$._command_not_operand_expression, $._pattern_command_operand_expression],
117
+ [$._command_not_operand_expression, $._chained_match_pattern],
118
+ [$._yield_pattern_not_operand_expression, $._yield_value],
119
+ [$._command_value, $._command_not_operand_expression, $._test_pattern_not_operand_expression],
120
+ [$._command_not_operand_expression, $._test_pattern_not_operand_expression],
121
+ [$._non_pattern_expression, $._command_not_operand_expression],
122
+ [$._expression, $._test_pattern_not_operand_expression],
123
+ [$._expression, $._command_not_operand_expression],
124
+ [$._command_value, $._command_not_operand_expression],
125
+ [$._signed_command_argument_list, $._yield_signed_argument_list],
126
+ [$._chained_match_pattern, $._yield_value],
127
+ [$._endless_body_rescue, $._yield_method_body_rescue],
128
+ [$._body_expr, $._yield_method_rest],
129
+ [$._pattern_command_not, $._command_not],
130
+ [$._negated_chained_test_pattern, $._yield_test_pattern],
131
+ [$._chained_test_pattern, $._negated_chained_test_pattern, $._yield_test_pattern, $._command_not],
132
+ [$._chained_test_pattern, $._negated_chained_test_pattern, $._command_not],
133
+ [$._command_not, $._test_pattern_not],
134
+ [$.unary, $._command_not],
135
+ [$._command_value, $._argument_command_value, $._yield_value],
136
+ [$._argument_command_value, $._chained_match_pattern, $._yield_value],
137
+ [$._argument_command_value, $._yield_value, $.pair],
138
+ [$._argument_command_value, $._yield_value],
139
+ [$._argument_command_value, $._command_pair],
140
+ [$._argument_command_value, $.pair],
141
+ [$._argument_command_value, $._command_definition_pair],
142
+ [$._argument_command_value, $._chained_match_pattern],
143
+ [$._argument_command_value, $._chained_test_pattern],
144
+ [$._command_value, $._argument_command_value],
145
+ [$._command_pair_key_arguments, $._yield_command_pair_key_arguments],
146
+ [$._yield_argument_list, $._yield_call_pair_key_arguments],
147
+ [$.command_call, $._command_pair, $._yield_command_pair],
148
+ [$._command_pair, $._yield_command_pair],
149
+ [$._command_value, $._command_pair, $._yield_command_pair],
150
+ [$._pattern_unary, $.unary],
151
+ [$._arg, $._pattern_arg],
152
+ [$._chained_assignment, $._pattern_chained_assignment],
153
+ [$.command_assignment, $._pattern_command_assignment],
154
+ [$.assignment, $._pattern_assignment],
155
+ [$._command_argument, $._yield_call_pair_key_arguments],
156
+ [$._yield_argument, $._yield_call_pair_key_arguments],
157
+ [$._yield_argument, $._command_argument, $._yield_call_pair_key_arguments],
158
+ [$._yield_argument, $._yield_pair_key_arguments],
159
+ [$._yield_pattern_not, $._test_pattern_not],
160
+ [$._yield_argument_list, $._yield_pair_key_arguments],
161
+ [$._body_expr, $._yield_value],
162
+ [$._endless_command_operand, $._yield_value],
163
+ [$._yield_argument, $._command_argument],
164
+ [$._command_value, $._yield_value, $.pair],
165
+ [$._command_value, $._chained_match_pattern, $._yield_value],
166
+ [$._command_value, $._yield_value],
167
+ [$._yield_value, $.pair],
168
+ [$._yield_value, $._yield_command_pair],
169
+ [$._chained_command_argument_list, $.command_argument_list],
170
+ [$._pair_block_argument, $.block_argument],
171
+ [$.command_call_with_block, $._super_command_with_block],
172
+ [$.command_call, $._command_pair],
173
+ [$._command_value, $._command_pair],
174
+ [$._statement, $._chained_test_pattern],
175
+ [$._chained_test_pattern, $.command_call],
176
+ [$._command_value, $._chained_test_pattern],
177
+ [$._non_pattern_expression, $._chained_test_pattern],
93
178
  [$._chained_primary, $._chained_lhs],
179
+ [$._command_value, $.pair],
180
+ [$._command_value, $._command_definition_pair],
181
+ [$._chained_match_pattern, $.command_call],
182
+ [$.call, $._variable],
183
+ [$._primary, $.call],
184
+ [$._primary, $._variable],
185
+ [$._primary, $.command_call_with_block, $._variable],
186
+ [$._primary, $._super_command, $.command_call_with_block, $._variable],
187
+ [$._non_pattern_expression, $._chained_match_pattern],
188
+ [$._command_value, $._chained_match_pattern],
94
189
  [$._array_pattern_n, $.as_pattern, $._find_pattern_body],
95
190
  ],
96
191
 
97
192
  supertypes: ($) => [
98
193
  $._statement,
194
+ $._argument_expression,
195
+ $._command_value_expression,
196
+ $._ordinary_rhs_expression,
197
+ $._yield_assignment_rhs,
198
+ $._command_not_operand_expression,
199
+ $._yield_not_operand_expression,
200
+ $._test_pattern_not_operand_expression,
201
+ $._yield_pattern_not_operand_expression,
202
+ $._pattern_command_operand_expression,
203
+ $._command_argument_expression,
204
+ $._yield_argument_expression,
205
+ $._value_argument_expression,
206
+ $._pattern_arg,
99
207
  $._arg,
100
208
  $._method_name,
101
209
  $._expression,
@@ -144,66 +252,30 @@ module.exports = grammar({
144
252
 
145
253
  method: ($) => seq('def', $._method_rest),
146
254
 
147
- singleton_method: ($) =>
148
- seq(
149
- 'def',
150
- seq(
151
- choice(
152
- field('object', choice($._variable, $.self, $._nonlocal_variable)),
153
- seq('(', field('object', $._arg), ')')
154
- ),
155
- choice('.', '::')
156
- ),
157
- $._method_rest
158
- ),
255
+ singleton_method: ($) => singletonMethod($, $._method_rest),
159
256
 
160
- _method_rest: ($) =>
161
- seq(
162
- field('name', $._method_name),
163
- choice(
164
- $._body_expr,
165
- seq(
166
- field('parameters', alias($.parameters, $.method_parameters)),
167
- choice(seq(optional($._terminator), optional(field('body', $.body_statement)), 'end'), $._body_expr)
168
- ),
169
- seq(
170
- optional(field('parameters', alias($.bare_parameters, $.method_parameters))),
171
- $._terminator,
172
- optional(field('body', $.body_statement)),
173
- 'end'
174
- )
175
- )
176
- ),
257
+ _method_rest: ($) => methodRest($, $._body_expr),
177
258
 
178
259
  rescue_modifier_arg: ($) => prec(PREC.RESCUE, seq(field('body', $._arg), 'rescue', field('handler', $._arg))),
179
260
 
261
+ _command_value_rescue: ($) =>
262
+ prec(
263
+ PREC.RESCUE,
264
+ seq(field('body', alias($._command_value_expression, $._expression)), 'rescue', field('handler', $._arg))
265
+ ),
266
+
180
267
  rescue_modifier_expression: ($) =>
181
- prec(PREC.RESCUE, seq(field('body', $._expression), 'rescue', field('handler', $._arg))),
268
+ prec(PREC.RESCUE, seq(field('body', $._non_pattern_expression), 'rescue', field('handler', $._arg))),
269
+
270
+ _body_expr: ($) => seq('=', field('body', endlessBody($, $._arg, $._endless_body_rescue))),
182
271
 
183
- _body_expr: ($) => seq('=', field('body', choice($._arg, alias($.rescue_modifier_arg, $.rescue_modifier)))),
272
+ _endless_body_rescue: ($) => endlessBodyRescue($, $._arg),
184
273
 
185
274
  _command_method: ($) => seq('def', $._command_method_rest),
186
275
 
187
- _command_singleton_method: ($) =>
188
- seq(
189
- 'def',
190
- seq(
191
- choice(
192
- field('object', choice($._variable, $.self, $._nonlocal_variable)),
193
- seq('(', field('object', $._arg), ')')
194
- ),
195
- choice('.', '::')
196
- ),
197
- $._command_method_rest
198
- ),
276
+ _command_singleton_method: ($) => singletonMethod($, $._command_method_rest),
199
277
 
200
- _command_method_rest: ($) =>
201
- seq(
202
- field('name', $._method_name),
203
- optional(field('parameters', alias($.parameters, $.method_parameters))),
204
- '=',
205
- field('body', $._endless_command)
206
- ),
278
+ _command_method_rest: ($) => endlessMethodRest($, $._endless_command),
207
279
 
208
280
  // Ruby 4.0's default parser (Prism) lets an endless body hold at most one `rescue`, applied outside any `not`; a
209
281
  // further `rescue` applies to the whole definition.
@@ -223,7 +295,8 @@ module.exports = grammar({
223
295
  alias($._command_singleton_method, $.singleton_method)
224
296
  ),
225
297
 
226
- _endless_command_not: ($) => prec.right(PREC.NOT, seq(field('operator', 'not'), field('operand', $._expression))),
298
+ _endless_command_not: ($) =>
299
+ choice($._test_pattern_not, prec.right(PREC.NOT, seq(field('operator', 'not'), field('operand', $._expression)))),
227
300
 
228
301
  _endless_command_rescue: ($) =>
229
302
  prec(PREC.RESCUE, seq(field('body', $._endless_command_operand), 'rescue', field('handler', $._arg))),
@@ -298,7 +371,7 @@ module.exports = grammar({
298
371
  ),
299
372
 
300
373
  return_command: ($) => prec.left(seq('return', alias($.command_argument_list, $.argument_list))),
301
- yield_command: ($) => prec.left(seq('yield', alias($.command_argument_list, $.argument_list))),
374
+ yield_command: ($) => prec.left(seq('yield', alias($._yield_argument_list, $.argument_list))),
302
375
  break_command: ($) => prec.left(seq('break', alias($.command_argument_list, $.argument_list))),
303
376
  next_command: ($) => prec.left(seq('next', alias($.command_argument_list, $.argument_list))),
304
377
  return: () => prec.left('return'),
@@ -597,65 +670,147 @@ module.exports = grammar({
597
670
  // This naming convention is based on Ruby's standard grammar.
598
671
  _expression: ($) =>
599
672
  choice(
600
- alias($._command_method, $.method),
601
- alias($._command_singleton_method, $.singleton_method),
602
- alias($.command_binary, $.binary),
603
- alias($.command_unary, $.unary),
604
- alias($.command_assignment, $.assignment),
605
- alias($.command_operator_assignment, $.operator_assignment),
606
- alias($.command_call, $.call),
607
- alias($.command_call_with_block, $.call),
608
- $._chained_arg,
609
- alias($._chained_assignment, $.assignment),
610
- alias($._chained_operator_assignment, $.operator_assignment),
611
- alias($.return_command, $.return),
612
- alias($.yield_command, $.yield),
613
- alias($.break_command, $.break),
614
- alias($.next_command, $.next),
673
+ $._non_pattern_expression,
615
674
  alias($._chained_match_pattern, $.match_pattern),
675
+ alias($._negated_command_match_pattern, $.match_pattern),
616
676
  alias($._chained_test_pattern, $.test_pattern),
617
677
  $.match_pattern,
678
+ $.test_pattern
679
+ ),
680
+
681
+ _non_pattern_expression: ($) =>
682
+ choice(
683
+ alias($.command_binary, $.binary),
684
+ alias($.command_unary, $.unary),
685
+ $._command_unary_arg,
686
+ $._command_value
687
+ ),
688
+
689
+ _command_value: ($) => commandValue($, true),
690
+
691
+ _command_value_expression: ($) => $._command_value,
692
+
693
+ _command_not_operand_expression: ($) =>
694
+ prec.right(
695
+ PREC.NOT - 1,
696
+ choice(
697
+ commandValue($, false),
698
+ alias($._ordinary_chained_assignment, $.assignment),
699
+ alias($.command_operator_assignment, $.operator_assignment),
700
+ alias($._chained_operator_assignment, $.operator_assignment),
701
+ alias($.command_unary, $.unary),
702
+ $._command_unary_arg,
703
+ prec.dynamic(3, $.match_pattern)
704
+ )
705
+ ),
706
+
707
+ _yield_not_operand_expression: ($) =>
708
+ choice(
709
+ $._yield_value,
710
+ alias($._yield_unary, $.unary),
711
+ alias($._yield_not_operator_assignment, $.operator_assignment)
712
+ ),
713
+
714
+ _test_pattern_not_operand_expression: ($) =>
715
+ choice(
618
716
  $.test_pattern,
619
- $._arg
717
+ alias($._negated_chained_test_pattern, $.test_pattern),
718
+ alias($._test_pattern_not, $.unary)
719
+ ),
720
+
721
+ _yield_pattern_not_operand_expression: ($) =>
722
+ choice($.test_pattern, alias($._yield_test_pattern, $.test_pattern), alias($._yield_pattern_not, $.unary)),
723
+
724
+ _argument_command_value: ($) =>
725
+ choice(
726
+ commandValue($, false),
727
+ alias($._ordinary_chained_assignment, $.assignment),
728
+ alias($._ordinary_chained_operator_assignment, $.operator_assignment)
620
729
  ),
621
730
 
622
731
  _chained_match_pattern: ($) =>
623
- prec(
624
- 100,
732
+ choice(
733
+ prec.dynamic(
734
+ 1,
735
+ seq(
736
+ field(
737
+ 'value',
738
+ choice(
739
+ $._chained_arg,
740
+ alias($._chained_command, $.call),
741
+ alias($._pattern_command_assignment, $.assignment),
742
+ alias($._pattern_chained_assignment, $.assignment),
743
+ alias($._chained_operator_assignment, $.operator_assignment),
744
+ alias($.command_operator_assignment, $.operator_assignment),
745
+ alias($.command_call_with_block, $.call),
746
+ alias($._receiver_command, $.call),
747
+ alias($._command_method, $.method),
748
+ alias($._command_singleton_method, $.singleton_method),
749
+ alias($._pattern_command_binary, $.binary),
750
+ alias($.command_unary, $.unary),
751
+ $._command_unary_arg,
752
+ alias($.yield_command, $.yield)
753
+ )
754
+ ),
755
+ '=>',
756
+ field('pattern', $._pattern_top_expr_body)
757
+ )
758
+ ),
625
759
  seq(
626
- field(
627
- 'value',
628
- choice(
629
- $._chained_arg,
630
- alias($._command_method, $.method),
631
- alias($._command_singleton_method, $.singleton_method)
632
- )
633
- ),
760
+ field('value', choice($.if_modifier, $.unless_modifier, $.while_modifier, $.until_modifier)),
634
761
  '=>',
635
762
  field('pattern', $._pattern_top_expr_body)
763
+ ),
764
+ prec(
765
+ PREC.PATTERN,
766
+ seq(field('value', alias($._super_command, $.call)), '=>', field('pattern', $._pattern_top_expr_body))
636
767
  )
637
768
  ),
638
- _chained_test_pattern: ($) =>
769
+ _negated_command_match_pattern: ($) =>
639
770
  prec(
640
- 100,
641
- seq(
642
- field(
643
- 'value',
644
- choice(
645
- $._chained_arg,
646
- alias($._chained_command, $.call),
647
- alias($._command_method, $.method),
648
- alias($._command_singleton_method, $.singleton_method)
649
- )
650
- ),
651
- 'in',
652
- field('pattern', $._pattern_top_expr_body)
771
+ PREC.PATTERN,
772
+ seq(field('value', alias($._pattern_command_not, $.unary)), '=>', field('pattern', $._pattern_top_expr_body))
773
+ ),
774
+
775
+ _chained_test_pattern: ($) => chainedTestPattern($),
776
+
777
+ _negated_chained_test_pattern: ($) => prec(PREC.PATTERN, chainedTestPattern($, false)),
778
+
779
+ match_pattern: ($) =>
780
+ prec(
781
+ PREC.PATTERN,
782
+ prec.dynamic(
783
+ 1,
784
+ seq(field('value', alias($._pattern_arg, $._arg)), '=>', field('pattern', $._pattern_top_expr_body))
653
785
  )
654
786
  ),
655
787
 
656
- match_pattern: ($) => prec(100, seq(field('value', $._arg), '=>', field('pattern', $._pattern_top_expr_body))),
788
+ test_pattern: ($) =>
789
+ prec(
790
+ PREC.PATTERN,
791
+ prec.dynamic(
792
+ 2,
793
+ seq(field('value', alias($._pattern_arg, $._arg)), 'in', field('pattern', $._pattern_top_expr_body))
794
+ )
795
+ ),
796
+
797
+ _pattern_arg: ($) =>
798
+ choice(
799
+ alias($._unary_minus_pow, $.unary),
800
+ $._primary,
801
+ $.operator_assignment,
802
+ $.conditional,
803
+ $.range,
804
+ $.binary,
805
+ alias($._pattern_unary, $.unary),
806
+ alias($._pattern_assignment, $.assignment)
807
+ ),
657
808
 
658
- test_pattern: ($) => prec(100, seq(field('value', $._arg), 'in', field('pattern', $._pattern_top_expr_body))),
809
+ _pattern_unary: ($) =>
810
+ choice(
811
+ prec(PREC.DEFINED, seq(field('operator', 'defined?'), field('operand', choice($._arg, $.begin)))),
812
+ strongUnaryExpression($._arg, choice(alias($._unary_minus, '-'), '+'))
813
+ ),
659
814
 
660
815
  _arg: ($) =>
661
816
  choice(
@@ -681,45 +836,7 @@ module.exports = grammar({
681
836
  )
682
837
  ),
683
838
 
684
- _primary: ($) =>
685
- choice(
686
- $.parenthesized_statements,
687
- $._lhs,
688
- alias($._function_identifier_call, $.call),
689
- $.call,
690
- $.array,
691
- $.string_array,
692
- $.symbol_array,
693
- $.hash,
694
- $.subshell,
695
- $._literal,
696
- $.string,
697
- $.character,
698
- $.chained_string,
699
- $.regex,
700
- $.lambda,
701
- $.method,
702
- $.singleton_method,
703
- $.class,
704
- $.singleton_class,
705
- $.module,
706
- $.begin,
707
- $.while,
708
- $.until,
709
- $.if,
710
- $.unless,
711
- $.for,
712
- $.case,
713
- $.case_match,
714
- $.return,
715
- $.yield,
716
- $.break,
717
- $.next,
718
- $.redo,
719
- $.retry,
720
- alias($.parenthesized_unary, $.unary),
721
- $.heredoc_beginning
722
- ),
839
+ _primary: ($) => primaryExpression($, $._lhs, $.call, $.method, $.singleton_method),
723
840
 
724
841
  parenthesized_statements: ($) => seq('(', optional($._statements), ')'),
725
842
 
@@ -745,28 +862,45 @@ module.exports = grammar({
745
862
  command_call: ($) =>
746
863
  choice(
747
864
  seq(
748
- choice($._call, field('method', choice($._variable, $._function_identifier))),
865
+ field('method', choice($._variable, $._function_identifier)),
749
866
  field('arguments', alias($.command_argument_list, $.argument_list))
750
867
  ),
868
+ $._super_command,
869
+ $._receiver_command,
751
870
  $._chained_command
752
871
  ),
753
872
 
873
+ _super_command: ($) =>
874
+ prec.dynamic(
875
+ 1,
876
+ seq(
877
+ field('method', $.super),
878
+ field(
879
+ 'arguments',
880
+ choice(
881
+ alias($.command_argument_list, $.argument_list),
882
+ alias($._signed_command_argument_list, $.argument_list)
883
+ )
884
+ )
885
+ )
886
+ ),
887
+
888
+ _receiver_command: ($) => seq($._call, field('arguments', alias($.command_argument_list, $.argument_list))),
889
+
754
890
  _chained_command: ($) =>
755
891
  seq($._chained_command_call, field('arguments', alias($._chained_command_argument_list, $.argument_list))),
756
892
 
757
- command_call_with_block: ($) => {
758
- const receiver = choice($._call, field('method', choice($._variable, $._function_identifier)));
759
- const args = field('arguments', alias($.command_argument_list, $.argument_list));
760
- const chainedArgs = field('arguments', alias($._chained_command_argument_list, $.argument_list));
761
- const block = field('block', $.block);
762
- const doBlock = field('block', $.do_block);
763
- return choice(
764
- seq(receiver, prec(PREC.CURLY_BLOCK, seq(args, block))),
765
- seq(receiver, prec(PREC.DO_BLOCK, seq(args, doBlock))),
766
- seq($._chained_command_call, prec(PREC.CURLY_BLOCK, seq(chainedArgs, block))),
767
- seq($._chained_command_call, prec(PREC.DO_BLOCK, seq(chainedArgs, doBlock)))
768
- );
769
- },
893
+ command_call_with_block: ($) =>
894
+ choice(
895
+ commandCallWithBlock(
896
+ $,
897
+ choice($._call, field('method', choice($._variable, $._function_identifier, $.super))),
898
+ $.command_argument_list
899
+ ),
900
+ commandCallWithBlock($, $._chained_command_call, $._chained_command_argument_list)
901
+ ),
902
+
903
+ _super_command_with_block: ($) => commandCallWithBlock($, field('method', $.super), $.command_argument_list),
770
904
 
771
905
  _chained_arg: ($) =>
772
906
  choice(
@@ -812,32 +946,14 @@ module.exports = grammar({
812
946
  );
813
947
  },
814
948
 
815
- call: ($) => {
816
- const receiver = choice($._call, field('method', choice($._variable, $._function_identifier)));
817
-
818
- const args = field('arguments', $.argument_list);
819
- const receiverArguments = seq(
820
- choice(receiver, prec.left(PREC.CALL, seq(field('receiver', $._primary), field('operator', $._call_operator)))),
821
- args
822
- );
823
-
824
- const block = field('block', $.block);
825
- const doBlock = field('block', $.do_block);
826
- return choice(
827
- receiverArguments,
828
- prec(PREC.CURLY_BLOCK, seq(receiverArguments, block)),
829
- prec(PREC.DO_BLOCK, seq(receiverArguments, doBlock)),
830
- prec(PREC.CURLY_BLOCK, seq(receiver, block)),
831
- prec(PREC.DO_BLOCK, seq(receiver, doBlock))
832
- );
833
- },
949
+ call: ($) => callExpression($, $._primary, $._call),
834
950
 
835
951
  _chained_command_argument_list: ($) =>
952
+ prec.right(choice(commaSep1($._command_argument), $._signed_command_argument_list)),
953
+
954
+ _signed_command_argument_list: ($) =>
836
955
  prec.right(
837
- choice(
838
- commaSep1($._argument),
839
- seq(choice($._chained_plus_arg, alias($._chained_plus_pair, $.pair)), repeat(seq(',', $._argument)))
840
- )
956
+ seq(choice($._chained_plus_arg, alias($._chained_plus_pair, $.pair)), repeat(seq(',', $._command_argument)))
841
957
  ),
842
958
 
843
959
  _chained_plus_arg: ($) =>
@@ -854,17 +970,223 @@ module.exports = grammar({
854
970
  _chained_plus_argument: ($) =>
855
971
  prec.right(PREC.COMPLEMENT, seq(field('operator', alias($._unary_plus, '+')), field('operand', $._arg))),
856
972
 
857
- command_argument_list: ($) => prec.right(commaSep1($._argument)),
973
+ command_argument_list: ($) => prec.right(commaSep1($._command_argument)),
974
+
975
+ _yield_argument_list: ($) => prec.right(commaSep1($._yield_argument)),
976
+
977
+ _yield_argument: ($) =>
978
+ prec.left(1, argument($, alias($._yield_argument_expression, $._expression), $._yield_command_pair)),
979
+
980
+ _yield_argument_expression: ($) => prec(PREC.RESCUE, $._yield_value),
981
+
982
+ _yield_value: ($) =>
983
+ choice(
984
+ $._arg,
985
+ alias($._yield_call, $.call),
986
+ alias($._yield_not, $.unary),
987
+ alias($._yield_pattern_not, $.unary),
988
+ alias($._yield_method, $.method),
989
+ alias($._yield_singleton_method, $.singleton_method),
990
+ alias($.yield_command, $.yield)
991
+ ),
992
+
993
+ _yield_call: ($) =>
994
+ choice(
995
+ seq(
996
+ choice(field('method', choice($._variable, $._function_identifier, $.super)), $._call),
997
+ field('arguments', alias($._yield_argument_list, $.argument_list))
998
+ ),
999
+ seq(field('method', $.super), field('arguments', alias($._yield_signed_argument_list, $.argument_list)))
1000
+ ),
1001
+
1002
+ _yield_signed_argument_list: ($) =>
1003
+ prec.right(
1004
+ seq(choice($._chained_plus_arg, alias($._chained_plus_pair, $.pair)), repeat(seq(',', $._yield_argument)))
1005
+ ),
1006
+
1007
+ _yield_not: ($) =>
1008
+ prec.right(
1009
+ PREC.NOT,
1010
+ seq(field('operator', 'not'), field('operand', alias($._yield_not_operand_expression, $._expression)))
1011
+ ),
1012
+
1013
+ _yield_not_operator_assignment: ($) =>
1014
+ prec.right(
1015
+ PREC.ASSIGN,
1016
+ seq(
1017
+ field('left', choice($._lhs, $._chained_lhs)),
1018
+ field('operator', assignmentOperator($)),
1019
+ field('right', alias($._yield_assignment_rhs, $._expression))
1020
+ )
1021
+ ),
1022
+
1023
+ _yield_nested_assignment: ($) =>
1024
+ prec.right(
1025
+ PREC.ASSIGN,
1026
+ seq(
1027
+ field('left', choice($._lhs, $._chained_lhs)),
1028
+ '=',
1029
+ field('right', alias($._yield_assignment_rhs, $._expression))
1030
+ )
1031
+ ),
1032
+
1033
+ _yield_assignment_rhs: ($) =>
1034
+ choice(
1035
+ $._yield_value,
1036
+ alias($._yield_not_operator_assignment, $.operator_assignment),
1037
+ alias($._yield_nested_assignment, $.assignment),
1038
+ alias($._yield_rescue, $.rescue_modifier)
1039
+ ),
1040
+
1041
+ _yield_unary: ($) =>
1042
+ prec.right(
1043
+ PREC.COMPLEMENT,
1044
+ seq(field('operator', '!'), field('operand', alias($._yield_argument_expression, $._expression)))
1045
+ ),
1046
+
1047
+ _yield_pattern_not: ($) =>
1048
+ prec.dynamic(
1049
+ 3,
1050
+ prec.right(
1051
+ PREC.NOT,
1052
+ seq(field('operator', 'not'), field('operand', alias($._yield_pattern_not_operand_expression, $._expression)))
1053
+ )
1054
+ ),
1055
+
1056
+ _yield_test_pattern: ($) =>
1057
+ prec(
1058
+ PREC.PATTERN,
1059
+ prec.dynamic(
1060
+ 1,
1061
+ seq(
1062
+ field(
1063
+ 'value',
1064
+ choice(
1065
+ alias($._yield_not, $.unary),
1066
+ alias($._yield_unary, $.unary),
1067
+ alias($._yield_method, $.method),
1068
+ alias($._yield_singleton_method, $.singleton_method),
1069
+ alias($.yield_command, $.yield)
1070
+ )
1071
+ ),
1072
+ 'in',
1073
+ field('pattern', $._pattern_top_expr_body)
1074
+ )
1075
+ )
1076
+ ),
1077
+
1078
+ _yield_method: ($) => seq('def', $._yield_method_rest),
1079
+
1080
+ _yield_singleton_method: ($) => singletonMethod($, $._yield_method_rest),
1081
+
1082
+ _yield_method_rest: ($) => endlessMethodRest($, endlessBody($, $._yield_value, $._yield_method_body_rescue)),
1083
+
1084
+ _yield_method_body_rescue: ($) => endlessBodyRescue($, $._yield_value),
1085
+
1086
+ _yield_rescue: ($) =>
1087
+ prec(
1088
+ PREC.RESCUE,
1089
+ seq(field('body', alias($._yield_argument_expression, $._expression)), 'rescue', field('handler', $._arg))
1090
+ ),
858
1091
 
859
1092
  argument_list: ($) => prec.right(seq(token.immediate('('), optional($._argument_list_with_trailing_comma), ')')),
860
1093
 
861
- _argument_list_with_trailing_comma: ($) => prec.right(seq(commaSep1($._argument), optional(','))),
1094
+ _argument_list_with_trailing_comma: ($) =>
1095
+ prec.right(seq($._argument, repeat(seq(',', $._value_argument)), optional(','))),
1096
+
1097
+ _value_argument_expression: ($) => $._arg,
1098
+
1099
+ _command_argument_expression: ($) => $._argument_command_value,
862
1100
 
863
- _argument: ($) =>
1101
+ _value_argument: ($) =>
864
1102
  prec.left(
865
- choice($._expression, $.splat_argument, $.hash_splat_argument, $.forward_argument, $.block_argument, $.pair)
1103
+ choice(
1104
+ alias($._value_argument_expression, $._expression),
1105
+ $.splat_argument,
1106
+ $.hash_splat_argument,
1107
+ $.forward_argument,
1108
+ $.block_argument,
1109
+ $.pair
1110
+ )
1111
+ ),
1112
+
1113
+ _command_argument: ($) =>
1114
+ prec.left(
1115
+ 1,
1116
+ choice(
1117
+ alias($._command_argument_expression, $._expression),
1118
+ $.splat_argument,
1119
+ $.hash_splat_argument,
1120
+ $.forward_argument,
1121
+ $.block_argument,
1122
+ $.pair,
1123
+ alias($._command_definition_pair, $.pair),
1124
+ alias($._command_pair, $.pair)
1125
+ )
866
1126
  ),
867
1127
 
1128
+ _command_pair: ($) => commandPair($, $._command_pair_key),
1129
+
1130
+ _yield_command_pair: ($) => commandPair($, $._yield_command_pair_key, false),
1131
+
1132
+ _yield_command_pair_key: ($) =>
1133
+ seq(
1134
+ choice(field('method', choice($._variable, $._function_identifier)), $._call),
1135
+ field('arguments', alias($._yield_command_pair_key_arguments, $.argument_list))
1136
+ ),
1137
+
1138
+ _yield_command_pair_key_arguments: ($) =>
1139
+ prec.left(1, choice(alias($._yield_call_pair_key, $.call), alias($._pair_block_argument, $.block_argument))),
1140
+
1141
+ _yield_pair_key: ($) => prec.left(seq('yield', alias($._yield_pair_key_arguments, $.argument_list))),
1142
+
1143
+ _yield_pair_key_arguments: ($) => yieldPairKeyArguments($, true),
1144
+
1145
+ _yield_call_pair_key_arguments: ($) => yieldPairKeyArguments($, false),
1146
+
1147
+ _yield_call_pair_key: ($) =>
1148
+ seq(
1149
+ choice(field('method', choice($._variable, $._function_identifier, $.super)), $._call),
1150
+ field('arguments', alias($._yield_call_pair_key_arguments, $.argument_list))
1151
+ ),
1152
+
1153
+ _command_pair_key: ($) =>
1154
+ seq(
1155
+ choice(field('method', choice($._variable, $._function_identifier)), $._call),
1156
+ field('arguments', alias($._command_pair_key_arguments, $.argument_list))
1157
+ ),
1158
+
1159
+ _command_pair_key_arguments: ($) =>
1160
+ prec.left(
1161
+ 1,
1162
+ choice(
1163
+ alias($.command_call, $.call),
1164
+ alias($.command_call_with_block, $.call),
1165
+ alias($._pair_block_argument, $.block_argument)
1166
+ )
1167
+ ),
1168
+
1169
+ _pair_block_argument: ($) => prec.dynamic(1, seq(alias($._block_ampersand, '&'), $._arg)),
1170
+
1171
+ _command_definition_pair: ($) =>
1172
+ prec.dynamic(
1173
+ 2,
1174
+ prec.right(
1175
+ seq(
1176
+ field(
1177
+ 'key',
1178
+ choice(alias($._command_method, $.method), alias($._command_singleton_method, $.singleton_method))
1179
+ ),
1180
+ '=>',
1181
+ field('value', $._arg)
1182
+ )
1183
+ )
1184
+ ),
1185
+
1186
+ _argument: ($) => argument($, alias($._argument_expression, $._expression)),
1187
+
1188
+ _argument_expression: ($) => choice($._argument_command_value, $.match_pattern, $.test_pattern),
1189
+
868
1190
  forward_argument: () => '...',
869
1191
  splat_argument: ($) => prec.right(seq(alias($._splat_star, '*'), optional($._arg))),
870
1192
  hash_splat_argument: ($) => prec.right(seq(alias($._hash_splat_star_star, '**'), optional($._arg))),
@@ -882,10 +1204,15 @@ module.exports = grammar({
882
1204
  block: ($) =>
883
1205
  prec(
884
1206
  PREC.CURLY_BLOCK,
885
- seq('{', field('parameters', optional($.block_parameters)), optional(field('body', $.block_body)), '}')
1207
+ prec.dynamic(
1208
+ 2,
1209
+ seq('{', field('parameters', optional($.block_parameters)), optional(field('body', $.block_body)), '}')
1210
+ )
886
1211
  ),
887
1212
 
888
1213
  _arg_rhs: ($) => choice($._arg, alias($.rescue_modifier_arg, $.rescue_modifier)),
1214
+
1215
+ _ordinary_rhs_expression: ($) => prec(PREC.ASSIGN, $._arg_rhs),
889
1216
  _chained_lhs: ($) =>
890
1217
  choice(
891
1218
  alias($._chained_command_call, $.call),
@@ -912,10 +1239,10 @@ module.exports = grammar({
912
1239
  field(
913
1240
  'right',
914
1241
  choice(
915
- $._expression,
1242
+ alias($._command_value_expression, $._expression),
916
1243
  $.splat_argument,
917
1244
  $.right_assignment_list,
918
- alias($.rescue_modifier_expression, $.rescue_modifier)
1245
+ alias($._command_value_rescue, $.rescue_modifier)
919
1246
  )
920
1247
  )
921
1248
  )
@@ -927,7 +1254,42 @@ module.exports = grammar({
927
1254
  seq(
928
1255
  field('left', $._chained_lhs),
929
1256
  field('operator', assignmentOperator($)),
930
- field('right', choice($._expression, alias($.rescue_modifier_expression, $.rescue_modifier)))
1257
+ field(
1258
+ 'right',
1259
+ choice(alias($._command_value_expression, $._expression), alias($._command_value_rescue, $.rescue_modifier))
1260
+ )
1261
+ )
1262
+ ),
1263
+
1264
+ _pattern_assignment: ($) =>
1265
+ prec.right(
1266
+ PREC.ASSIGN,
1267
+ seq(field('left', $._lhs), '=', field('right', alias($._ordinary_rhs_expression, $._expression)))
1268
+ ),
1269
+
1270
+ _pattern_command_assignment: ($) =>
1271
+ prec.right(
1272
+ PREC.ASSIGN,
1273
+ seq(
1274
+ field('left', $._lhs),
1275
+ '=',
1276
+ field(
1277
+ 'right',
1278
+ choice(alias($._command_value_expression, $._expression), alias($._command_value_rescue, $.rescue_modifier))
1279
+ )
1280
+ )
1281
+ ),
1282
+
1283
+ _pattern_chained_assignment: ($) =>
1284
+ prec.right(
1285
+ PREC.ASSIGN,
1286
+ seq(
1287
+ field('left', $._chained_lhs),
1288
+ '=',
1289
+ field(
1290
+ 'right',
1291
+ choice(alias($._command_value_expression, $._expression), alias($._command_value_rescue, $.rescue_modifier))
1292
+ )
931
1293
  )
932
1294
  ),
933
1295
 
@@ -938,7 +1300,10 @@ module.exports = grammar({
938
1300
  seq(
939
1301
  field('left', choice($._lhs, $.left_assignment_list)),
940
1302
  '=',
941
- field('right', choice($._arg_rhs, $.splat_argument, $.right_assignment_list))
1303
+ field(
1304
+ 'right',
1305
+ choice(alias($._ordinary_rhs_expression, $._expression), $.splat_argument, $.right_assignment_list)
1306
+ )
942
1307
  )
943
1308
  )
944
1309
  ),
@@ -949,14 +1314,21 @@ module.exports = grammar({
949
1314
  seq(
950
1315
  field('left', choice($._lhs, $.left_assignment_list)),
951
1316
  '=',
952
- field('right', choice($._expression, alias($.rescue_modifier_expression, $.rescue_modifier)))
1317
+ field(
1318
+ 'right',
1319
+ choice(alias($._command_value_expression, $._expression), alias($._command_value_rescue, $.rescue_modifier))
1320
+ )
953
1321
  )
954
1322
  ),
955
1323
 
956
1324
  operator_assignment: ($) =>
957
1325
  prec.right(
958
1326
  PREC.ASSIGN,
959
- seq(field('left', $._lhs), field('operator', assignmentOperator($)), field('right', $._arg_rhs))
1327
+ seq(
1328
+ field('left', $._lhs),
1329
+ field('operator', assignmentOperator($)),
1330
+ field('right', alias($._ordinary_rhs_expression, $._expression))
1331
+ )
960
1332
  ),
961
1333
 
962
1334
  command_operator_assignment: ($) =>
@@ -965,7 +1337,10 @@ module.exports = grammar({
965
1337
  seq(
966
1338
  field('left', $._lhs),
967
1339
  field('operator', assignmentOperator($)),
968
- field('right', choice($._expression, alias($.rescue_modifier_expression, $.rescue_modifier)))
1340
+ field(
1341
+ 'right',
1342
+ choice(alias($._command_value_expression, $._expression), alias($._command_value_rescue, $.rescue_modifier))
1343
+ )
969
1344
  )
970
1345
  ),
971
1346
 
@@ -980,21 +1355,101 @@ module.exports = grammar({
980
1355
  _range_sign: ($) =>
981
1356
  prec.right(PREC.UNARY_MINUS, seq(field('operator', alias($._binary_minus, '-')), field('operand', $._arg))),
982
1357
 
983
- _chained_binary: ($) => binaryExpression($, $._chained_arg, alias($._binary_plus, '+')),
1358
+ _chained_binary: ($) => binaryExpression($, choice($._chained_arg, alias($.command_call_with_block, $.call))),
1359
+
1360
+ _chained_unary: ($) =>
1361
+ prec.right(
1362
+ PREC.COMPLEMENT,
1363
+ seq(field('operator', '!'), field('operand', choice($._chained_arg, alias($.command_call_with_block, $.call))))
1364
+ ),
1365
+
1366
+ _command_unary_arg: ($) =>
1367
+ choice(
1368
+ alias($._chained_unary, $.unary),
1369
+ alias($._command_unary_binary, $.binary),
1370
+ alias($._command_unary_conditional, $.conditional),
1371
+ alias($._command_unary_range, $.range)
1372
+ ),
1373
+
1374
+ _command_unary_binary: ($) => binaryExpression($, $._command_unary_arg),
1375
+
1376
+ _command_unary_conditional: ($) => conditionalExpression($, $._command_unary_arg),
1377
+
1378
+ _command_unary_range: ($) => rangeExpression($, $._command_unary_arg, false),
984
1379
 
985
1380
  binary: ($) => binaryExpression($, $._arg),
986
1381
 
1382
+ _pattern_command_binary: ($) =>
1383
+ prec.left(
1384
+ 1,
1385
+ seq(
1386
+ field('left', $._expression),
1387
+ field('operator', choice('or', 'and')),
1388
+ field('right', alias($.command_call, $.call))
1389
+ )
1390
+ ),
1391
+
987
1392
  command_binary: ($) =>
988
1393
  prec.left(
1394
+ 1,
989
1395
  seq(field('left', $._expression), field('operator', choice('or', 'and')), field('right', $._expression))
990
1396
  ),
991
1397
 
992
- unary: ($) => unaryExpression($._arg, choice(alias($._unary_minus, '-'), '+')),
1398
+ unary: ($) => unaryExpression($._arg, choice(alias($._unary_minus, '-'), '+'), choice($._arg, $.begin)),
1399
+
1400
+ command_unary: ($) =>
1401
+ prec.right(
1402
+ PREC.COMPLEMENT,
1403
+ seq(field('operator', '!'), field('operand', alias($._command_argument_expression, $._expression)))
1404
+ ),
1405
+
1406
+ _pattern_command_operand_expression: ($) => alias($.command_call, $.call),
993
1407
 
994
- command_unary: ($) => unaryExpression($._expression, choice(alias($._unary_minus, '-'), '+')),
1408
+ _pattern_command_not: ($) =>
1409
+ prec.right(
1410
+ PREC.NOT,
1411
+ seq(field('operator', 'not'), field('operand', alias($._pattern_command_operand_expression, $._expression)))
1412
+ ),
1413
+
1414
+ _command_not: ($) =>
1415
+ prec.right(
1416
+ PREC.NOT,
1417
+ seq(field('operator', 'not'), field('operand', alias($._command_not_operand_expression, $._expression)))
1418
+ ),
1419
+
1420
+ _ordinary_chained_assignment: ($) =>
1421
+ prec.right(
1422
+ PREC.ASSIGN,
1423
+ seq(field('left', $._chained_lhs), '=', field('right', alias($._ordinary_rhs_expression, $._expression)))
1424
+ ),
1425
+
1426
+ _ordinary_chained_operator_assignment: ($) =>
1427
+ prec.right(
1428
+ PREC.ASSIGN,
1429
+ seq(
1430
+ field('left', $._chained_lhs),
1431
+ field('operator', assignmentOperator($)),
1432
+ field('right', alias($._ordinary_rhs_expression, $._expression))
1433
+ )
1434
+ ),
1435
+
1436
+ _test_pattern_not: ($) =>
1437
+ prec.dynamic(
1438
+ 3,
1439
+ prec.right(
1440
+ PREC.NOT,
1441
+ seq(field('operator', 'not'), field('operand', alias($._test_pattern_not_operand_expression, $._expression)))
1442
+ )
1443
+ ),
995
1444
 
996
1445
  parenthesized_unary: ($) =>
997
- prec(PREC.CALL, seq(field('operator', choice('defined?', 'not')), field('operand', $.parenthesized_statements))),
1446
+ choice(
1447
+ prec(PREC.CALL, seq(field('operator', 'defined?'), field('operand', $.parenthesized_statements))),
1448
+ prec(
1449
+ PREC.CALL,
1450
+ seq(field('operator', alias($._not_parenthesized, 'not')), field('operand', $.parenthesized_statements))
1451
+ )
1452
+ ),
998
1453
 
999
1454
  unary_literal: ($) =>
1000
1455
  prec.right(
@@ -1019,22 +1474,9 @@ module.exports = grammar({
1019
1474
 
1020
1475
  _function_identifier: ($) => choice(alias($.identifier_suffix, $.identifier), alias($.constant_suffix, $.constant)),
1021
1476
  _function_identifier_call: ($) => prec.left(field('method', $._function_identifier)),
1022
- _lhs: ($) =>
1023
- prec.left(
1024
- choice(
1025
- $._variable,
1026
- $.self,
1027
- $._nonlocal_variable,
1028
- $.true,
1029
- $.false,
1030
- $.nil,
1031
- $.scope_resolution,
1032
- $.element_reference,
1033
- alias($._call, $.call)
1034
- )
1035
- ),
1477
+ _lhs: ($) => leftHandSide($, $.scope_resolution, $.element_reference, alias($._call, $.call)),
1036
1478
 
1037
- _variable: ($) => prec.right(choice($.super, $.identifier, $.constant)),
1479
+ _variable: ($) => prec.right(choice($.super, reserved('variables', $.identifier), $.constant)),
1038
1480
 
1039
1481
  operator: () =>
1040
1482
  choice(
@@ -1072,7 +1514,7 @@ module.exports = grammar({
1072
1514
 
1073
1515
  _method_name: ($) =>
1074
1516
  choice(
1075
- $.identifier,
1517
+ reserved('methodNames', $.identifier),
1076
1518
  $._function_identifier,
1077
1519
  $.constant,
1078
1520
  $.setter,
@@ -1089,19 +1531,7 @@ module.exports = grammar({
1089
1531
  undef: ($) => seq('undef', commaSep1($._method_name)),
1090
1532
  alias: ($) => seq('alias', field('name', $._method_name), field('alias', $._method_name)),
1091
1533
 
1092
- comment: ($) =>
1093
- choice(
1094
- $._line_comment,
1095
- token(
1096
- prec(
1097
- PREC.COMMENT,
1098
- choice(
1099
- seq('#', /.*/),
1100
- seq(/=begin.*\r?\n/, repeat(choice(/[^=]/, /=[^e]/, /=e[^n]/, /=en[^d]/)), /[\s*]*=end.*/)
1101
- )
1102
- )
1103
- )
1104
- ),
1534
+ comment: ($) => choice($._line_comment, $._block_comment, token(prec(PREC.COMMENT, seq('#', /.*/)))),
1105
1535
 
1106
1536
  integer: () => /0[bB][01](_?[01])*|0[oO]?[0-7](_?[0-7])*|(0[dD])?\d(_?\d)*|0[xX][0-9a-fA-F](_?[0-9a-fA-F])*/,
1107
1537
  _int_or_float: ($) => choice($.integer, $.float),
@@ -1182,33 +1612,36 @@ module.exports = grammar({
1182
1612
  )
1183
1613
  ),
1184
1614
 
1185
- array: ($) => seq('[', optional($._argument_list_with_trailing_comma), ']'),
1615
+ array: ($) => seq('[', optional(seq(commaSep1($._value_argument), optional(','))), ']'),
1186
1616
 
1187
1617
  hash: ($) => seq('{', optional(seq(commaSep1(choice($.pair, $.hash_splat_argument)), optional(','))), '}'),
1188
1618
 
1189
1619
  pair: ($) =>
1190
- prec.right(
1191
- choice(
1192
- seq(field('key', $._arg), '=>', field('value', $._arg)),
1193
- seq(field('key', choice($.string)), token.immediate(':'), field('value', $._arg)),
1194
- seq(
1195
- field(
1196
- 'key',
1620
+ prec.dynamic(
1621
+ 3,
1622
+ prec.right(
1623
+ choice(
1624
+ seq(field('key', $._arg), '=>', field('value', $._arg)),
1625
+ seq(field('key', choice($.string)), token.immediate(':'), field('value', $._arg)),
1626
+ seq(
1627
+ field(
1628
+ 'key',
1629
+ choice(
1630
+ $.hash_key_symbol,
1631
+ alias($.identifier, $.hash_key_symbol),
1632
+ alias($.constant, $.hash_key_symbol),
1633
+ alias($.identifier_suffix, $.hash_key_symbol),
1634
+ alias($.constant_suffix, $.hash_key_symbol)
1635
+ )
1636
+ ),
1637
+ token.immediate(':'),
1197
1638
  choice(
1198
- $.hash_key_symbol,
1199
- alias($.identifier, $.hash_key_symbol),
1200
- alias($.constant, $.hash_key_symbol),
1201
- alias($.identifier_suffix, $.hash_key_symbol),
1202
- alias($.constant_suffix, $.hash_key_symbol)
1639
+ field('value', optional($._arg)),
1640
+ // This alternative never matches, because '_no_line_break' tokens do not exist.
1641
+ // The purpose is give a hint to the scanner that it should not produce any line-break
1642
+ // terminators at this point.
1643
+ $._no_line_break
1203
1644
  )
1204
- ),
1205
- token.immediate(':'),
1206
- choice(
1207
- field('value', optional($._arg)),
1208
- // This alternative never matches, because '_no_line_break' tokens do not exist.
1209
- // The purpose is give a hint to the scanner that it should not produce any line-break
1210
- // terminators at this point.
1211
- $._no_line_break
1212
1645
  )
1213
1646
  )
1214
1647
  )
@@ -1226,7 +1659,7 @@ module.exports = grammar({
1226
1659
 
1227
1660
  empty_statement: () => prec(-1, ';'),
1228
1661
 
1229
- _terminator: ($) => choice($._line_break, ';'),
1662
+ _terminator: ($) => choice(prec.dynamic(1, $._line_break), ';'),
1230
1663
  },
1231
1664
  });
1232
1665
 
@@ -1302,11 +1735,22 @@ function assignmentOperator($) {
1302
1735
  /**
1303
1736
  * @param {RuleOrLiteral} operand
1304
1737
  * @param {RuleOrLiteral} sign
1738
+ * @param {RuleOrLiteral} [definedOperand]
1305
1739
  */
1306
- function unaryExpression(operand, sign) {
1740
+ function unaryExpression(operand, sign, definedOperand = operand) {
1307
1741
  return choice(
1308
- prec(PREC.DEFINED, seq(field('operator', 'defined?'), field('operand', operand))),
1742
+ prec(PREC.DEFINED, seq(field('operator', 'defined?'), field('operand', definedOperand))),
1309
1743
  prec.right(PREC.NOT, seq(field('operator', 'not'), field('operand', operand))),
1744
+ strongUnaryExpression(operand, sign)
1745
+ );
1746
+ }
1747
+
1748
+ /**
1749
+ * @param {RuleOrLiteral} operand
1750
+ * @param {RuleOrLiteral} sign
1751
+ */
1752
+ function strongUnaryExpression(operand, sign) {
1753
+ return choice(
1310
1754
  prec.right(PREC.UNARY_MINUS, seq(field('operator', sign), field('operand', operand))),
1311
1755
  prec.right(PREC.COMPLEMENT, seq(field('operator', choice('!', '~')), field('operand', operand)))
1312
1756
  );
@@ -1315,9 +1759,9 @@ function unaryExpression(operand, sign) {
1315
1759
  /**
1316
1760
  * @param {GrammarSymbols<string>} $
1317
1761
  * @param {RuleOrLiteral} left
1318
- * @param {RuleOrLiteral} plus
1762
+ * @param {RuleOrLiteral} right
1319
1763
  */
1320
- function binaryExpression($, left, plus = '+') {
1764
+ function binaryExpression($, left, right = $._arg) {
1321
1765
  // oxlint-disable typescript/unbound-method -- The DSL's `prec` functions do not use `this`.
1322
1766
  /** @type {[(precedence: number, rule: RuleOrLiteral) => Rule, number, RuleOrLiteral][]} */
1323
1767
  const operators = [
@@ -1329,7 +1773,7 @@ function binaryExpression($, left, plus = '+') {
1329
1773
  [prec.left, PREC.COMPARISON, choice('<', '<=', '>', '>=')],
1330
1774
  [prec.left, PREC.BITWISE_AND, alias($._bitwise_and, '&')],
1331
1775
  [prec.left, PREC.BITWISE_OR, choice('^', '|')],
1332
- [prec.left, PREC.ADDITIVE, choice(plus, alias($._binary_minus, '-'))],
1776
+ [prec.left, PREC.ADDITIVE, choice('+', alias($._binary_plus, '+'), alias($._binary_minus, '-'))],
1333
1777
  [prec.left, PREC.MULTIPLICATIVE, choice('/', '%', alias($._binary_star, '*'))],
1334
1778
  [prec.right, PREC.RELATIONAL, choice('==', '!=', '===', '<=>', '=~', '!~')],
1335
1779
  [prec.right, PREC.EXPONENTIAL, alias($._binary_star_star, '**')],
@@ -1338,7 +1782,7 @@ function binaryExpression($, left, plus = '+') {
1338
1782
 
1339
1783
  return choice(
1340
1784
  ...operators.map(([fn, precedence, operator]) =>
1341
- fn(precedence, seq(field('left', left), field('operator', operator), field('right', $._arg)))
1785
+ fn(precedence, seq(field('left', left), field('operator', operator), field('right', right)))
1342
1786
  )
1343
1787
  );
1344
1788
  }
@@ -1346,8 +1790,9 @@ function binaryExpression($, left, plus = '+') {
1346
1790
  /**
1347
1791
  * @param {GrammarSymbols<string>} $
1348
1792
  * @param {RuleOrLiteral} object
1793
+ * @param {boolean} allowDoBlock
1349
1794
  */
1350
- function elementReference($, object) {
1795
+ function elementReference($, object, allowDoBlock = true) {
1351
1796
  return prec.left(
1352
1797
  1,
1353
1798
  seq(
@@ -1355,7 +1800,7 @@ function elementReference($, object) {
1355
1800
  alias($._element_reference_bracket, '['),
1356
1801
  optional($._argument_list_with_trailing_comma),
1357
1802
  ']',
1358
- optional(field('block', choice($.block, $.do_block)))
1803
+ optional(field('block', allowDoBlock ? choice($.block, $.do_block) : $.block))
1359
1804
  )
1360
1805
  );
1361
1806
  }
@@ -1363,11 +1808,12 @@ function elementReference($, object) {
1363
1808
  /**
1364
1809
  * @param {GrammarSymbols<string>} $
1365
1810
  * @param {RuleOrLiteral} condition
1811
+ * @param {RuleOrLiteral} branch
1366
1812
  */
1367
- function conditionalExpression($, condition) {
1813
+ function conditionalExpression($, condition, branch = $._arg) {
1368
1814
  return prec.right(
1369
1815
  PREC.CONDITIONAL,
1370
- seq(field('condition', condition), '?', field('consequence', $._arg), ':', field('alternative', $._arg))
1816
+ seq(field('condition', condition), '?', field('consequence', branch), ':', field('alternative', branch))
1371
1817
  );
1372
1818
  }
1373
1819
 
@@ -1375,10 +1821,318 @@ function conditionalExpression($, condition) {
1375
1821
  * @param {GrammarSymbols<string>} $
1376
1822
  * @param {RuleOrLiteral} begin
1377
1823
  * @param {boolean} allowBeginless
1824
+ * @param {RuleOrLiteral} endValue
1378
1825
  */
1379
- function rangeExpression($, begin, allowBeginless) {
1380
- const end = field('end', choice($._arg, alias($._range_sign, $.unary)));
1826
+ function rangeExpression($, begin, allowBeginless, endValue = $._arg) {
1827
+ const end = field('end', choice(endValue, alias($._range_sign, $.unary)));
1381
1828
  const operator = field('operator', choice('..', '...'));
1382
1829
  const bounded = seq(field('begin', begin), operator, optional(end));
1383
1830
  return prec.right(PREC.RANGE, allowBeginless ? choice(bounded, seq(operator, end)) : bounded);
1384
1831
  }
1832
+
1833
+ /**
1834
+ * @param {GrammarSymbols<string>} $
1835
+ * @param {RuleOrLiteral} receiver
1836
+ * @param {RuleOrLiteral} argumentsRule
1837
+ */
1838
+ function commandCallWithBlock($, receiver, argumentsRule) {
1839
+ const args = field('arguments', alias(argumentsRule, $.argument_list));
1840
+ return choice(
1841
+ seq(receiver, prec(PREC.CURLY_BLOCK, seq(args, field('block', $.block)))),
1842
+ prec.dynamic(1, seq(receiver, prec(PREC.DO_BLOCK, seq(args, field('block', $.do_block)))))
1843
+ );
1844
+ }
1845
+
1846
+ /**
1847
+ * @param {GrammarSymbols<string>} $
1848
+ * @param {RuleOrLiteral} key
1849
+ * @param {boolean} allowBlockContinuation
1850
+ */
1851
+ function commandPair($, key, allowBlockContinuation = true) {
1852
+ const value = $._arg;
1853
+ return prec.dynamic(
1854
+ 1,
1855
+ choice(
1856
+ prec.right(PREC.PATTERN, seq(field('key', alias($._super_command, $.call)), '=>', field('value', value))),
1857
+ prec.right(
1858
+ seq(
1859
+ field(
1860
+ 'key',
1861
+ choice(
1862
+ alias(key, $.call),
1863
+ alias($._super_command_with_block, $.call),
1864
+ alias($._yield_pair_key, $.yield),
1865
+ alias(allowBlockContinuation ? $._pattern_command_not : $._yield_not, $.unary),
1866
+ alias($._chained_assignment, $.assignment),
1867
+ alias($._chained_operator_assignment, $.operator_assignment),
1868
+ ...(allowBlockContinuation ? [$._chained_arg] : [])
1869
+ )
1870
+ ),
1871
+ '=>',
1872
+ field('value', value)
1873
+ )
1874
+ )
1875
+ )
1876
+ );
1877
+ }
1878
+
1879
+ /**
1880
+ * @param {GrammarSymbols<string>} $
1881
+ * @param {RuleOrLiteral} expression
1882
+ * @param {RuleOrLiteral} commandPairRule
1883
+ */
1884
+ function argument($, expression, commandPairRule = $._command_pair) {
1885
+ return prec.left(
1886
+ choice(
1887
+ expression,
1888
+ $.splat_argument,
1889
+ $.hash_splat_argument,
1890
+ $.forward_argument,
1891
+ $.block_argument,
1892
+ $.pair,
1893
+ alias(commandPairRule, $.pair),
1894
+ alias($._command_definition_pair, $.pair)
1895
+ )
1896
+ );
1897
+ }
1898
+
1899
+ /**
1900
+ * @param {GrammarSymbols<string>} $
1901
+ * @param {RuleOrLiteral} rest
1902
+ */
1903
+ function singletonMethod($, rest) {
1904
+ return seq(
1905
+ 'def',
1906
+ seq(
1907
+ choice(
1908
+ field('object', choice($._variable, $.self, $._nonlocal_variable)),
1909
+ seq('(', field('object', $._arg), ')')
1910
+ ),
1911
+ choice('.', '::')
1912
+ ),
1913
+ rest
1914
+ );
1915
+ }
1916
+
1917
+ /**
1918
+ * @param {GrammarSymbols<string>} $
1919
+ * @param {RuleOrLiteral} body
1920
+ */
1921
+ function endlessMethodRest($, body) {
1922
+ return seq(
1923
+ field('name', $._method_name),
1924
+ optional(field('parameters', alias($.parameters, $.method_parameters))),
1925
+ '=',
1926
+ field('body', body)
1927
+ );
1928
+ }
1929
+
1930
+ /**
1931
+ * @param {GrammarSymbols<string>} $
1932
+ * @param {RuleOrLiteral} value
1933
+ * @param {RuleOrLiteral} rescue
1934
+ */
1935
+ function endlessBody($, value, rescue) {
1936
+ return choice(value, alias(rescue, $.rescue_modifier));
1937
+ }
1938
+
1939
+ /**
1940
+ * @param {GrammarSymbols<string>} $
1941
+ * @param {RuleOrLiteral} value
1942
+ */
1943
+ function endlessBodyRescue($, value) {
1944
+ return prec(PREC.RESCUE, seq(field('body', value), 'rescue', field('handler', $._arg)));
1945
+ }
1946
+
1947
+ /**
1948
+ * @param {GrammarSymbols<string>} $
1949
+ * @param {boolean} allowCall
1950
+ */
1951
+ function yieldPairKeyArguments($, allowCall) {
1952
+ return prec.right(
1953
+ 1,
1954
+ seq(
1955
+ repeat(seq($._yield_argument, ',')),
1956
+ choice(
1957
+ $.pair,
1958
+ $.splat_argument,
1959
+ $.hash_splat_argument,
1960
+ alias($._yield_command_pair, $.pair),
1961
+ alias($._command_definition_pair, $.pair),
1962
+ ...(allowCall ? [alias($._yield_call_pair_key, $.call)] : [])
1963
+ )
1964
+ )
1965
+ );
1966
+ }
1967
+
1968
+ /**
1969
+ * @param {GrammarSymbols<string>} $
1970
+ * @param {RuleOrLiteral} lhs
1971
+ * @param {RuleOrLiteral} call
1972
+ * @param {RuleOrLiteral} method
1973
+ * @param {RuleOrLiteral} singletonMethod
1974
+ */
1975
+ function primaryExpression($, lhs, call, method, singletonMethod) {
1976
+ return choice(
1977
+ prec(1, $.super),
1978
+ $.parenthesized_statements,
1979
+ lhs,
1980
+ alias($._function_identifier_call, $.call),
1981
+ call,
1982
+ $.array,
1983
+ $.string_array,
1984
+ $.symbol_array,
1985
+ $.hash,
1986
+ $.subshell,
1987
+ $._literal,
1988
+ $.string,
1989
+ $.character,
1990
+ $.chained_string,
1991
+ $.regex,
1992
+ $.lambda,
1993
+ method,
1994
+ singletonMethod,
1995
+ $.class,
1996
+ $.singleton_class,
1997
+ $.module,
1998
+ $.begin,
1999
+ $.while,
2000
+ $.until,
2001
+ $.if,
2002
+ $.unless,
2003
+ $.for,
2004
+ $.case,
2005
+ $.case_match,
2006
+ $.return,
2007
+ $.yield,
2008
+ $.break,
2009
+ $.next,
2010
+ $.redo,
2011
+ $.retry,
2012
+ alias($.parenthesized_unary, $.unary),
2013
+ $.heredoc_beginning
2014
+ );
2015
+ }
2016
+
2017
+ /**
2018
+ * @param {GrammarSymbols<string>} $
2019
+ * @param {RuleOrLiteral} scopeResolution
2020
+ * @param {RuleOrLiteral} elementReference
2021
+ * @param {RuleOrLiteral} member
2022
+ */
2023
+ function leftHandSide($, scopeResolution, elementReference, member) {
2024
+ return prec.left(
2025
+ choice($._variable, $.self, $._nonlocal_variable, $.true, $.false, $.nil, scopeResolution, elementReference, member)
2026
+ );
2027
+ }
2028
+
2029
+ /**
2030
+ * @param {GrammarSymbols<string>} $
2031
+ * @param {RuleOrLiteral} primary
2032
+ * @param {RuleOrLiteral} member
2033
+ * @param {boolean} allowDoBlock
2034
+ */
2035
+ function callExpression($, primary, member, allowDoBlock = true) {
2036
+ const receiver = choice(member, field('method', choice($._variable, $._function_identifier, $.super)));
2037
+
2038
+ const args = field('arguments', $.argument_list);
2039
+ const receiverArguments = seq(
2040
+ choice(receiver, prec.left(PREC.CALL, seq(field('receiver', primary), field('operator', $._call_operator)))),
2041
+ args
2042
+ );
2043
+
2044
+ const block = field('block', $.block);
2045
+ const doBlock = field('block', $.do_block);
2046
+ return choice(
2047
+ receiverArguments,
2048
+ prec(PREC.CURLY_BLOCK, seq(receiverArguments, block)),
2049
+ ...(allowDoBlock ? [prec(PREC.DO_BLOCK, seq(receiverArguments, doBlock))] : []),
2050
+ prec(PREC.CURLY_BLOCK, seq(receiver, block)),
2051
+ ...(allowDoBlock ? [prec(PREC.DO_BLOCK, seq(receiver, doBlock))] : [])
2052
+ );
2053
+ }
2054
+
2055
+ /**
2056
+ * @param {GrammarSymbols<string>} $
2057
+ * @param {RuleOrLiteral} bodyExpression
2058
+ */
2059
+ function methodRest($, bodyExpression) {
2060
+ return seq(
2061
+ field('name', $._method_name),
2062
+ choice(
2063
+ bodyExpression,
2064
+ seq(
2065
+ field('parameters', alias($.parameters, $.method_parameters)),
2066
+ choice(seq(optional($._terminator), optional(field('body', $.body_statement)), 'end'), bodyExpression)
2067
+ ),
2068
+ seq(
2069
+ optional(field('parameters', alias($.bare_parameters, $.method_parameters))),
2070
+ $._terminator,
2071
+ optional(field('body', $.body_statement)),
2072
+ 'end'
2073
+ )
2074
+ )
2075
+ );
2076
+ }
2077
+
2078
+ /**
2079
+ * @param {GrammarSymbols<string>} $
2080
+ * @param {boolean} allowAssignment
2081
+ */
2082
+ function commandValue($, allowAssignment) {
2083
+ return choice(
2084
+ prec(0, alias($._command_not, $.unary)),
2085
+ prec(0, alias($._test_pattern_not, $.unary)),
2086
+ alias($._command_method, $.method),
2087
+ alias($._command_singleton_method, $.singleton_method),
2088
+ ...(allowAssignment
2089
+ ? [alias($.command_assignment, $.assignment), alias($.command_operator_assignment, $.operator_assignment)]
2090
+ : []),
2091
+ alias($.command_call, $.call),
2092
+ alias($.command_call_with_block, $.call),
2093
+ $._chained_arg,
2094
+ ...(allowAssignment
2095
+ ? [alias($._chained_assignment, $.assignment), alias($._chained_operator_assignment, $.operator_assignment)]
2096
+ : []),
2097
+ alias($.return_command, $.return),
2098
+ alias($.yield_command, $.yield),
2099
+ alias($.break_command, $.break),
2100
+ alias($.next_command, $.next),
2101
+ $._arg
2102
+ );
2103
+ }
2104
+
2105
+ /** @param {GrammarSymbols<string>} $ */
2106
+ function chainedTestPattern($, allowModifiers = true) {
2107
+ return prec.dynamic(
2108
+ 1,
2109
+ seq(
2110
+ field(
2111
+ 'value',
2112
+ choice(
2113
+ $._chained_arg,
2114
+ alias($._pattern_command_assignment, $.assignment),
2115
+ alias($._pattern_chained_assignment, $.assignment),
2116
+ alias($._chained_operator_assignment, $.operator_assignment),
2117
+ alias($.command_operator_assignment, $.operator_assignment),
2118
+ alias($.command_call_with_block, $.call),
2119
+ alias($._chained_command, $.call),
2120
+ alias($._command_method, $.method),
2121
+ alias($._command_singleton_method, $.singleton_method),
2122
+ alias($._receiver_command, $.call),
2123
+ alias($._pattern_command_binary, $.binary),
2124
+ alias($.command_unary, $.unary),
2125
+ $._command_unary_arg,
2126
+ alias($._command_not, $.unary),
2127
+ alias($.yield_command, $.yield),
2128
+ alias($._super_command, $.call),
2129
+ ...(allowModifiers
2130
+ ? [$.if_modifier, $.unless_modifier, $.while_modifier, $.until_modifier, $.rescue_modifier]
2131
+ : [])
2132
+ )
2133
+ ),
2134
+ 'in',
2135
+ field('pattern', $._pattern_top_expr_body)
2136
+ )
2137
+ );
2138
+ }