@willbooster/tree-sitter-ruby 2.0.4 → 2.0.6

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/README.md CHANGED
@@ -5,14 +5,14 @@
5
5
  [![Test](https://github.com/WillBooster/tree-sitter-ruby/actions/workflows/test.yml/badge.svg)](https://github.com/WillBooster/tree-sitter-ruby/actions/workflows/test.yml)
6
6
  [![Test rust](https://github.com/WillBooster/tree-sitter-ruby/actions/workflows/test-rust.yml/badge.svg)](https://github.com/WillBooster/tree-sitter-ruby/actions/workflows/test-rust.yml)
7
7
  [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
8
- [![wbfy](https://img.shields.io/badge/wbfy-20.36.11-1e90ff.svg)](https://github.com/WillBooster/shared/tree/main/packages/wbfy)
8
+ [![wbfy](https://img.shields.io/badge/wbfy-20.41.8-1e90ff.svg)](https://github.com/WillBooster/shared/tree/main/packages/wbfy)
9
9
  [![crates.io](https://img.shields.io/crates/v/willbooster-tree-sitter-ruby.svg)](https://crates.io/crates/willbooster-tree-sitter-ruby)
10
10
 
11
11
  Ruby grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter), forked from
12
12
  [tree-sitter/tree-sitter-ruby](https://github.com/tree-sitter/tree-sitter-ruby). We are grateful
13
13
  to its authors and contributors. This is not an official release of that project.
14
14
 
15
- This fork extends the upstream grammar to parse anonymous block forwarding and spaced block arguments, with a parser generated by
15
+ This fork extends the upstream grammar to parse anonymous block forwarding, spaced block arguments, and command calls in endless methods, with a parser generated by
16
16
  [WillBooster/tree-sitter](https://github.com/WillBooster/tree-sitter), whose compact parse tables make the
17
17
  parser smaller. The parser carries that fork's own ABI number (`0x57420001`), so it loads only with the WillBooster
18
18
  runtime; upstream's tree-sitter runtime rejects it. Use runtime 2.0.18 or later so contiguous included ranges do not terminate comments.
package/grammar.js CHANGED
@@ -65,6 +65,8 @@ module.exports = grammar({
65
65
  '/',
66
66
  $._block_ampersand,
67
67
  $._splat_star,
68
+ $._unary_plus,
69
+ $._binary_plus,
68
70
  $._unary_minus,
69
71
  $._unary_minus_num,
70
72
  $._binary_minus,
@@ -86,6 +88,11 @@ module.exports = grammar({
86
88
 
87
89
  word: ($) => $.identifier,
88
90
 
91
+ conflicts: ($) => [
92
+ [$._chained_primary, $._chained_lhs],
93
+ [$._array_pattern_n, $.as_pattern, $._find_pattern_body],
94
+ ],
95
+
89
96
  supertypes: ($) => [
90
97
  $._statement,
91
98
  $._arg,
@@ -139,7 +146,13 @@ module.exports = grammar({
139
146
  singleton_method: ($) =>
140
147
  seq(
141
148
  'def',
142
- seq(choice(field('object', $._variable), seq('(', field('object', $._arg), ')')), choice('.', '::')),
149
+ seq(
150
+ choice(
151
+ field('object', choice($._variable, $.self, $._nonlocal_variable)),
152
+ seq('(', field('object', $._arg), ')')
153
+ ),
154
+ choice('.', '::')
155
+ ),
143
156
  $._method_rest
144
157
  ),
145
158
 
@@ -168,6 +181,52 @@ module.exports = grammar({
168
181
 
169
182
  _body_expr: ($) => seq('=', field('body', choice($._arg, alias($.rescue_modifier_arg, $.rescue_modifier)))),
170
183
 
184
+ _command_method: ($) => seq('def', $._command_method_rest),
185
+
186
+ _command_singleton_method: ($) =>
187
+ seq(
188
+ 'def',
189
+ seq(
190
+ choice(
191
+ field('object', choice($._variable, $.self, $._nonlocal_variable)),
192
+ seq('(', field('object', $._arg), ')')
193
+ ),
194
+ choice('.', '::')
195
+ ),
196
+ $._command_method_rest
197
+ ),
198
+
199
+ _command_method_rest: ($) =>
200
+ seq(
201
+ field('name', $._method_name),
202
+ optional(field('parameters', alias($.parameters, $.method_parameters))),
203
+ '=',
204
+ field('body', $._endless_command)
205
+ ),
206
+
207
+ // Ruby 4.0's default parser (Prism) lets an endless body hold at most one `rescue`, applied outside any `not`; a
208
+ // further `rescue` applies to the whole definition.
209
+ _endless_command: ($) => choice($._endless_command_operand, alias($._endless_command_rescue, $.rescue_modifier)),
210
+
211
+ _endless_command_operand: ($) =>
212
+ choice(
213
+ alias($.command_call, $.call),
214
+ alias($.command_call_with_block, $.call),
215
+ $._chained_arg,
216
+ alias($._chained_assignment, $.assignment),
217
+ alias($._chained_operator_assignment, $.operator_assignment),
218
+ alias($.return_command, $.return),
219
+ alias($.yield_command, $.yield),
220
+ alias($._endless_command_not, $.unary),
221
+ alias($._command_method, $.method),
222
+ alias($._command_singleton_method, $.singleton_method)
223
+ ),
224
+
225
+ _endless_command_not: ($) => prec.right(PREC.NOT, seq(field('operator', 'not'), field('operand', $._expression))),
226
+
227
+ _endless_command_rescue: ($) =>
228
+ prec(PREC.RESCUE, seq(field('body', $._endless_command_operand), 'rescue', field('handler', $._arg))),
229
+
171
230
  parameters: ($) => seq('(', commaSep($._formal_parameter), ')'),
172
231
 
173
232
  bare_parameters: ($) => seq($._simple_formal_parameter, repeat(seq(',', $._formal_parameter))),
@@ -537,22 +596,62 @@ module.exports = grammar({
537
596
  // This naming convention is based on Ruby's standard grammar.
538
597
  _expression: ($) =>
539
598
  choice(
599
+ alias($._command_method, $.method),
600
+ alias($._command_singleton_method, $.singleton_method),
540
601
  alias($.command_binary, $.binary),
541
602
  alias($.command_unary, $.unary),
542
603
  alias($.command_assignment, $.assignment),
543
604
  alias($.command_operator_assignment, $.operator_assignment),
544
605
  alias($.command_call, $.call),
545
606
  alias($.command_call_with_block, $.call),
546
- prec.left(alias($._chained_command_call, $.call)),
607
+ $._chained_arg,
608
+ alias($._chained_assignment, $.assignment),
609
+ alias($._chained_operator_assignment, $.operator_assignment),
547
610
  alias($.return_command, $.return),
548
611
  alias($.yield_command, $.yield),
549
612
  alias($.break_command, $.break),
550
613
  alias($.next_command, $.next),
614
+ alias($._chained_match_pattern, $.match_pattern),
615
+ alias($._chained_test_pattern, $.test_pattern),
551
616
  $.match_pattern,
552
617
  $.test_pattern,
553
618
  $._arg
554
619
  ),
555
620
 
621
+ _chained_match_pattern: ($) =>
622
+ prec(
623
+ 100,
624
+ seq(
625
+ field(
626
+ 'value',
627
+ choice(
628
+ $._chained_arg,
629
+ alias($._command_method, $.method),
630
+ alias($._command_singleton_method, $.singleton_method)
631
+ )
632
+ ),
633
+ '=>',
634
+ field('pattern', $._pattern_top_expr_body)
635
+ )
636
+ ),
637
+ _chained_test_pattern: ($) =>
638
+ prec(
639
+ 100,
640
+ seq(
641
+ field(
642
+ 'value',
643
+ choice(
644
+ $._chained_arg,
645
+ alias($._chained_command, $.call),
646
+ alias($._command_method, $.method),
647
+ alias($._command_singleton_method, $.singleton_method)
648
+ )
649
+ ),
650
+ 'in',
651
+ field('pattern', $._pattern_top_expr_body)
652
+ )
653
+ ),
654
+
556
655
  match_pattern: ($) => prec(100, seq(field('value', $._arg), '=>', field('pattern', $._pattern_top_expr_body))),
557
656
 
558
657
  test_pattern: ($) => prec(100, seq(field('value', $._arg), 'in', field('pattern', $._pattern_top_expr_body))),
@@ -623,17 +722,7 @@ module.exports = grammar({
623
722
 
624
723
  parenthesized_statements: ($) => seq('(', optional($._statements), ')'),
625
724
 
626
- element_reference: ($) =>
627
- prec.left(
628
- 1,
629
- seq(
630
- field('object', $._primary),
631
- alias($._element_reference_bracket, '['),
632
- optional($._argument_list_with_trailing_comma),
633
- ']',
634
- optional(field('block', choice($.block, $.do_block)))
635
- )
636
- ),
725
+ element_reference: ($) => elementReference($, $._primary),
637
726
 
638
727
  scope_resolution: ($) =>
639
728
  prec.left(
@@ -653,29 +742,75 @@ module.exports = grammar({
653
742
  ),
654
743
 
655
744
  command_call: ($) =>
656
- seq(
657
- choice($._call, $._chained_command_call, field('method', choice($._variable, $._function_identifier))),
658
- field('arguments', alias($.command_argument_list, $.argument_list))
745
+ choice(
746
+ seq(
747
+ choice($._call, field('method', choice($._variable, $._function_identifier))),
748
+ field('arguments', alias($.command_argument_list, $.argument_list))
749
+ ),
750
+ $._chained_command
659
751
  ),
660
752
 
753
+ _chained_command: ($) =>
754
+ seq($._chained_command_call, field('arguments', alias($._chained_command_argument_list, $.argument_list))),
755
+
661
756
  command_call_with_block: ($) => {
662
757
  const receiver = choice($._call, field('method', choice($._variable, $._function_identifier)));
663
758
  const args = field('arguments', alias($.command_argument_list, $.argument_list));
759
+ const chainedArgs = field('arguments', alias($._chained_command_argument_list, $.argument_list));
664
760
  const block = field('block', $.block);
665
761
  const doBlock = field('block', $.do_block);
666
762
  return choice(
667
763
  seq(receiver, prec(PREC.CURLY_BLOCK, seq(args, block))),
668
- seq(receiver, prec(PREC.DO_BLOCK, seq(args, doBlock)))
764
+ seq(receiver, prec(PREC.DO_BLOCK, seq(args, doBlock))),
765
+ seq($._chained_command_call, prec(PREC.CURLY_BLOCK, seq(chainedArgs, block))),
766
+ seq($._chained_command_call, prec(PREC.DO_BLOCK, seq(chainedArgs, doBlock)))
669
767
  );
670
768
  },
671
769
 
770
+ _chained_arg: ($) =>
771
+ choice(
772
+ $._chained_primary,
773
+ alias($._chained_binary, $.binary),
774
+ alias($._chained_conditional, $.conditional),
775
+ alias($._chained_range, $.range)
776
+ ),
777
+
778
+ _chained_primary: ($) =>
779
+ choice(
780
+ prec.left(alias($._chained_command_call, $.call)),
781
+ alias($._chained_call, $.call),
782
+ alias($._chained_element_reference, $.element_reference),
783
+ alias($._chained_scope_resolution, $.scope_resolution)
784
+ ),
785
+
672
786
  _chained_command_call: ($) =>
673
787
  seq(
674
- field('receiver', alias($.command_call_with_block, $.call)),
788
+ field('receiver', choice(alias($.command_call_with_block, $.call), $._chained_primary)),
675
789
  field('operator', $._call_operator),
676
790
  field('method', choice($.identifier, $._function_identifier, $.operator, $.constant))
677
791
  ),
678
792
 
793
+ _chained_scope_resolution: ($) =>
794
+ prec.left(
795
+ PREC.CALL + 1,
796
+ seq(field('scope', $._chained_primary), token.immediate('::'), field('name', $.constant))
797
+ ),
798
+
799
+ _chained_element_reference: ($) => elementReference($, $._chained_primary),
800
+
801
+ _chained_call: ($) => {
802
+ const receiver = $._chained_command_call;
803
+ const receiverArguments = seq(
804
+ choice(receiver, seq(field('receiver', $._chained_primary), field('operator', $._call_operator))),
805
+ field('arguments', $.argument_list)
806
+ );
807
+ return choice(
808
+ receiverArguments,
809
+ prec(PREC.CURLY_BLOCK, seq(choice(receiver, receiverArguments), field('block', $.block))),
810
+ prec(PREC.DO_BLOCK, seq(choice(receiver, receiverArguments), field('block', $.do_block)))
811
+ );
812
+ },
813
+
679
814
  call: ($) => {
680
815
  const receiver = choice($._call, field('method', choice($._variable, $._function_identifier)));
681
816
 
@@ -696,6 +831,28 @@ module.exports = grammar({
696
831
  );
697
832
  },
698
833
 
834
+ _chained_command_argument_list: ($) =>
835
+ prec.right(
836
+ choice(
837
+ commaSep1($._argument),
838
+ seq(choice($._chained_plus_arg, alias($._chained_plus_pair, $.pair)), repeat(seq(',', $._argument)))
839
+ )
840
+ ),
841
+
842
+ _chained_plus_arg: ($) =>
843
+ choice(
844
+ alias($._chained_plus_argument, $.unary),
845
+ alias($._chained_plus_binary, $.binary),
846
+ alias($._chained_plus_conditional, $.conditional),
847
+ alias($._chained_plus_range, $.range)
848
+ ),
849
+ _chained_plus_binary: ($) => binaryExpression($, $._chained_plus_arg),
850
+ _chained_plus_conditional: ($) => conditionalExpression($, $._chained_plus_arg),
851
+ _chained_plus_range: ($) => rangeExpression($, $._chained_plus_arg, false),
852
+ _chained_plus_pair: ($) => prec.right(seq(field('key', $._chained_plus_arg), '=>', field('value', $._arg))),
853
+ _chained_plus_argument: ($) =>
854
+ prec.right(PREC.COMPLEMENT, seq(field('operator', alias($._unary_plus, '+')), field('operand', $._arg))),
855
+
699
856
  command_argument_list: ($) => prec.right(commaSep1($._argument)),
700
857
 
701
858
  argument_list: ($) => prec.right(seq(token.immediate('('), optional($._argument_list_with_trailing_comma), ')')),
@@ -728,6 +885,51 @@ module.exports = grammar({
728
885
  ),
729
886
 
730
887
  _arg_rhs: ($) => choice($._arg, alias($.rescue_modifier_arg, $.rescue_modifier)),
888
+ _chained_lhs: ($) =>
889
+ choice(
890
+ alias($._chained_command_call, $.call),
891
+ alias($._chained_element_reference, $.element_reference),
892
+ alias($._chained_scope_resolution, $.scope_resolution)
893
+ ),
894
+
895
+ _chained_left_assignment_list: ($) =>
896
+ prec.left(
897
+ -1,
898
+ seq(
899
+ $._chained_lhs,
900
+ ',',
901
+ optional(seq(commaSep1(choice($._lhs, $.rest_assignment, $.destructured_left_assignment)), optional(',')))
902
+ )
903
+ ),
904
+
905
+ _chained_assignment: ($) =>
906
+ prec.right(
907
+ PREC.ASSIGN,
908
+ seq(
909
+ field('left', choice($._chained_lhs, alias($._chained_left_assignment_list, $.left_assignment_list))),
910
+ '=',
911
+ field(
912
+ 'right',
913
+ choice(
914
+ $._expression,
915
+ $.splat_argument,
916
+ $.right_assignment_list,
917
+ alias($.rescue_modifier_expression, $.rescue_modifier)
918
+ )
919
+ )
920
+ )
921
+ ),
922
+
923
+ _chained_operator_assignment: ($) =>
924
+ prec.right(
925
+ PREC.ASSIGN,
926
+ seq(
927
+ field('left', $._chained_lhs),
928
+ field('operator', choice('+=', '-=', '*=', '**=', '/=', '||=', '|=', '&&=', '&=', '%=', '>>=', '<<=', '^=')),
929
+ field('right', choice($._expression, alias($.rescue_modifier_expression, $.rescue_modifier)))
930
+ )
931
+ ),
932
+
731
933
  assignment: ($) =>
732
934
  prec.right(
733
935
  PREC.ASSIGN,
@@ -770,83 +972,29 @@ module.exports = grammar({
770
972
  )
771
973
  ),
772
974
 
773
- conditional: ($) =>
774
- prec.right(
775
- PREC.CONDITIONAL,
776
- seq(field('condition', $._arg), '?', field('consequence', $._arg), ':', field('alternative', $._arg))
777
- ),
975
+ conditional: ($) => conditionalExpression($, $._arg),
778
976
 
779
- range: ($) => {
780
- const begin = field('begin', $._arg);
781
- const end = field('end', $._arg);
782
- const operator = field('operator', choice('..', '...'));
783
- return prec.right(PREC.RANGE, choice(seq(begin, operator, end), seq(operator, end), seq(begin, operator)));
784
- },
977
+ _chained_conditional: ($) => conditionalExpression($, $._chained_arg),
785
978
 
786
- binary: ($) => {
787
- // oxlint-disable typescript/unbound-method -- The DSL's `prec` functions do not use `this`.
788
- /** @type {[(precedence: number, rule: RuleOrLiteral) => Rule, number, RuleOrLiteral][]} */
789
- const operators = [
790
- [prec.left, PREC.AND, 'and'],
791
- [prec.left, PREC.OR, 'or'],
792
- [prec.left, PREC.BOOLEAN_OR, '||'],
793
- [prec.left, PREC.BOOLEAN_AND, '&&'],
794
- [prec.left, PREC.SHIFT, choice('<<', '>>')],
795
- [prec.left, PREC.COMPARISON, choice('<', '<=', '>', '>=')],
796
- [prec.left, PREC.BITWISE_AND, alias($._bitwise_and, '&')],
797
- [prec.left, PREC.BITWISE_OR, choice('^', '|')],
798
- [prec.left, PREC.ADDITIVE, choice('+', alias($._binary_minus, '-'))],
799
- [prec.left, PREC.MULTIPLICATIVE, choice('/', '%', alias($._binary_star, '*'))],
800
- [prec.right, PREC.RELATIONAL, choice('==', '!=', '===', '<=>', '=~', '!~')],
801
- [prec.right, PREC.EXPONENTIAL, alias($._binary_star_star, '**')],
802
- ];
803
- // oxlint-enable typescript/unbound-method
979
+ range: ($) => rangeExpression($, $._arg, true),
804
980
 
805
- return choice(
806
- ...operators.map(([fn, precedence, operator]) =>
807
- fn(precedence, seq(field('left', $._arg), field('operator', operator), field('right', $._arg)))
808
- )
809
- );
810
- },
981
+ _chained_range: ($) => rangeExpression($, $._chained_arg, false),
982
+
983
+ _range_sign: ($) =>
984
+ prec.right(PREC.UNARY_MINUS, seq(field('operator', alias($._binary_minus, '-')), field('operand', $._arg))),
985
+
986
+ _chained_binary: ($) => binaryExpression($, $._chained_arg, alias($._binary_plus, '+')),
987
+
988
+ binary: ($) => binaryExpression($, $._arg),
811
989
 
812
990
  command_binary: ($) =>
813
991
  prec.left(
814
992
  seq(field('left', $._expression), field('operator', choice('or', 'and')), field('right', $._expression))
815
993
  ),
816
994
 
817
- unary: ($) => {
818
- // oxlint-disable typescript/unbound-method -- The DSL's `prec` functions do not use `this`.
819
- /** @type {[(precedence: number, rule: RuleOrLiteral) => Rule, number, RuleOrLiteral][]} */
820
- const operators = [
821
- [prec, PREC.DEFINED, 'defined?'],
822
- [prec.right, PREC.NOT, 'not'],
823
- [prec.right, PREC.UNARY_MINUS, choice(alias($._unary_minus, '-'), alias($._binary_minus, '-'), '+')],
824
- [prec.right, PREC.COMPLEMENT, choice('!', '~')],
825
- ];
826
- // oxlint-enable typescript/unbound-method
827
- return choice(
828
- ...operators.map(([fn, precedence, operator]) =>
829
- fn(precedence, seq(field('operator', operator), field('operand', $._arg)))
830
- )
831
- );
832
- },
995
+ unary: ($) => unaryExpression($._arg, choice(alias($._unary_minus, '-'), '+')),
833
996
 
834
- command_unary: ($) => {
835
- // oxlint-disable typescript/unbound-method -- The DSL's `prec` functions do not use `this`.
836
- /** @type {[(precedence: number, rule: RuleOrLiteral) => Rule, number, RuleOrLiteral][]} */
837
- const operators = [
838
- [prec, PREC.DEFINED, 'defined?'],
839
- [prec.right, PREC.NOT, 'not'],
840
- [prec.right, PREC.UNARY_MINUS, choice(alias($._unary_minus, '-'), '+')],
841
- [prec.right, PREC.COMPLEMENT, choice('!', '~')],
842
- ];
843
- // oxlint-enable typescript/unbound-method
844
- return choice(
845
- ...operators.map(([fn, precedence, operator]) =>
846
- fn(precedence, seq(field('operator', operator), field('operand', $._expression)))
847
- )
848
- );
849
- },
997
+ command_unary: ($) => unaryExpression($._expression, choice(alias($._unary_minus, '-'), '+')),
850
998
 
851
999
  parenthesized_unary: ($) =>
852
1000
  prec(PREC.CALL, seq(field('operator', choice('defined?', 'not')), field('operand', $.parenthesized_statements))),
@@ -876,10 +1024,20 @@ module.exports = grammar({
876
1024
  _function_identifier_call: ($) => prec.left(field('method', $._function_identifier)),
877
1025
  _lhs: ($) =>
878
1026
  prec.left(
879
- choice($._variable, $.true, $.false, $.nil, $.scope_resolution, $.element_reference, alias($._call, $.call))
1027
+ choice(
1028
+ $._variable,
1029
+ $.self,
1030
+ $._nonlocal_variable,
1031
+ $.true,
1032
+ $.false,
1033
+ $.nil,
1034
+ $.scope_resolution,
1035
+ $.element_reference,
1036
+ alias($._call, $.call)
1037
+ )
880
1038
  ),
881
1039
 
882
- _variable: ($) => prec.right(choice($.self, $.super, $._nonlocal_variable, $.identifier, $.constant)),
1040
+ _variable: ($) => prec.right(choice($.super, $.identifier, $.constant)),
883
1041
 
884
1042
  operator: () =>
885
1043
  choice(
@@ -1122,3 +1280,87 @@ function commaSep1(rule) {
1122
1280
  function commaSep(rule) {
1123
1281
  return optional(commaSep1(rule));
1124
1282
  }
1283
+
1284
+ /**
1285
+ * @param {RuleOrLiteral} operand
1286
+ * @param {RuleOrLiteral} sign
1287
+ */
1288
+ function unaryExpression(operand, sign) {
1289
+ return choice(
1290
+ prec(PREC.DEFINED, seq(field('operator', 'defined?'), field('operand', operand))),
1291
+ prec.right(PREC.NOT, seq(field('operator', 'not'), field('operand', operand))),
1292
+ prec.right(PREC.UNARY_MINUS, seq(field('operator', sign), field('operand', operand))),
1293
+ prec.right(PREC.COMPLEMENT, seq(field('operator', choice('!', '~')), field('operand', operand)))
1294
+ );
1295
+ }
1296
+
1297
+ /**
1298
+ * @param {GrammarSymbols<string>} $
1299
+ * @param {RuleOrLiteral} left
1300
+ * @param {RuleOrLiteral} plus
1301
+ */
1302
+ function binaryExpression($, left, plus = '+') {
1303
+ // oxlint-disable typescript/unbound-method -- The DSL's `prec` functions do not use `this`.
1304
+ /** @type {[(precedence: number, rule: RuleOrLiteral) => Rule, number, RuleOrLiteral][]} */
1305
+ const operators = [
1306
+ [prec.left, PREC.AND, 'and'],
1307
+ [prec.left, PREC.OR, 'or'],
1308
+ [prec.left, PREC.BOOLEAN_OR, '||'],
1309
+ [prec.left, PREC.BOOLEAN_AND, '&&'],
1310
+ [prec.left, PREC.SHIFT, choice('<<', '>>')],
1311
+ [prec.left, PREC.COMPARISON, choice('<', '<=', '>', '>=')],
1312
+ [prec.left, PREC.BITWISE_AND, alias($._bitwise_and, '&')],
1313
+ [prec.left, PREC.BITWISE_OR, choice('^', '|')],
1314
+ [prec.left, PREC.ADDITIVE, choice(plus, alias($._binary_minus, '-'))],
1315
+ [prec.left, PREC.MULTIPLICATIVE, choice('/', '%', alias($._binary_star, '*'))],
1316
+ [prec.right, PREC.RELATIONAL, choice('==', '!=', '===', '<=>', '=~', '!~')],
1317
+ [prec.right, PREC.EXPONENTIAL, alias($._binary_star_star, '**')],
1318
+ ];
1319
+ // oxlint-enable typescript/unbound-method
1320
+
1321
+ return choice(
1322
+ ...operators.map(([fn, precedence, operator]) =>
1323
+ fn(precedence, seq(field('left', left), field('operator', operator), field('right', $._arg)))
1324
+ )
1325
+ );
1326
+ }
1327
+
1328
+ /**
1329
+ * @param {GrammarSymbols<string>} $
1330
+ * @param {RuleOrLiteral} object
1331
+ */
1332
+ function elementReference($, object) {
1333
+ return prec.left(
1334
+ 1,
1335
+ seq(
1336
+ field('object', object),
1337
+ alias($._element_reference_bracket, '['),
1338
+ optional($._argument_list_with_trailing_comma),
1339
+ ']',
1340
+ optional(field('block', choice($.block, $.do_block)))
1341
+ )
1342
+ );
1343
+ }
1344
+
1345
+ /**
1346
+ * @param {GrammarSymbols<string>} $
1347
+ * @param {RuleOrLiteral} condition
1348
+ */
1349
+ function conditionalExpression($, condition) {
1350
+ return prec.right(
1351
+ PREC.CONDITIONAL,
1352
+ seq(field('condition', condition), '?', field('consequence', $._arg), ':', field('alternative', $._arg))
1353
+ );
1354
+ }
1355
+
1356
+ /**
1357
+ * @param {GrammarSymbols<string>} $
1358
+ * @param {RuleOrLiteral} begin
1359
+ * @param {boolean} allowBeginless
1360
+ */
1361
+ function rangeExpression($, begin, allowBeginless) {
1362
+ const end = field('end', choice($._arg, alias($._range_sign, $.unary)));
1363
+ const operator = field('operator', choice('..', '...'));
1364
+ const bounded = seq(field('begin', begin), operator, optional(end));
1365
+ return prec.right(PREC.RANGE, allowBeginless ? choice(bounded, seq(operator, end)) : bounded);
1366
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willbooster/tree-sitter-ruby",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "Ruby grammar for tree-sitter",
5
5
  "keywords": [
6
6
  "incremental",
@@ -47,7 +47,7 @@
47
47
  "@willbooster/oxfmt-config": "1.2.2",
48
48
  "@willbooster/oxlint-config": "1.4.8",
49
49
  "@willbooster/wb": "22.26.1",
50
- "@willbooster/web-tree-sitter": "2.0.24",
50
+ "@willbooster/web-tree-sitter": "2.0.27",
51
51
  "conventional-changelog-conventionalcommits": "10.4.1",
52
52
  "lefthook": "2.2.1",
53
53
  "oxfmt": "0.72.0",
@@ -57,7 +57,6 @@
57
57
  "semantic-release": "25.0.9",
58
58
  "sort-package-json": "4.0.0",
59
59
  "tree-sitter-cli": "0.27.1",
60
- "typescript": "7.0.2",
61
60
  "vite": "8.3.4",
62
61
  "vitest": "5.0.3",
63
62
  "wrangler": "4.149.0"
@@ -57,10 +57,22 @@
57
57
  "type": "call",
58
58
  "named": true
59
59
  },
60
+ {
61
+ "type": "conditional",
62
+ "named": true
63
+ },
64
+ {
65
+ "type": "element_reference",
66
+ "named": true
67
+ },
60
68
  {
61
69
  "type": "match_pattern",
62
70
  "named": true
63
71
  },
72
+ {
73
+ "type": "method",
74
+ "named": true
75
+ },
64
76
  {
65
77
  "type": "next",
66
78
  "named": true
@@ -69,10 +81,22 @@
69
81
  "type": "operator_assignment",
70
82
  "named": true
71
83
  },
84
+ {
85
+ "type": "range",
86
+ "named": true
87
+ },
72
88
  {
73
89
  "type": "return",
74
90
  "named": true
75
91
  },
92
+ {
93
+ "type": "scope_resolution",
94
+ "named": true
95
+ },
96
+ {
97
+ "type": "singleton_method",
98
+ "named": true
99
+ },
76
100
  {
77
101
  "type": "test_pattern",
78
102
  "named": true
@@ -91,6 +115,10 @@
91
115
  "type": "_lhs",
92
116
  "named": true,
93
117
  "subtypes": [
118
+ {
119
+ "type": "_nonlocal_variable",
120
+ "named": true
121
+ },
94
122
  {
95
123
  "type": "_variable",
96
124
  "named": true
@@ -115,6 +143,10 @@
115
143
  "type": "scope_resolution",
116
144
  "named": true
117
145
  },
146
+ {
147
+ "type": "self",
148
+ "named": true
149
+ },
118
150
  {
119
151
  "type": "true",
120
152
  "named": true
@@ -577,10 +609,6 @@
577
609
  "type": "_variable",
578
610
  "named": true,
579
611
  "subtypes": [
580
- {
581
- "type": "_nonlocal_variable",
582
- "named": true
583
- },
584
612
  {
585
613
  "type": "constant",
586
614
  "named": true
@@ -589,10 +617,6 @@
589
617
  "type": "identifier",
590
618
  "named": true
591
619
  },
592
- {
593
- "type": "self",
594
- "named": true
595
- },
596
620
  {
597
621
  "type": "super",
598
622
  "named": true
@@ -1288,6 +1312,14 @@
1288
1312
  {
1289
1313
  "type": "_primary",
1290
1314
  "named": true
1315
+ },
1316
+ {
1317
+ "type": "element_reference",
1318
+ "named": true
1319
+ },
1320
+ {
1321
+ "type": "scope_resolution",
1322
+ "named": true
1291
1323
  }
1292
1324
  ]
1293
1325
  }
@@ -1464,6 +1496,18 @@
1464
1496
  {
1465
1497
  "type": "_arg",
1466
1498
  "named": true
1499
+ },
1500
+ {
1501
+ "type": "call",
1502
+ "named": true
1503
+ },
1504
+ {
1505
+ "type": "element_reference",
1506
+ "named": true
1507
+ },
1508
+ {
1509
+ "type": "scope_resolution",
1510
+ "named": true
1467
1511
  }
1468
1512
  ]
1469
1513
  },
@@ -1647,6 +1691,14 @@
1647
1691
  {
1648
1692
  "type": "_primary",
1649
1693
  "named": true
1694
+ },
1695
+ {
1696
+ "type": "element_reference",
1697
+ "named": true
1698
+ },
1699
+ {
1700
+ "type": "scope_resolution",
1701
+ "named": true
1650
1702
  }
1651
1703
  ]
1652
1704
  }
@@ -2378,6 +2430,26 @@
2378
2430
  {
2379
2431
  "type": "_arg",
2380
2432
  "named": true
2433
+ },
2434
+ {
2435
+ "type": "call",
2436
+ "named": true
2437
+ },
2438
+ {
2439
+ "type": "element_reference",
2440
+ "named": true
2441
+ },
2442
+ {
2443
+ "type": "method",
2444
+ "named": true
2445
+ },
2446
+ {
2447
+ "type": "scope_resolution",
2448
+ "named": true
2449
+ },
2450
+ {
2451
+ "type": "singleton_method",
2452
+ "named": true
2381
2453
  }
2382
2454
  ]
2383
2455
  }
@@ -2399,9 +2471,37 @@
2399
2471
  "type": "body_statement",
2400
2472
  "named": true
2401
2473
  },
2474
+ {
2475
+ "type": "call",
2476
+ "named": true
2477
+ },
2478
+ {
2479
+ "type": "element_reference",
2480
+ "named": true
2481
+ },
2482
+ {
2483
+ "type": "method",
2484
+ "named": true
2485
+ },
2402
2486
  {
2403
2487
  "type": "rescue_modifier",
2404
2488
  "named": true
2489
+ },
2490
+ {
2491
+ "type": "return",
2492
+ "named": true
2493
+ },
2494
+ {
2495
+ "type": "scope_resolution",
2496
+ "named": true
2497
+ },
2498
+ {
2499
+ "type": "singleton_method",
2500
+ "named": true
2501
+ },
2502
+ {
2503
+ "type": "yield",
2504
+ "named": true
2405
2505
  }
2406
2506
  ]
2407
2507
  },
@@ -2769,6 +2869,18 @@
2769
2869
  {
2770
2870
  "type": "_pattern_primitive",
2771
2871
  "named": true
2872
+ },
2873
+ {
2874
+ "type": "call",
2875
+ "named": true
2876
+ },
2877
+ {
2878
+ "type": "element_reference",
2879
+ "named": true
2880
+ },
2881
+ {
2882
+ "type": "scope_resolution",
2883
+ "named": true
2772
2884
  }
2773
2885
  ]
2774
2886
  },
@@ -3010,6 +3122,10 @@
3010
3122
  {
3011
3123
  "type": "_primary",
3012
3124
  "named": true
3125
+ },
3126
+ {
3127
+ "type": "element_reference",
3128
+ "named": true
3013
3129
  }
3014
3130
  ]
3015
3131
  }
@@ -3073,9 +3189,37 @@
3073
3189
  "type": "body_statement",
3074
3190
  "named": true
3075
3191
  },
3192
+ {
3193
+ "type": "call",
3194
+ "named": true
3195
+ },
3196
+ {
3197
+ "type": "element_reference",
3198
+ "named": true
3199
+ },
3200
+ {
3201
+ "type": "method",
3202
+ "named": true
3203
+ },
3076
3204
  {
3077
3205
  "type": "rescue_modifier",
3078
3206
  "named": true
3207
+ },
3208
+ {
3209
+ "type": "return",
3210
+ "named": true
3211
+ },
3212
+ {
3213
+ "type": "scope_resolution",
3214
+ "named": true
3215
+ },
3216
+ {
3217
+ "type": "singleton_method",
3218
+ "named": true
3219
+ },
3220
+ {
3221
+ "type": "yield",
3222
+ "named": true
3079
3223
  }
3080
3224
  ]
3081
3225
  },
@@ -3097,9 +3241,17 @@
3097
3241
  "type": "_arg",
3098
3242
  "named": true
3099
3243
  },
3244
+ {
3245
+ "type": "_nonlocal_variable",
3246
+ "named": true
3247
+ },
3100
3248
  {
3101
3249
  "type": "_variable",
3102
3250
  "named": true
3251
+ },
3252
+ {
3253
+ "type": "self",
3254
+ "named": true
3103
3255
  }
3104
3256
  ]
3105
3257
  },
@@ -3258,6 +3410,26 @@
3258
3410
  {
3259
3411
  "type": "_arg",
3260
3412
  "named": true
3413
+ },
3414
+ {
3415
+ "type": "call",
3416
+ "named": true
3417
+ },
3418
+ {
3419
+ "type": "element_reference",
3420
+ "named": true
3421
+ },
3422
+ {
3423
+ "type": "method",
3424
+ "named": true
3425
+ },
3426
+ {
3427
+ "type": "scope_resolution",
3428
+ "named": true
3429
+ },
3430
+ {
3431
+ "type": "singleton_method",
3432
+ "named": true
3261
3433
  }
3262
3434
  ]
3263
3435
  }
Binary file
package/tree-sitter.json CHANGED
@@ -19,7 +19,7 @@
19
19
  }
20
20
  ],
21
21
  "metadata": {
22
- "version": "2.0.4",
22
+ "version": "2.0.6",
23
23
  "license": "MIT",
24
24
  "description": "Ruby grammar for tree-sitter",
25
25
  "authors": [