parser 2.7.1.4 → 3.0.1.1

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 +2 -1
  4. data/lib/parser/ast/processor.rb +3 -7
  5. data/lib/parser/base.rb +7 -5
  6. data/lib/parser/builders/default.rb +178 -29
  7. data/lib/parser/context.rb +4 -0
  8. data/lib/parser/current.rb +20 -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 +7 -6
  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/ruby31.rb +8075 -0
  28. data/lib/parser/rubymotion.rb +6086 -0
  29. data/lib/parser/runner.rb +9 -4
  30. data/lib/parser/source/buffer.rb +50 -27
  31. data/lib/parser/source/comment.rb +14 -1
  32. data/lib/parser/source/comment/associator.rb +18 -5
  33. data/lib/parser/source/map/{endless_definition.rb → method_definition.rb} +5 -3
  34. data/lib/parser/source/range.rb +2 -2
  35. data/lib/parser/source/tree_rewriter.rb +27 -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 +1 -17
  40. metadata +9 -97
  41. data/.gitignore +0 -34
  42. data/.travis.yml +0 -40
  43. data/.yardopts +0 -21
  44. data/CHANGELOG.md +0 -1116
  45. data/CONTRIBUTING.md +0 -17
  46. data/Gemfile +0 -10
  47. data/README.md +0 -309
  48. data/Rakefile +0 -167
  49. data/ci/run_rubocop_specs +0 -14
  50. data/doc/AST_FORMAT.md +0 -2283
  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 -2550
  56. data/lib/parser/macruby.y +0 -2208
  57. data/lib/parser/ruby18.y +0 -1936
  58. data/lib/parser/ruby19.y +0 -2185
  59. data/lib/parser/ruby20.y +0 -2363
  60. data/lib/parser/ruby21.y +0 -2364
  61. data/lib/parser/ruby22.y +0 -2371
  62. data/lib/parser/ruby23.y +0 -2377
  63. data/lib/parser/ruby24.y +0 -2415
  64. data/lib/parser/ruby25.y +0 -2412
  65. data/lib/parser/ruby26.y +0 -2420
  66. data/lib/parser/ruby27.y +0 -2950
  67. data/lib/parser/ruby28.y +0 -3043
  68. data/lib/parser/rubymotion.y +0 -2192
  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 -103
  73. data/test/parse_helper.rb +0 -323
  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 -9780
  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 -361
  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: c4dbd5dfd3a249d65b4d2b20c54b668749b3d5360e7feef7772924c135b78d86
4
- data.tar.gz: ca30aca7f92a24fb96ef74c1a21149d9d43fb541d86bdae0b113f5ea5e267137
3
+ metadata.gz: 6c85d02ca4bf90dcc1d33424dd323ae54b9e60581a6473012e950f82ce15d28e
4
+ data.tar.gz: ebe2c4eb02779209b8a34e051d717a6af84da81fadfeff79d9eab194ecf95d93
5
5
  SHA512:
6
- metadata.gz: deb6edb6b828f309ebc6eb58e19613fe13c490e780895dfad01aceeeb0111781bc9e90b81bf6be35069afed44bd5f683c8120f134abd3d6aa7546a15fb370c19
7
- data.tar.gz: 0c5a25dade42d9c74bc115aa8ecfd8dbfbcdeadc0fee6e994f44532ed994ac0c47aeccccc5405ddc9b5bd3804e4c47874163e6d468e47cb14ddd647ffb2c118c
6
+ metadata.gz: 173d8e1bbbbbf0ef06d06f1ea59dc41ca49c8b39c6931523dc70bac259eee1e9c9263730d560afe106c70f88f01ae14edc77862d20a4924a674131ca90b9807c
7
+ data.tar.gz: 1698922a4ff14bf3e826f10b826a8a8e0c3aaf7fefd20669a4666c0ed6ea8a3ed405acbb28fe90985510dedff6414c0330d5affa4639840178bf20dee561e4a9
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,5 @@ 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'
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
 
@@ -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
 
@@ -163,8 +161,6 @@ module Parser
163
161
  ])
164
162
  end
165
163
 
166
- alias on_def_e on_def
167
-
168
164
  def on_defs(node)
169
165
  definee_node, name, args_node, body_node = *node
170
166
 
@@ -174,8 +170,6 @@ module Parser
174
170
  ])
175
171
  end
176
172
 
177
- alias on_defs_e on_defs
178
-
179
173
  alias on_undef process_regular_node
180
174
  alias on_alias process_regular_node
181
175
 
@@ -246,6 +240,8 @@ module Parser
246
240
 
247
241
  alias on_case_match process_regular_node
248
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
249
245
  alias on_in_pattern process_regular_node
250
246
  alias on_if_guard process_regular_node
251
247
  alias on_unless_guard process_regular_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
  #
@@ -103,7 +103,7 @@ module Parser
103
103
  ##
104
104
  # AST compatibility attribute; arguments forwarding initially
105
105
  # didn't have support for leading arguments
106
- # (i.e. `def m(a, ...); end` was a syntax error). However, Ruby 2.8
106
+ # (i.e. `def m(a, ...); end` was a syntax error). However, Ruby 3.0
107
107
  # added support for any number of arguments in front of the `...`.
108
108
  #
109
109
  # If set to false (the default):
@@ -120,7 +120,7 @@ module Parser
120
120
  # s(:def, :m, s(:args, s(:arg, :a), s(:arg, :b), s(:forward_arg)))
121
121
  #
122
122
  # It does't matter that much on 2.7 (because there can't be any leading arguments),
123
- # but on 2.8 it should be better enabled to use a single AST format.
123
+ # but on 3.0 it should be better enabled to use a single AST format.
124
124
  #
125
125
  # @return [Boolean]
126
126
  attr_accessor :emit_forward_arg
@@ -128,6 +128,83 @@ module Parser
128
128
 
129
129
  @emit_forward_arg = false
130
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
207
+
131
208
  class << self
132
209
  ##
133
210
  # @api private
@@ -138,6 +215,8 @@ module Parser
138
215
  @emit_index = true
139
216
  @emit_arg_inside_procarg0 = true
140
217
  @emit_forward_arg = true
218
+ @emit_kwargs = true
219
+ @emit_match_pattern = true
141
220
  end
142
221
  end
143
222
 
@@ -310,18 +389,23 @@ module Parser
310
389
  if !dedent_level.nil?
311
390
  dedenter = Lexer::Dedenter.new(dedent_level)
312
391
 
313
- if node.type == :str
392
+ case node.type
393
+ when :str
314
394
  str = node.children.first
315
395
  dedenter.dedent(str)
316
- elsif node.type == :dstr || node.type == :xstr
317
- node.children.each do |str_node|
396
+ when :dstr, :xstr
397
+ children = node.children.map do |str_node|
318
398
  if str_node.type == :str
319
399
  str = str_node.children.first
320
400
  dedenter.dedent(str)
401
+ next nil if str.empty?
321
402
  else
322
403
  dedenter.interrupt
323
404
  end
405
+ str_node
324
406
  end
407
+
408
+ node = node.updated(nil, children.compact)
325
409
  end
326
410
  end
327
411
 
@@ -589,7 +673,11 @@ module Parser
589
673
  when :ident
590
674
  name, = *node
591
675
 
592
- 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)
593
681
 
594
682
  @parser.static_env.declare(name)
595
683
 
@@ -651,15 +739,6 @@ module Parser
651
739
  binary_op_map(lhs, eql_t, rhs))
652
740
  end
653
741
 
654
- def rassign(lhs, assoc_t, rhs)
655
- n(:rasgn, [lhs, rhs], binary_op_map(lhs, assoc_t, rhs))
656
- end
657
-
658
- def multi_rassign(lhs, assoc_t, rhs)
659
- n(:mrasgn, [ lhs, rhs ],
660
- binary_op_map(lhs, assoc_t, rhs))
661
- end
662
-
663
742
  #
664
743
  # Class and module definition
665
744
  #
@@ -689,20 +768,25 @@ module Parser
689
768
 
690
769
  def def_method(def_t, name_t, args,
691
770
  body, end_t)
771
+ check_reserved_for_numparam(value(name_t), loc(name_t))
772
+
692
773
  n(:def, [ value(name_t).to_sym, args, body ],
693
774
  definition_map(def_t, nil, name_t, end_t))
694
775
  end
695
776
 
696
777
  def def_endless_method(def_t, name_t, args,
697
778
  assignment_t, body)
698
- 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 ],
699
782
  endless_definition_map(def_t, nil, name_t, assignment_t, body))
700
783
  end
701
784
 
702
785
  def def_singleton(def_t, definee, dot_t,
703
786
  name_t, args,
704
787
  body, end_t)
705
- return unless validate_definee(definee)
788
+ validate_definee(definee)
789
+ check_reserved_for_numparam(value(name_t), loc(name_t))
706
790
 
707
791
  n(:defs, [ definee, value(name_t).to_sym, args, body ],
708
792
  definition_map(def_t, dot_t, name_t, end_t))
@@ -711,9 +795,10 @@ module Parser
711
795
  def def_endless_singleton(def_t, definee, dot_t,
712
796
  name_t, args,
713
797
  assignment_t, body)
714
- return unless validate_definee(definee)
798
+ validate_definee(definee)
799
+ check_reserved_for_numparam(value(name_t), loc(name_t))
715
800
 
716
- n(:defs_e, [ definee, value(name_t).to_sym, args, body ],
801
+ n(:defs, [ definee, value(name_t).to_sym, args, body ],
717
802
  endless_definition_map(def_t, dot_t, name_t, assignment_t, body))
718
803
  end
719
804
 
@@ -756,11 +841,15 @@ module Parser
756
841
  end
757
842
 
758
843
  def arg(name_t)
844
+ check_reserved_for_numparam(value(name_t), loc(name_t))
845
+
759
846
  n(:arg, [ value(name_t).to_sym ],
760
847
  variable_map(name_t))
761
848
  end
762
849
 
763
850
  def optarg(name_t, eql_t, value)
851
+ check_reserved_for_numparam(value(name_t), loc(name_t))
852
+
764
853
  n(:optarg, [ value(name_t).to_sym, value ],
765
854
  variable_map(name_t).
766
855
  with_operator(loc(eql_t)).
@@ -769,6 +858,7 @@ module Parser
769
858
 
770
859
  def restarg(star_t, name_t=nil)
771
860
  if name_t
861
+ check_reserved_for_numparam(value(name_t), loc(name_t))
772
862
  n(:restarg, [ value(name_t).to_sym ],
773
863
  arg_prefix_map(star_t, name_t))
774
864
  else
@@ -778,17 +868,23 @@ module Parser
778
868
  end
779
869
 
780
870
  def kwarg(name_t)
871
+ check_reserved_for_numparam(value(name_t), loc(name_t))
872
+
781
873
  n(:kwarg, [ value(name_t).to_sym ],
782
874
  kwarg_map(name_t))
783
875
  end
784
876
 
785
877
  def kwoptarg(name_t, value)
878
+ check_reserved_for_numparam(value(name_t), loc(name_t))
879
+
786
880
  n(:kwoptarg, [ value(name_t).to_sym, value ],
787
881
  kwarg_map(name_t, value))
788
882
  end
789
883
 
790
884
  def kwrestarg(dstar_t, name_t=nil)
791
885
  if name_t
886
+ check_reserved_for_numparam(value(name_t), loc(name_t))
887
+
792
888
  n(:kwrestarg, [ value(name_t).to_sym ],
793
889
  arg_prefix_map(dstar_t, name_t))
794
890
  else
@@ -803,11 +899,15 @@ module Parser
803
899
  end
804
900
 
805
901
  def shadowarg(name_t)
902
+ check_reserved_for_numparam(value(name_t), loc(name_t))
903
+
806
904
  n(:shadowarg, [ value(name_t).to_sym ],
807
905
  variable_map(name_t))
808
906
  end
809
907
 
810
908
  def blockarg(amper_t, name_t)
909
+ check_reserved_for_numparam(value(name_t), loc(name_t))
910
+
811
911
  n(:blockarg, [ value(name_t).to_sym ],
812
912
  arg_prefix_map(amper_t, name_t))
813
913
  end
@@ -911,6 +1011,11 @@ module Parser
911
1011
  def call_method(receiver, dot_t, selector_t,
912
1012
  lparen_t=nil, args=[], rparen_t=nil)
913
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
+
914
1019
  if selector_t.nil?
915
1020
  n(type, [ receiver, :call, *args ],
916
1021
  send_map(receiver, dot_t, nil, lparen_t, args, rparen_t))
@@ -988,6 +1093,10 @@ module Parser
988
1093
  end
989
1094
 
990
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
+
991
1100
  if self.class.emit_index
992
1101
  n(:index, [ receiver, *indexes ],
993
1102
  index_map(receiver, lbrack_t, rbrack_t))
@@ -1150,6 +1259,10 @@ module Parser
1150
1259
  end
1151
1260
  end
1152
1261
 
1262
+ if %i[yield super].include?(type) && self.class.emit_kwargs
1263
+ rewrite_hash_args_to_kwargs(args)
1264
+ end
1265
+
1153
1266
  n(type, args,
1154
1267
  keyword_map(keyword_t, lparen_t, args, rparen_t))
1155
1268
  end
@@ -1283,6 +1396,16 @@ module Parser
1283
1396
  binary_op_map(lhs, in_t, rhs))
1284
1397
  end
1285
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
+
1286
1409
  def in_pattern(in_t, pattern, guard, then_t, body)
1287
1410
  children = [pattern, guard, body]
1288
1411
  n(:in_pattern, children,
@@ -1560,8 +1683,10 @@ module Parser
1560
1683
  end
1561
1684
  end
1562
1685
 
1563
- def check_assignment_to_numparam(node)
1564
- 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
1565
1690
 
1566
1691
  assigning_to_numparam =
1567
1692
  @parser.context.in_dynamic_block? &&
@@ -1569,7 +1694,17 @@ module Parser
1569
1694
  @parser.max_numparam_stack.has_numparams?
1570
1695
 
1571
1696
  if assigning_to_numparam
1572
- 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
1573
1708
  end
1574
1709
  end
1575
1710
 
@@ -1589,7 +1724,7 @@ module Parser
1589
1724
  end
1590
1725
 
1591
1726
  def check_lvar_name(name, loc)
1592
- if name =~ /\A[[[:lower:]]|_][[[:alnum:]]_]*\z/
1727
+ if name =~ /\A[[[:lower:]]_][[[:alnum:]]_]*\z/
1593
1728
  # OK
1594
1729
  else
1595
1730
  diagnostic :error, :lvar_name, { name: name }, loc
@@ -1803,17 +1938,17 @@ module Parser
1803
1938
  end
1804
1939
 
1805
1940
  def definition_map(keyword_t, operator_t, name_t, end_t)
1806
- Source::Map::Definition.new(loc(keyword_t),
1807
- loc(operator_t), loc(name_t),
1808
- loc(end_t))
1941
+ Source::Map::MethodDefinition.new(loc(keyword_t),
1942
+ loc(operator_t), loc(name_t),
1943
+ loc(end_t), nil, nil)
1809
1944
  end
1810
1945
 
1811
1946
  def endless_definition_map(keyword_t, operator_t, name_t, assignment_t, body_e)
1812
1947
  body_l = body_e.loc.expression
1813
1948
 
1814
- Source::Map::EndlessDefinition.new(loc(keyword_t),
1815
- loc(operator_t), loc(name_t),
1816
- 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)
1817
1952
  end
1818
1953
 
1819
1954
  def send_map(receiver_e, dot_t, selector_t, begin_t=nil, args=[], end_t=nil)
@@ -2070,6 +2205,20 @@ module Parser
2070
2205
  true
2071
2206
  end
2072
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
2073
2222
  end
2074
2223
 
2075
2224
  end