parser 2.7.1.1 → 3.0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/lib/parser.rb +1 -0
  3. data/lib/parser/all.rb +2 -0
  4. data/lib/parser/ast/processor.rb +5 -0
  5. data/lib/parser/base.rb +7 -5
  6. data/lib/parser/builders/default.rb +263 -23
  7. data/lib/parser/context.rb +5 -0
  8. data/lib/parser/current.rb +24 -6
  9. data/lib/parser/current_arg_stack.rb +5 -2
  10. data/lib/parser/diagnostic.rb +1 -1
  11. data/lib/parser/diagnostic/engine.rb +1 -2
  12. data/lib/parser/lexer.rb +887 -803
  13. data/lib/parser/macruby.rb +2214 -2189
  14. data/lib/parser/max_numparam_stack.rb +13 -5
  15. data/lib/parser/messages.rb +18 -0
  16. data/lib/parser/meta.rb +6 -5
  17. data/lib/parser/ruby18.rb +9 -3
  18. data/lib/parser/ruby19.rb +2297 -2289
  19. data/lib/parser/ruby20.rb +2413 -2397
  20. data/lib/parser/ruby21.rb +2419 -2411
  21. data/lib/parser/ruby22.rb +2468 -2460
  22. data/lib/parser/ruby23.rb +2452 -2452
  23. data/lib/parser/ruby24.rb +2435 -2430
  24. data/lib/parser/ruby25.rb +2220 -2214
  25. data/lib/parser/ruby26.rb +2220 -2214
  26. data/lib/parser/ruby27.rb +3715 -3615
  27. data/lib/parser/ruby28.rb +8047 -0
  28. data/lib/parser/ruby30.rb +8060 -0
  29. data/lib/parser/ruby31.rb +8226 -0
  30. data/lib/parser/rubymotion.rb +2190 -2182
  31. data/lib/parser/runner.rb +31 -2
  32. data/lib/parser/runner/ruby_rewrite.rb +2 -2
  33. data/lib/parser/source/buffer.rb +53 -28
  34. data/lib/parser/source/comment.rb +14 -1
  35. data/lib/parser/source/comment/associator.rb +31 -8
  36. data/lib/parser/source/map/method_definition.rb +25 -0
  37. data/lib/parser/source/range.rb +10 -3
  38. data/lib/parser/source/tree_rewriter.rb +100 -10
  39. data/lib/parser/source/tree_rewriter/action.rb +114 -21
  40. data/lib/parser/static_environment.rb +4 -0
  41. data/lib/parser/tree_rewriter.rb +1 -2
  42. data/lib/parser/variables_stack.rb +4 -0
  43. data/lib/parser/version.rb +1 -1
  44. data/parser.gemspec +3 -18
  45. metadata +17 -98
  46. data/.gitignore +0 -33
  47. data/.travis.yml +0 -42
  48. data/.yardopts +0 -21
  49. data/CHANGELOG.md +0 -1075
  50. data/CONTRIBUTING.md +0 -17
  51. data/Gemfile +0 -10
  52. data/README.md +0 -309
  53. data/Rakefile +0 -166
  54. data/ci/run_rubocop_specs +0 -14
  55. data/doc/AST_FORMAT.md +0 -2180
  56. data/doc/CUSTOMIZATION.md +0 -37
  57. data/doc/INTERNALS.md +0 -21
  58. data/doc/css/.gitkeep +0 -0
  59. data/doc/css/common.css +0 -68
  60. data/lib/parser/lexer.rl +0 -2536
  61. data/lib/parser/macruby.y +0 -2198
  62. data/lib/parser/ruby18.y +0 -1934
  63. data/lib/parser/ruby19.y +0 -2175
  64. data/lib/parser/ruby20.y +0 -2353
  65. data/lib/parser/ruby21.y +0 -2357
  66. data/lib/parser/ruby22.y +0 -2364
  67. data/lib/parser/ruby23.y +0 -2370
  68. data/lib/parser/ruby24.y +0 -2408
  69. data/lib/parser/ruby25.y +0 -2405
  70. data/lib/parser/ruby26.y +0 -2413
  71. data/lib/parser/ruby27.y +0 -2941
  72. data/lib/parser/rubymotion.y +0 -2182
  73. data/test/bug_163/fixtures/input.rb +0 -5
  74. data/test/bug_163/fixtures/output.rb +0 -5
  75. data/test/bug_163/rewriter.rb +0 -20
  76. data/test/helper.rb +0 -60
  77. data/test/parse_helper.rb +0 -319
  78. data/test/racc_coverage_helper.rb +0 -133
  79. data/test/test_base.rb +0 -31
  80. data/test/test_current.rb +0 -29
  81. data/test/test_diagnostic.rb +0 -96
  82. data/test/test_diagnostic_engine.rb +0 -62
  83. data/test/test_encoding.rb +0 -99
  84. data/test/test_lexer.rb +0 -3608
  85. data/test/test_lexer_stack_state.rb +0 -78
  86. data/test/test_parse_helper.rb +0 -80
  87. data/test/test_parser.rb +0 -9430
  88. data/test/test_runner_parse.rb +0 -35
  89. data/test/test_runner_rewrite.rb +0 -47
  90. data/test/test_source_buffer.rb +0 -162
  91. data/test/test_source_comment.rb +0 -36
  92. data/test/test_source_comment_associator.rb +0 -367
  93. data/test/test_source_map.rb +0 -15
  94. data/test/test_source_range.rb +0 -187
  95. data/test/test_source_rewriter.rb +0 -541
  96. data/test/test_source_rewriter_action.rb +0 -46
  97. data/test/test_source_tree_rewriter.rb +0 -253
  98. data/test/test_static_environment.rb +0 -45
  99. data/test/using_tree_rewriter/fixtures/input.rb +0 -3
  100. data/test/using_tree_rewriter/fixtures/output.rb +0 -3
  101. 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: fb7c9797808fcd8920ef34ccce6dae7f416d0fe3084a863fa3fec7fa30b086fc
4
- data.tar.gz: 828a937688a35e277c7d435197ca2d023458de366a8e94fbaa67bdd6d3a04145
3
+ metadata.gz: 0b1e9fbbc406eb2665aa17f066247e6584182ebe365b3f1d2ace35628f3f12c6
4
+ data.tar.gz: 8522d4ff0b299c14cb386156a6f04e7d7828bf8c33ed1331a22829ff873312c1
5
5
  SHA512:
6
- metadata.gz: 679bc103f3d8b2663a1ec2de6c3acac41c90c1d738b40bf4b5ed945b8e3f51e22359caa0789e55009f3bd2c45ac832d00182db9ba9be1f43b18e6fe0e0508278
7
- data.tar.gz: b4f4d29766e23ca406644fb578e2134f28a9983d765d4aa45117dcb5a9ee012f27c2b8b65eccf11b7e3818b1543a62cc0483aa510a51352bc2260ad0fd650acd
6
+ metadata.gz: 5871c263e07cdd6bf88f661419578977f9ddd9e01e1631bab14ff7fb485f466a7b8dacebcda30514d7d1f3c6746b8d2e1f6c6feb7de57a899a1cacfb728c05af
7
+ data.tar.gz: 4decb43386adfd5be04356d3c9667c1880fa974ad14bc190312bf25a379fad92e4353b0812bcb8810e1863892f14a0daaf6d0c5d31523e2a45a1bb35f65c4ab0
data/lib/parser.rb CHANGED
@@ -46,6 +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/method_definition'
49
50
  require 'parser/source/map/send'
50
51
  require 'parser/source/map/index'
51
52
  require 'parser/source/map/condition'
data/lib/parser/all.rb CHANGED
@@ -10,3 +10,5 @@ require 'parser/ruby24'
10
10
  require 'parser/ruby25'
11
11
  require 'parser/ruby26'
12
12
  require 'parser/ruby27'
13
+ require 'parser/ruby30'
14
+ require 'parser/ruby31'
@@ -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
 
@@ -124,6 +125,7 @@ module Parser
124
125
  alias on_kwarg process_argument_node
125
126
  alias on_kwoptarg process_argument_node
126
127
  alias on_kwrestarg process_argument_node
128
+ alias on_forward_arg process_argument_node
127
129
 
128
130
  def on_procarg0(node)
129
131
  if node.children[0].is_a?(Symbol)
@@ -238,6 +240,8 @@ module Parser
238
240
 
239
241
  alias on_case_match process_regular_node
240
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
241
245
  alias on_in_pattern process_regular_node
242
246
  alias on_if_guard process_regular_node
243
247
  alias on_unless_guard process_regular_node
@@ -250,6 +254,7 @@ module Parser
250
254
  alias on_array_pattern_with_tail process_regular_node
251
255
  alias on_hash_pattern process_regular_node
252
256
  alias on_const_pattern process_regular_node
257
+ alias on_find_pattern process_regular_node
253
258
 
254
259
  # @private
255
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
 
@@ -648,23 +768,38 @@ module Parser
648
768
 
649
769
  def def_method(def_t, name_t, args,
650
770
  body, end_t)
771
+ check_reserved_for_numparam(value(name_t), loc(name_t))
772
+
651
773
  n(:def, [ value(name_t).to_sym, args, body ],
652
774
  definition_map(def_t, nil, name_t, end_t))
653
775
  end
654
776
 
777
+ def def_endless_method(def_t, name_t, args,
778
+ assignment_t, body)
779
+ check_reserved_for_numparam(value(name_t), loc(name_t))
780
+
781
+ n(:def, [ value(name_t).to_sym, args, body ],
782
+ endless_definition_map(def_t, nil, name_t, assignment_t, body))
783
+ end
784
+
655
785
  def def_singleton(def_t, definee, dot_t,
656
786
  name_t, args,
657
787
  body, end_t)
658
- case definee.type
659
- when :int, :str, :dstr, :sym, :dsym,
660
- :regexp, :array, :hash
788
+ validate_definee(definee)
789
+ check_reserved_for_numparam(value(name_t), loc(name_t))
661
790
 
662
- diagnostic :error, :singleton_literal, nil, definee.loc.expression
791
+ n(:defs, [ definee, value(name_t).to_sym, args, body ],
792
+ definition_map(def_t, dot_t, name_t, end_t))
793
+ end
663
794
 
664
- else
665
- n(:defs, [ definee, value(name_t).to_sym, args, body ],
666
- definition_map(def_t, dot_t, name_t, end_t))
667
- end
795
+ def def_endless_singleton(def_t, definee, dot_t,
796
+ name_t, args,
797
+ assignment_t, body)
798
+ validate_definee(definee)
799
+ check_reserved_for_numparam(value(name_t), loc(name_t))
800
+
801
+ n(:defs, [ definee, value(name_t).to_sym, args, body ],
802
+ endless_definition_map(def_t, dot_t, name_t, assignment_t, body))
668
803
  end
669
804
 
670
805
  def undef_method(undef_t, names)
@@ -691,16 +826,30 @@ module Parser
691
826
  n(:numargs, [ max_numparam ], nil)
692
827
  end
693
828
 
694
- def forward_args(begin_t, dots_t, end_t)
695
- 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))
696
841
  end
697
842
 
698
843
  def arg(name_t)
844
+ check_reserved_for_numparam(value(name_t), loc(name_t))
845
+
699
846
  n(:arg, [ value(name_t).to_sym ],
700
847
  variable_map(name_t))
701
848
  end
702
849
 
703
850
  def optarg(name_t, eql_t, value)
851
+ check_reserved_for_numparam(value(name_t), loc(name_t))
852
+
704
853
  n(:optarg, [ value(name_t).to_sym, value ],
705
854
  variable_map(name_t).
706
855
  with_operator(loc(eql_t)).
@@ -709,6 +858,7 @@ module Parser
709
858
 
710
859
  def restarg(star_t, name_t=nil)
711
860
  if name_t
861
+ check_reserved_for_numparam(value(name_t), loc(name_t))
712
862
  n(:restarg, [ value(name_t).to_sym ],
713
863
  arg_prefix_map(star_t, name_t))
714
864
  else
@@ -718,17 +868,23 @@ module Parser
718
868
  end
719
869
 
720
870
  def kwarg(name_t)
871
+ check_reserved_for_numparam(value(name_t), loc(name_t))
872
+
721
873
  n(:kwarg, [ value(name_t).to_sym ],
722
874
  kwarg_map(name_t))
723
875
  end
724
876
 
725
877
  def kwoptarg(name_t, value)
878
+ check_reserved_for_numparam(value(name_t), loc(name_t))
879
+
726
880
  n(:kwoptarg, [ value(name_t).to_sym, value ],
727
881
  kwarg_map(name_t, value))
728
882
  end
729
883
 
730
884
  def kwrestarg(dstar_t, name_t=nil)
731
885
  if name_t
886
+ check_reserved_for_numparam(value(name_t), loc(name_t))
887
+
732
888
  n(:kwrestarg, [ value(name_t).to_sym ],
733
889
  arg_prefix_map(dstar_t, name_t))
734
890
  else
@@ -743,11 +899,15 @@ module Parser
743
899
  end
744
900
 
745
901
  def shadowarg(name_t)
902
+ check_reserved_for_numparam(value(name_t), loc(name_t))
903
+
746
904
  n(:shadowarg, [ value(name_t).to_sym ],
747
905
  variable_map(name_t))
748
906
  end
749
907
 
750
908
  def blockarg(amper_t, name_t)
909
+ check_reserved_for_numparam(value(name_t), loc(name_t))
910
+
751
911
  n(:blockarg, [ value(name_t).to_sym ],
752
912
  arg_prefix_map(amper_t, name_t))
753
913
  end
@@ -851,6 +1011,11 @@ module Parser
851
1011
  def call_method(receiver, dot_t, selector_t,
852
1012
  lparen_t=nil, args=[], rparen_t=nil)
853
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
+
854
1019
  if selector_t.nil?
855
1020
  n(type, [ receiver, :call, *args ],
856
1021
  send_map(receiver, dot_t, nil, lparen_t, args, rparen_t))
@@ -928,6 +1093,10 @@ module Parser
928
1093
  end
929
1094
 
930
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
+
931
1100
  if self.class.emit_index
932
1101
  n(:index, [ receiver, *indexes ],
933
1102
  index_map(receiver, lbrack_t, rbrack_t))
@@ -1090,6 +1259,10 @@ module Parser
1090
1259
  end
1091
1260
  end
1092
1261
 
1262
+ if %i[yield super].include?(type) && self.class.emit_kwargs
1263
+ rewrite_hash_args_to_kwargs(args)
1264
+ end
1265
+
1093
1266
  n(type, args,
1094
1267
  keyword_map(keyword_t, lparen_t, args, rparen_t))
1095
1268
  end
@@ -1223,6 +1396,16 @@ module Parser
1223
1396
  binary_op_map(lhs, in_t, rhs))
1224
1397
  end
1225
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
+
1226
1409
  def in_pattern(in_t, pattern, guard, then_t, body)
1227
1410
  children = [pattern, guard, body]
1228
1411
  n(:in_pattern, children,
@@ -1239,8 +1422,10 @@ module Parser
1239
1422
 
1240
1423
  def match_var(name_t)
1241
1424
  name = value(name_t).to_sym
1425
+ name_l = loc(name_t)
1242
1426
 
1243
- check_duplicate_pattern_variable(name, loc(name_t))
1427
+ check_lvar_name(name, name_l)
1428
+ check_duplicate_pattern_variable(name, name_l)
1244
1429
  @parser.static_env.declare(name)
1245
1430
 
1246
1431
  n(:match_var, [ name ],
@@ -1253,6 +1438,7 @@ module Parser
1253
1438
  expr_l = loc(name_t)
1254
1439
  name_l = expr_l.adjust(end_pos: -1)
1255
1440
 
1441
+ check_lvar_name(name, name_l)
1256
1442
  check_duplicate_pattern_variable(name, name_l)
1257
1443
  @parser.static_env.declare(name)
1258
1444
 
@@ -1293,6 +1479,9 @@ module Parser
1293
1479
  Source::Map::Variable.new(name_l, expr_l))
1294
1480
  when :begin
1295
1481
  match_hash_var_from_str(begin_t, string.children, end_t)
1482
+ else
1483
+ # we only can get here if there is an interpolation, e.g., ``in "#{ a }":`
1484
+ diagnostic :error, :pm_interp_in_var_name, nil, loc(begin_t).join(loc(end_t))
1296
1485
  end
1297
1486
  end
1298
1487
 
@@ -1334,6 +1523,11 @@ module Parser
1334
1523
  collection_map(lbrack_t, elements, rbrack_t))
1335
1524
  end
1336
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
+
1337
1531
  def match_with_trailing_comma(match, comma_t)
1338
1532
  n(:match_with_trailing_comma, [ match ], expr_map(match.loc.expression.join(loc(comma_t))))
1339
1533
  end
@@ -1489,8 +1683,10 @@ module Parser
1489
1683
  end
1490
1684
  end
1491
1685
 
1492
- def check_assignment_to_numparam(node)
1493
- 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
1494
1690
 
1495
1691
  assigning_to_numparam =
1496
1692
  @parser.context.in_dynamic_block? &&
@@ -1498,7 +1694,17 @@ module Parser
1498
1694
  @parser.max_numparam_stack.has_numparams?
1499
1695
 
1500
1696
  if assigning_to_numparam
1501
- 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
1502
1708
  end
1503
1709
  end
1504
1710
 
@@ -1518,7 +1724,7 @@ module Parser
1518
1724
  end
1519
1725
 
1520
1726
  def check_lvar_name(name, loc)
1521
- if name =~ /\A[[[:lower:]]|_][[[:alnum:]]_]*\z/
1727
+ if name =~ /\A[[[:lower:]]_][[[:alnum:]]_]*\z/
1522
1728
  # OK
1523
1729
  else
1524
1730
  diagnostic :error, :lvar_name, { name: name }, loc
@@ -1732,9 +1938,17 @@ module Parser
1732
1938
  end
1733
1939
 
1734
1940
  def definition_map(keyword_t, operator_t, name_t, end_t)
1735
- Source::Map::Definition.new(loc(keyword_t),
1736
- loc(operator_t), loc(name_t),
1737
- loc(end_t))
1941
+ Source::Map::MethodDefinition.new(loc(keyword_t),
1942
+ loc(operator_t), loc(name_t),
1943
+ loc(end_t), nil, nil)
1944
+ end
1945
+
1946
+ def endless_definition_map(keyword_t, operator_t, name_t, assignment_t, body_e)
1947
+ body_l = body_e.loc.expression
1948
+
1949
+ Source::Map::MethodDefinition.new(loc(keyword_t),
1950
+ loc(operator_t), loc(name_t), nil,
1951
+ loc(assignment_t), body_l)
1738
1952
  end
1739
1953
 
1740
1954
  def send_map(receiver_e, dot_t, selector_t, begin_t=nil, args=[], end_t=nil)
@@ -1979,6 +2193,32 @@ module Parser
1979
2193
  @parser.send :yyerror
1980
2194
  end
1981
2195
  end
2196
+
2197
+ def validate_definee(definee)
2198
+ case definee.type
2199
+ when :int, :str, :dstr, :sym, :dsym,
2200
+ :regexp, :array, :hash
2201
+
2202
+ diagnostic :error, :singleton_literal, nil, definee.loc.expression
2203
+ false
2204
+ else
2205
+ true
2206
+ end
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
1982
2222
  end
1983
2223
 
1984
2224
  end