parser 3.0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b1e9fbbc406eb2665aa17f066247e6584182ebe365b3f1d2ace35628f3f12c6
4
- data.tar.gz: 8522d4ff0b299c14cb386156a6f04e7d7828bf8c33ed1331a22829ff873312c1
3
+ metadata.gz: 7ed45256e09de6d92098e12e73a655fe9d4f35518f573984bf1d92ac87ae8ded
4
+ data.tar.gz: 68ee7fca4f6d1794e2fb160552b01b983466cd482cad8783ba5f7b1466d0e70b
5
5
  SHA512:
6
- metadata.gz: 5871c263e07cdd6bf88f661419578977f9ddd9e01e1631bab14ff7fb485f466a7b8dacebcda30514d7d1f3c6746b8d2e1f6c6feb7de57a899a1cacfb728c05af
7
- data.tar.gz: 4decb43386adfd5be04356d3c9667c1880fa974ad14bc190312bf25a379fad92e4353b0812bcb8810e1863892f14a0daaf6d0c5d31523e2a45a1bb35f65c4ab0
6
+ metadata.gz: 2f8f0785aba15f53c97b046aa5155ffeff4063b12fb611612bd7c3b94affb282487b5aad5ca783d2b928a91333db6e572a2a8a466fe9c7f5716354cb23644471
7
+ data.tar.gz: b8ecfc04463142cffb2aaad920e95e11257a1a6f7587bf439620b73e59102f15850c413dc807b613379678de9878aa2d941f3fa65ab20716f6be6d80fcf03299
@@ -161,7 +161,7 @@ module Parser
161
161
  #
162
162
  # ```
163
163
  # (send nil :foo
164
- # (hash
164
+ # (kwargs
165
165
  # (pair
166
166
  # (sym :a)
167
167
  # (int 42))
@@ -518,12 +518,52 @@ module Parser
518
518
  n(:pair, [ key, value ], pair_map)
519
519
  end
520
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
+
521
535
  def kwsplat(dstar_t, arg)
522
536
  n(:kwsplat, [ arg ],
523
537
  unary_op_map(dstar_t, arg))
524
538
  end
525
539
 
526
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
+
527
567
  n(:hash, [ *pairs ],
528
568
  collection_map(begin_t, pairs, end_t))
529
569
  end
@@ -608,19 +648,29 @@ module Parser
608
648
  when :ident
609
649
  name, = *node
610
650
 
611
- if @parser.static_env.declared?(name)
612
- if name.to_s == parser.current_arg_stack.top
613
- diagnostic :error, :circular_argument_reference,
614
- { :var_name => name.to_s }, node.loc.expression
615
- 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
616
655
 
617
- node.updated(:lvar)
618
- else
619
- name, = *node
620
- 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 ],
621
664
  var_send_map(node))
622
665
  end
623
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
+
624
674
  else
625
675
  node
626
676
  end
@@ -664,7 +714,7 @@ module Parser
664
714
  node.updated(:gvasgn)
665
715
 
666
716
  when :const
667
- unless @parser.context.dynamic_const_definition_allowed?
717
+ if @parser.context.in_def
668
718
  diagnostic :error, :dynamic_const, nil, node.loc.expression
669
719
  end
670
720
 
@@ -683,6 +733,17 @@ module Parser
683
733
 
684
734
  node.updated(:lvasgn)
685
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
+
686
747
  when :nil, :self, :true, :false,
687
748
  :__FILE__, :__LINE__, :__ENCODING__
688
749
  diagnostic :error, :invalid_assignment, nil, node.loc.expression
@@ -818,8 +879,14 @@ module Parser
818
879
 
819
880
  def args(begin_t, args, end_t, check_args=true)
820
881
  args = check_duplicate_args(args) if check_args
821
- n(:args, args,
822
- 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
823
890
  end
824
891
 
825
892
  def numargs(max_numparam)
@@ -906,9 +973,12 @@ module Parser
906
973
  end
907
974
 
908
975
  def blockarg(amper_t, name_t)
909
- 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
910
979
 
911
- n(:blockarg, [ value(name_t).to_sym ],
980
+ arg_name = name_t ? value(name_t).to_sym : nil
981
+ n(:blockarg, [ arg_name ],
912
982
  arg_prefix_map(amper_t, name_t))
913
983
  end
914
984
 
@@ -1683,6 +1753,21 @@ module Parser
1683
1753
  end
1684
1754
  end
1685
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
+
1686
1771
  def check_assignment_to_numparam(name, loc)
1687
1772
  # MRI < 2.7 treats numbered parameters as regular variables
1688
1773
  # and so it's allowed to perform assignments like `_1 = 42`.
@@ -9,60 +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 empty?
36
- @stack.empty?
37
- end
38
-
39
- def in_class?
40
- @stack.last == :class
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
41
41
  end
42
42
 
43
- def indirectly_in_def?
44
- @stack.include?(:def) || @stack.include?(:defs)
45
- end
46
-
47
- def class_definition_allowed?
48
- def_index = stack.rindex { |item| [:def, :defs].include?(item) }
49
- sclass_index = stack.rindex(:sclass)
50
-
51
- def_index.nil? || (!sclass_index.nil? && sclass_index > def_index)
52
- end
53
- alias module_definition_allowed? class_definition_allowed?
54
- alias dynamic_const_definition_allowed? class_definition_allowed?
55
-
56
- def in_block?
57
- @stack.last == :block
58
- end
59
-
60
- def in_lambda?
61
- @stack.last == :lambda
62
- end
43
+ attr_accessor(*FLAGS)
63
44
 
64
45
  def in_dynamic_block?
65
- in_block? || in_lambda?
46
+ in_block || in_lambda
66
47
  end
67
48
  end
68
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
@@ -66,7 +66,7 @@ module Parser
66
66
  CurrentRuby = Ruby25
67
67
 
68
68
  when /^2\.6\./
69
- current_version = '2.6.8'
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.4'
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.2'
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
@@ -93,7 +93,7 @@ module Parser
93
93
  CurrentRuby = Ruby30
94
94
 
95
95
  when /^3\.1\./
96
- current_version = '3.1.0-dev'
96
+ current_version = '3.1.0'
97
97
  if RUBY_VERSION != current_version
98
98
  warn_syntax_deviation 'parser/ruby31', current_version
99
99
  end
@@ -103,8 +103,8 @@ module Parser
103
103
 
104
104
  else # :nocov:
105
105
  # Keep this in sync with released Ruby.
106
- warn_syntax_deviation 'parser/ruby30', '3.0.x'
107
- require 'parser/ruby30'
108
- CurrentRuby = Ruby30
106
+ warn_syntax_deviation 'parser/ruby31', '3.1.x'
107
+ require 'parser/ruby31'
108
+ CurrentRuby = Ruby31
109
109
  end
110
110
  end
@@ -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}"),