@willbooster/tree-sitter-ruby 2.0.8 → 2.0.9

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