rubocop-ast 1.37.0 → 1.41.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 +4 -4
- data/lib/rubocop/ast/builder.rb +24 -15
- data/lib/rubocop/ast/builder_prism.rb +11 -0
- 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/block_node.rb +7 -6
- data/lib/rubocop/ast/node/ensure_node.rb +13 -0
- data/lib/rubocop/ast/node/if_node.rb +2 -2
- data/lib/rubocop/ast/node/masgn_node.rb +1 -1
- data/lib/rubocop/ast/node/mixin/descendence.rb +3 -3
- data/lib/rubocop/ast/node/mixin/hash_element_node.rb +2 -0
- data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +7 -7
- data/lib/rubocop/ast/node/mixin/parameterized_node.rb +1 -1
- 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 +28 -19
- data/lib/rubocop/ast/node_pattern/node.rb +7 -1
- data/lib/rubocop/ast/node_pattern/parser.racc.rb +40 -42
- data/lib/rubocop/ast/processed_source.rb +88 -13
- data/lib/rubocop/ast/token.rb +2 -1
- data/lib/rubocop/ast/traversal.rb +31 -21
- data/lib/rubocop/ast/utilities/simple_forwardable.rb +16 -5
- data/lib/rubocop/ast/version.rb +1 -1
- metadata +6 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19ee463e3a3cb36f4cac11ef8a15c891d15ab7a7b616cab272bcef1e5d1511ad
|
4
|
+
data.tar.gz: d01d708fe51840b874ac59409db40e12860f04d639159606633bcaf31b73a22a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3172e1d4d9ec2d01a910ef63dbb2593b8c685936e9399ecc6d701cbb808969f25eadf6a7b46bce1993202693c03c11b9bc724be0c2c0e4018213a96ffc41e3b0
|
7
|
+
data.tar.gz: 33871fb889a66acdc8c39c7007f3b829cd2158f3a3c6cc111a924f1350bb1b0bcafa17de4e2c4216f0065449455b29cbec12fa3483cea9eb5623301a9060219e
|
data/lib/rubocop/ast/builder.rb
CHANGED
@@ -2,20 +2,13 @@
|
|
2
2
|
|
3
3
|
module RuboCop
|
4
4
|
module AST
|
5
|
-
#
|
6
|
-
#
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# builder = RuboCop::AST::Builder.new
|
13
|
-
# require 'parser/ruby25'
|
14
|
-
# parser = Parser::Ruby25.new(builder)
|
15
|
-
# root_node = parser.parse(buffer)
|
16
|
-
class Builder < Parser::Builders::Default
|
17
|
-
self.emit_forward_arg = true if respond_to?(:emit_forward_arg=)
|
18
|
-
self.emit_match_pattern = true if respond_to?(:emit_match_pattern=)
|
5
|
+
# Common functionality between the parser and prism builder
|
6
|
+
# @api private
|
7
|
+
module BuilderExtensions
|
8
|
+
def self.included(base)
|
9
|
+
base.emit_forward_arg = true
|
10
|
+
base.emit_match_pattern = true
|
11
|
+
end
|
19
12
|
|
20
13
|
# @api private
|
21
14
|
NODE_MAP = {
|
@@ -39,6 +32,7 @@ module RuboCop
|
|
39
32
|
gvasgn: AsgnNode,
|
40
33
|
block: BlockNode,
|
41
34
|
numblock: BlockNode,
|
35
|
+
itblock: BlockNode,
|
42
36
|
break: BreakNode,
|
43
37
|
case_match: CaseMatchNode,
|
44
38
|
casgn: CasgnNode,
|
@@ -107,7 +101,7 @@ module RuboCop
|
|
107
101
|
node_klass(type).new(type, children, location: source_map)
|
108
102
|
end
|
109
103
|
|
110
|
-
#
|
104
|
+
# Overwrite the base method to allow strings with invalid encoding
|
111
105
|
# More details here https://github.com/whitequark/parser/issues/283
|
112
106
|
def string_value(token)
|
113
107
|
value(token)
|
@@ -119,5 +113,20 @@ module RuboCop
|
|
119
113
|
NODE_MAP[type] || Node
|
120
114
|
end
|
121
115
|
end
|
116
|
+
|
117
|
+
# `RuboCop::AST::Builder` is an AST builder that is utilized to let `Parser`
|
118
|
+
# generate ASTs with {RuboCop::AST::Node}.
|
119
|
+
#
|
120
|
+
# @example
|
121
|
+
# buffer = Parser::Source::Buffer.new('(string)')
|
122
|
+
# buffer.source = 'puts :foo'
|
123
|
+
#
|
124
|
+
# builder = RuboCop::AST::Builder.new
|
125
|
+
# require 'parser/ruby25'
|
126
|
+
# parser = Parser::Ruby25.new(builder)
|
127
|
+
# root_node = parser.parse(buffer)
|
128
|
+
class Builder < Parser::Builders::Default
|
129
|
+
include BuilderExtensions
|
130
|
+
end
|
122
131
|
end
|
123
132
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module AST
|
5
|
+
# A parser builder, based on the one provided by prism,
|
6
|
+
# which is capable of emitting AST for more recent Rubies.
|
7
|
+
class BuilderPrism < Prism::Translation::Parser::Builder
|
8
|
+
include BuilderExtensions
|
9
|
+
end
|
10
|
+
end
|
11
|
+
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:
|
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
|
@@ -11,6 +11,8 @@ module RuboCop
|
|
11
11
|
class BlockNode < Node
|
12
12
|
include MethodIdentifierPredicates
|
13
13
|
|
14
|
+
IT_BLOCK_ARGUMENT = [ArgNode.new(:arg, [:it])].freeze
|
15
|
+
private_constant :IT_BLOCK_ARGUMENT
|
14
16
|
VOID_CONTEXT_METHODS = %i[each tap].freeze
|
15
17
|
private_constant :VOID_CONTEXT_METHODS
|
16
18
|
|
@@ -46,10 +48,10 @@ module RuboCop
|
|
46
48
|
#
|
47
49
|
# @return [Array<Node>]
|
48
50
|
def arguments
|
49
|
-
if
|
50
|
-
[].freeze # Numbered parameters have no block arguments.
|
51
|
-
else
|
51
|
+
if block_type?
|
52
52
|
node_parts[1]
|
53
|
+
else
|
54
|
+
[].freeze # Numblocks and itblocks have no explicit block arguments.
|
53
55
|
end
|
54
56
|
end
|
55
57
|
|
@@ -60,6 +62,8 @@ module RuboCop
|
|
60
62
|
def argument_list
|
61
63
|
if numblock_type?
|
62
64
|
numbered_arguments
|
65
|
+
elsif itblock_type?
|
66
|
+
IT_BLOCK_ARGUMENT
|
63
67
|
else
|
64
68
|
arguments.argument_list
|
65
69
|
end
|
@@ -153,10 +157,7 @@ module RuboCop
|
|
153
157
|
|
154
158
|
private
|
155
159
|
|
156
|
-
# Numbered arguments of this `numblock`.
|
157
160
|
def numbered_arguments
|
158
|
-
return [].freeze unless numblock_type?
|
159
|
-
|
160
161
|
max_param = children[1]
|
161
162
|
1.upto(max_param).map do |i|
|
162
163
|
ArgNode.new(:arg, [:"_#{i}"])
|
@@ -6,11 +6,24 @@ module RuboCop
|
|
6
6
|
# node when the builder constructs the AST, making its methods available
|
7
7
|
# to all `ensure` nodes within RuboCop.
|
8
8
|
class EnsureNode < Node
|
9
|
+
DEPRECATION_WARNING_LOCATION_CACHE = [] # rubocop:disable Style/MutableConstant
|
10
|
+
private_constant :DEPRECATION_WARNING_LOCATION_CACHE
|
11
|
+
|
9
12
|
# Returns the body of the `ensure` clause.
|
10
13
|
#
|
11
14
|
# @return [Node, nil] The body of the `ensure`.
|
12
15
|
# @deprecated Use `EnsureNode#branch`
|
13
16
|
def body
|
17
|
+
first_caller = caller(1..1).first
|
18
|
+
|
19
|
+
unless DEPRECATION_WARNING_LOCATION_CACHE.include?(first_caller)
|
20
|
+
warn '`EnsureNode#body` is deprecated and will be changed in the next major version of ' \
|
21
|
+
'rubocop-ast. Use `EnsureNode#branch` instead to get the body of the `ensure` branch.'
|
22
|
+
warn "Called from:\n#{caller.join("\n")}\n\n"
|
23
|
+
|
24
|
+
DEPRECATION_WARNING_LOCATION_CACHE << first_caller
|
25
|
+
end
|
26
|
+
|
14
27
|
branch
|
15
28
|
end
|
16
29
|
|
@@ -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
|
@@ -20,7 +20,7 @@ module RuboCop
|
|
20
20
|
# @return [Array<Symbol>] names of all the variables being assigned
|
21
21
|
def names
|
22
22
|
assignments.map do |assignment|
|
23
|
-
if assignment.
|
23
|
+
if assignment.type?(:send, :indexasgn)
|
24
24
|
assignment.method_name
|
25
25
|
else
|
26
26
|
assignment.name
|
@@ -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
|
@@ -99,7 +99,9 @@ module RuboCop
|
|
99
99
|
|
100
100
|
def valid_argument_types?
|
101
101
|
[first, second].all? do |argument|
|
102
|
+
# rubocop:disable InternalAffairs/NodeTypeMultiplePredicates
|
102
103
|
argument.pair_type? || argument.kwsplat_type?
|
104
|
+
# rubocop:enable InternalAffairs/NodeTypeMultiplePredicates
|
103
105
|
end
|
104
106
|
end
|
105
107
|
|
@@ -39,10 +39,10 @@ module RuboCop
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
# The `block` or `
|
42
|
+
# The `block`, `numblock`, or `itblock` node associated with this method dispatch, if any.
|
43
43
|
#
|
44
|
-
# @return [BlockNode, nil] the `block` or `
|
45
|
-
# call or `nil`
|
44
|
+
# @return [BlockNode, nil] the `block`, `numblock`, or `itblock` node associated with this
|
45
|
+
# method call or `nil`
|
46
46
|
def block_node
|
47
47
|
parent if block_literal?
|
48
48
|
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
|
@@ -201,7 +201,7 @@ module RuboCop
|
|
201
201
|
|
202
202
|
return unless node.send_type? && node.receiver.nil? && arg.is_a?(::AST::Node)
|
203
203
|
|
204
|
-
return arg if arg.
|
204
|
+
return arg if arg.type?(:def, :defs)
|
205
205
|
|
206
206
|
def_modifier(arg)
|
207
207
|
end
|
@@ -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
|
@@ -57,7 +57,7 @@ module RuboCop
|
|
57
57
|
# @return [Boolean] whether the last argument of the node is a block pass
|
58
58
|
def block_argument?
|
59
59
|
arguments? &&
|
60
|
-
|
60
|
+
last_argument.type?(:block_pass, :blockarg)
|
61
61
|
end
|
62
62
|
|
63
63
|
# A specialized `ParameterizedNode` for node that have a single child
|
@@ -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,11 @@ 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
|
+
itblock: :any_block
|
116
117
|
}.freeze
|
117
118
|
private_constant :GROUP_FOR_TYPE
|
118
119
|
|
@@ -343,7 +344,7 @@ module RuboCop
|
|
343
344
|
|
344
345
|
# @!method receiver(node = self)
|
345
346
|
def_node_matcher :receiver, <<~PATTERN
|
346
|
-
{(send $_ ...) (
|
347
|
+
{(send $_ ...) (any_block (call $_ ...) ...)}
|
347
348
|
PATTERN
|
348
349
|
|
349
350
|
# @!method str_content(node = self)
|
@@ -528,21 +529,30 @@ module RuboCop
|
|
528
529
|
GROUP_FOR_TYPE[type] == :range
|
529
530
|
end
|
530
531
|
|
532
|
+
def any_block_type?
|
533
|
+
GROUP_FOR_TYPE[type] == :any_block
|
534
|
+
end
|
535
|
+
|
531
536
|
def guard_clause?
|
532
537
|
node = operator_keyword? ? rhs : self
|
533
538
|
|
534
539
|
node.match_guard_clause?
|
535
540
|
end
|
536
541
|
|
542
|
+
# Shortcut to safely check if a location is present
|
543
|
+
# @return [Boolean]
|
544
|
+
def loc?(which_loc)
|
545
|
+
return false unless loc.respond_to?(which_loc)
|
546
|
+
|
547
|
+
!loc.public_send(which_loc).nil?
|
548
|
+
end
|
549
|
+
|
537
550
|
# Shortcut to safely test a particular location, even if
|
538
551
|
# this location does not exist or is `nil`
|
539
552
|
def loc_is?(which_loc, str)
|
540
|
-
return false unless loc
|
541
|
-
|
542
|
-
location = loc.public_send(which_loc)
|
543
|
-
return false unless location
|
553
|
+
return false unless loc?(which_loc)
|
544
554
|
|
545
|
-
|
555
|
+
loc.public_send(which_loc).is?(str)
|
546
556
|
end
|
547
557
|
|
548
558
|
# @!method match_guard_clause?(node = self)
|
@@ -558,7 +568,7 @@ module RuboCop
|
|
558
568
|
PATTERN
|
559
569
|
|
560
570
|
# @!method lambda?(node = self)
|
561
|
-
def_node_matcher :lambda?, '(
|
571
|
+
def_node_matcher :lambda?, '(any_block (send nil? :lambda) ...)'
|
562
572
|
|
563
573
|
# @!method lambda_or_proc?(node = self)
|
564
574
|
def_node_matcher :lambda_or_proc?, '{lambda? proc?}'
|
@@ -571,7 +581,7 @@ module RuboCop
|
|
571
581
|
{
|
572
582
|
(send #global_const?({:Class :Module :Struct}) :new ...)
|
573
583
|
(send #global_const?(:Data) :define ...)
|
574
|
-
(
|
584
|
+
(any_block {
|
575
585
|
(send #global_const?({:Class :Module :Struct}) :new ...)
|
576
586
|
(send #global_const?(:Data) :define ...)
|
577
587
|
} ...)
|
@@ -581,20 +591,20 @@ module RuboCop
|
|
581
591
|
# @deprecated Use `:class_constructor?`
|
582
592
|
# @!method struct_constructor?(node = self)
|
583
593
|
def_node_matcher :struct_constructor?, <<~PATTERN
|
584
|
-
(
|
594
|
+
(any_block (send #global_const?(:Struct) :new ...) _ $_)
|
585
595
|
PATTERN
|
586
596
|
|
587
597
|
# @!method class_definition?(node = self)
|
588
598
|
def_node_matcher :class_definition?, <<~PATTERN
|
589
599
|
{(class _ _ $_)
|
590
600
|
(sclass _ $_)
|
591
|
-
(
|
601
|
+
(any_block (send #global_const?({:Struct :Class}) :new ...) _ $_)}
|
592
602
|
PATTERN
|
593
603
|
|
594
604
|
# @!method module_definition?(node = self)
|
595
605
|
def_node_matcher :module_definition?, <<~PATTERN
|
596
606
|
{(module _ $_)
|
597
|
-
(
|
607
|
+
(any_block (send #global_const?(:Module) :new ...) _ $_)}
|
598
608
|
PATTERN
|
599
609
|
|
600
610
|
# Some expressions are evaluated for their value, some for their side
|
@@ -657,8 +667,7 @@ module RuboCop
|
|
657
667
|
last_node = self
|
658
668
|
|
659
669
|
while (current_node = last_node.parent)
|
660
|
-
yield current_node if types.empty? ||
|
661
|
-
types.include?(current_node.type)
|
670
|
+
yield current_node if types.empty? || current_node.type?(*types)
|
662
671
|
last_node = current_node
|
663
672
|
end
|
664
673
|
end
|
@@ -677,7 +686,7 @@ module RuboCop
|
|
677
686
|
def case_if_value_used?
|
678
687
|
# (case <condition> <when...>)
|
679
688
|
# (if <condition> <truebranch> <falsebranch>)
|
680
|
-
sibling_index.zero?
|
689
|
+
sibling_index.zero? || parent.value_used?
|
681
690
|
end
|
682
691
|
|
683
692
|
def while_until_value_used?
|
@@ -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
|
@@ -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
|
-
# from Racc grammar file "
|
4
|
+
# This file is automatically generated by Racc 1.5.0
|
5
|
+
# from Racc grammar file "".
|
6
6
|
#
|
7
7
|
|
8
8
|
require 'racc/parser.rb'
|
@@ -14,15 +14,15 @@ module RuboCop
|
|
14
14
|
|
15
15
|
racc_action_table = [
|
16
16
|
14, 15, 16, 21, 18, 17, 19, 10, 11, 12,
|
17
|
-
60, 22, 20, 4,
|
18
|
-
28, 23, 56, 50,
|
17
|
+
60, 22, 20, 4, 40, 5, 43, 6, 7, 8,
|
18
|
+
28, 23, 56, 50, 66, 61, 24, 51, 51, 40,
|
19
19
|
58, 14, 15, 16, 21, 18, 17, 19, 10, 11,
|
20
20
|
12, nil, 22, 20, 4, nil, 5, nil, 6, 7,
|
21
21
|
8, 28, 23, nil, nil, -34, 14, 15, 16, 21,
|
22
22
|
18, 17, 19, 10, 11, 12, nil, 22, 20, 4,
|
23
23
|
nil, 5, nil, 6, 7, 8, 9, 23, 14, 15,
|
24
24
|
16, 21, 18, 17, 19, 10, 11, 12, nil, 22,
|
25
|
-
20, 4, nil, 5, nil, 6, 7, 8,
|
25
|
+
20, 4, nil, 5, nil, 6, 7, 8, 9, 23,
|
26
26
|
14, 15, 16, 21, 18, 17, 19, 10, 11, 12,
|
27
27
|
nil, 22, 20, 4, nil, 5, nil, 6, 7, 8,
|
28
28
|
9, 23, 14, 15, 16, 21, 18, 17, 19, 10,
|
@@ -33,7 +33,7 @@ racc_action_table = [
|
|
33
33
|
18, 17, 19, 10, 11, 12, nil, 22, 20, 4,
|
34
34
|
nil, 5, nil, 6, 7, 8, 9, 23, 14, 15,
|
35
35
|
16, 21, 18, 17, 19, 10, 11, 12, nil, 22,
|
36
|
-
20, 4, nil, 5, nil, 6, 7, 8,
|
36
|
+
20, 4, nil, 5, nil, 6, 7, 8, 28, 23,
|
37
37
|
14, 15, 16, 21, 18, 17, 19, 10, 11, 12,
|
38
38
|
nil, 22, 20, 4, 44, 5, nil, 6, 7, 8,
|
39
39
|
28, 23, 14, 15, 16, 21, 18, 17, 19, 10,
|
@@ -47,31 +47,31 @@ racc_action_table = [
|
|
47
47
|
20, 4, nil, 5, nil, 6, 7, 8, 9, 23,
|
48
48
|
14, 15, 16, 21, 18, 17, 19, 10, 11, 12,
|
49
49
|
nil, 22, 20, 4, nil, 5, nil, 6, 7, 8,
|
50
|
-
9, 23,
|
51
|
-
|
50
|
+
9, 23, 47, 48, 49, -1, -1, -1, -2, -2,
|
51
|
+
-2 ]
|
52
52
|
|
53
53
|
racc_action_check = [
|
54
54
|
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
|
55
|
-
54, 42, 42, 42,
|
56
|
-
42, 42, 42, 30,
|
55
|
+
54, 42, 42, 42, 11, 42, 24, 42, 42, 42,
|
56
|
+
42, 42, 42, 30, 62, 54, 1, 63, 30, 10,
|
57
57
|
42, 59, 59, 59, 59, 59, 59, 59, 59, 59,
|
58
58
|
59, nil, 59, 59, 59, nil, 59, nil, 59, 59,
|
59
|
-
59, 59, 59, nil, nil, 59,
|
59
|
+
59, 59, 59, nil, nil, 59, 5, 5, 5, 5,
|
60
|
+
5, 5, 5, 5, 5, 5, nil, 5, 5, 5,
|
61
|
+
nil, 5, nil, 5, 5, 5, 5, 5, 6, 6,
|
62
|
+
6, 6, 6, 6, 6, 6, 6, 6, nil, 6,
|
63
|
+
6, 6, nil, 6, nil, 6, 6, 6, 6, 6,
|
64
|
+
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
65
|
+
nil, 7, 7, 7, nil, 7, nil, 7, 7, 7,
|
66
|
+
7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
67
|
+
8, 8, nil, 8, 8, 8, nil, 8, nil, 8,
|
68
|
+
8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
|
69
|
+
9, 9, 9, 9, nil, 9, 9, 9, nil, 9,
|
70
|
+
nil, 9, 9, 9, 9, 9, 0, 0, 0, 0,
|
60
71
|
0, 0, 0, 0, 0, 0, nil, 0, 0, 0,
|
61
72
|
nil, 0, nil, 0, 0, 0, 0, 0, 4, 4,
|
62
73
|
4, 4, 4, 4, 4, 4, 4, 4, nil, 4,
|
63
74
|
4, 4, nil, 4, nil, 4, 4, 4, 4, 4,
|
64
|
-
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
65
|
-
nil, 5, 5, 5, nil, 5, nil, 5, 5, 5,
|
66
|
-
5, 5, 6, 6, 6, 6, 6, 6, 6, 6,
|
67
|
-
6, 6, nil, 6, 6, 6, nil, 6, nil, 6,
|
68
|
-
6, 6, 6, 6, 7, 7, 7, 7, 7, 7,
|
69
|
-
7, 7, 7, 7, nil, 7, 7, 7, nil, 7,
|
70
|
-
nil, 7, 7, 7, 7, 7, 8, 8, 8, 8,
|
71
|
-
8, 8, 8, 8, 8, 8, nil, 8, 8, 8,
|
72
|
-
nil, 8, nil, 8, 8, 8, 8, 8, 9, 9,
|
73
|
-
9, 9, 9, 9, 9, 9, 9, 9, nil, 9,
|
74
|
-
9, 9, nil, 9, nil, 9, 9, 9, 9, 9,
|
75
75
|
27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
76
76
|
nil, 27, 27, 27, 27, 27, nil, 27, 27, 27,
|
77
77
|
27, 27, 28, 28, 28, 28, 28, 28, 28, 28,
|
@@ -85,17 +85,17 @@ racc_action_check = [
|
|
85
85
|
50, 50, nil, 50, nil, 50, 50, 50, 50, 50,
|
86
86
|
61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
|
87
87
|
nil, 61, 61, 61, nil, 61, nil, 61, 61, 61,
|
88
|
-
61, 61,
|
89
|
-
|
88
|
+
61, 61, 29, 29, 29, 25, 25, 25, 26, 26,
|
89
|
+
26 ]
|
90
90
|
|
91
91
|
racc_action_pointer = [
|
92
|
-
|
93
|
-
|
94
|
-
nil, nil, nil, nil,
|
92
|
+
164, 26, nil, nil, 186, 54, 76, 98, 120, 142,
|
93
|
+
17, 2, nil, nil, nil, nil, nil, nil, nil, nil,
|
94
|
+
nil, nil, nil, nil, 16, 318, 321, 208, 230, 315,
|
95
95
|
-2, nil, nil, 252, nil, nil, nil, nil, nil, nil,
|
96
96
|
274, nil, -2, nil, nil, nil, nil, nil, nil, nil,
|
97
97
|
296, nil, nil, nil, -6, nil, nil, nil, nil, 29,
|
98
|
-
nil, 318,
|
98
|
+
nil, 318, -2, -3, nil, nil, nil ]
|
99
99
|
|
100
100
|
racc_action_default = [
|
101
101
|
-47, -47, -1, -2, -31, -47, -47, -47, -47, -47,
|
@@ -107,26 +107,26 @@ racc_action_default = [
|
|
107
107
|
-37, -47, -47, -47, -35, -39, -26 ]
|
108
108
|
|
109
109
|
racc_goto_table = [
|
110
|
-
1, 33,
|
111
|
-
|
112
|
-
nil, nil, nil, nil, nil, nil,
|
113
|
-
nil, nil, nil, 53,
|
114
|
-
55,
|
110
|
+
1, 33, 64, 32, 25, 34, 35, 36, 37, 38,
|
111
|
+
54, 26, 39, 41, 27, 42, 46, 63, 62, nil,
|
112
|
+
nil, nil, nil, nil, nil, nil, 45, 25, 38, nil,
|
113
|
+
nil, nil, nil, 53, 26, nil, nil, nil, nil, nil,
|
114
|
+
55, 57, 25, nil, nil, nil, 59, nil, nil, 26,
|
115
115
|
34, nil, nil, nil, nil, nil, nil, nil, nil, 53,
|
116
116
|
nil, 65 ]
|
117
117
|
|
118
118
|
racc_goto_check = [
|
119
|
-
1, 5,
|
120
|
-
|
121
|
-
nil, nil, nil, nil, nil, nil,
|
122
|
-
nil, nil, nil, 1,
|
123
|
-
1,
|
119
|
+
1, 5, 13, 9, 2, 1, 1, 1, 1, 1,
|
120
|
+
14, 3, 6, 6, 4, 8, 10, 11, 12, nil,
|
121
|
+
nil, nil, nil, nil, nil, nil, 9, 2, 1, nil,
|
122
|
+
nil, nil, nil, 1, 3, nil, nil, nil, nil, nil,
|
123
|
+
1, 9, 2, nil, nil, nil, 5, nil, nil, 3,
|
124
124
|
1, nil, nil, nil, nil, nil, nil, nil, nil, 1,
|
125
125
|
nil, 1 ]
|
126
126
|
|
127
127
|
racc_goto_pointer = [
|
128
|
-
nil, 0,
|
129
|
-
-
|
128
|
+
nil, 0, 0, 7, 10, -4, 2, nil, -8, -1,
|
129
|
+
-13, -42, -41, -57, -30 ]
|
130
130
|
|
131
131
|
racc_goto_default = [
|
132
132
|
nil, 29, 2, 3, nil, nil, nil, 13, nil, nil,
|
@@ -239,7 +239,6 @@ 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)
|
243
242
|
|
244
243
|
Racc_token_to_s_table = [
|
245
244
|
"$end",
|
@@ -290,7 +289,6 @@ Racc_token_to_s_table = [
|
|
290
289
|
"opt_rest",
|
291
290
|
"rest",
|
292
291
|
"arg_list" ]
|
293
|
-
Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor)
|
294
292
|
|
295
293
|
Racc_debug_parser = false
|
296
294
|
|
@@ -4,6 +4,27 @@ require 'digest/sha1'
|
|
4
4
|
|
5
5
|
module RuboCop
|
6
6
|
module AST
|
7
|
+
# A `Prism` interface's class that provides a fixed `Prism::ParseLexResult` instead of parsing.
|
8
|
+
#
|
9
|
+
# This class implements the `parse_lex` method to return a preparsed `Prism::ParseLexResult`
|
10
|
+
# rather than parsing the source code. When the parse result is already available externally,
|
11
|
+
# such as in Ruby LSP, the Prism parsing process can be bypassed.
|
12
|
+
class PrismPreparsed
|
13
|
+
def initialize(prism_result)
|
14
|
+
unless prism_result.is_a?(Prism::ParseLexResult)
|
15
|
+
raise ArgumentError, <<~MESSAGE
|
16
|
+
Expected a `Prism::ParseLexResult` object, but received `#{prism_result.class}`.
|
17
|
+
MESSAGE
|
18
|
+
end
|
19
|
+
|
20
|
+
@prism_result = prism_result
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_lex(_source, **_prism_options)
|
24
|
+
@prism_result
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
7
28
|
# ProcessedSource contains objects which are generated by Parser
|
8
29
|
# and other information such as disabled lines for cops.
|
9
30
|
# It also provides a convenient way to access source lines.
|
@@ -25,7 +46,9 @@ module RuboCop
|
|
25
46
|
new(file, ruby_version, path, parser_engine: parser_engine)
|
26
47
|
end
|
27
48
|
|
28
|
-
def initialize(
|
49
|
+
def initialize(
|
50
|
+
source, ruby_version, path = nil, parser_engine: :parser_whitequark, prism_result: nil
|
51
|
+
)
|
29
52
|
parser_engine = parser_engine.to_sym
|
30
53
|
unless PARSER_ENGINES.include?(parser_engine)
|
31
54
|
raise ArgumentError, 'The keyword argument `parser_engine` accepts `parser_whitequark` ' \
|
@@ -44,7 +67,7 @@ module RuboCop
|
|
44
67
|
@parser_engine = parser_engine
|
45
68
|
@parser_error = nil
|
46
69
|
|
47
|
-
parse(source, ruby_version, parser_engine)
|
70
|
+
parse(source, ruby_version, parser_engine, prism_result)
|
48
71
|
end
|
49
72
|
|
50
73
|
def ast_with_comments
|
@@ -202,7 +225,7 @@ module RuboCop
|
|
202
225
|
end
|
203
226
|
end
|
204
227
|
|
205
|
-
def parse(source, ruby_version, parser_engine)
|
228
|
+
def parse(source, ruby_version, parser_engine, prism_result)
|
206
229
|
buffer_name = @path || STRING_SOURCE_NAME
|
207
230
|
@buffer = Parser::Source::Buffer.new(buffer_name, 1)
|
208
231
|
|
@@ -216,7 +239,9 @@ module RuboCop
|
|
216
239
|
return
|
217
240
|
end
|
218
241
|
|
219
|
-
|
242
|
+
parser = create_parser(ruby_version, parser_engine, prism_result)
|
243
|
+
|
244
|
+
@ast, @comments, @tokens = tokenize(parser)
|
220
245
|
end
|
221
246
|
|
222
247
|
def tokenize(parser)
|
@@ -285,12 +310,7 @@ module RuboCop
|
|
285
310
|
raise ArgumentError, "RuboCop found unknown Ruby version: #{ruby_version.inspect}"
|
286
311
|
end
|
287
312
|
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
|
313
|
+
require_prism
|
294
314
|
|
295
315
|
case ruby_version
|
296
316
|
when 3.3
|
@@ -306,10 +326,64 @@ module RuboCop
|
|
306
326
|
end
|
307
327
|
end
|
308
328
|
|
309
|
-
def
|
310
|
-
|
329
|
+
def builder_class(parser_engine)
|
330
|
+
case parser_engine
|
331
|
+
when :parser_whitequark
|
332
|
+
RuboCop::AST::Builder
|
333
|
+
when :parser_prism
|
334
|
+
require_prism
|
335
|
+
require_relative 'builder_prism'
|
336
|
+
RuboCop::AST::BuilderPrism
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
# Prism is a native extension, a `LoadError` will be raised if linked to an incompatible
|
341
|
+
# Ruby version. Only raise if it really was caused by Prism not being present.
|
342
|
+
# rubocop:disable Metrics/MethodLength
|
343
|
+
def require_prism
|
344
|
+
require 'prism'
|
345
|
+
required_prism_version = '1.4.0'
|
346
|
+
if required_prism_version > Prism::VERSION
|
347
|
+
# While Prism is not yet a dependency, users may run with outdated versions that
|
348
|
+
# don't have all the parsers.
|
349
|
+
warn <<~MESSAGE
|
350
|
+
Error: Prism version #{Prism::VERSION} was loaded, but rubocop-ast requires #{required_prism_version}.
|
351
|
+
* If you're using Bundler and don't yet have `gem 'prism'` as a dependency, add it now.
|
352
|
+
* If you're using Bundler and already have `gem 'prism'` as a dependency, update it to the most recent version.
|
353
|
+
* If you don't use Bundler, run `gem update prism`.
|
354
|
+
MESSAGE
|
355
|
+
exit!
|
356
|
+
end
|
357
|
+
rescue LoadError => e
|
358
|
+
raise unless e.path == 'prism'
|
359
|
+
|
360
|
+
warn "Error: Unable to load Prism. Add `gem 'prism'` to your Gemfile."
|
361
|
+
exit!
|
362
|
+
end
|
363
|
+
# rubocop:enable Metrics/MethodLength
|
364
|
+
|
365
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
366
|
+
def create_parser(ruby_version, parser_engine, prism_result)
|
367
|
+
builder = builder_class(parser_engine).new
|
368
|
+
|
369
|
+
parser_class = parser_class(ruby_version, parser_engine)
|
370
|
+
|
371
|
+
# NOTE: Check if the `Prism#initialize` method has the `:parser` keyword argument.
|
372
|
+
# The `:parser` keyword argument cannot be used to switch parsers because older versions of
|
373
|
+
# Prism do not support it.
|
374
|
+
parser_switch_available = parser_class.instance_method(:initialize).parameters.assoc(:key)
|
375
|
+
|
376
|
+
parser_instance = if prism_result && parser_switch_available
|
377
|
+
# NOTE: Since it is intended for use with Ruby LSP, it targets only Prism.
|
378
|
+
# If there is no reuse of a pre-parsed result, such as in Ruby LSP,
|
379
|
+
# regular parsing with Prism occurs, and `else` branch will be executed.
|
380
|
+
prism_reparsed = PrismPreparsed.new(prism_result)
|
381
|
+
parser_class.new(builder, parser: prism_reparsed)
|
382
|
+
else
|
383
|
+
parser_class.new(builder)
|
384
|
+
end
|
311
385
|
|
312
|
-
|
386
|
+
parser_instance.tap do |parser|
|
313
387
|
# On JRuby there's a risk that we hang in tokenize() if we
|
314
388
|
# don't set the all errors as fatal flag. The problem is caused by a bug
|
315
389
|
# in Racc that is discussed in issue #93 of the whitequark/parser
|
@@ -321,6 +395,7 @@ module RuboCop
|
|
321
395
|
end
|
322
396
|
end
|
323
397
|
end
|
398
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
324
399
|
|
325
400
|
def first_token_index(range_or_node)
|
326
401
|
begin_pos = source_range(range_or_node).begin_pos
|
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?
|
@@ -26,16 +26,18 @@ module RuboCop
|
|
26
26
|
SEND = 'send(TYPE_TO_METHOD[child.type], child)'
|
27
27
|
assign_code = 'child = node.children[%<index>i]'
|
28
28
|
code = "#{assign_code}\n#{SEND}"
|
29
|
+
# How a particular child node should be visited. For example, if a child node
|
30
|
+
# can be nil it should be guarded behind a nil check. Or, if a child node is a literal
|
31
|
+
# (like a symbol) then the literal itself should not be visited.
|
29
32
|
TEMPLATE = {
|
30
33
|
skip: '',
|
31
34
|
always: code,
|
32
35
|
nil?: "#{code} if child"
|
33
36
|
}.freeze
|
34
37
|
|
35
|
-
def def_callback(type, *
|
36
|
-
|
37
|
-
|
38
|
-
body: self.body(signature, arity_check))
|
38
|
+
def def_callback(type, *child_node_types,
|
39
|
+
expected_children_count: child_node_types.size..child_node_types.size,
|
40
|
+
body: self.body(child_node_types, expected_children_count))
|
39
41
|
type, *aliases = type
|
40
42
|
lineno = caller_locations(1, 1).first.lineno
|
41
43
|
module_eval(<<~RUBY, __FILE__, lineno)
|
@@ -49,16 +51,23 @@ module RuboCop
|
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
52
|
-
def body(
|
53
|
-
|
54
|
-
|
55
|
-
|
54
|
+
def body(child_node_types, expected_children_count)
|
55
|
+
visit_children_code =
|
56
|
+
child_node_types
|
57
|
+
.map.with_index do |child_type, i|
|
58
|
+
TEMPLATE.fetch(child_type).gsub('%<index>i', i.to_s)
|
56
59
|
end
|
57
|
-
.unshift(prelude)
|
58
60
|
.join("\n")
|
61
|
+
|
62
|
+
<<~BODY
|
63
|
+
#{children_count_check_code(expected_children_count)}
|
64
|
+
#{visit_children_code}
|
65
|
+
BODY
|
59
66
|
end
|
60
67
|
|
61
|
-
def
|
68
|
+
def children_count_check_code(range)
|
69
|
+
return '' unless ENV.fetch('RUBOCOP_DEBUG', false)
|
70
|
+
|
62
71
|
<<~RUBY
|
63
72
|
n = node.children.size
|
64
73
|
raise DebugError, [
|
@@ -72,18 +81,18 @@ module RuboCop
|
|
72
81
|
extend CallbackCompiler
|
73
82
|
send_code = CallbackCompiler::SEND
|
74
83
|
|
75
|
-
###
|
84
|
+
### children count == 0
|
76
85
|
no_children = %i[true false nil self cbase zsuper redo retry
|
77
86
|
forward_args forwarded_args match_nil_pattern
|
78
87
|
forward_arg forwarded_restarg forwarded_kwrestarg
|
79
88
|
lambda empty_else kwnilarg
|
80
89
|
__FILE__ __LINE__ __ENCODING__]
|
81
90
|
|
82
|
-
###
|
91
|
+
### children count == 0..1
|
83
92
|
opt_symbol_child = %i[restarg kwrestarg]
|
84
93
|
opt_node_child = %i[splat kwsplat match_rest]
|
85
94
|
|
86
|
-
###
|
95
|
+
### children count == 1
|
87
96
|
literal_child = %i[int float complex
|
88
97
|
rational str sym lvar
|
89
98
|
ivar cvar gvar nth_ref back_ref
|
@@ -100,12 +109,12 @@ module RuboCop
|
|
100
109
|
NO_CHILD_NODES = (no_children + opt_symbol_child + literal_child).to_set.freeze
|
101
110
|
private_constant :NO_CHILD_NODES # Used by Commissioner
|
102
111
|
|
103
|
-
###
|
112
|
+
### children count > 1
|
104
113
|
symbol_then_opt_node = %i[lvasgn ivasgn cvasgn gvasgn]
|
105
114
|
symbol_then_node_or_nil = %i[optarg kwoptarg]
|
106
115
|
node_then_opt_node = %i[while until module sclass]
|
107
116
|
|
108
|
-
### variable
|
117
|
+
### variable children count
|
109
118
|
many_node_children = %i[dstr dsym xstr regexp array hash pair
|
110
119
|
mlhs masgn or_asgn and_asgn rasgn mrasgn
|
111
120
|
undef alias args super yield or and
|
@@ -121,18 +130,18 @@ module RuboCop
|
|
121
130
|
|
122
131
|
### Callbacks for above
|
123
132
|
def_callback no_children
|
124
|
-
def_callback opt_symbol_child, :skip,
|
125
|
-
def_callback opt_node_child, :nil?,
|
133
|
+
def_callback opt_symbol_child, :skip, expected_children_count: 0..1
|
134
|
+
def_callback opt_node_child, :nil?, expected_children_count: 0..1
|
126
135
|
|
127
136
|
def_callback literal_child, :skip
|
128
137
|
def_callback node_child, :always
|
129
138
|
def_callback node_or_nil_child, :nil?
|
130
139
|
|
131
|
-
def_callback symbol_then_opt_node, :skip, :nil?,
|
140
|
+
def_callback symbol_then_opt_node, :skip, :nil?, expected_children_count: 1..2
|
132
141
|
def_callback symbol_then_node_or_nil, :skip, :nil?
|
133
142
|
def_callback node_then_opt_node, :always, :nil?
|
134
143
|
|
135
|
-
def_callback many_symbol_children, :skip,
|
144
|
+
def_callback many_symbol_children, :skip, expected_children_count: (0..)
|
136
145
|
def_callback many_node_children, body: <<~RUBY
|
137
146
|
node.children.each { |child| #{send_code} }
|
138
147
|
RUBY
|
@@ -143,13 +152,14 @@ module RuboCop
|
|
143
152
|
|
144
153
|
### Other particular cases
|
145
154
|
def_callback :const, :nil?, :skip
|
146
|
-
def_callback :casgn, :nil?, :skip, :nil?,
|
155
|
+
def_callback :casgn, :nil?, :skip, :nil?, expected_children_count: 2..3
|
147
156
|
def_callback :class, :always, :nil?, :nil?
|
148
157
|
def_callback :def, :skip, :always, :nil?
|
149
158
|
def_callback :op_asgn, :always, :skip, :always
|
150
159
|
def_callback :if, :always, :nil?, :nil?
|
151
160
|
def_callback :block, :always, :always, :nil?
|
152
161
|
def_callback :numblock, :always, :skip, :nil?
|
162
|
+
def_callback :itblock, :always, :skip, :nil?
|
153
163
|
def_callback :defs, :always, :skip, :always, :nil?
|
154
164
|
|
155
165
|
def_callback %i[send csend], body: <<~RUBY
|
@@ -167,7 +177,7 @@ module RuboCop
|
|
167
177
|
|
168
178
|
to_define = ::Parser::Meta::NODE_TYPES.to_a
|
169
179
|
to_define -= defined
|
170
|
-
to_define -= %i[numargs ident] # transient
|
180
|
+
to_define -= %i[numargs itarg ident] # transient
|
171
181
|
to_define -= %i[blockarg_expr restarg_expr] # obsolete
|
172
182
|
to_define -= %i[objc_kwarg objc_restarg objc_varargs] # mac_ruby
|
173
183
|
def_callback to_define, body: <<~RUBY
|
@@ -5,11 +5,22 @@ module RuboCop
|
|
5
5
|
module SimpleForwardable
|
6
6
|
def def_delegators(accessor, *methods)
|
7
7
|
methods.each do |method|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
if method.end_with?('=') && method.to_s != '[]='
|
9
|
+
# Defining a delegator for `foo=` can't use `foo=(...)` because it is a
|
10
|
+
# syntax error. Fall back to doing a slower `public_send` instead.
|
11
|
+
# TODO: Use foo(method, ...) when Ruby 3.1 is required.
|
12
|
+
class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
13
|
+
def #{method}(*args, **kwargs, &blk) # def example=(*args, **kwargs, &blk)
|
14
|
+
#{accessor}.public_send(:#{method}, *args, **kwargs, &blk) # foo.public_send(:example=, *args, **kwargs, &blk)
|
15
|
+
end # end
|
16
|
+
RUBY
|
17
|
+
else
|
18
|
+
class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
19
|
+
def #{method}(...) # def example(...)
|
20
|
+
#{accessor}.#{method}(...) # foo.example(...)
|
21
|
+
end # end
|
22
|
+
RUBY
|
23
|
+
end
|
13
24
|
end
|
14
25
|
end
|
15
26
|
end
|
data/lib/rubocop/ast/version.rb
CHANGED
metadata
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-ast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.41.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
8
8
|
- Jonas Arvidsson
|
9
9
|
- Yuji Nakayama
|
10
|
-
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date:
|
12
|
+
date: 2025-03-20 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: parser
|
@@ -18,14 +17,14 @@ dependencies:
|
|
18
17
|
requirements:
|
19
18
|
- - ">="
|
20
19
|
- !ruby/object:Gem::Version
|
21
|
-
version: 3.3.
|
20
|
+
version: 3.3.7.2
|
22
21
|
type: :runtime
|
23
22
|
prerelease: false
|
24
23
|
version_requirements: !ruby/object:Gem::Requirement
|
25
24
|
requirements:
|
26
25
|
- - ">="
|
27
26
|
- !ruby/object:Gem::Version
|
28
|
-
version: 3.3.
|
27
|
+
version: 3.3.7.2
|
29
28
|
description: " RuboCop's Node and NodePattern classes.\n"
|
30
29
|
email: rubocop@googlegroups.com
|
31
30
|
executables: []
|
@@ -39,6 +38,7 @@ files:
|
|
39
38
|
- lib/rubocop-ast.rb
|
40
39
|
- lib/rubocop/ast.rb
|
41
40
|
- lib/rubocop/ast/builder.rb
|
41
|
+
- lib/rubocop/ast/builder_prism.rb
|
42
42
|
- lib/rubocop/ast/ext/range.rb
|
43
43
|
- lib/rubocop/ast/node.rb
|
44
44
|
- lib/rubocop/ast/node/alias_node.rb
|
@@ -147,7 +147,6 @@ metadata:
|
|
147
147
|
documentation_uri: https://docs.rubocop.org/rubocop-ast/
|
148
148
|
bug_tracker_uri: https://github.com/rubocop/rubocop-ast/issues
|
149
149
|
rubygems_mfa_required: 'true'
|
150
|
-
post_install_message:
|
151
150
|
rdoc_options: []
|
152
151
|
require_paths:
|
153
152
|
- lib
|
@@ -162,8 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
161
|
- !ruby/object:Gem::Version
|
163
162
|
version: '0'
|
164
163
|
requirements: []
|
165
|
-
rubygems_version: 3.
|
166
|
-
signing_key:
|
164
|
+
rubygems_version: 3.6.2
|
167
165
|
specification_version: 4
|
168
166
|
summary: RuboCop tools to deal with Ruby code AST.
|
169
167
|
test_files: []
|