parser 2.6.0.0 → 3.1.0.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 (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