parser 2.7.1.3 → 3.0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/lib/parser.rb +1 -1
  3. data/lib/parser/all.rb +1 -1
  4. data/lib/parser/ast/processor.rb +5 -7
  5. data/lib/parser/base.rb +7 -5
  6. data/lib/parser/builders/default.rb +225 -29
  7. data/lib/parser/context.rb +5 -0
  8. data/lib/parser/current.rb +11 -11
  9. data/lib/parser/current_arg_stack.rb +5 -2
  10. data/lib/parser/lexer.rb +23780 -0
  11. data/lib/parser/macruby.rb +6149 -0
  12. data/lib/parser/max_numparam_stack.rb +13 -5
  13. data/lib/parser/messages.rb +3 -0
  14. data/lib/parser/meta.rb +8 -7
  15. data/lib/parser/ruby18.rb +5667 -0
  16. data/lib/parser/ruby19.rb +6092 -0
  17. data/lib/parser/ruby20.rb +6527 -0
  18. data/lib/parser/ruby21.rb +6578 -0
  19. data/lib/parser/ruby22.rb +6613 -0
  20. data/lib/parser/ruby23.rb +6624 -0
  21. data/lib/parser/ruby24.rb +6694 -0
  22. data/lib/parser/ruby25.rb +6662 -0
  23. data/lib/parser/ruby26.rb +6676 -0
  24. data/lib/parser/ruby27.rb +7862 -0
  25. data/lib/parser/ruby28.rb +8047 -0
  26. data/lib/parser/ruby30.rb +8060 -0
  27. data/lib/parser/rubymotion.rb +6086 -0
  28. data/lib/parser/runner.rb +4 -4
  29. data/lib/parser/source/buffer.rb +50 -27
  30. data/lib/parser/source/comment.rb +1 -1
  31. data/lib/parser/source/comment/associator.rb +1 -1
  32. data/lib/parser/source/map/{endless_definition.rb → method_definition.rb} +5 -3
  33. data/lib/parser/source/range.rb +3 -3
  34. data/lib/parser/source/tree_rewriter.rb +94 -1
  35. data/lib/parser/source/tree_rewriter/action.rb +39 -0
  36. data/lib/parser/static_environment.rb +4 -0
  37. data/lib/parser/variables_stack.rb +4 -0
  38. data/lib/parser/version.rb +1 -1
  39. data/parser.gemspec +2 -18
  40. metadata +13 -102
  41. data/.gitignore +0 -34
  42. data/.travis.yml +0 -40
  43. data/.yardopts +0 -21
  44. data/CHANGELOG.md +0 -1101
  45. data/CONTRIBUTING.md +0 -17
  46. data/Gemfile +0 -10
  47. data/README.md +0 -308
  48. data/Rakefile +0 -167
  49. data/ci/run_rubocop_specs +0 -14
  50. data/doc/AST_FORMAT.md +0 -2229
  51. data/doc/CUSTOMIZATION.md +0 -37
  52. data/doc/INTERNALS.md +0 -21
  53. data/doc/css/.gitkeep +0 -0
  54. data/doc/css/common.css +0 -68
  55. data/lib/parser/lexer.rl +0 -2543
  56. data/lib/parser/macruby.y +0 -2198
  57. data/lib/parser/ruby18.y +0 -1934
  58. data/lib/parser/ruby19.y +0 -2175
  59. data/lib/parser/ruby20.y +0 -2353
  60. data/lib/parser/ruby21.y +0 -2357
  61. data/lib/parser/ruby22.y +0 -2364
  62. data/lib/parser/ruby23.y +0 -2370
  63. data/lib/parser/ruby24.y +0 -2408
  64. data/lib/parser/ruby25.y +0 -2405
  65. data/lib/parser/ruby26.y +0 -2413
  66. data/lib/parser/ruby27.y +0 -2941
  67. data/lib/parser/ruby28.y +0 -3016
  68. data/lib/parser/rubymotion.y +0 -2182
  69. data/test/bug_163/fixtures/input.rb +0 -5
  70. data/test/bug_163/fixtures/output.rb +0 -5
  71. data/test/bug_163/rewriter.rb +0 -20
  72. data/test/helper.rb +0 -79
  73. data/test/parse_helper.rb +0 -313
  74. data/test/racc_coverage_helper.rb +0 -133
  75. data/test/test_ast_processor.rb +0 -32
  76. data/test/test_base.rb +0 -31
  77. data/test/test_current.rb +0 -31
  78. data/test/test_diagnostic.rb +0 -95
  79. data/test/test_diagnostic_engine.rb +0 -59
  80. data/test/test_encoding.rb +0 -99
  81. data/test/test_lexer.rb +0 -3617
  82. data/test/test_lexer_stack_state.rb +0 -78
  83. data/test/test_meta.rb +0 -12
  84. data/test/test_parse_helper.rb +0 -80
  85. data/test/test_parser.rb +0 -9596
  86. data/test/test_runner_parse.rb +0 -56
  87. data/test/test_runner_rewrite.rb +0 -47
  88. data/test/test_source_buffer.rb +0 -165
  89. data/test/test_source_comment.rb +0 -36
  90. data/test/test_source_comment_associator.rb +0 -399
  91. data/test/test_source_map.rb +0 -14
  92. data/test/test_source_range.rb +0 -192
  93. data/test/test_source_rewriter.rb +0 -541
  94. data/test/test_source_rewriter_action.rb +0 -46
  95. data/test/test_source_tree_rewriter.rb +0 -263
  96. data/test/test_static_environment.rb +0 -45
  97. data/test/using_tree_rewriter/fixtures/input.rb +0 -3
  98. data/test/using_tree_rewriter/fixtures/output.rb +0 -3
  99. data/test/using_tree_rewriter/using_tree_rewriter.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bab855c4abc633b9ba13f855d816f20948ee539f27bea7878b574f4d0b3232f7
4
- data.tar.gz: 929aa201a2c06738c6202c8efb2afd2dda77e630805738007c39f3b8274fa717
3
+ metadata.gz: dced4877039fb67469d83e8d10c513c2ca05cc09878b487e60a29a9795bef7f1
4
+ data.tar.gz: c7827038c9b8acfe02c7878e3f74c46184106ff1939a8fa8f0eb2d60c7560cc4
5
5
  SHA512:
6
- metadata.gz: 78e2e37d1ef61d2c125c1462ecb2e48ab8f76a06fd97bcba28ea4acd5fa60f77a296f859fd6ad67a787027b7a9e62d0fc34bedc8c23522bce21213d1ca49d780
7
- data.tar.gz: 07fa5ad8fe63b8503ced8fa0143062385f1d2f99e542f80cc32375269a9ad75f07cc2b0e00838232a71a9e797ba5cab28b661d8a58765f558e29353462641f06
6
+ metadata.gz: 6c1bc36f5b08e5ccb99d6dc7774a7e7041709b14d0ddecaa2aa63cacabd9e1be39ce28fbceb9c9c90512cd79d19e20d163386621694a9265fcdf6085c82aaf5e
7
+ data.tar.gz: 4c3f661941751ea6f66b2e1089fd5d53125e12b0c4819d7e80123143d1798736ba5169cc09b4f3be1dff50c56d8a609355c751c20b1236a3d7288c6d9fee9875
data/lib/parser.rb CHANGED
@@ -46,7 +46,7 @@ module Parser
46
46
  require 'parser/source/map/variable'
47
47
  require 'parser/source/map/keyword'
48
48
  require 'parser/source/map/definition'
49
- require 'parser/source/map/endless_definition'
49
+ require 'parser/source/map/method_definition'
50
50
  require 'parser/source/map/send'
51
51
  require 'parser/source/map/index'
52
52
  require 'parser/source/map/condition'
data/lib/parser/all.rb CHANGED
@@ -10,4 +10,4 @@ require 'parser/ruby24'
10
10
  require 'parser/ruby25'
11
11
  require 'parser/ruby26'
12
12
  require 'parser/ruby27'
13
- require 'parser/ruby28'
13
+ require 'parser/ruby30'
@@ -20,6 +20,7 @@ module Parser
20
20
  alias on_array process_regular_node
21
21
  alias on_pair process_regular_node
22
22
  alias on_hash process_regular_node
23
+ alias on_kwargs process_regular_node
23
24
  alias on_irange process_regular_node
24
25
  alias on_erange process_regular_node
25
26
 
@@ -75,9 +76,6 @@ module Parser
75
76
  alias on_mlhs process_regular_node
76
77
  alias on_masgn process_regular_node
77
78
 
78
- alias on_rasgn process_regular_node
79
- alias on_mrasgn process_regular_node
80
-
81
79
  def on_const(node)
82
80
  scope_node, name = *node
83
81
 
@@ -127,6 +125,7 @@ module Parser
127
125
  alias on_kwarg process_argument_node
128
126
  alias on_kwoptarg process_argument_node
129
127
  alias on_kwrestarg process_argument_node
128
+ alias on_forward_arg process_argument_node
130
129
 
131
130
  def on_procarg0(node)
132
131
  if node.children[0].is_a?(Symbol)
@@ -162,8 +161,6 @@ module Parser
162
161
  ])
163
162
  end
164
163
 
165
- alias on_def_e on_def
166
-
167
164
  def on_defs(node)
168
165
  definee_node, name, args_node, body_node = *node
169
166
 
@@ -173,8 +170,6 @@ module Parser
173
170
  ])
174
171
  end
175
172
 
176
- alias on_defs_e on_defs
177
-
178
173
  alias on_undef process_regular_node
179
174
  alias on_alias process_regular_node
180
175
 
@@ -245,6 +240,8 @@ module Parser
245
240
 
246
241
  alias on_case_match process_regular_node
247
242
  alias on_in_match process_regular_node
243
+ alias on_match_pattern process_regular_node
244
+ alias on_match_pattern_p process_regular_node
248
245
  alias on_in_pattern process_regular_node
249
246
  alias on_if_guard process_regular_node
250
247
  alias on_unless_guard process_regular_node
@@ -257,6 +254,7 @@ module Parser
257
254
  alias on_array_pattern_with_tail process_regular_node
258
255
  alias on_hash_pattern process_regular_node
259
256
  alias on_const_pattern process_regular_node
257
+ alias on_find_pattern process_regular_node
260
258
 
261
259
  # @private
262
260
  def process_variable_node(node)
data/lib/parser/base.rb CHANGED
@@ -109,6 +109,7 @@ module Parser
109
109
  end
110
110
  private_class_method :setup_source_buffer
111
111
 
112
+ attr_reader :lexer
112
113
  attr_reader :diagnostics
113
114
  attr_reader :builder
114
115
  attr_reader :static_env
@@ -177,16 +178,16 @@ module Parser
177
178
  end
178
179
 
179
180
  ##
180
- # Parses a source buffer and returns the AST.
181
+ # Parses a source buffer and returns the AST, or `nil` in case of a non fatal error.
181
182
  #
182
183
  # @param [Parser::Source::Buffer] source_buffer The source buffer to parse.
183
- # @return [Parser::AST::Node]
184
+ # @return [Parser::AST::Node, nil]
184
185
  #
185
186
  def parse(source_buffer)
186
187
  @lexer.source_buffer = source_buffer
187
188
  @source_buffer = source_buffer
188
189
 
189
- do_parse
190
+ do_parse || nil # Force `false` to `nil`, see https://github.com/ruby/racc/pull/136
190
191
  ensure
191
192
  # Don't keep references to the source file.
192
193
  @source_buffer = nil
@@ -210,8 +211,9 @@ module Parser
210
211
 
211
212
  ##
212
213
  # Parses a source buffer and returns the AST, the source code comments,
213
- # and the tokens emitted by the lexer. If `recover` is true and a fatal
214
- # {SyntaxError} is encountered, `nil` is returned instead of the AST, and
214
+ # and the tokens emitted by the lexer. In case of a fatal error, a {SyntaxError}
215
+ # is raised, unless `recover` is true. In case of an error
216
+ # (non-fatal or recovered), `nil` is returned instead of the AST, and
215
217
  # comments as well as tokens are only returned up to the location of
216
218
  # the error.
217
219
  #
@@ -80,6 +80,8 @@ module Parser
80
80
  attr_accessor :emit_index
81
81
  end
82
82
 
83
+ @emit_index = false
84
+
83
85
  class << self
84
86
  ##
85
87
  # AST compatibility attribute; causes a single non-mlhs
@@ -95,7 +97,113 @@ module Parser
95
97
  attr_accessor :emit_arg_inside_procarg0
96
98
  end
97
99
 
98
- @emit_index = false
100
+ @emit_arg_inside_procarg0 = false
101
+
102
+ class << self
103
+ ##
104
+ # AST compatibility attribute; arguments forwarding initially
105
+ # didn't have support for leading arguments
106
+ # (i.e. `def m(a, ...); end` was a syntax error). However, Ruby 3.0
107
+ # added support for any number of arguments in front of the `...`.
108
+ #
109
+ # If set to false (the default):
110
+ # 1. `def m(...) end` is emitted as
111
+ # s(:def, :m, s(:forward_args), nil)
112
+ # 2. `def m(a, b, ...) end` is emitted as
113
+ # s(:def, :m,
114
+ # s(:args, s(:arg, :a), s(:arg, :b), s(:forward_arg)))
115
+ #
116
+ # If set to true it uses a single format:
117
+ # 1. `def m(...) end` is emitted as
118
+ # s(:def, :m, s(:args, s(:forward_arg)))
119
+ # 2. `def m(a, b, ...) end` is emitted as
120
+ # s(:def, :m, s(:args, s(:arg, :a), s(:arg, :b), s(:forward_arg)))
121
+ #
122
+ # It does't matter that much on 2.7 (because there can't be any leading arguments),
123
+ # but on 3.0 it should be better enabled to use a single AST format.
124
+ #
125
+ # @return [Boolean]
126
+ attr_accessor :emit_forward_arg
127
+ end
128
+
129
+ @emit_forward_arg = false
130
+
131
+ class << self
132
+ ##
133
+ # AST compatibility attribute; Starting from Ruby 2.7 keyword arguments
134
+ # of method calls that are passed explicitly as a hash (i.e. with curly braces)
135
+ # are treated as positional arguments and Ruby 2.7 emits a warning on such method
136
+ # call. Ruby 3.0 given an ArgumentError.
137
+ #
138
+ # If set to false (the default) the last hash argument is emitted as `hash`:
139
+ #
140
+ # ```
141
+ # (send nil :foo
142
+ # (hash
143
+ # (pair
144
+ # (sym :bar)
145
+ # (int 42))))
146
+ # ```
147
+ #
148
+ # If set to true it is emitted as `kwargs`:
149
+ #
150
+ # ```
151
+ # (send nil :foo
152
+ # (kwargs
153
+ # (pair
154
+ # (sym :bar)
155
+ # (int 42))))
156
+ # ```
157
+ #
158
+ # Note that `kwargs` node is just a replacement for `hash` argument,
159
+ # so if there's are multiple arguments (or a `kwsplat`) all of them
160
+ # are wrapped into `kwargs` instead of `hash`:
161
+ #
162
+ # ```
163
+ # (send nil :foo
164
+ # (hash
165
+ # (pair
166
+ # (sym :a)
167
+ # (int 42))
168
+ # (kwsplat
169
+ # (send nil :b))
170
+ # (pair
171
+ # (sym :c)
172
+ # (int 10))))
173
+ # ```
174
+ attr_accessor :emit_kwargs
175
+ end
176
+
177
+ @emit_kwargs = false
178
+
179
+ class << self
180
+ ##
181
+ # AST compatibility attribute; Starting from 3.0 Ruby returns
182
+ # true/false from single-line pattern matching with `in` keyword.
183
+ #
184
+ # Before 3.0 there was an exception if given value doesn't match pattern.
185
+ #
186
+ # NOTE: This attribute affects only Ruby 2.7 grammar.
187
+ # 3.0 grammar always emits `match_pattern`/`match_pattern_p`
188
+ #
189
+ # If compatibility attribute set to false `foo in bar` is emitted as `in_match`:
190
+ #
191
+ # ```
192
+ # (in-match
193
+ # (send nil :foo)
194
+ # (match-var :bar))
195
+ # ```
196
+ #
197
+ # If set to true it's emitted as `match_pattern_p`:
198
+ # ```
199
+ # (match-pattern-p
200
+ # (send nil :foo)
201
+ # (match-var :bar))
202
+ # ```
203
+ attr_accessor :emit_match_pattern
204
+ end
205
+
206
+ @emit_match_pattern = false
99
207
 
100
208
  class << self
101
209
  ##
@@ -106,6 +214,9 @@ module Parser
106
214
  @emit_encoding = true
107
215
  @emit_index = true
108
216
  @emit_arg_inside_procarg0 = true
217
+ @emit_forward_arg = true
218
+ @emit_kwargs = true
219
+ @emit_match_pattern = true
109
220
  end
110
221
  end
111
222
 
@@ -278,18 +389,23 @@ module Parser
278
389
  if !dedent_level.nil?
279
390
  dedenter = Lexer::Dedenter.new(dedent_level)
280
391
 
281
- if node.type == :str
392
+ case node.type
393
+ when :str
282
394
  str = node.children.first
283
395
  dedenter.dedent(str)
284
- elsif node.type == :dstr || node.type == :xstr
285
- node.children.each do |str_node|
396
+ when :dstr, :xstr
397
+ children = node.children.map do |str_node|
286
398
  if str_node.type == :str
287
399
  str = str_node.children.first
288
400
  dedenter.dedent(str)
401
+ next nil if str.empty?
289
402
  else
290
403
  dedenter.interrupt
291
404
  end
405
+ str_node
292
406
  end
407
+
408
+ node = node.updated(nil, children.compact)
293
409
  end
294
410
  end
295
411
 
@@ -557,7 +673,11 @@ module Parser
557
673
  when :ident
558
674
  name, = *node
559
675
 
560
- check_assignment_to_numparam(node)
676
+ var_name = node.children[0].to_s
677
+ name_loc = node.loc.expression
678
+
679
+ check_assignment_to_numparam(var_name, name_loc)
680
+ check_reserved_for_numparam(var_name, name_loc)
561
681
 
562
682
  @parser.static_env.declare(name)
563
683
 
@@ -619,15 +739,6 @@ module Parser
619
739
  binary_op_map(lhs, eql_t, rhs))
620
740
  end
621
741
 
622
- def rassign(lhs, assoc_t, rhs)
623
- n(:rasgn, [lhs, rhs], binary_op_map(lhs, assoc_t, rhs))
624
- end
625
-
626
- def multi_rassign(lhs, assoc_t, rhs)
627
- n(:mrasgn, [ lhs, rhs ],
628
- binary_op_map(lhs, assoc_t, rhs))
629
- end
630
-
631
742
  #
632
743
  # Class and module definition
633
744
  #
@@ -657,20 +768,25 @@ module Parser
657
768
 
658
769
  def def_method(def_t, name_t, args,
659
770
  body, end_t)
771
+ check_reserved_for_numparam(value(name_t), loc(name_t))
772
+
660
773
  n(:def, [ value(name_t).to_sym, args, body ],
661
774
  definition_map(def_t, nil, name_t, end_t))
662
775
  end
663
776
 
664
777
  def def_endless_method(def_t, name_t, args,
665
778
  assignment_t, body)
666
- n(:def_e, [ value(name_t).to_sym, args, body ],
779
+ check_reserved_for_numparam(value(name_t), loc(name_t))
780
+
781
+ n(:def, [ value(name_t).to_sym, args, body ],
667
782
  endless_definition_map(def_t, nil, name_t, assignment_t, body))
668
783
  end
669
784
 
670
785
  def def_singleton(def_t, definee, dot_t,
671
786
  name_t, args,
672
787
  body, end_t)
673
- return unless validate_definee(definee)
788
+ validate_definee(definee)
789
+ check_reserved_for_numparam(value(name_t), loc(name_t))
674
790
 
675
791
  n(:defs, [ definee, value(name_t).to_sym, args, body ],
676
792
  definition_map(def_t, dot_t, name_t, end_t))
@@ -679,9 +795,10 @@ module Parser
679
795
  def def_endless_singleton(def_t, definee, dot_t,
680
796
  name_t, args,
681
797
  assignment_t, body)
682
- return unless validate_definee(definee)
798
+ validate_definee(definee)
799
+ check_reserved_for_numparam(value(name_t), loc(name_t))
683
800
 
684
- n(:defs_e, [ definee, value(name_t).to_sym, args, body ],
801
+ n(:defs, [ definee, value(name_t).to_sym, args, body ],
685
802
  endless_definition_map(def_t, dot_t, name_t, assignment_t, body))
686
803
  end
687
804
 
@@ -709,16 +826,30 @@ module Parser
709
826
  n(:numargs, [ max_numparam ], nil)
710
827
  end
711
828
 
712
- def forward_args(begin_t, dots_t, end_t)
713
- n(:forward_args, [], collection_map(begin_t, token_map(dots_t), end_t))
829
+ def forward_only_args(begin_t, dots_t, end_t)
830
+ if self.class.emit_forward_arg
831
+ arg = forward_arg(dots_t)
832
+ n(:args, [ arg ],
833
+ collection_map(begin_t, [ arg ], end_t))
834
+ else
835
+ n(:forward_args, [], collection_map(begin_t, token_map(dots_t), end_t))
836
+ end
837
+ end
838
+
839
+ def forward_arg(dots_t)
840
+ n(:forward_arg, [], token_map(dots_t))
714
841
  end
715
842
 
716
843
  def arg(name_t)
844
+ check_reserved_for_numparam(value(name_t), loc(name_t))
845
+
717
846
  n(:arg, [ value(name_t).to_sym ],
718
847
  variable_map(name_t))
719
848
  end
720
849
 
721
850
  def optarg(name_t, eql_t, value)
851
+ check_reserved_for_numparam(value(name_t), loc(name_t))
852
+
722
853
  n(:optarg, [ value(name_t).to_sym, value ],
723
854
  variable_map(name_t).
724
855
  with_operator(loc(eql_t)).
@@ -727,6 +858,7 @@ module Parser
727
858
 
728
859
  def restarg(star_t, name_t=nil)
729
860
  if name_t
861
+ check_reserved_for_numparam(value(name_t), loc(name_t))
730
862
  n(:restarg, [ value(name_t).to_sym ],
731
863
  arg_prefix_map(star_t, name_t))
732
864
  else
@@ -736,17 +868,23 @@ module Parser
736
868
  end
737
869
 
738
870
  def kwarg(name_t)
871
+ check_reserved_for_numparam(value(name_t), loc(name_t))
872
+
739
873
  n(:kwarg, [ value(name_t).to_sym ],
740
874
  kwarg_map(name_t))
741
875
  end
742
876
 
743
877
  def kwoptarg(name_t, value)
878
+ check_reserved_for_numparam(value(name_t), loc(name_t))
879
+
744
880
  n(:kwoptarg, [ value(name_t).to_sym, value ],
745
881
  kwarg_map(name_t, value))
746
882
  end
747
883
 
748
884
  def kwrestarg(dstar_t, name_t=nil)
749
885
  if name_t
886
+ check_reserved_for_numparam(value(name_t), loc(name_t))
887
+
750
888
  n(:kwrestarg, [ value(name_t).to_sym ],
751
889
  arg_prefix_map(dstar_t, name_t))
752
890
  else
@@ -761,11 +899,15 @@ module Parser
761
899
  end
762
900
 
763
901
  def shadowarg(name_t)
902
+ check_reserved_for_numparam(value(name_t), loc(name_t))
903
+
764
904
  n(:shadowarg, [ value(name_t).to_sym ],
765
905
  variable_map(name_t))
766
906
  end
767
907
 
768
908
  def blockarg(amper_t, name_t)
909
+ check_reserved_for_numparam(value(name_t), loc(name_t))
910
+
769
911
  n(:blockarg, [ value(name_t).to_sym ],
770
912
  arg_prefix_map(amper_t, name_t))
771
913
  end
@@ -869,6 +1011,11 @@ module Parser
869
1011
  def call_method(receiver, dot_t, selector_t,
870
1012
  lparen_t=nil, args=[], rparen_t=nil)
871
1013
  type = call_type_for_dot(dot_t)
1014
+
1015
+ if self.class.emit_kwargs
1016
+ rewrite_hash_args_to_kwargs(args)
1017
+ end
1018
+
872
1019
  if selector_t.nil?
873
1020
  n(type, [ receiver, :call, *args ],
874
1021
  send_map(receiver, dot_t, nil, lparen_t, args, rparen_t))
@@ -946,6 +1093,10 @@ module Parser
946
1093
  end
947
1094
 
948
1095
  def index(receiver, lbrack_t, indexes, rbrack_t)
1096
+ if self.class.emit_kwargs
1097
+ rewrite_hash_args_to_kwargs(indexes)
1098
+ end
1099
+
949
1100
  if self.class.emit_index
950
1101
  n(:index, [ receiver, *indexes ],
951
1102
  index_map(receiver, lbrack_t, rbrack_t))
@@ -1108,6 +1259,10 @@ module Parser
1108
1259
  end
1109
1260
  end
1110
1261
 
1262
+ if %i[yield super].include?(type) && self.class.emit_kwargs
1263
+ rewrite_hash_args_to_kwargs(args)
1264
+ end
1265
+
1111
1266
  n(type, args,
1112
1267
  keyword_map(keyword_t, lparen_t, args, rparen_t))
1113
1268
  end
@@ -1241,6 +1396,16 @@ module Parser
1241
1396
  binary_op_map(lhs, in_t, rhs))
1242
1397
  end
1243
1398
 
1399
+ def match_pattern(lhs, match_t, rhs)
1400
+ n(:match_pattern, [lhs, rhs],
1401
+ binary_op_map(lhs, match_t, rhs))
1402
+ end
1403
+
1404
+ def match_pattern_p(lhs, match_t, rhs)
1405
+ n(:match_pattern_p, [lhs, rhs],
1406
+ binary_op_map(lhs, match_t, rhs))
1407
+ end
1408
+
1244
1409
  def in_pattern(in_t, pattern, guard, then_t, body)
1245
1410
  children = [pattern, guard, body]
1246
1411
  n(:in_pattern, children,
@@ -1358,6 +1523,11 @@ module Parser
1358
1523
  collection_map(lbrack_t, elements, rbrack_t))
1359
1524
  end
1360
1525
 
1526
+ def find_pattern(lbrack_t, elements, rbrack_t)
1527
+ n(:find_pattern, elements,
1528
+ collection_map(lbrack_t, elements, rbrack_t))
1529
+ end
1530
+
1361
1531
  def match_with_trailing_comma(match, comma_t)
1362
1532
  n(:match_with_trailing_comma, [ match ], expr_map(match.loc.expression.join(loc(comma_t))))
1363
1533
  end
@@ -1513,8 +1683,10 @@ module Parser
1513
1683
  end
1514
1684
  end
1515
1685
 
1516
- def check_assignment_to_numparam(node)
1517
- name = node.children[0].to_s
1686
+ def check_assignment_to_numparam(name, loc)
1687
+ # MRI < 2.7 treats numbered parameters as regular variables
1688
+ # and so it's allowed to perform assignments like `_1 = 42`.
1689
+ return if @parser.version < 27
1518
1690
 
1519
1691
  assigning_to_numparam =
1520
1692
  @parser.context.in_dynamic_block? &&
@@ -1522,7 +1694,17 @@ module Parser
1522
1694
  @parser.max_numparam_stack.has_numparams?
1523
1695
 
1524
1696
  if assigning_to_numparam
1525
- diagnostic :error, :cant_assign_to_numparam, { :name => name }, node.loc.expression
1697
+ diagnostic :error, :cant_assign_to_numparam, { :name => name }, loc
1698
+ end
1699
+ end
1700
+
1701
+ def check_reserved_for_numparam(name, loc)
1702
+ # MRI < 3.0 accepts assignemnt to variables like _1
1703
+ # if it's not a numbered parameter. MRI 3.0 and newer throws an error.
1704
+ return if @parser.version < 30
1705
+
1706
+ if name =~ /\A_([1-9])\z/
1707
+ diagnostic :error, :reserved_for_numparam, { :name => name }, loc
1526
1708
  end
1527
1709
  end
1528
1710
 
@@ -1756,17 +1938,17 @@ module Parser
1756
1938
  end
1757
1939
 
1758
1940
  def definition_map(keyword_t, operator_t, name_t, end_t)
1759
- Source::Map::Definition.new(loc(keyword_t),
1760
- loc(operator_t), loc(name_t),
1761
- loc(end_t))
1941
+ Source::Map::MethodDefinition.new(loc(keyword_t),
1942
+ loc(operator_t), loc(name_t),
1943
+ loc(end_t), nil, nil)
1762
1944
  end
1763
1945
 
1764
1946
  def endless_definition_map(keyword_t, operator_t, name_t, assignment_t, body_e)
1765
1947
  body_l = body_e.loc.expression
1766
1948
 
1767
- Source::Map::EndlessDefinition.new(loc(keyword_t),
1768
- loc(operator_t), loc(name_t),
1769
- loc(assignment_t), body_l)
1949
+ Source::Map::MethodDefinition.new(loc(keyword_t),
1950
+ loc(operator_t), loc(name_t), nil,
1951
+ loc(assignment_t), body_l)
1770
1952
  end
1771
1953
 
1772
1954
  def send_map(receiver_e, dot_t, selector_t, begin_t=nil, args=[], end_t=nil)
@@ -2023,6 +2205,20 @@ module Parser
2023
2205
  true
2024
2206
  end
2025
2207
  end
2208
+
2209
+ def rewrite_hash_args_to_kwargs(args)
2210
+ if args.any? && kwargs?(args.last)
2211
+ # foo(..., bar: baz)
2212
+ args[args.length - 1] = args[args.length - 1].updated(:kwargs)
2213
+ elsif args.length > 1 && args.last.type == :block_pass && kwargs?(args[args.length - 2])
2214
+ # foo(..., bar: baz, &blk)
2215
+ args[args.length - 2] = args[args.length - 2].updated(:kwargs)
2216
+ end
2217
+ end
2218
+
2219
+ def kwargs?(node)
2220
+ node.type == :hash && node.loc.begin.nil? && node.loc.end.nil?
2221
+ end
2026
2222
  end
2027
2223
 
2028
2224
  end