rubocop-ast 1.24.1 → 1.46.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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/rubocop/ast/builder.rb +104 -85
  4. data/lib/rubocop/ast/builder_prism.rb +11 -0
  5. data/lib/rubocop/ast/ext/range.rb +2 -2
  6. data/lib/rubocop/ast/node/args_node.rb +1 -1
  7. data/lib/rubocop/ast/node/array_node.rb +9 -5
  8. data/lib/rubocop/ast/node/asgn_node.rb +2 -0
  9. data/lib/rubocop/ast/node/block_node.rb +27 -8
  10. data/lib/rubocop/ast/node/casgn_node.rb +4 -12
  11. data/lib/rubocop/ast/node/complex_node.rb +13 -0
  12. data/lib/rubocop/ast/node/const_node.rb +1 -52
  13. data/lib/rubocop/ast/node/csend_node.rb +2 -2
  14. data/lib/rubocop/ast/node/def_node.rb +1 -1
  15. data/lib/rubocop/ast/node/ensure_node.rb +36 -0
  16. data/lib/rubocop/ast/node/for_node.rb +1 -1
  17. data/lib/rubocop/ast/node/hash_node.rb +1 -1
  18. data/lib/rubocop/ast/node/if_node.rb +11 -4
  19. data/lib/rubocop/ast/node/in_pattern_node.rb +1 -1
  20. data/lib/rubocop/ast/node/keyword_begin_node.rb +44 -0
  21. data/lib/rubocop/ast/node/keyword_splat_node.rb +10 -3
  22. data/lib/rubocop/ast/node/masgn_node.rb +63 -0
  23. data/lib/rubocop/ast/node/mixin/basic_literal_node.rb +1 -1
  24. data/lib/rubocop/ast/node/mixin/collection_node.rb +1 -1
  25. data/lib/rubocop/ast/node/mixin/constant_node.rb +62 -0
  26. data/lib/rubocop/ast/node/mixin/descendence.rb +3 -3
  27. data/lib/rubocop/ast/node/mixin/hash_element_node.rb +2 -0
  28. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +29 -19
  29. data/lib/rubocop/ast/node/mixin/numeric_node.rb +2 -2
  30. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +2 -2
  31. data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +7 -2
  32. data/lib/rubocop/ast/node/mlhs_node.rb +29 -0
  33. data/lib/rubocop/ast/node/op_asgn_node.rb +3 -1
  34. data/lib/rubocop/ast/node/rational_node.rb +13 -0
  35. data/lib/rubocop/ast/node/str_node.rb +37 -1
  36. data/lib/rubocop/ast/node/until_node.rb +1 -1
  37. data/lib/rubocop/ast/node/var_node.rb +15 -0
  38. data/lib/rubocop/ast/node/when_node.rb +1 -1
  39. data/lib/rubocop/ast/node/while_node.rb +1 -1
  40. data/lib/rubocop/ast/node.rb +131 -46
  41. data/lib/rubocop/ast/node_pattern/compiler/atom_subcompiler.rb +1 -1
  42. data/lib/rubocop/ast/node_pattern/compiler/binding.rb +3 -3
  43. data/lib/rubocop/ast/node_pattern/compiler/debug.rb +4 -9
  44. data/lib/rubocop/ast/node_pattern/compiler/sequence_subcompiler.rb +3 -4
  45. data/lib/rubocop/ast/node_pattern/compiler.rb +1 -1
  46. data/lib/rubocop/ast/node_pattern/lexer.rex.rb +1 -2
  47. data/lib/rubocop/ast/node_pattern/node.rb +15 -6
  48. data/lib/rubocop/ast/node_pattern/parser.racc.rb +4 -2
  49. data/lib/rubocop/ast/node_pattern/parser.rb +1 -1
  50. data/lib/rubocop/ast/node_pattern/with_meta.rb +3 -4
  51. data/lib/rubocop/ast/node_pattern.rb +1 -1
  52. data/lib/rubocop/ast/processed_source.rb +159 -58
  53. data/lib/rubocop/ast/token.rb +2 -1
  54. data/lib/rubocop/ast/traversal.rb +35 -25
  55. data/lib/rubocop/ast/utilities/simple_forwardable.rb +27 -0
  56. data/lib/rubocop/ast/version.rb +1 -1
  57. data/lib/rubocop/ast.rb +10 -1
  58. metadata +21 -19
  59. data/lib/rubocop/ast/ext/range_min_max.rb +0 -18
@@ -76,9 +76,6 @@ module RuboCop
76
76
  OPERATOR_KEYWORDS = %i[and or].to_set.freeze
77
77
  # @api private
78
78
  SPECIAL_KEYWORDS = %w[__FILE__ __LINE__ __ENCODING__].to_set.freeze
79
- # @api private
80
- ARGUMENT_TYPES = %i[arg optarg restarg kwarg kwoptarg kwrestarg
81
- blockarg forward_arg shadowarg].to_set.freeze
82
79
 
83
80
  LITERAL_RECURSIVE_METHODS = (COMPARISON_OPERATORS + %i[* ! <=>]).freeze
84
81
  LITERAL_RECURSIVE_TYPES = (OPERATOR_KEYWORDS + COMPOSITE_LITERALS + %i[begin pair]).freeze
@@ -88,6 +85,65 @@ module RuboCop
88
85
  EMPTY_PROPERTIES = {}.freeze
89
86
  private_constant :EMPTY_CHILDREN, :EMPTY_PROPERTIES
90
87
 
88
+ # @api private
89
+ GROUP_FOR_TYPE = {
90
+ def: :any_def,
91
+ defs: :any_def,
92
+
93
+ arg: :argument,
94
+ optarg: :argument,
95
+ restarg: :argument,
96
+ kwarg: :argument,
97
+ kwoptarg: :argument,
98
+ kwrestarg: :argument,
99
+ blockarg: :argument,
100
+ forward_arg: :argument,
101
+ shadowarg: :argument,
102
+
103
+ true: :boolean,
104
+ false: :boolean,
105
+
106
+ int: :numeric,
107
+ float: :numeric,
108
+ rational: :numeric,
109
+ complex: :numeric,
110
+
111
+ irange: :range,
112
+ erange: :range,
113
+
114
+ send: :call,
115
+ csend: :call,
116
+
117
+ block: :any_block,
118
+ numblock: :any_block,
119
+ itblock: :any_block,
120
+
121
+ match_pattern: :any_match_pattern,
122
+ match_pattern_p: :any_match_pattern
123
+ }.freeze
124
+ private_constant :GROUP_FOR_TYPE
125
+
126
+ # Define a +recursive_?+ predicate method for the given node kind.
127
+ private_class_method def self.def_recursive_literal_predicate(kind) # rubocop:disable Metrics/MethodLength
128
+ recursive_kind = "recursive_#{kind}?"
129
+ kind_filter = "#{kind}?"
130
+
131
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
132
+ def #{recursive_kind} # def recursive_literal?
133
+ case type # case type
134
+ when :send # when :send
135
+ LITERAL_RECURSIVE_METHODS.include?(method_name) && # LITERAL_RECURSIVE_METHODS.include?(method_name) &&
136
+ receiver.send(:#{recursive_kind}) && # receiver.send(:recursive_literal?) &&
137
+ arguments.all?(&:#{recursive_kind}) # arguments.all?(&:recursive_literal?)
138
+ when LITERAL_RECURSIVE_TYPES # when LITERAL_RECURSIVE_TYPES
139
+ children.compact.all?(&:#{recursive_kind}) # children.compact.all?(&:recursive_literal?)
140
+ else # else
141
+ send(:#{kind_filter}) # send(:literal?)
142
+ end # end
143
+ end # end
144
+ RUBY
145
+ end
146
+
91
147
  # @see https://www.rubydoc.info/gems/ast/AST/Node:initialize
92
148
  def initialize(type, children = EMPTY_CHILDREN, properties = EMPTY_PROPERTIES)
93
149
  @mutable_attributes = {}
@@ -105,6 +161,16 @@ module RuboCop
105
161
  end
106
162
  end
107
163
 
164
+ # Determine if the node is one of several node types in a single query
165
+ # Allows specific single node types, as well as "grouped" types
166
+ # (e.g. `:boolean` for `:true` or `:false`)
167
+ def type?(*types)
168
+ return true if types.include?(type)
169
+
170
+ group_type = GROUP_FOR_TYPE[type]
171
+ !group_type.nil? && types.include?(group_type)
172
+ end
173
+
108
174
  (Parser::Meta::NODE_TYPES - [:send]).each do |node_type|
109
175
  method_name = "#{node_type.to_s.gsub(/\W/, '')}_type?"
110
176
  class_eval <<~RUBY, __FILE__, __LINE__ + 1
@@ -206,7 +272,7 @@ module RuboCop
206
272
  def right_siblings
207
273
  return [].freeze unless parent
208
274
 
209
- parent.children[sibling_index + 1..].freeze
275
+ parent.children[(sibling_index + 1)..].freeze
210
276
  end
211
277
 
212
278
  # Common destructuring method. This can be used to normalize
@@ -284,20 +350,19 @@ module RuboCop
284
350
 
285
351
  # @!method receiver(node = self)
286
352
  def_node_matcher :receiver, <<~PATTERN
287
- {(send $_ ...) ({block numblock} (call $_ ...) ...)}
353
+ {(send $_ ...) (any_block (call $_ ...) ...)}
288
354
  PATTERN
289
355
 
290
356
  # @!method str_content(node = self)
291
357
  def_node_matcher :str_content, '(str $_)'
292
358
 
293
359
  def const_name
294
- return unless const_type?
360
+ return unless const_type? || casgn_type?
295
361
 
296
- namespace, name = *self
297
362
  if namespace && !namespace.cbase_type?
298
- "#{namespace.const_name}::#{name}"
363
+ "#{namespace.const_name}::#{short_name}"
299
364
  else
300
- name.to_s
365
+ short_name.to_s
301
366
  end
302
367
  end
303
368
 
@@ -326,13 +391,13 @@ module RuboCop
326
391
  # what class or module is this method/constant/etc definition in?
327
392
  # returns nil if answer cannot be determined
328
393
  ancestors = each_ancestor(:class, :module, :sclass, :casgn, :block)
329
- result = ancestors.map do |ancestor|
394
+ result = ancestors.filter_map do |ancestor|
330
395
  parent_module_name_part(ancestor) do |full_name|
331
396
  return nil unless full_name
332
397
 
333
398
  full_name
334
399
  end
335
- end.compact.reverse.join('::')
400
+ end.reverse.join('::')
336
401
  result.empty? ? 'Object' : result
337
402
  end
338
403
 
@@ -380,22 +445,11 @@ module RuboCop
380
445
  IMMUTABLE_LITERALS.include?(type)
381
446
  end
382
447
 
383
- %i[literal basic_literal].each do |kind|
384
- recursive_kind = :"recursive_#{kind}?"
385
- kind_filter = :"#{kind}?"
386
- define_method(recursive_kind) do
387
- case type
388
- when :send
389
- LITERAL_RECURSIVE_METHODS.include?(method_name) &&
390
- receiver.send(recursive_kind) &&
391
- arguments.all?(&recursive_kind)
392
- when LITERAL_RECURSIVE_TYPES
393
- children.compact.all?(&recursive_kind)
394
- else
395
- send(kind_filter)
396
- end
397
- end
398
- end
448
+ # @!macro [attach] def_recursive_literal_predicate
449
+ # @!method recursive_$1?
450
+ # @return [Boolean]
451
+ def_recursive_literal_predicate :literal
452
+ def_recursive_literal_predicate :basic_literal
399
453
 
400
454
  def variable?
401
455
  VARIABLES.include?(type)
@@ -450,11 +504,11 @@ module RuboCop
450
504
  end
451
505
 
452
506
  def parenthesized_call?
453
- loc.respond_to?(:begin) && loc.begin && loc.begin.is?('(')
507
+ loc_is?(:begin, '(')
454
508
  end
455
509
 
456
510
  def call_type?
457
- send_type? || csend_type?
511
+ GROUP_FOR_TYPE[type] == :call
458
512
  end
459
513
 
460
514
  def chained?
@@ -465,28 +519,56 @@ module RuboCop
465
519
  parent&.send_type? && parent.arguments.include?(self)
466
520
  end
467
521
 
522
+ def any_def_type?
523
+ GROUP_FOR_TYPE[type] == :any_def
524
+ end
525
+
468
526
  def argument_type?
469
- ARGUMENT_TYPES.include?(type)
527
+ GROUP_FOR_TYPE[type] == :argument
470
528
  end
471
529
 
472
530
  def boolean_type?
473
- true_type? || false_type?
531
+ GROUP_FOR_TYPE[type] == :boolean
474
532
  end
475
533
 
476
534
  def numeric_type?
477
- int_type? || float_type? || rational_type? || complex_type?
535
+ GROUP_FOR_TYPE[type] == :numeric
478
536
  end
479
537
 
480
538
  def range_type?
481
- irange_type? || erange_type?
539
+ GROUP_FOR_TYPE[type] == :range
540
+ end
541
+
542
+ def any_block_type?
543
+ GROUP_FOR_TYPE[type] == :any_block
544
+ end
545
+
546
+ def any_match_pattern_type?
547
+ GROUP_FOR_TYPE[type] == :any_match_pattern
482
548
  end
483
549
 
484
550
  def guard_clause?
485
- node = and_type? || or_type? ? rhs : self
551
+ node = operator_keyword? ? rhs : self
486
552
 
487
553
  node.match_guard_clause?
488
554
  end
489
555
 
556
+ # Shortcut to safely check if a location is present
557
+ # @return [Boolean]
558
+ def loc?(which_loc)
559
+ return false unless loc.respond_to?(which_loc)
560
+
561
+ !loc.public_send(which_loc).nil?
562
+ end
563
+
564
+ # Shortcut to safely test a particular location, even if
565
+ # this location does not exist or is `nil`
566
+ def loc_is?(which_loc, str)
567
+ return false unless loc?(which_loc)
568
+
569
+ loc.public_send(which_loc).is?(str)
570
+ end
571
+
490
572
  # @!method match_guard_clause?(node = self)
491
573
  def_node_matcher :match_guard_clause?, <<~PATTERN
492
574
  [${(send nil? {:raise :fail} ...) return break next} single_line?]
@@ -500,7 +582,7 @@ module RuboCop
500
582
  PATTERN
501
583
 
502
584
  # @!method lambda?(node = self)
503
- def_node_matcher :lambda?, '({block numblock} (send nil? :lambda) ...)'
585
+ def_node_matcher :lambda?, '(any_block (send nil? :lambda) ...)'
504
586
 
505
587
  # @!method lambda_or_proc?(node = self)
506
588
  def_node_matcher :lambda_or_proc?, '{lambda? proc?}'
@@ -510,27 +592,33 @@ module RuboCop
510
592
 
511
593
  # @!method class_constructor?(node = self)
512
594
  def_node_matcher :class_constructor?, <<~PATTERN
513
- { (send #global_const?({:Class :Module :Struct}) :new ...)
514
- (block (send #global_const?({:Class :Module :Struct}) :new ...) ...)}
595
+ {
596
+ (send #global_const?({:Class :Module :Struct}) :new ...)
597
+ (send #global_const?(:Data) :define ...)
598
+ (any_block {
599
+ (send #global_const?({:Class :Module :Struct}) :new ...)
600
+ (send #global_const?(:Data) :define ...)
601
+ } ...)
602
+ }
515
603
  PATTERN
516
604
 
517
605
  # @deprecated Use `:class_constructor?`
518
606
  # @!method struct_constructor?(node = self)
519
607
  def_node_matcher :struct_constructor?, <<~PATTERN
520
- ({block numblock} (send #global_const?(:Struct) :new ...) _ $_)
608
+ (any_block (send #global_const?(:Struct) :new ...) _ $_)
521
609
  PATTERN
522
610
 
523
611
  # @!method class_definition?(node = self)
524
612
  def_node_matcher :class_definition?, <<~PATTERN
525
613
  {(class _ _ $_)
526
614
  (sclass _ $_)
527
- ({block numblock} (send #global_const?({:Struct :Class}) :new ...) _ $_)}
615
+ (any_block (send #global_const?({:Struct :Class}) :new ...) _ $_)}
528
616
  PATTERN
529
617
 
530
618
  # @!method module_definition?(node = self)
531
619
  def_node_matcher :module_definition?, <<~PATTERN
532
620
  {(module _ $_)
533
- ({block numblock} (send #global_const?(:Module) :new ...) _ $_)}
621
+ (any_block (send #global_const?(:Module) :new ...) _ $_)}
534
622
  PATTERN
535
623
 
536
624
  # Some expressions are evaluated for their value, some for their side
@@ -541,8 +629,7 @@ module RuboCop
541
629
  # So, does the return value of this node matter? If we changed it to
542
630
  # `(...; nil)`, might that affect anything?
543
631
  #
544
- # rubocop:disable Metrics/MethodLength
545
- def value_used?
632
+ def value_used? # rubocop:disable Metrics/MethodLength
546
633
  # Be conservative and return true if we're not sure.
547
634
  return false if parent.nil?
548
635
 
@@ -563,7 +650,6 @@ module RuboCop
563
650
  true
564
651
  end
565
652
  end
566
- # rubocop:enable Metrics/MethodLength
567
653
 
568
654
  # Some expressions are evaluated for their value, some for their side
569
655
  # effects, and some for both.
@@ -595,8 +681,7 @@ module RuboCop
595
681
  last_node = self
596
682
 
597
683
  while (current_node = last_node.parent)
598
- yield current_node if types.empty? ||
599
- types.include?(current_node.type)
684
+ yield current_node if types.empty? || current_node.type?(*types)
600
685
  last_node = current_node
601
686
  end
602
687
  end
@@ -615,7 +700,7 @@ module RuboCop
615
700
  def case_if_value_used?
616
701
  # (case <condition> <when...>)
617
702
  # (if <condition> <truebranch> <falsebranch>)
618
- sibling_index.zero? ? true : parent.value_used?
703
+ sibling_index.zero? || parent.value_used?
619
704
  end
620
705
 
621
706
  def while_until_value_used?
@@ -38,7 +38,7 @@ module RuboCop
38
38
  end
39
39
 
40
40
  def visit_set
41
- set = node.children.map(&:child).to_set.freeze
41
+ set = node.children.to_set(&:child).freeze
42
42
  NodePattern::Sets[set]
43
43
  end
44
44
 
@@ -26,8 +26,9 @@ module RuboCop
26
26
  var
27
27
  end
28
28
 
29
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
30
- def union_bind(enum)
29
+ # Yields for each branch of the given union, forbidding unification of
30
+ # bindings which only appear in a subset of the union.
31
+ def union_bind(enum) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
31
32
  # We need to reset @bound before each branch is processed.
32
33
  # Moreover we need to keep track of newly encountered wildcards.
33
34
  # Var `newly_bound_intersection` will hold those that are encountered
@@ -62,7 +63,6 @@ module RuboCop
62
63
 
63
64
  result
64
65
  end
65
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
66
66
 
67
67
  private
68
68
 
@@ -15,10 +15,12 @@ module RuboCop
15
15
  @visit = {}
16
16
  end
17
17
 
18
+ # rubocop:disable Naming/PredicateMethod
18
19
  def enter(node_id)
19
20
  @visit[node_id] = false
20
21
  true
21
22
  end
23
+ # rubocop:enable Naming/PredicateMethod
22
24
 
23
25
  def success(node_id)
24
26
  @visit[node_id] = true
@@ -47,7 +49,7 @@ module RuboCop
47
49
  # @return [String] a Rainbow colorized version of ruby
48
50
  def colorize(color_scheme = COLOR_SCHEME)
49
51
  map = color_map(color_scheme)
50
- ast.loc.expression.source_buffer.source.chars.map.with_index do |char, i|
52
+ ast.source_range.source_buffer.source.chars.map.with_index do |char, i|
51
53
  Rainbow(char).color(map[i])
52
54
  end.join
53
55
  end
@@ -109,14 +111,7 @@ module RuboCop
109
111
  private
110
112
 
111
113
  def ruby_ast(ruby)
112
- buffer = ::Parser::Source::Buffer.new('(ruby)', source: ruby)
113
- ruby_parser.parse(buffer)
114
- end
115
-
116
- def ruby_parser
117
- require 'parser/current'
118
- builder = ::RuboCop::AST::Builder.new
119
- ::Parser::CurrentRuby.new(builder)
114
+ ProcessedSource.new(ruby, RUBY_VERSION.to_f, '(ruby)').ast
120
115
  end
121
116
  end
122
117
 
@@ -13,8 +13,8 @@ module RuboCop
13
13
  # Doc on how this fits in the compiling process:
14
14
  # /docs/modules/ROOT/pages/node_pattern.adoc
15
15
  #
16
- # rubocop:disable Metrics/ClassLength
17
- class SequenceSubcompiler < Subcompiler
16
+ class SequenceSubcompiler < Subcompiler # rubocop:disable Metrics/ClassLength
17
+ # Shift of 1 from standard Ruby indices
18
18
  DELTA = 1
19
19
  POSITIVE = :positive?.to_proc
20
20
  private_constant :POSITIVE
@@ -261,7 +261,7 @@ module RuboCop
261
261
  arities = children
262
262
  .reverse
263
263
  .map(&:arity_range)
264
- .map { |r| last = last.begin + r.begin..last.max + r.max }
264
+ .map { |r| last = (last.begin + r.begin)..(last.max + r.max) }
265
265
  .reverse!
266
266
  arities.push last_arity
267
267
  end
@@ -413,7 +413,6 @@ module RuboCop
413
413
  @in_sync = sub_compilers.all?(&:in_sync)
414
414
  end
415
415
  end
416
- # rubocop:enable Metrics/ClassLength
417
416
  end
418
417
  end
419
418
  end
@@ -9,7 +9,7 @@ module RuboCop
9
9
  # Doc on how this fits in the compiling process:
10
10
  # /docs/modules/ROOT/pages/node_pattern.adoc
11
11
  class Compiler
12
- extend Forwardable
12
+ extend SimpleForwardable
13
13
  attr_reader :captures, :named_parameters, :positional_parameters, :binding
14
14
 
15
15
  def initialize
@@ -2,7 +2,7 @@
2
2
  # encoding: UTF-8
3
3
  #--
4
4
  # This file is automatically generated. Do not modify it.
5
- # Generated by: oedipus_lex version 2.6.0.
5
+ # Generated by: oedipus_lex version 2.6.2.
6
6
  # Source: lib/rubocop/ast/node_pattern/lexer.rex
7
7
  #++
8
8
 
@@ -70,7 +70,6 @@ class RuboCop::AST::NodePattern::LexerRex
70
70
  yield
71
71
  end
72
72
 
73
-
74
73
  ##
75
74
  # The current scanner class. Must be overridden in subclasses.
76
75
 
@@ -5,9 +5,8 @@ module RuboCop
5
5
  class NodePattern
6
6
  # Base class for AST Nodes of a `NodePattern`
7
7
  class Node < ::Parser::AST::Node
8
- extend Forwardable
8
+ extend SimpleForwardable
9
9
  include ::RuboCop::AST::Descendence
10
- using Ext::RangeMinMax
11
10
 
12
11
  MATCHES_WITHIN_SET = %i[symbol number string].to_set.freeze
13
12
  private_constant :MATCHES_WITHIN_SET
@@ -49,7 +48,7 @@ module RuboCop
49
48
  children[0]
50
49
  end
51
50
 
52
- # @return [Integer] nb of captures of that node and its descendants
51
+ # @return [Integer] nb of captures that this node will emit
53
52
  def nb_captures
54
53
  children_nodes.sum(&:nb_captures)
55
54
  end
@@ -75,6 +74,10 @@ module RuboCop
75
74
  self.class.new(type, children, { location: location })
76
75
  end
77
76
 
77
+ def source_range
78
+ loc.expression
79
+ end
80
+
78
81
  INT_TO_RANGE = Hash.new { |h, k| h[k] = k..k }
79
82
  private_constant :INT_TO_RANGE
80
83
 
@@ -176,7 +179,7 @@ module RuboCop
176
179
  class AnyOrder < Node
177
180
  include ForbidInSeqHead
178
181
 
179
- ARITIES = Hash.new { |h, k| h[k] = k - 1..Float::INFINITY }
182
+ ARITIES = Hash.new { |h, k| h[k] = (k - 1)..Float::INFINITY }
180
183
  private_constant :ARITIES
181
184
 
182
185
  def term_nodes
@@ -203,7 +206,7 @@ module RuboCop
203
206
  include ForbidInSeqHead
204
207
 
205
208
  def arity
206
- min, max = children.map(&:arity_range).map(&:minmax).transpose.map(&:sum)
209
+ min, max = children.map { |child| child.arity_range.minmax }.transpose.map(&:sum)
207
210
  min == max ? min || 0 : min..max # NOTE: || 0 for empty case, where min == max == nil.
208
211
  end
209
212
 
@@ -219,7 +222,7 @@ module RuboCop
219
222
  # Node class for `{ ... }`
220
223
  class Union < Node
221
224
  def arity
222
- minima, maxima = children.map(&:arity_range).map(&:minmax).transpose
225
+ minima, maxima = children.map { |child| child.arity_range.minmax }.transpose
223
226
  min = minima.min
224
227
  max = maxima.max
225
228
  min == max ? min : min..max
@@ -240,6 +243,12 @@ module RuboCop
240
243
 
241
244
  [with(children: new_children)]
242
245
  end
246
+
247
+ # Each child in a union must contain the same number
248
+ # of captures. Only one branch ends up capturing.
249
+ def nb_captures
250
+ child.nb_captures
251
+ end
243
252
  end
244
253
 
245
254
  # Registry
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
  #
3
3
  # DO NOT MODIFY!!!!
4
- # This file is automatically generated by Racc 1.5.1
5
- # from Racc grammar file "".
4
+ # This file is automatically generated by Racc 1.8.1
5
+ # from Racc grammar file "parser.y".
6
6
  #
7
7
 
8
8
  require 'racc/parser.rb'
@@ -239,6 +239,7 @@ Racc_arg = [
239
239
  racc_shift_n,
240
240
  racc_reduce_n,
241
241
  racc_use_result_var ]
242
+ Ractor.make_shareable(Racc_arg) if defined?(Ractor)
242
243
 
243
244
  Racc_token_to_s_table = [
244
245
  "$end",
@@ -289,6 +290,7 @@ Racc_token_to_s_table = [
289
290
  "opt_rest",
290
291
  "rest",
291
292
  "arg_list" ]
293
+ Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor)
292
294
 
293
295
  Racc_debug_parser = false
294
296
 
@@ -11,7 +11,7 @@ module RuboCop
11
11
  # Doc on how this fits in the compiling process:
12
12
  # /docs/modules/ROOT/pages/node_pattern.adoc
13
13
  class Parser < Racc::Parser
14
- extend Forwardable
14
+ extend SimpleForwardable
15
15
 
16
16
  Builder = NodePattern::Builder
17
17
  Lexer = NodePattern::Lexer
@@ -48,12 +48,12 @@ module RuboCop
48
48
 
49
49
  def emit_unary_op(type, operator_t = nil, *children)
50
50
  children[-1] = children[-1].first if children[-1].is_a?(Array) # token?
51
- map = source_map(children.first.loc.expression, operator_t: operator_t)
51
+ map = source_map(children.first.source_range, operator_t: operator_t)
52
52
  n(type, children, map)
53
53
  end
54
54
 
55
55
  def emit_list(type, begin_t, children, end_t)
56
- expr = children.first.loc.expression.join(children.last.loc.expression)
56
+ expr = children.first.source_range.join(children.last.source_range)
57
57
  map = source_map(expr, begin_t: begin_t, end_t: end_t)
58
58
  n(type, children, map)
59
59
  end
@@ -79,8 +79,7 @@ module RuboCop
79
79
  end
80
80
 
81
81
  def join_exprs(left_expr, right_expr)
82
- left_expr.loc.expression
83
- .join(right_expr.loc.expression)
82
+ left_expr.source_range.join(right_expr.source_range)
84
83
  end
85
84
 
86
85
  def source_map(token_or_range, begin_t: nil, end_t: nil, operator_t: nil, selector_t: nil)
@@ -48,7 +48,7 @@ module RuboCop
48
48
  end
49
49
  end
50
50
 
51
- extend Forwardable
51
+ extend SimpleForwardable
52
52
  include MethodDefiner
53
53
  Invalid = Class.new(StandardError)
54
54