parser 2.6.0.0 → 3.1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/lib/parser/all.rb +3 -0
  3. data/lib/parser/ast/processor.rb +48 -1
  4. data/lib/parser/base.rb +30 -6
  5. data/lib/parser/builders/default.rb +670 -38
  6. data/lib/parser/context.rb +24 -26
  7. data/lib/parser/current.rb +36 -9
  8. data/lib/parser/current_arg_stack.rb +46 -0
  9. data/lib/parser/diagnostic/engine.rb +1 -2
  10. data/lib/parser/diagnostic.rb +1 -1
  11. data/lib/parser/lexer/dedenter.rb +58 -49
  12. data/lib/parser/lexer/explanation.rb +1 -1
  13. data/lib/parser/lexer.rb +13837 -11893
  14. data/lib/parser/macruby.rb +2544 -2489
  15. data/lib/parser/max_numparam_stack.rb +56 -0
  16. data/lib/parser/messages.rb +78 -44
  17. data/lib/parser/meta.rb +13 -3
  18. data/lib/parser/ruby18.rb +2313 -2259
  19. data/lib/parser/ruby19.rb +2537 -2488
  20. data/lib/parser/ruby20.rb +2724 -2673
  21. data/lib/parser/ruby21.rb +2766 -2727
  22. data/lib/parser/ruby22.rb +2683 -2628
  23. data/lib/parser/ruby23.rb +2796 -2755
  24. data/lib/parser/ruby24.rb +2812 -2771
  25. data/lib/parser/ruby25.rb +2703 -2670
  26. data/lib/parser/ruby26.rb +2794 -2747
  27. data/lib/parser/ruby27.rb +7914 -0
  28. data/lib/parser/ruby28.rb +8047 -0
  29. data/lib/parser/ruby30.rb +8096 -0
  30. data/lib/parser/ruby31.rb +8354 -0
  31. data/lib/parser/rubymotion.rb +2527 -2485
  32. data/lib/parser/runner/ruby_parse.rb +2 -2
  33. data/lib/parser/runner/ruby_rewrite.rb +2 -2
  34. data/lib/parser/runner.rb +36 -2
  35. data/lib/parser/source/buffer.rb +53 -28
  36. data/lib/parser/source/comment/associator.rb +31 -8
  37. data/lib/parser/source/comment.rb +14 -1
  38. data/lib/parser/source/map/method_definition.rb +25 -0
  39. data/lib/parser/source/range.rb +19 -3
  40. data/lib/parser/source/tree_rewriter/action.rb +137 -28
  41. data/lib/parser/source/tree_rewriter.rb +144 -14
  42. data/lib/parser/static_environment.rb +23 -0
  43. data/lib/parser/tree_rewriter.rb +3 -3
  44. data/lib/parser/variables_stack.rb +36 -0
  45. data/lib/parser/version.rb +1 -1
  46. data/lib/parser.rb +4 -0
  47. data/parser.gemspec +12 -19
  48. metadata +34 -99
  49. data/.gitignore +0 -32
  50. data/.travis.yml +0 -45
  51. data/.yardopts +0 -21
  52. data/CHANGELOG.md +0 -943
  53. data/CONTRIBUTING.md +0 -17
  54. data/Gemfile +0 -10
  55. data/README.md +0 -301
  56. data/Rakefile +0 -165
  57. data/ci/run_rubocop_specs +0 -14
  58. data/doc/AST_FORMAT.md +0 -1735
  59. data/doc/CUSTOMIZATION.md +0 -37
  60. data/doc/INTERNALS.md +0 -21
  61. data/doc/css/.gitkeep +0 -0
  62. data/doc/css/common.css +0 -68
  63. data/lib/parser/lexer.rl +0 -2383
  64. data/lib/parser/macruby.y +0 -2198
  65. data/lib/parser/ruby18.y +0 -1934
  66. data/lib/parser/ruby19.y +0 -2175
  67. data/lib/parser/ruby20.y +0 -2353
  68. data/lib/parser/ruby21.y +0 -2357
  69. data/lib/parser/ruby22.y +0 -2364
  70. data/lib/parser/ruby23.y +0 -2370
  71. data/lib/parser/ruby24.y +0 -2408
  72. data/lib/parser/ruby25.y +0 -2405
  73. data/lib/parser/ruby26.y +0 -2413
  74. data/lib/parser/rubymotion.y +0 -2182
  75. data/test/bug_163/fixtures/input.rb +0 -5
  76. data/test/bug_163/fixtures/output.rb +0 -5
  77. data/test/bug_163/rewriter.rb +0 -20
  78. data/test/helper.rb +0 -52
  79. data/test/parse_helper.rb +0 -315
  80. data/test/racc_coverage_helper.rb +0 -133
  81. data/test/test_base.rb +0 -31
  82. data/test/test_current.rb +0 -27
  83. data/test/test_diagnostic.rb +0 -96
  84. data/test/test_diagnostic_engine.rb +0 -62
  85. data/test/test_encoding.rb +0 -99
  86. data/test/test_lexer.rb +0 -3543
  87. data/test/test_lexer_stack_state.rb +0 -78
  88. data/test/test_parse_helper.rb +0 -80
  89. data/test/test_parser.rb +0 -7087
  90. data/test/test_runner_rewrite.rb +0 -47
  91. data/test/test_source_buffer.rb +0 -162
  92. data/test/test_source_comment.rb +0 -36
  93. data/test/test_source_comment_associator.rb +0 -367
  94. data/test/test_source_map.rb +0 -15
  95. data/test/test_source_range.rb +0 -172
  96. data/test/test_source_rewriter.rb +0 -541
  97. data/test/test_source_rewriter_action.rb +0 -46
  98. data/test/test_source_tree_rewriter.rb +0 -173
  99. data/test/test_static_environment.rb +0 -45
  100. data/test/using_tree_rewriter/fixtures/input.rb +0 -3
  101. data/test/using_tree_rewriter/fixtures/output.rb +0 -3
  102. data/test/using_tree_rewriter/using_tree_rewriter.rb +0 -9
@@ -82,6 +82,129 @@ module Parser
82
82
 
83
83
  @emit_index = false
84
84
 
85
+ class << self
86
+ ##
87
+ # AST compatibility attribute; causes a single non-mlhs
88
+ # block argument to be wrapped in s(:procarg0).
89
+ #
90
+ # If set to false (the default), block arguments `|a|` are emitted as
91
+ # `s(:args, s(:procarg0, :a))`
92
+ #
93
+ # If set to true, block arguments `|a|` are emitted as
94
+ # `s(:args, s(:procarg0, s(:arg, :a))`
95
+ #
96
+ # @return [Boolean]
97
+ attr_accessor :emit_arg_inside_procarg0
98
+ end
99
+
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
+ # (kwargs
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
+
85
208
  class << self
86
209
  ##
87
210
  # @api private
@@ -90,6 +213,10 @@ module Parser
90
213
  @emit_procarg0 = true
91
214
  @emit_encoding = true
92
215
  @emit_index = true
216
+ @emit_arg_inside_procarg0 = true
217
+ @emit_forward_arg = true
218
+ @emit_kwargs = true
219
+ @emit_match_pattern = true
93
220
  end
94
221
  end
95
222
 
@@ -262,18 +389,23 @@ module Parser
262
389
  if !dedent_level.nil?
263
390
  dedenter = Lexer::Dedenter.new(dedent_level)
264
391
 
265
- if node.type == :str
392
+ case node.type
393
+ when :str
266
394
  str = node.children.first
267
395
  dedenter.dedent(str)
268
- elsif node.type == :dstr || node.type == :xstr
269
- node.children.each do |str_node|
396
+ when :dstr, :xstr
397
+ children = node.children.map do |str_node|
270
398
  if str_node.type == :str
271
399
  str = str_node.children.first
272
400
  dedenter.dedent(str)
401
+ next nil if str.empty?
273
402
  else
274
403
  dedenter.interrupt
275
404
  end
405
+ str_node
276
406
  end
407
+
408
+ node = node.updated(nil, children.compact)
277
409
  end
278
410
  end
279
411
 
@@ -386,12 +518,52 @@ module Parser
386
518
  n(:pair, [ key, value ], pair_map)
387
519
  end
388
520
 
521
+ def pair_label(key_t)
522
+ key_l = loc(key_t)
523
+ value_l = key_l.adjust(end_pos: -1)
524
+
525
+ label = value(key_t)
526
+ value =
527
+ if label =~ /\A[[:lower:]]/
528
+ n(:ident, [ label.to_sym ], Source::Map::Variable.new(value_l))
529
+ else
530
+ n(:const, [ nil, label.to_sym ], Source::Map::Constant.new(nil, value_l, value_l))
531
+ end
532
+ pair_keyword(key_t, accessible(value))
533
+ end
534
+
389
535
  def kwsplat(dstar_t, arg)
390
536
  n(:kwsplat, [ arg ],
391
537
  unary_op_map(dstar_t, arg))
392
538
  end
393
539
 
394
540
  def associate(begin_t, pairs, end_t)
541
+ 0.upto(pairs.length - 1) do |i|
542
+ (i + 1).upto(pairs.length - 1) do |j|
543
+ key1, = *pairs[i]
544
+ key2, = *pairs[j]
545
+
546
+ do_warn = false
547
+
548
+ # keys have to be simple nodes, MRI ignores equal composite keys like
549
+ # `{ a(1) => 1, a(1) => 1 }`
550
+ case key1.type
551
+ when :sym, :str, :int, :float
552
+ if key1 == key2
553
+ do_warn = true
554
+ end
555
+ when :rational, :complex, :regexp
556
+ if @parser.version >= 31 && key1 == key2
557
+ do_warn = true
558
+ end
559
+ end
560
+
561
+ if do_warn
562
+ diagnostic :warning, :duplicate_hash_key, nil, key2.loc.expression
563
+ end
564
+ end
565
+ end
566
+
395
567
  n(:hash, [ *pairs ],
396
568
  collection_map(begin_t, pairs, end_t))
397
569
  end
@@ -476,14 +648,29 @@ module Parser
476
648
  when :ident
477
649
  name, = *node
478
650
 
479
- if @parser.static_env.declared?(name)
480
- node.updated(:lvar)
481
- else
482
- name, = *node
483
- n(:send, [ nil, name ],
651
+ if %w[? !].any? { |c| name.to_s.end_with?(c) }
652
+ diagnostic :error, :invalid_id_to_get,
653
+ { :identifier => name.to_s }, node.loc.expression
654
+ end
655
+
656
+ # Numbered parameters are not declared anywhere,
657
+ # so they take precedence over method calls in numblock contexts
658
+ if @parser.version >= 27 && @parser.try_declare_numparam(node)
659
+ return node.updated(:lvar)
660
+ end
661
+
662
+ unless @parser.static_env.declared?(name)
663
+ return n(:send, [ nil, name ],
484
664
  var_send_map(node))
485
665
  end
486
666
 
667
+ if name.to_s == parser.current_arg_stack.top
668
+ diagnostic :error, :circular_argument_reference,
669
+ { :var_name => name.to_s }, node.loc.expression
670
+ end
671
+
672
+ node.updated(:lvar)
673
+
487
674
  else
488
675
  node
489
676
  end
@@ -527,7 +714,7 @@ module Parser
527
714
  node.updated(:gvasgn)
528
715
 
529
716
  when :const
530
- unless @parser.context.dynamic_const_definition_allowed?
717
+ if @parser.context.in_def
531
718
  diagnostic :error, :dynamic_const, nil, node.loc.expression
532
719
  end
533
720
 
@@ -535,10 +722,28 @@ module Parser
535
722
 
536
723
  when :ident
537
724
  name, = *node
725
+
726
+ var_name = node.children[0].to_s
727
+ name_loc = node.loc.expression
728
+
729
+ check_assignment_to_numparam(var_name, name_loc)
730
+ check_reserved_for_numparam(var_name, name_loc)
731
+
538
732
  @parser.static_env.declare(name)
539
733
 
540
734
  node.updated(:lvasgn)
541
735
 
736
+ when :match_var
737
+ name, = *node
738
+
739
+ var_name = node.children[0].to_s
740
+ name_loc = node.loc.expression
741
+
742
+ check_assignment_to_numparam(var_name, name_loc)
743
+ check_reserved_for_numparam(var_name, name_loc)
744
+
745
+ node
746
+
542
747
  when :nil, :self, :true, :false,
543
748
  :__FILE__, :__LINE__, :__ENCODING__
544
749
  diagnostic :error, :invalid_assignment, nil, node.loc.expression
@@ -624,23 +829,38 @@ module Parser
624
829
 
625
830
  def def_method(def_t, name_t, args,
626
831
  body, end_t)
832
+ check_reserved_for_numparam(value(name_t), loc(name_t))
833
+
627
834
  n(:def, [ value(name_t).to_sym, args, body ],
628
835
  definition_map(def_t, nil, name_t, end_t))
629
836
  end
630
837
 
838
+ def def_endless_method(def_t, name_t, args,
839
+ assignment_t, body)
840
+ check_reserved_for_numparam(value(name_t), loc(name_t))
841
+
842
+ n(:def, [ value(name_t).to_sym, args, body ],
843
+ endless_definition_map(def_t, nil, name_t, assignment_t, body))
844
+ end
845
+
631
846
  def def_singleton(def_t, definee, dot_t,
632
847
  name_t, args,
633
848
  body, end_t)
634
- case definee.type
635
- when :int, :str, :dstr, :sym, :dsym,
636
- :regexp, :array, :hash
849
+ validate_definee(definee)
850
+ check_reserved_for_numparam(value(name_t), loc(name_t))
637
851
 
638
- diagnostic :error, :singleton_literal, nil, definee.loc.expression
852
+ n(:defs, [ definee, value(name_t).to_sym, args, body ],
853
+ definition_map(def_t, dot_t, name_t, end_t))
854
+ end
639
855
 
640
- else
641
- n(:defs, [ definee, value(name_t).to_sym, args, body ],
642
- definition_map(def_t, dot_t, name_t, end_t))
643
- end
856
+ def def_endless_singleton(def_t, definee, dot_t,
857
+ name_t, args,
858
+ assignment_t, body)
859
+ validate_definee(definee)
860
+ check_reserved_for_numparam(value(name_t), loc(name_t))
861
+
862
+ n(:defs, [ definee, value(name_t).to_sym, args, body ],
863
+ endless_definition_map(def_t, dot_t, name_t, assignment_t, body))
644
864
  end
645
865
 
646
866
  def undef_method(undef_t, names)
@@ -659,16 +879,44 @@ module Parser
659
879
 
660
880
  def args(begin_t, args, end_t, check_args=true)
661
881
  args = check_duplicate_args(args) if check_args
662
- n(:args, args,
663
- collection_map(begin_t, args, end_t))
882
+ validate_no_forward_arg_after_restarg(args)
883
+
884
+ map = collection_map(begin_t, args, end_t)
885
+ if !self.class.emit_forward_arg && args.length == 1 && args[0].type == :forward_arg
886
+ n(:forward_args, [], map)
887
+ else
888
+ n(:args, args, map)
889
+ end
890
+ end
891
+
892
+ def numargs(max_numparam)
893
+ n(:numargs, [ max_numparam ], nil)
894
+ end
895
+
896
+ def forward_only_args(begin_t, dots_t, end_t)
897
+ if self.class.emit_forward_arg
898
+ arg = forward_arg(dots_t)
899
+ n(:args, [ arg ],
900
+ collection_map(begin_t, [ arg ], end_t))
901
+ else
902
+ n(:forward_args, [], collection_map(begin_t, token_map(dots_t), end_t))
903
+ end
904
+ end
905
+
906
+ def forward_arg(dots_t)
907
+ n(:forward_arg, [], token_map(dots_t))
664
908
  end
665
909
 
666
910
  def arg(name_t)
911
+ check_reserved_for_numparam(value(name_t), loc(name_t))
912
+
667
913
  n(:arg, [ value(name_t).to_sym ],
668
914
  variable_map(name_t))
669
915
  end
670
916
 
671
917
  def optarg(name_t, eql_t, value)
918
+ check_reserved_for_numparam(value(name_t), loc(name_t))
919
+
672
920
  n(:optarg, [ value(name_t).to_sym, value ],
673
921
  variable_map(name_t).
674
922
  with_operator(loc(eql_t)).
@@ -677,6 +925,7 @@ module Parser
677
925
 
678
926
  def restarg(star_t, name_t=nil)
679
927
  if name_t
928
+ check_reserved_for_numparam(value(name_t), loc(name_t))
680
929
  n(:restarg, [ value(name_t).to_sym ],
681
930
  arg_prefix_map(star_t, name_t))
682
931
  else
@@ -686,17 +935,23 @@ module Parser
686
935
  end
687
936
 
688
937
  def kwarg(name_t)
938
+ check_reserved_for_numparam(value(name_t), loc(name_t))
939
+
689
940
  n(:kwarg, [ value(name_t).to_sym ],
690
941
  kwarg_map(name_t))
691
942
  end
692
943
 
693
944
  def kwoptarg(name_t, value)
945
+ check_reserved_for_numparam(value(name_t), loc(name_t))
946
+
694
947
  n(:kwoptarg, [ value(name_t).to_sym, value ],
695
948
  kwarg_map(name_t, value))
696
949
  end
697
950
 
698
951
  def kwrestarg(dstar_t, name_t=nil)
699
952
  if name_t
953
+ check_reserved_for_numparam(value(name_t), loc(name_t))
954
+
700
955
  n(:kwrestarg, [ value(name_t).to_sym ],
701
956
  arg_prefix_map(dstar_t, name_t))
702
957
  else
@@ -705,19 +960,36 @@ module Parser
705
960
  end
706
961
  end
707
962
 
963
+ def kwnilarg(dstar_t, nil_t)
964
+ n0(:kwnilarg,
965
+ arg_prefix_map(dstar_t, nil_t))
966
+ end
967
+
708
968
  def shadowarg(name_t)
969
+ check_reserved_for_numparam(value(name_t), loc(name_t))
970
+
709
971
  n(:shadowarg, [ value(name_t).to_sym ],
710
972
  variable_map(name_t))
711
973
  end
712
974
 
713
975
  def blockarg(amper_t, name_t)
714
- n(:blockarg, [ value(name_t).to_sym ],
976
+ if !name_t.nil?
977
+ check_reserved_for_numparam(value(name_t), loc(name_t))
978
+ end
979
+
980
+ arg_name = name_t ? value(name_t).to_sym : nil
981
+ n(:blockarg, [ arg_name ],
715
982
  arg_prefix_map(amper_t, name_t))
716
983
  end
717
984
 
718
985
  def procarg0(arg)
719
986
  if self.class.emit_procarg0
720
- arg.updated(:procarg0)
987
+ if arg.type == :arg && self.class.emit_arg_inside_procarg0
988
+ n(:procarg0, [ arg ],
989
+ Source::Map::Collection.new(nil, nil, arg.location.expression))
990
+ else
991
+ arg.updated(:procarg0)
992
+ end
721
993
  else
722
994
  arg
723
995
  end
@@ -802,9 +1074,18 @@ module Parser
802
1074
  end
803
1075
  end
804
1076
 
1077
+ def forwarded_args(dots_t)
1078
+ n(:forwarded_args, [], token_map(dots_t))
1079
+ end
1080
+
805
1081
  def call_method(receiver, dot_t, selector_t,
806
1082
  lparen_t=nil, args=[], rparen_t=nil)
807
1083
  type = call_type_for_dot(dot_t)
1084
+
1085
+ if self.class.emit_kwargs
1086
+ rewrite_hash_args_to_kwargs(args)
1087
+ end
1088
+
808
1089
  if selector_t.nil?
809
1090
  n(type, [ receiver, :call, *args ],
810
1091
  send_map(receiver, dot_t, nil, lparen_t, args, rparen_t))
@@ -831,19 +1112,26 @@ module Parser
831
1112
  end
832
1113
 
833
1114
  last_arg = call_args.last
834
- if last_arg && last_arg.type == :block_pass
1115
+ if last_arg && (last_arg.type == :block_pass || last_arg.type == :forwarded_args)
835
1116
  diagnostic :error, :block_and_blockarg, nil, last_arg.loc.expression, [loc(begin_t)]
836
1117
  end
837
1118
 
1119
+ if args.type == :numargs
1120
+ block_type = :numblock
1121
+ args = args.children[0]
1122
+ else
1123
+ block_type = :block
1124
+ end
1125
+
838
1126
  if [:send, :csend, :index, :super, :zsuper, :lambda].include?(method_call.type)
839
- n(:block, [ method_call, args, body ],
1127
+ n(block_type, [ method_call, args, body ],
840
1128
  block_map(method_call.loc.expression, begin_t, end_t))
841
1129
  else
842
1130
  # Code like "return foo 1 do end" is reduced in a weird sequence.
843
1131
  # Here, method_call is actually (return).
844
1132
  actual_send, = *method_call
845
1133
  block =
846
- n(:block, [ actual_send, args, body ],
1134
+ n(block_type, [ actual_send, args, body ],
847
1135
  block_map(actual_send.loc.expression, begin_t, end_t))
848
1136
 
849
1137
  n(method_call.type, [ block ],
@@ -875,6 +1163,10 @@ module Parser
875
1163
  end
876
1164
 
877
1165
  def index(receiver, lbrack_t, indexes, rbrack_t)
1166
+ if self.class.emit_kwargs
1167
+ rewrite_hash_args_to_kwargs(indexes)
1168
+ end
1169
+
878
1170
  if self.class.emit_index
879
1171
  n(:index, [ receiver, *indexes ],
880
1172
  index_map(receiver, lbrack_t, rbrack_t))
@@ -1037,6 +1329,10 @@ module Parser
1037
1329
  end
1038
1330
  end
1039
1331
 
1332
+ if %i[yield super].include?(type) && self.class.emit_kwargs
1333
+ rewrite_hash_args_to_kwargs(args)
1334
+ end
1335
+
1040
1336
  n(type, args,
1041
1337
  keyword_map(keyword_t, lparen_t, args, rparen_t))
1042
1338
  end
@@ -1155,6 +1451,219 @@ module Parser
1155
1451
  end
1156
1452
  end
1157
1453
 
1454
+ #
1455
+ # PATTERN MATCHING
1456
+ #
1457
+
1458
+ def case_match(case_t, expr, in_bodies, else_t, else_body, end_t)
1459
+ else_body = n(:empty_else, nil, token_map(else_t)) if else_t && !else_body
1460
+ n(:case_match, [ expr, *(in_bodies << else_body)],
1461
+ condition_map(case_t, expr, nil, nil, else_t, else_body, end_t))
1462
+ end
1463
+
1464
+ def in_match(lhs, in_t, rhs)
1465
+ n(:in_match, [lhs, rhs],
1466
+ binary_op_map(lhs, in_t, rhs))
1467
+ end
1468
+
1469
+ def match_pattern(lhs, match_t, rhs)
1470
+ n(:match_pattern, [lhs, rhs],
1471
+ binary_op_map(lhs, match_t, rhs))
1472
+ end
1473
+
1474
+ def match_pattern_p(lhs, match_t, rhs)
1475
+ n(:match_pattern_p, [lhs, rhs],
1476
+ binary_op_map(lhs, match_t, rhs))
1477
+ end
1478
+
1479
+ def in_pattern(in_t, pattern, guard, then_t, body)
1480
+ children = [pattern, guard, body]
1481
+ n(:in_pattern, children,
1482
+ keyword_map(in_t, then_t, children.compact, nil))
1483
+ end
1484
+
1485
+ def if_guard(if_t, if_body)
1486
+ n(:if_guard, [if_body], guard_map(if_t, if_body))
1487
+ end
1488
+
1489
+ def unless_guard(unless_t, unless_body)
1490
+ n(:unless_guard, [unless_body], guard_map(unless_t, unless_body))
1491
+ end
1492
+
1493
+ def match_var(name_t)
1494
+ name = value(name_t).to_sym
1495
+ name_l = loc(name_t)
1496
+
1497
+ check_lvar_name(name, name_l)
1498
+ check_duplicate_pattern_variable(name, name_l)
1499
+ @parser.static_env.declare(name)
1500
+
1501
+ n(:match_var, [ name ],
1502
+ variable_map(name_t))
1503
+ end
1504
+
1505
+ def match_hash_var(name_t)
1506
+ name = value(name_t).to_sym
1507
+
1508
+ expr_l = loc(name_t)
1509
+ name_l = expr_l.adjust(end_pos: -1)
1510
+
1511
+ check_lvar_name(name, name_l)
1512
+ check_duplicate_pattern_variable(name, name_l)
1513
+ @parser.static_env.declare(name)
1514
+
1515
+ n(:match_var, [ name ],
1516
+ Source::Map::Variable.new(name_l, expr_l))
1517
+ end
1518
+
1519
+ def match_hash_var_from_str(begin_t, strings, end_t)
1520
+ if strings.length > 1
1521
+ diagnostic :error, :pm_interp_in_var_name, nil, loc(begin_t).join(loc(end_t))
1522
+ end
1523
+
1524
+ string = strings[0]
1525
+
1526
+ case string.type
1527
+ when :str
1528
+ # MRI supports plain strings in hash pattern matching
1529
+ name, = *string
1530
+ name_l = string.loc.expression
1531
+
1532
+ check_lvar_name(name, name_l)
1533
+ check_duplicate_pattern_variable(name, name_l)
1534
+
1535
+ @parser.static_env.declare(name)
1536
+
1537
+ if (begin_l = string.loc.begin)
1538
+ # exclude beginning of the string from the location of the variable
1539
+ name_l = name_l.adjust(begin_pos: begin_l.length)
1540
+ end
1541
+
1542
+ if (end_l = string.loc.end)
1543
+ # exclude end of the string from the location of the variable
1544
+ name_l = name_l.adjust(end_pos: -end_l.length)
1545
+ end
1546
+
1547
+ expr_l = loc(begin_t).join(string.loc.expression).join(loc(end_t))
1548
+ n(:match_var, [ name.to_sym ],
1549
+ Source::Map::Variable.new(name_l, expr_l))
1550
+ when :begin
1551
+ match_hash_var_from_str(begin_t, string.children, end_t)
1552
+ else
1553
+ # we only can get here if there is an interpolation, e.g., ``in "#{ a }":`
1554
+ diagnostic :error, :pm_interp_in_var_name, nil, loc(begin_t).join(loc(end_t))
1555
+ end
1556
+ end
1557
+
1558
+ def match_rest(star_t, name_t = nil)
1559
+ if name_t.nil?
1560
+ n0(:match_rest,
1561
+ unary_op_map(star_t))
1562
+ else
1563
+ name = match_var(name_t)
1564
+ n(:match_rest, [ name ],
1565
+ unary_op_map(star_t, name))
1566
+ end
1567
+ end
1568
+
1569
+ def hash_pattern(lbrace_t, kwargs, rbrace_t)
1570
+ args = check_duplicate_args(kwargs)
1571
+ n(:hash_pattern, args,
1572
+ collection_map(lbrace_t, args, rbrace_t))
1573
+ end
1574
+
1575
+ def array_pattern(lbrack_t, elements, rbrack_t)
1576
+ return n(:array_pattern, nil, collection_map(lbrack_t, [], rbrack_t)) if elements.nil?
1577
+
1578
+ trailing_comma = false
1579
+
1580
+ node_elements = elements.map do |element|
1581
+ if element.type == :match_with_trailing_comma
1582
+ trailing_comma = true
1583
+ element.children.first
1584
+ else
1585
+ trailing_comma = false
1586
+ element
1587
+ end
1588
+ end
1589
+
1590
+ node_type = trailing_comma ? :array_pattern_with_tail : :array_pattern
1591
+
1592
+ n(node_type, node_elements,
1593
+ collection_map(lbrack_t, elements, rbrack_t))
1594
+ end
1595
+
1596
+ def find_pattern(lbrack_t, elements, rbrack_t)
1597
+ n(:find_pattern, elements,
1598
+ collection_map(lbrack_t, elements, rbrack_t))
1599
+ end
1600
+
1601
+ def match_with_trailing_comma(match, comma_t)
1602
+ n(:match_with_trailing_comma, [ match ], expr_map(match.loc.expression.join(loc(comma_t))))
1603
+ end
1604
+
1605
+ def const_pattern(const, ldelim_t, pattern, rdelim_t)
1606
+ n(:const_pattern, [const, pattern],
1607
+ Source::Map::Collection.new(
1608
+ loc(ldelim_t), loc(rdelim_t),
1609
+ const.loc.expression.join(loc(rdelim_t))
1610
+ )
1611
+ )
1612
+ end
1613
+
1614
+ def pin(pin_t, var)
1615
+ n(:pin, [ var ],
1616
+ send_unary_op_map(pin_t, var))
1617
+ end
1618
+
1619
+ def match_alt(left, pipe_t, right)
1620
+ source_map = binary_op_map(left, pipe_t, right)
1621
+
1622
+ n(:match_alt, [ left, right ],
1623
+ source_map)
1624
+ end
1625
+
1626
+ def match_as(value, assoc_t, as)
1627
+ source_map = binary_op_map(value, assoc_t, as)
1628
+
1629
+ n(:match_as, [ value, as ],
1630
+ source_map)
1631
+ end
1632
+
1633
+ def match_nil_pattern(dstar_t, nil_t)
1634
+ n0(:match_nil_pattern,
1635
+ arg_prefix_map(dstar_t, nil_t))
1636
+ end
1637
+
1638
+ def match_pair(label_type, label, value)
1639
+ if label_type == :label
1640
+ check_duplicate_pattern_key(label[0], label[1])
1641
+ pair_keyword(label, value)
1642
+ else
1643
+ begin_t, parts, end_t = label
1644
+ label_loc = loc(begin_t).join(loc(end_t))
1645
+
1646
+ # quoted label like "label": value
1647
+ if (var_name = static_string(parts))
1648
+ check_duplicate_pattern_key(var_name, label_loc)
1649
+ else
1650
+ diagnostic :error, :pm_interp_in_var_name, nil, label_loc
1651
+ end
1652
+
1653
+ pair_quoted(begin_t, parts, end_t, value)
1654
+ end
1655
+ end
1656
+
1657
+ def match_label(label_type, label)
1658
+ if label_type == :label
1659
+ match_hash_var(label)
1660
+ else
1661
+ # quoted label like "label": value
1662
+ begin_t, strings, end_t = label
1663
+ match_hash_var_from_str(begin_t, strings, end_t)
1664
+ end
1665
+ end
1666
+
1158
1667
  private
1159
1668
 
1160
1669
  #
@@ -1210,18 +1719,18 @@ module Parser
1210
1719
  case this_arg.type
1211
1720
  when :arg, :optarg, :restarg, :blockarg,
1212
1721
  :kwarg, :kwoptarg, :kwrestarg,
1213
- :shadowarg, :procarg0
1722
+ :shadowarg
1214
1723
 
1215
- this_name, = *this_arg
1724
+ check_duplicate_arg(this_arg, map)
1216
1725
 
1217
- that_arg = map[this_name]
1218
- that_name, = *that_arg
1726
+ when :procarg0
1219
1727
 
1220
- if that_arg.nil?
1221
- map[this_name] = this_arg
1222
- elsif arg_name_collides?(this_name, that_name)
1223
- diagnostic :error, :duplicate_argument, nil,
1224
- this_arg.loc.name, [ that_arg.loc.name ]
1728
+ if this_arg.children[0].is_a?(Symbol)
1729
+ # s(:procarg0, :a)
1730
+ check_duplicate_arg(this_arg, map)
1731
+ else
1732
+ # s(:procarg0, s(:arg, :a), ...)
1733
+ check_duplicate_args(this_arg.children, map)
1225
1734
  end
1226
1735
 
1227
1736
  when :mlhs
@@ -1230,6 +1739,60 @@ module Parser
1230
1739
  end
1231
1740
  end
1232
1741
 
1742
+ def check_duplicate_arg(this_arg, map={})
1743
+ this_name, = *this_arg
1744
+
1745
+ that_arg = map[this_name]
1746
+ that_name, = *that_arg
1747
+
1748
+ if that_arg.nil?
1749
+ map[this_name] = this_arg
1750
+ elsif arg_name_collides?(this_name, that_name)
1751
+ diagnostic :error, :duplicate_argument, nil,
1752
+ this_arg.loc.name, [ that_arg.loc.name ]
1753
+ end
1754
+ end
1755
+
1756
+ def validate_no_forward_arg_after_restarg(args)
1757
+ restarg = nil
1758
+ forward_arg = nil
1759
+ args.each do |arg|
1760
+ case arg.type
1761
+ when :restarg then restarg = arg
1762
+ when :forward_arg then forward_arg = arg
1763
+ end
1764
+ end
1765
+
1766
+ if !forward_arg.nil? && !restarg.nil?
1767
+ diagnostic :error, :forward_arg_after_restarg, nil, forward_arg.loc.expression, [restarg.loc.expression]
1768
+ end
1769
+ end
1770
+
1771
+ def check_assignment_to_numparam(name, loc)
1772
+ # MRI < 2.7 treats numbered parameters as regular variables
1773
+ # and so it's allowed to perform assignments like `_1 = 42`.
1774
+ return if @parser.version < 27
1775
+
1776
+ assigning_to_numparam =
1777
+ @parser.context.in_dynamic_block? &&
1778
+ name =~ /\A_([1-9])\z/ &&
1779
+ @parser.max_numparam_stack.has_numparams?
1780
+
1781
+ if assigning_to_numparam
1782
+ diagnostic :error, :cant_assign_to_numparam, { :name => name }, loc
1783
+ end
1784
+ end
1785
+
1786
+ def check_reserved_for_numparam(name, loc)
1787
+ # MRI < 3.0 accepts assignemnt to variables like _1
1788
+ # if it's not a numbered parameter. MRI 3.0 and newer throws an error.
1789
+ return if @parser.version < 30
1790
+
1791
+ if name =~ /\A_([1-9])\z/
1792
+ diagnostic :error, :reserved_for_numparam, { :name => name }, loc
1793
+ end
1794
+ end
1795
+
1233
1796
  def arg_name_collides?(this_name, that_name)
1234
1797
  case @parser.version
1235
1798
  when 18
@@ -1245,6 +1808,32 @@ module Parser
1245
1808
  end
1246
1809
  end
1247
1810
 
1811
+ def check_lvar_name(name, loc)
1812
+ if name =~ /\A[[[:lower:]]_][[[:alnum:]]_]*\z/
1813
+ # OK
1814
+ else
1815
+ diagnostic :error, :lvar_name, { name: name }, loc
1816
+ end
1817
+ end
1818
+
1819
+ def check_duplicate_pattern_variable(name, loc)
1820
+ return if name.to_s.start_with?('_')
1821
+
1822
+ if @parser.pattern_variables.declared?(name)
1823
+ diagnostic :error, :duplicate_variable_name, { name: name.to_s }, loc
1824
+ end
1825
+
1826
+ @parser.pattern_variables.declare(name)
1827
+ end
1828
+
1829
+ def check_duplicate_pattern_key(name, loc)
1830
+ if @parser.pattern_hash_keys.declared?(name)
1831
+ diagnostic :error, :duplicate_pattern_key, { name: name.to_s }, loc
1832
+ end
1833
+
1834
+ @parser.pattern_hash_keys.declare(name)
1835
+ end
1836
+
1248
1837
  #
1249
1838
  # SOURCE MAPS
1250
1839
  #
@@ -1389,10 +1978,12 @@ module Parser
1389
1978
  end
1390
1979
 
1391
1980
  def range_map(start_e, op_t, end_e)
1392
- if end_e
1981
+ if start_e && end_e
1393
1982
  expr_l = join_exprs(start_e, end_e)
1394
- else
1983
+ elsif start_e
1395
1984
  expr_l = start_e.loc.expression.join(loc(op_t))
1985
+ elsif end_e
1986
+ expr_l = loc(op_t).join(end_e.loc.expression)
1396
1987
  end
1397
1988
 
1398
1989
  Source::Map::Operator.new(loc(op_t), expr_l)
@@ -1432,9 +2023,17 @@ module Parser
1432
2023
  end
1433
2024
 
1434
2025
  def definition_map(keyword_t, operator_t, name_t, end_t)
1435
- Source::Map::Definition.new(loc(keyword_t),
1436
- loc(operator_t), loc(name_t),
1437
- loc(end_t))
2026
+ Source::Map::MethodDefinition.new(loc(keyword_t),
2027
+ loc(operator_t), loc(name_t),
2028
+ loc(end_t), nil, nil)
2029
+ end
2030
+
2031
+ def endless_definition_map(keyword_t, operator_t, name_t, assignment_t, body_e)
2032
+ body_l = body_e.loc.expression
2033
+
2034
+ Source::Map::MethodDefinition.new(loc(keyword_t),
2035
+ loc(operator_t), loc(name_t), nil,
2036
+ loc(assignment_t), body_l)
1438
2037
  end
1439
2038
 
1440
2039
  def send_map(receiver_e, dot_t, selector_t, begin_t=nil, args=[], end_t=nil)
@@ -1591,6 +2190,13 @@ module Parser
1591
2190
  begin_l.join(end_l))
1592
2191
  end
1593
2192
 
2193
+ def guard_map(keyword_t, guard_body_e)
2194
+ keyword_l = loc(keyword_t)
2195
+ guard_body_l = guard_body_e.loc.expression
2196
+
2197
+ Source::Map::Keyword.new(keyword_l, nil, nil, keyword_l.join(guard_body_l))
2198
+ end
2199
+
1594
2200
  #
1595
2201
  # HELPERS
1596
2202
  #
@@ -1672,6 +2278,32 @@ module Parser
1672
2278
  @parser.send :yyerror
1673
2279
  end
1674
2280
  end
2281
+
2282
+ def validate_definee(definee)
2283
+ case definee.type
2284
+ when :int, :str, :dstr, :sym, :dsym,
2285
+ :regexp, :array, :hash
2286
+
2287
+ diagnostic :error, :singleton_literal, nil, definee.loc.expression
2288
+ false
2289
+ else
2290
+ true
2291
+ end
2292
+ end
2293
+
2294
+ def rewrite_hash_args_to_kwargs(args)
2295
+ if args.any? && kwargs?(args.last)
2296
+ # foo(..., bar: baz)
2297
+ args[args.length - 1] = args[args.length - 1].updated(:kwargs)
2298
+ elsif args.length > 1 && args.last.type == :block_pass && kwargs?(args[args.length - 2])
2299
+ # foo(..., bar: baz, &blk)
2300
+ args[args.length - 2] = args[args.length - 2].updated(:kwargs)
2301
+ end
2302
+ end
2303
+
2304
+ def kwargs?(node)
2305
+ node.type == :hash && node.loc.begin.nil? && node.loc.end.nil?
2306
+ end
1675
2307
  end
1676
2308
 
1677
2309
  end