rubocop-ast 1.37.0 → 1.38.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71290c5f117f13043b681f7ce182d115284b84675bbfc0bf35448152ebfb42bd
4
- data.tar.gz: 3c13a0e8e089409da5dd353bfea60c3981f56dac094f7a650690f3862bdf3e36
3
+ metadata.gz: 3a3205a51f90d1dc493ef4c1ec96a4f40ed796dfc58bfc3661db72e67e134abc
4
+ data.tar.gz: 6d55fec1f58d712845ecb936db794934ea264e64b0adeb2c097fae63a5e5cb3e
5
5
  SHA512:
6
- metadata.gz: '08c425d33229f9116b91905ef14ea762ad2d17603ae581795d3101526a51ee6a4c8e1ab2e508f2355b688e4143f668e71767f8283934ee3b27f045315add0a28'
7
- data.tar.gz: 58173b8980810073f670c9087905923661d8a3fe0a43c17b354388ee07728611a6c5d1a690a2813184a6d4286c29c090d11d4f28de001ae395bfb774c53720bc
6
+ metadata.gz: 9468ab39ad7cd4ca56f0781605f07136dc89dfcbafc51482d5045799b468bf389d3c61671f49c7242f3dfbcc99090f3bd4b0c178d08b6038818b0158e3078658
7
+ data.tar.gz: a5b2b0604abdd935bfba3213a908678b5697cee7345f5b9941bfdddbfc08ceb8e86cab35895490f2612fd71937baa2ff5b7d75bb2ee4dafb5efd656178dc00c1
@@ -32,7 +32,7 @@ module RuboCop
32
32
  #
33
33
  # @return [Array<Node>] array of argument nodes.
34
34
  def argument_list
35
- each_descendant(*ARGUMENT_TYPES).to_a.freeze
35
+ each_descendant(:argument).to_a.freeze
36
36
  end
37
37
  end
38
38
  end
@@ -7,8 +7,8 @@ module RuboCop
7
7
  # to all `array` nodes within RuboCop.
8
8
  class ArrayNode < Node
9
9
  PERCENT_LITERAL_TYPES = {
10
- string: /^%[wW]/,
11
- symbol: /^%[iI]/
10
+ string: /\A%[wW]/,
11
+ symbol: /\A%[iI]/
12
12
  }.freeze
13
13
  private_constant :PERCENT_LITERAL_TYPES
14
14
 
@@ -50,7 +50,7 @@ module RuboCop
50
50
  # @return [Boolean] whether the array is enclosed in percent brackets
51
51
  def percent_literal?(type = nil)
52
52
  if type
53
- loc.begin && loc.begin.source =~ PERCENT_LITERAL_TYPES[type]
53
+ loc.begin&.source&.match?(PERCENT_LITERAL_TYPES.fetch(type))
54
54
  else
55
55
  loc.begin&.source&.start_with?('%')
56
56
  end
@@ -47,14 +47,14 @@ module RuboCop
47
47
  #
48
48
  # @return [Boolean] whether the node has an `else` clause
49
49
  def else?
50
- loc.respond_to?(:else) && loc.else
50
+ loc?(:else)
51
51
  end
52
52
 
53
53
  # Checks whether the `if` node is a ternary operator.
54
54
  #
55
55
  # @return [Boolean] whether the `if` node is a ternary operator
56
56
  def ternary?
57
- loc.respond_to?(:question)
57
+ loc?(:question)
58
58
  end
59
59
 
60
60
  # Returns the keyword of the `if` statement as a string. Returns an empty
@@ -25,7 +25,7 @@ module RuboCop
25
25
  children.each do |child|
26
26
  next unless child.is_a?(::AST::Node)
27
27
 
28
- yield child if types.empty? || types.include?(child.type)
28
+ yield child if types.empty? || child.type?(*types)
29
29
  end
30
30
 
31
31
  self
@@ -95,7 +95,7 @@ module RuboCop
95
95
  def each_node(*types, &block)
96
96
  return to_enum(__method__, *types) unless block
97
97
 
98
- yield self if types.empty? || types.include?(type)
98
+ yield self if types.empty? || type?(*types)
99
99
 
100
100
  visit_descendants(types, &block)
101
101
 
@@ -108,7 +108,7 @@ module RuboCop
108
108
  children.each do |child|
109
109
  next unless child.is_a?(::AST::Node)
110
110
 
111
- yield child if types.empty? || types.include?(child.type)
111
+ yield child if types.empty? || child.type?(*types)
112
112
  child.visit_descendants(types, &block)
113
113
  end
114
114
  end
@@ -105,7 +105,7 @@ module RuboCop
105
105
  #
106
106
  # @return [Boolean] whether the dispatched method is a setter
107
107
  def setter_method?
108
- loc.respond_to?(:operator) && loc.operator
108
+ loc?(:operator)
109
109
  end
110
110
  alias assignment? setter_method?
111
111
 
@@ -165,7 +165,7 @@ module RuboCop
165
165
  #
166
166
  # @return [Boolean] whether the dispatched method has a block
167
167
  def block_literal?
168
- (parent&.block_type? || parent&.numblock_type?) && eql?(parent.send_node)
168
+ parent&.any_block_type? && eql?(parent.send_node)
169
169
  end
170
170
 
171
171
  # Checks whether this node is an arithmetic operation
@@ -260,7 +260,7 @@ module RuboCop
260
260
  ^{ # or the parent is...
261
261
  sclass class module class_constructor? # a class-like node
262
262
  [ { # or some "wrapper"
263
- kwbegin begin block numblock
263
+ kwbegin begin any_block
264
264
  (if _condition <%0 _>) # note: we're excluding the condition of `if` nodes
265
265
  }
266
266
  #in_macro_scope? # that is itself in a macro scope
@@ -14,6 +14,11 @@ module RuboCop
14
14
  SEMANTIC_OR = 'or'
15
15
  private_constant :SEMANTIC_OR
16
16
 
17
+ LOGICAL_OPERATORS = [LOGICAL_AND, LOGICAL_OR].freeze
18
+ private_constant :LOGICAL_OPERATORS
19
+ SEMANTIC_OPERATORS = [SEMANTIC_AND, SEMANTIC_OR].freeze
20
+ private_constant :SEMANTIC_OPERATORS
21
+
17
22
  # Returns the operator as a string.
18
23
  #
19
24
  # @return [String] the operator
@@ -25,14 +30,14 @@ module RuboCop
25
30
  #
26
31
  # @return [Boolean] whether this is a logical operator
27
32
  def logical_operator?
28
- operator == LOGICAL_AND || operator == LOGICAL_OR
33
+ LOGICAL_OPERATORS.include?(operator)
29
34
  end
30
35
 
31
36
  # Checks whether this is a semantic operator.
32
37
  #
33
38
  # @return [Boolean] whether this is a semantic operator
34
39
  def semantic_operator?
35
- operator == SEMANTIC_AND || operator == SEMANTIC_OR
40
+ SEMANTIC_OPERATORS.include?(operator)
36
41
  end
37
42
  end
38
43
  end
@@ -13,6 +13,7 @@ module RuboCop
13
13
  :q => /\A%q/,
14
14
  :Q => /\A%Q/
15
15
  }.freeze
16
+ private_constant :PERCENT_LITERAL_TYPES
16
17
 
17
18
  def single_quoted?
18
19
  loc_is?(:begin, "'")
@@ -42,13 +43,12 @@ module RuboCop
42
43
  #
43
44
  # @return [Boolean] whether the string is enclosed in percent brackets
44
45
  def percent_literal?(type = nil)
45
- opening_delimiter = loc.begin if loc.respond_to?(:begin)
46
- return false unless opening_delimiter
46
+ return false unless loc?(:begin)
47
47
 
48
48
  if type
49
- opening_delimiter.source.match?(PERCENT_LITERAL_TYPES.fetch(type))
49
+ loc.begin.source.match?(PERCENT_LITERAL_TYPES.fetch(type))
50
50
  else
51
- opening_delimiter.source.start_with?('%')
51
+ loc.begin.source.start_with?('%')
52
52
  end
53
53
  end
54
54
  end
@@ -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
@@ -98,7 +95,7 @@ module RuboCop
98
95
  kwrestarg: :argument,
99
96
  blockarg: :argument,
100
97
  forward_arg: :argument,
101
- shardowarg: :argument,
98
+ shadowarg: :argument,
102
99
 
103
100
  true: :boolean,
104
101
  false: :boolean,
@@ -112,7 +109,10 @@ module RuboCop
112
109
  erange: :range,
113
110
 
114
111
  send: :call,
115
- csend: :call
112
+ csend: :call,
113
+
114
+ block: :any_block,
115
+ numblock: :any_block
116
116
  }.freeze
117
117
  private_constant :GROUP_FOR_TYPE
118
118
 
@@ -343,7 +343,7 @@ module RuboCop
343
343
 
344
344
  # @!method receiver(node = self)
345
345
  def_node_matcher :receiver, <<~PATTERN
346
- {(send $_ ...) ({block numblock} (call $_ ...) ...)}
346
+ {(send $_ ...) (any_block (call $_ ...) ...)}
347
347
  PATTERN
348
348
 
349
349
  # @!method str_content(node = self)
@@ -528,21 +528,30 @@ module RuboCop
528
528
  GROUP_FOR_TYPE[type] == :range
529
529
  end
530
530
 
531
+ def any_block_type?
532
+ GROUP_FOR_TYPE[type] == :any_block
533
+ end
534
+
531
535
  def guard_clause?
532
536
  node = operator_keyword? ? rhs : self
533
537
 
534
538
  node.match_guard_clause?
535
539
  end
536
540
 
541
+ # Shortcut to safely check if a location is present
542
+ # @return [Boolean]
543
+ def loc?(which_loc)
544
+ return false unless loc.respond_to?(which_loc)
545
+
546
+ !loc.public_send(which_loc).nil?
547
+ end
548
+
537
549
  # Shortcut to safely test a particular location, even if
538
550
  # this location does not exist or is `nil`
539
551
  def loc_is?(which_loc, str)
540
- return false unless loc.respond_to?(which_loc)
541
-
542
- location = loc.public_send(which_loc)
543
- return false unless location
552
+ return false unless loc?(which_loc)
544
553
 
545
- location.is?(str)
554
+ loc.public_send(which_loc).is?(str)
546
555
  end
547
556
 
548
557
  # @!method match_guard_clause?(node = self)
@@ -558,7 +567,7 @@ module RuboCop
558
567
  PATTERN
559
568
 
560
569
  # @!method lambda?(node = self)
561
- def_node_matcher :lambda?, '({block numblock} (send nil? :lambda) ...)'
570
+ def_node_matcher :lambda?, '(any_block (send nil? :lambda) ...)'
562
571
 
563
572
  # @!method lambda_or_proc?(node = self)
564
573
  def_node_matcher :lambda_or_proc?, '{lambda? proc?}'
@@ -571,7 +580,7 @@ module RuboCop
571
580
  {
572
581
  (send #global_const?({:Class :Module :Struct}) :new ...)
573
582
  (send #global_const?(:Data) :define ...)
574
- ({block numblock} {
583
+ (any_block {
575
584
  (send #global_const?({:Class :Module :Struct}) :new ...)
576
585
  (send #global_const?(:Data) :define ...)
577
586
  } ...)
@@ -581,20 +590,20 @@ module RuboCop
581
590
  # @deprecated Use `:class_constructor?`
582
591
  # @!method struct_constructor?(node = self)
583
592
  def_node_matcher :struct_constructor?, <<~PATTERN
584
- ({block numblock} (send #global_const?(:Struct) :new ...) _ $_)
593
+ (any_block (send #global_const?(:Struct) :new ...) _ $_)
585
594
  PATTERN
586
595
 
587
596
  # @!method class_definition?(node = self)
588
597
  def_node_matcher :class_definition?, <<~PATTERN
589
598
  {(class _ _ $_)
590
599
  (sclass _ $_)
591
- ({block numblock} (send #global_const?({:Struct :Class}) :new ...) _ $_)}
600
+ (any_block (send #global_const?({:Struct :Class}) :new ...) _ $_)}
592
601
  PATTERN
593
602
 
594
603
  # @!method module_definition?(node = self)
595
604
  def_node_matcher :module_definition?, <<~PATTERN
596
605
  {(module _ $_)
597
- ({block numblock} (send #global_const?(:Module) :new ...) _ $_)}
606
+ (any_block (send #global_const?(:Module) :new ...) _ $_)}
598
607
  PATTERN
599
608
 
600
609
  # Some expressions are evaluated for their value, some for their side
@@ -657,8 +666,7 @@ module RuboCop
657
666
  last_node = self
658
667
 
659
668
  while (current_node = last_node.parent)
660
- yield current_node if types.empty? ||
661
- types.include?(current_node.type)
669
+ yield current_node if types.empty? || current_node.type?(*types)
662
670
  last_node = current_node
663
671
  end
664
672
  end
@@ -48,7 +48,7 @@ module RuboCop
48
48
  children[0]
49
49
  end
50
50
 
51
- # @return [Integer] nb of captures of that node and its descendants
51
+ # @return [Integer] nb of captures that this node will emit
52
52
  def nb_captures
53
53
  children_nodes.sum(&:nb_captures)
54
54
  end
@@ -243,6 +243,12 @@ module RuboCop
243
243
 
244
244
  [with(children: new_children)]
245
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
246
252
  end
247
253
 
248
254
  # Registry
@@ -285,19 +285,14 @@ module RuboCop
285
285
  raise ArgumentError, "RuboCop found unknown Ruby version: #{ruby_version.inspect}"
286
286
  end
287
287
  when :parser_prism
288
- begin
289
- require 'prism'
290
- rescue LoadError
291
- warn "Error: Unable to load Prism. Add `gem 'prism'` to your Gemfile."
292
- exit!
293
- end
288
+ require_prism
294
289
 
295
290
  case ruby_version
296
291
  when 3.3
297
- require 'prism/translation/parser33'
292
+ require_prism_translation_parser(ruby_version)
298
293
  Prism::Translation::Parser33
299
294
  when 3.4
300
- require 'prism/translation/parser34'
295
+ require_prism_translation_parser(ruby_version)
301
296
  Prism::Translation::Parser34
302
297
  else
303
298
  raise ArgumentError, 'RuboCop supports target Ruby versions 3.3 and above with Prism. ' \
@@ -306,6 +301,31 @@ module RuboCop
306
301
  end
307
302
  end
308
303
 
304
+ # Prism is a native extension, a `LoadError` will be raised if linked to an incompatible
305
+ # Ruby version. Only raise if it really was caused by Prism not being present.
306
+ def require_prism
307
+ require 'prism'
308
+ rescue LoadError => e
309
+ raise unless e.path == 'prism'
310
+
311
+ warn "Error: Unable to load Prism. Add `gem 'prism'` to your Gemfile."
312
+ exit!
313
+ end
314
+
315
+ # While Prism is not yet a dependency, users may run with outdated versions that
316
+ # don't have all the parsers.
317
+ def require_prism_translation_parser(version)
318
+ require "prism/translation/parser#{version.to_s.delete('.')}"
319
+ rescue LoadError
320
+ warn <<~MESSAGE
321
+ Error: Unable to load Prism parser for Ruby #{version}.
322
+ * If you're using Bundler and don't yet have `gem 'prism'` as a dependency, add it now.
323
+ * If you're using Bundler and already have `gem 'prism'` as a dependency, update it to the most recent version.
324
+ * If you don't use Bundler, run `gem update prism`.
325
+ MESSAGE
326
+ exit!
327
+ end
328
+
309
329
  def create_parser(ruby_version, parser_engine)
310
330
  builder = RuboCop::AST::Builder.new
311
331
 
@@ -5,6 +5,7 @@ module RuboCop
5
5
  # A basic wrapper around Parser's tokens.
6
6
  class Token
7
7
  LEFT_PAREN_TYPES = %i[tLPAREN tLPAREN2].freeze
8
+ LEFT_CURLY_TYPES = %i[tLCURLY tLAMBEG].freeze
8
9
 
9
10
  attr_reader :pos, :type, :text
10
11
 
@@ -83,7 +84,7 @@ module RuboCop
83
84
  end
84
85
 
85
86
  def left_curly_brace?
86
- type == :tLCURLY || type == :tLAMBEG
87
+ LEFT_CURLY_TYPES.include?(type)
87
88
  end
88
89
 
89
90
  def right_curly_brace?
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module AST
5
5
  module Version
6
- STRING = '1.37.0'
6
+ STRING = '1.38.0'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-ast
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.37.0
4
+ version: 1.38.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-12-13 00:00:00.000000000 Z
13
+ date: 2025-01-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: parser