parser 2.7.2.0 → 3.1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +25 -0
  3. data/lib/parser/all.rb +2 -0
  4. data/lib/parser/ast/processor.rb +3 -0
  5. data/lib/parser/base.rb +1 -0
  6. data/lib/parser/builders/default.rb +225 -27
  7. data/lib/parser/context.rb +22 -37
  8. data/lib/parser/current.rb +28 -10
  9. data/lib/parser/current_arg_stack.rb +5 -2
  10. data/lib/parser/lexer/dedenter.rb +7 -1
  11. data/lib/parser/lexer/explanation.rb +1 -1
  12. data/lib/parser/lexer.rb +12728 -11483
  13. data/lib/parser/macruby.rb +2476 -2448
  14. data/lib/parser/max_numparam_stack.rb +16 -8
  15. data/lib/parser/messages.rb +5 -0
  16. data/lib/parser/meta.rb +2 -1
  17. data/lib/parser/ruby18.rb +2161 -2116
  18. data/lib/parser/ruby19.rb +2458 -2424
  19. data/lib/parser/ruby20.rb +2634 -2598
  20. data/lib/parser/ruby21.rb +2700 -2667
  21. data/lib/parser/ruby22.rb +2533 -2491
  22. data/lib/parser/ruby23.rb +2616 -2571
  23. data/lib/parser/ruby24.rb +2651 -2609
  24. data/lib/parser/ruby25.rb +2545 -2513
  25. data/lib/parser/ruby26.rb +2669 -2624
  26. data/lib/parser/ruby27.rb +3953 -3842
  27. data/lib/parser/ruby30.rb +4089 -4045
  28. data/lib/parser/ruby31.rb +8354 -0
  29. data/lib/parser/ruby32.rb +8330 -0
  30. data/lib/parser/rubymotion.rb +2454 -2415
  31. data/lib/parser/runner.rb +12 -1
  32. data/lib/parser/source/buffer.rb +50 -27
  33. data/lib/parser/source/comment/associator.rb +17 -4
  34. data/lib/parser/source/comment.rb +13 -0
  35. data/lib/parser/source/tree_rewriter.rb +27 -0
  36. data/lib/parser/static_environment.rb +13 -0
  37. data/lib/parser/variables_stack.rb +4 -0
  38. data/lib/parser/version.rb +1 -1
  39. data/parser.gemspec +1 -1
  40. metadata +9 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3efc381a3ad92df723e4a698afbceb63f65fdb7c892f690dbd569ba298307d8b
4
- data.tar.gz: b9e78eb7dd39f6539fc21883fbec26b1a0c2d377c68bf060d485df5521318e54
3
+ metadata.gz: 12a38198be7971a87e3fbc2514f45120238a8004b1b267382a481ea971c8d9ec
4
+ data.tar.gz: ec1a2a51e94eb30280b31e5f26cb28cb1e50b94a9d3a11ae35616b79eaf11b52
5
5
  SHA512:
6
- metadata.gz: 3c9b2d1df5a463c289f2881c0064c956e88560bc14af30bbb9fe3828ae7a3e1f8a88352172e353b196f34ba1e98640b6bf38bcbb50bef0f8661aacf9e8ccdc1b
7
- data.tar.gz: e394d70911b7d86ee7049b0ecaab839120da2f90372630e48c6bb3c14f3b45b35322a2d99ca516df6cc2e8a8e7c0c79aca1031c3dfa28b0026c300ea10b51ed4
6
+ metadata.gz: e37d66e7c76e0af7d9ad1e9c3c635741436f92d0eef67032fdad83c38090c90cdb9be49018e20786ae540b24d18628695ab4b372a94c96e93b1ce36418e41da5
7
+ data.tar.gz: 9ad75e610252fb6db157948fb162b0907baedeac7c4107574b78b3869c2490afabec269ab31303ceec2a3a7f17659eb06b43e9b6677b279fb412abade076b93a
data/LICENSE.txt ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2013-2016 whitequark <whitequark@whitequark.org>
2
+
3
+ Parts of the source are derived from ruby_parser:
4
+ Copyright (c) Ryan Davis, seattle.rb
5
+
6
+ MIT License
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ "Software"), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be
17
+ included in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/lib/parser/all.rb CHANGED
@@ -11,3 +11,5 @@ require 'parser/ruby25'
11
11
  require 'parser/ruby26'
12
12
  require 'parser/ruby27'
13
13
  require 'parser/ruby30'
14
+ require 'parser/ruby31'
15
+ require 'parser/ruby32'
@@ -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
 
@@ -239,6 +240,8 @@ module Parser
239
240
 
240
241
  alias on_case_match process_regular_node
241
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
242
245
  alias on_in_pattern process_regular_node
243
246
  alias on_if_guard process_regular_node
244
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
@@ -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
+ # (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
+
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
 
@@ -434,12 +518,52 @@ module Parser
434
518
  n(:pair, [ key, value ], pair_map)
435
519
  end
436
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
+
437
535
  def kwsplat(dstar_t, arg)
438
536
  n(:kwsplat, [ arg ],
439
537
  unary_op_map(dstar_t, arg))
440
538
  end
441
539
 
442
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
+
443
567
  n(:hash, [ *pairs ],
444
568
  collection_map(begin_t, pairs, end_t))
445
569
  end
@@ -524,19 +648,29 @@ module Parser
524
648
  when :ident
525
649
  name, = *node
526
650
 
527
- if @parser.static_env.declared?(name)
528
- if name.to_s == parser.current_arg_stack.top
529
- diagnostic :error, :circular_argument_reference,
530
- { :var_name => name.to_s }, node.loc.expression
531
- end
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
532
655
 
533
- node.updated(:lvar)
534
- else
535
- name, = *node
536
- n(:send, [ nil, name ],
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 ],
537
664
  var_send_map(node))
538
665
  end
539
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
+
540
674
  else
541
675
  node
542
676
  end
@@ -580,7 +714,7 @@ module Parser
580
714
  node.updated(:gvasgn)
581
715
 
582
716
  when :const
583
- unless @parser.context.dynamic_const_definition_allowed?
717
+ if @parser.context.in_def
584
718
  diagnostic :error, :dynamic_const, nil, node.loc.expression
585
719
  end
586
720
 
@@ -599,6 +733,17 @@ module Parser
599
733
 
600
734
  node.updated(:lvasgn)
601
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
+
602
747
  when :nil, :self, :true, :false,
603
748
  :__FILE__, :__LINE__, :__ENCODING__
604
749
  diagnostic :error, :invalid_assignment, nil, node.loc.expression
@@ -655,14 +800,6 @@ module Parser
655
800
  binary_op_map(lhs, eql_t, rhs))
656
801
  end
657
802
 
658
- def rassign(lhs, assoc_t, rhs)
659
- assign(rhs, assoc_t, lhs)
660
- end
661
-
662
- def multi_rassign(lhs, assoc_t, rhs)
663
- multi_assign(rhs, assoc_t, lhs)
664
- end
665
-
666
803
  #
667
804
  # Class and module definition
668
805
  #
@@ -742,8 +879,14 @@ module Parser
742
879
 
743
880
  def args(begin_t, args, end_t, check_args=true)
744
881
  args = check_duplicate_args(args) if check_args
745
- n(:args, args,
746
- 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
747
890
  end
748
891
 
749
892
  def numargs(max_numparam)
@@ -830,9 +973,12 @@ module Parser
830
973
  end
831
974
 
832
975
  def blockarg(amper_t, name_t)
833
- check_reserved_for_numparam(value(name_t), loc(name_t))
976
+ if !name_t.nil?
977
+ check_reserved_for_numparam(value(name_t), loc(name_t))
978
+ end
834
979
 
835
- n(:blockarg, [ value(name_t).to_sym ],
980
+ arg_name = name_t ? value(name_t).to_sym : nil
981
+ n(:blockarg, [ arg_name ],
836
982
  arg_prefix_map(amper_t, name_t))
837
983
  end
838
984
 
@@ -935,6 +1081,11 @@ module Parser
935
1081
  def call_method(receiver, dot_t, selector_t,
936
1082
  lparen_t=nil, args=[], rparen_t=nil)
937
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
+
938
1089
  if selector_t.nil?
939
1090
  n(type, [ receiver, :call, *args ],
940
1091
  send_map(receiver, dot_t, nil, lparen_t, args, rparen_t))
@@ -1012,6 +1163,10 @@ module Parser
1012
1163
  end
1013
1164
 
1014
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
+
1015
1170
  if self.class.emit_index
1016
1171
  n(:index, [ receiver, *indexes ],
1017
1172
  index_map(receiver, lbrack_t, rbrack_t))
@@ -1174,6 +1329,10 @@ module Parser
1174
1329
  end
1175
1330
  end
1176
1331
 
1332
+ if %i[yield super].include?(type) && self.class.emit_kwargs
1333
+ rewrite_hash_args_to_kwargs(args)
1334
+ end
1335
+
1177
1336
  n(type, args,
1178
1337
  keyword_map(keyword_t, lparen_t, args, rparen_t))
1179
1338
  end
@@ -1307,6 +1466,16 @@ module Parser
1307
1466
  binary_op_map(lhs, in_t, rhs))
1308
1467
  end
1309
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
+
1310
1479
  def in_pattern(in_t, pattern, guard, then_t, body)
1311
1480
  children = [pattern, guard, body]
1312
1481
  n(:in_pattern, children,
@@ -1584,6 +1753,21 @@ module Parser
1584
1753
  end
1585
1754
  end
1586
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
+
1587
1771
  def check_assignment_to_numparam(name, loc)
1588
1772
  # MRI < 2.7 treats numbered parameters as regular variables
1589
1773
  # and so it's allowed to perform assignments like `_1 = 42`.
@@ -1601,7 +1785,7 @@ module Parser
1601
1785
 
1602
1786
  def check_reserved_for_numparam(name, loc)
1603
1787
  # MRI < 3.0 accepts assignemnt to variables like _1
1604
- # if it's not a numbererd parameter. MRI 3.0 and newer throws an error.
1788
+ # if it's not a numbered parameter. MRI 3.0 and newer throws an error.
1605
1789
  return if @parser.version < 30
1606
1790
 
1607
1791
  if name =~ /\A_([1-9])\z/
@@ -1625,7 +1809,7 @@ module Parser
1625
1809
  end
1626
1810
 
1627
1811
  def check_lvar_name(name, loc)
1628
- if name =~ /\A[[[:lower:]]|_][[[:alnum:]]_]*\z/
1812
+ if name =~ /\A[[[:lower:]]_][[[:alnum:]]_]*\z/
1629
1813
  # OK
1630
1814
  else
1631
1815
  diagnostic :error, :lvar_name, { name: name }, loc
@@ -2106,6 +2290,20 @@ module Parser
2106
2290
  true
2107
2291
  end
2108
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
2109
2307
  end
2110
2308
 
2111
2309
  end
@@ -9,56 +9,41 @@ module Parser
9
9
  # + :sclass - in the singleton class body (class << obj; end)
10
10
  # + :def - in the method body (def m; end)
11
11
  # + :defs - in the singleton method body (def self.m; end)
12
+ # + :def_open_args - in the arglist of the method definition
13
+ # keep in mind that it's set **only** after reducing the first argument,
14
+ # if you need to handle the first argument check `lex_state == expr_fname`
12
15
  # + :block - in the block body (tap {})
13
16
  # + :lambda - in the lambda body (-> {})
14
17
  #
15
18
  class Context
16
- attr_reader :stack
19
+ FLAGS = %i[
20
+ in_defined
21
+ in_kwarg
22
+ in_argdef
23
+ in_def
24
+ in_class
25
+ in_block
26
+ in_lambda
27
+ ]
17
28
 
18
29
  def initialize
19
- @stack = []
20
- freeze
21
- end
22
-
23
- def push(state)
24
- @stack << state
25
- end
26
-
27
- def pop
28
- @stack.pop
30
+ reset
29
31
  end
30
32
 
31
33
  def reset
32
- @stack.clear
33
- end
34
-
35
- def in_class?
36
- @stack.last == :class
37
- end
38
-
39
- def indirectly_in_def?
40
- @stack.include?(:def) || @stack.include?(:defs)
41
- end
42
-
43
- def class_definition_allowed?
44
- def_index = stack.rindex { |item| [:def, :defs].include?(item) }
45
- sclass_index = stack.rindex(:sclass)
46
-
47
- def_index.nil? || (!sclass_index.nil? && sclass_index > def_index)
34
+ @in_defined = false
35
+ @in_kwarg = false
36
+ @in_argdef = false
37
+ @in_def = false
38
+ @in_class = false
39
+ @in_block = false
40
+ @in_lambda = false
48
41
  end
49
- alias module_definition_allowed? class_definition_allowed?
50
- alias dynamic_const_definition_allowed? class_definition_allowed?
51
42
 
52
- def in_block?
53
- @stack.last == :block
54
- end
55
-
56
- def in_lambda?
57
- @stack.last == :lambda
58
- end
43
+ attr_accessor(*FLAGS)
59
44
 
60
45
  def in_dynamic_block?
61
- in_block? || in_lambda?
46
+ in_block || in_lambda
62
47
  end
63
48
  end
64
49
  end
@@ -3,9 +3,9 @@
3
3
  module Parser
4
4
  class << self
5
5
  def warn_syntax_deviation(feature, version)
6
- warn "warning: parser/current is loading #{feature}, which recognizes"
7
- warn "warning: #{version}-compliant syntax, but you are running #{RUBY_VERSION}."
8
- warn "warning: please see https://github.com/whitequark/parser#compatibility-with-ruby-mri."
6
+ warn "warning: parser/current is loading #{feature}, which recognizes" \
7
+ "#{version}-compliant syntax, but you are running #{RUBY_VERSION}.\n" \
8
+ "Please see https://github.com/whitequark/parser#compatibility-with-ruby-mri."
9
9
  end
10
10
  private :warn_syntax_deviation
11
11
  end
@@ -57,7 +57,7 @@ module Parser
57
57
  CurrentRuby = Ruby24
58
58
 
59
59
  when /^2\.5\./
60
- current_version = '2.5.8'
60
+ current_version = '2.5.9'
61
61
  if RUBY_VERSION != current_version
62
62
  warn_syntax_deviation 'parser/ruby25', current_version
63
63
  end
@@ -66,7 +66,7 @@ module Parser
66
66
  CurrentRuby = Ruby25
67
67
 
68
68
  when /^2\.6\./
69
- current_version = '2.6.6'
69
+ current_version = '2.6.9'
70
70
  if RUBY_VERSION != current_version
71
71
  warn_syntax_deviation 'parser/ruby26', current_version
72
72
  end
@@ -75,7 +75,7 @@ module Parser
75
75
  CurrentRuby = Ruby26
76
76
 
77
77
  when /^2\.7\./
78
- current_version = '2.7.2'
78
+ current_version = '2.7.5'
79
79
  if RUBY_VERSION != current_version
80
80
  warn_syntax_deviation 'parser/ruby27', current_version
81
81
  end
@@ -84,7 +84,7 @@ module Parser
84
84
  CurrentRuby = Ruby27
85
85
 
86
86
  when /^3\.0\./
87
- current_version = '3.0.0-dev'
87
+ current_version = '3.0.3'
88
88
  if RUBY_VERSION != current_version
89
89
  warn_syntax_deviation 'parser/ruby30', current_version
90
90
  end
@@ -92,10 +92,28 @@ module Parser
92
92
  require 'parser/ruby30'
93
93
  CurrentRuby = Ruby30
94
94
 
95
+ when /^3\.1\./
96
+ current_version = '3.1.1'
97
+ if RUBY_VERSION != current_version
98
+ warn_syntax_deviation 'parser/ruby31', current_version
99
+ end
100
+
101
+ require 'parser/ruby31'
102
+ CurrentRuby = Ruby31
103
+
104
+ when /^3\.2\./
105
+ current_version = '3.2.0-dev'
106
+ if RUBY_VERSION != current_version
107
+ warn_syntax_deviation 'parser/ruby32', current_version
108
+ end
109
+
110
+ require 'parser/ruby32'
111
+ CurrentRuby = Ruby32
112
+
95
113
  else # :nocov:
96
114
  # Keep this in sync with released Ruby.
97
- warn_syntax_deviation 'parser/ruby27', '2.7.x'
98
- require 'parser/ruby27'
99
- CurrentRuby = Ruby27
115
+ warn_syntax_deviation 'parser/ruby31', '3.1.x'
116
+ require 'parser/ruby31'
117
+ CurrentRuby = Ruby31
100
118
  end
101
119
  end
@@ -19,13 +19,16 @@ module Parser
19
19
  freeze
20
20
  end
21
21
 
22
+ def empty?
23
+ @stack.size == 0
24
+ end
25
+
22
26
  def push(value)
23
27
  @stack << value
24
28
  end
25
29
 
26
30
  def set(value)
27
- pop
28
- push(value)
31
+ @stack[@stack.length - 1] = value
29
32
  end
30
33
 
31
34
  def pop
@@ -38,7 +38,13 @@ module Parser
38
38
  # Prevent the following error when processing binary encoded source.
39
39
  # "\xC0".split # => ArgumentError (invalid byte sequence in UTF-8)
40
40
  lines = string.force_encoding(Encoding::BINARY).split("\\\n")
41
- lines.map! {|s| s.force_encoding(original_encoding) }
41
+ if lines.length == 1
42
+ # If the line continuation sequence was found but there is no second
43
+ # line, it was not really a line continuation and must be ignored.
44
+ lines = [string.force_encoding(original_encoding)]
45
+ else
46
+ lines.map! {|s| s.force_encoding(original_encoding) }
47
+ end
42
48
 
43
49
  if @at_line_begin
44
50
  lines_to_dedent = lines
@@ -18,7 +18,7 @@ module Parser
18
18
  def advance
19
19
  type, (val, range) = advance_before_explanation
20
20
 
21
- more = "(in-kwarg)" if @in_kwarg
21
+ more = "(in-kwarg)" if @context.in_kwarg
22
22
 
23
23
  puts decorate(range,
24
24
  Color.green("#{type} #{val.inspect}"),