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 +4 -4
- data/lib/rubocop/ast/node/args_node.rb +1 -1
- data/lib/rubocop/ast/node/array_node.rb +3 -3
- data/lib/rubocop/ast/node/if_node.rb +2 -2
- data/lib/rubocop/ast/node/mixin/descendence.rb +3 -3
- data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +3 -3
- data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +7 -2
- data/lib/rubocop/ast/node/str_node.rb +4 -4
- data/lib/rubocop/ast/node.rb +26 -18
- data/lib/rubocop/ast/node_pattern/node.rb +7 -1
- data/lib/rubocop/ast/processed_source.rb +28 -8
- data/lib/rubocop/ast/token.rb +2 -1
- data/lib/rubocop/ast/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a3205a51f90d1dc493ef4c1ec96a4f40ed796dfc58bfc3661db72e67e134abc
|
4
|
+
data.tar.gz: 6d55fec1f58d712845ecb936db794934ea264e64b0adeb2c097fae63a5e5cb3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9468ab39ad7cd4ca56f0781605f07136dc89dfcbafc51482d5045799b468bf389d3c61671f49c7242f3dfbcc99090f3bd4b0c178d08b6038818b0158e3078658
|
7
|
+
data.tar.gz: a5b2b0604abdd935bfba3213a908678b5697cee7345f5b9941bfdddbfc08ceb8e86cab35895490f2612fd71937baa2ff5b7d75bb2ee4dafb5efd656178dc00c1
|
@@ -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:
|
11
|
-
symbol:
|
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
|
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
|
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
|
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? ||
|
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? ||
|
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? ||
|
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
|
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
|
-
|
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
|
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
|
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
|
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
|
-
|
46
|
-
return false unless opening_delimiter
|
46
|
+
return false unless loc?(:begin)
|
47
47
|
|
48
48
|
if type
|
49
|
-
|
49
|
+
loc.begin.source.match?(PERCENT_LITERAL_TYPES.fetch(type))
|
50
50
|
else
|
51
|
-
|
51
|
+
loc.begin.source.start_with?('%')
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
data/lib/rubocop/ast/node.rb
CHANGED
@@ -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
|
-
|
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 $_ ...) (
|
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
|
541
|
-
|
542
|
-
location = loc.public_send(which_loc)
|
543
|
-
return false unless location
|
552
|
+
return false unless loc?(which_loc)
|
544
553
|
|
545
|
-
|
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?, '(
|
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
|
-
(
|
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
|
-
(
|
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
|
-
(
|
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
|
-
(
|
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
|
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
|
-
|
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
|
-
|
292
|
+
require_prism_translation_parser(ruby_version)
|
298
293
|
Prism::Translation::Parser33
|
299
294
|
when 3.4
|
300
|
-
|
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
|
|
data/lib/rubocop/ast/token.rb
CHANGED
@@ -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
|
87
|
+
LEFT_CURLY_TYPES.include?(type)
|
87
88
|
end
|
88
89
|
|
89
90
|
def right_curly_brace?
|
data/lib/rubocop/ast/version.rb
CHANGED
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.
|
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:
|
13
|
+
date: 2025-01-27 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: parser
|