rubocop-ast 1.32.3 → 1.38.1
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 +7 -0
- data/lib/rubocop/ast/node/args_node.rb +1 -1
- data/lib/rubocop/ast/node/array_node.rb +4 -4
- data/lib/rubocop/ast/node/asgn_node.rb +2 -0
- data/lib/rubocop/ast/node/block_node.rb +2 -2
- data/lib/rubocop/ast/node/casgn_node.rb +4 -12
- data/lib/rubocop/ast/node/const_node.rb +1 -52
- data/lib/rubocop/ast/node/ensure_node.rb +15 -0
- data/lib/rubocop/ast/node/for_node.rb +1 -1
- data/lib/rubocop/ast/node/hash_node.rb +1 -1
- data/lib/rubocop/ast/node/if_node.rb +10 -3
- data/lib/rubocop/ast/node/in_pattern_node.rb +1 -1
- data/lib/rubocop/ast/node/keyword_begin_node.rb +44 -0
- data/lib/rubocop/ast/node/masgn_node.rb +63 -0
- data/lib/rubocop/ast/node/mixin/constant_node.rb +62 -0
- 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 +8 -8
- data/lib/rubocop/ast/node/mixin/parameterized_node.rb +2 -2
- data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +7 -2
- data/lib/rubocop/ast/node/mlhs_node.rb +29 -0
- data/lib/rubocop/ast/node/op_asgn_node.rb +3 -1
- data/lib/rubocop/ast/node/str_node.rb +37 -1
- data/lib/rubocop/ast/node/until_node.rb +1 -1
- data/lib/rubocop/ast/node/var_node.rb +15 -0
- data/lib/rubocop/ast/node/when_node.rb +1 -1
- data/lib/rubocop/ast/node/while_node.rb +1 -1
- data/lib/rubocop/ast/node.rb +78 -22
- data/lib/rubocop/ast/node_pattern/lexer.rex.rb +1 -2
- data/lib/rubocop/ast/node_pattern/node.rb +7 -1
- data/lib/rubocop/ast/node_pattern/parser.racc.rb +42 -40
- data/lib/rubocop/ast/processed_source.rb +28 -8
- data/lib/rubocop/ast/token.rb +2 -1
- data/lib/rubocop/ast/utilities/simple_forwardable.rb +16 -5
- data/lib/rubocop/ast/version.rb +1 -1
- data/lib/rubocop/ast.rb +5 -0
- metadata +11 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7fd9852873f22808386ddc6962f7373509ec03930f3e5c667475d512480b705
|
4
|
+
data.tar.gz: b6d36926cd045b8486679af378d1fdd21875b941d3f5916fbb6876f04ef75e11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b83bb3a5b3c20a8831d6ad8e075d536b3ff8042d873ce6062161fbe1556e80da5fc4646499dc0432864ecb034ffe3ade83f7ac2f37562a9df22620b486e61e5a
|
7
|
+
data.tar.gz: d6f98f800797330d515911991c9215e8fa616cdcde7a73666aa0d25ff05b70b9274a1f0df689f8a820a6573c391bca487100a258a142c21a60f3fd8ea6e5c5e8
|
data/lib/rubocop/ast/builder.rb
CHANGED
@@ -63,8 +63,11 @@ module RuboCop
|
|
63
63
|
irange: RangeNode,
|
64
64
|
erange: RangeNode,
|
65
65
|
kwargs: HashNode,
|
66
|
+
kwbegin: KeywordBeginNode,
|
66
67
|
kwsplat: KeywordSplatNode,
|
67
68
|
lambda: LambdaNode,
|
69
|
+
masgn: MasgnNode,
|
70
|
+
mlhs: MlhsNode,
|
68
71
|
module: ModuleNode,
|
69
72
|
next: NextNode,
|
70
73
|
op_asgn: OpAsgnNode,
|
@@ -87,6 +90,10 @@ module RuboCop
|
|
87
90
|
sym: SymbolNode,
|
88
91
|
until: UntilNode,
|
89
92
|
until_post: UntilNode,
|
93
|
+
lvar: VarNode,
|
94
|
+
ivar: VarNode,
|
95
|
+
cvar: VarNode,
|
96
|
+
gvar: VarNode,
|
90
97
|
when: WhenNode,
|
91
98
|
while: WhileNode,
|
92
99
|
while_post: WhileNode,
|
@@ -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
|
|
@@ -34,7 +34,7 @@ module RuboCop
|
|
34
34
|
#
|
35
35
|
# @return [Boolean] whether the array is enclosed in square brackets
|
36
36
|
def square_brackets?
|
37
|
-
|
37
|
+
loc_is?(:begin, '[')
|
38
38
|
end
|
39
39
|
|
40
40
|
# Checks whether the `array` literal is delimited by percent brackets.
|
@@ -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
|
@@ -12,6 +12,7 @@ module RuboCop
|
|
12
12
|
def name
|
13
13
|
node_parts[0]
|
14
14
|
end
|
15
|
+
alias lhs name
|
15
16
|
|
16
17
|
# The expression being assigned to the variable.
|
17
18
|
#
|
@@ -19,6 +20,7 @@ module RuboCop
|
|
19
20
|
def expression
|
20
21
|
node_parts[1]
|
21
22
|
end
|
23
|
+
alias rhs expression
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
@@ -90,14 +90,14 @@ module RuboCop
|
|
90
90
|
#
|
91
91
|
# @return [Boolean] whether the `block` literal is enclosed in braces
|
92
92
|
def braces?
|
93
|
-
loc.end
|
93
|
+
loc.end.is?('}')
|
94
94
|
end
|
95
95
|
|
96
96
|
# Checks whether the `block` literal is delimited by `do`-`end` keywords.
|
97
97
|
#
|
98
98
|
# @return [Boolean] whether the `block` literal is enclosed in `do`-`end`
|
99
99
|
def keywords?
|
100
|
-
loc.end
|
100
|
+
loc.end.is?('end')
|
101
101
|
end
|
102
102
|
|
103
103
|
# The delimiters for this `block` literal.
|
@@ -6,19 +6,10 @@ module RuboCop
|
|
6
6
|
# This will be used in place of a plain node when the builder constructs
|
7
7
|
# the AST, making its methods available to all assignment nodes within RuboCop.
|
8
8
|
class CasgnNode < Node
|
9
|
-
|
10
|
-
#
|
11
|
-
# @return [Node, nil] the node associated with the scope (e.g. cbase, const, ...)
|
12
|
-
def namespace
|
13
|
-
node_parts[0]
|
14
|
-
end
|
9
|
+
include ConstantNode
|
15
10
|
|
16
|
-
|
17
|
-
|
18
|
-
# @return [Symbol] the name of the variable being assigned
|
19
|
-
def name
|
20
|
-
node_parts[1]
|
21
|
-
end
|
11
|
+
alias name short_name
|
12
|
+
alias lhs short_name
|
22
13
|
|
23
14
|
# The expression being assigned to the variable.
|
24
15
|
#
|
@@ -26,6 +17,7 @@ module RuboCop
|
|
26
17
|
def expression
|
27
18
|
node_parts[2]
|
28
19
|
end
|
20
|
+
alias rhs expression
|
29
21
|
end
|
30
22
|
end
|
31
23
|
end
|
@@ -4,58 +4,7 @@ module RuboCop
|
|
4
4
|
module AST
|
5
5
|
# A node extension for `const` nodes.
|
6
6
|
class ConstNode < Node
|
7
|
-
|
8
|
-
def namespace
|
9
|
-
children[0]
|
10
|
-
end
|
11
|
-
|
12
|
-
# @return [Symbol] the demodulized name of the constant: "::Foo::Bar" => :Bar
|
13
|
-
def short_name
|
14
|
-
children[1]
|
15
|
-
end
|
16
|
-
|
17
|
-
# @return [Boolean] if the constant is a Module / Class, according to the standard convention.
|
18
|
-
# Note: some classes might have uppercase in which case this method
|
19
|
-
# returns false
|
20
|
-
def module_name?
|
21
|
-
short_name.match?(/[[:lower:]]/)
|
22
|
-
end
|
23
|
-
alias class_name? module_name?
|
24
|
-
|
25
|
-
# @return [Boolean] if the constant starts with `::` (aka s(:cbase))
|
26
|
-
def absolute?
|
27
|
-
return false unless namespace
|
28
|
-
|
29
|
-
each_path.first.cbase_type?
|
30
|
-
end
|
31
|
-
|
32
|
-
# @return [Boolean] if the constant does not start with `::` (aka s(:cbase))
|
33
|
-
def relative?
|
34
|
-
!absolute?
|
35
|
-
end
|
36
|
-
|
37
|
-
# Yield nodes for the namespace
|
38
|
-
#
|
39
|
-
# For `::Foo::Bar::BAZ` => yields:
|
40
|
-
# s(:cbase), then
|
41
|
-
# s(:const, :Foo), then
|
42
|
-
# s(:const, s(:const, :Foo), :Bar)
|
43
|
-
def each_path(&block)
|
44
|
-
return to_enum(__method__) unless block
|
45
|
-
|
46
|
-
descendants = []
|
47
|
-
last = self
|
48
|
-
loop do
|
49
|
-
last = last.children.first
|
50
|
-
break if last.nil?
|
51
|
-
|
52
|
-
descendants << last
|
53
|
-
break unless last.const_type?
|
54
|
-
end
|
55
|
-
descendants.reverse_each(&block)
|
56
|
-
|
57
|
-
self
|
58
|
-
end
|
7
|
+
include ConstantNode
|
59
8
|
end
|
60
9
|
end
|
61
10
|
end
|
@@ -9,10 +9,25 @@ module RuboCop
|
|
9
9
|
# Returns the body of the `ensure` clause.
|
10
10
|
#
|
11
11
|
# @return [Node, nil] The body of the `ensure`.
|
12
|
+
# @deprecated Use `EnsureNode#branch`
|
12
13
|
def body
|
14
|
+
branch
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns an the ensure branch in the exception handling statement.
|
18
|
+
#
|
19
|
+
# @return [Node, nil] the body of the ensure branch.
|
20
|
+
def branch
|
13
21
|
node_parts[1]
|
14
22
|
end
|
15
23
|
|
24
|
+
# Returns the `rescue` node of the `ensure`, if present.
|
25
|
+
#
|
26
|
+
# @return [Node, nil] The `rescue` node.
|
27
|
+
def rescue_node
|
28
|
+
node_parts[0] if node_parts[0].rescue_type?
|
29
|
+
end
|
30
|
+
|
16
31
|
# Checks whether this node body is a void context.
|
17
32
|
# Always `true` for `ensure`.
|
18
33
|
#
|
@@ -25,6 +25,13 @@ module RuboCop
|
|
25
25
|
keyword == 'unless'
|
26
26
|
end
|
27
27
|
|
28
|
+
# Checks whether the `if` node has an `then` clause.
|
29
|
+
#
|
30
|
+
# @return [Boolean] whether the node has an `then` clause
|
31
|
+
def then?
|
32
|
+
loc_is?(:begin, 'then')
|
33
|
+
end
|
34
|
+
|
28
35
|
# Checks whether the `if` is an `elsif`. Parser handles these by nesting
|
29
36
|
# `if` nodes in the `else` branch.
|
30
37
|
#
|
@@ -40,14 +47,14 @@ module RuboCop
|
|
40
47
|
#
|
41
48
|
# @return [Boolean] whether the node has an `else` clause
|
42
49
|
def else?
|
43
|
-
loc
|
50
|
+
loc?(:else)
|
44
51
|
end
|
45
52
|
|
46
53
|
# Checks whether the `if` node is a ternary operator.
|
47
54
|
#
|
48
55
|
# @return [Boolean] whether the `if` node is a ternary operator
|
49
56
|
def ternary?
|
50
|
-
loc
|
57
|
+
loc?(:question)
|
51
58
|
end
|
52
59
|
|
53
60
|
# Returns the keyword of the `if` statement as a string. Returns an empty
|
@@ -102,7 +109,7 @@ module RuboCop
|
|
102
109
|
#
|
103
110
|
# @return [Boolean] whether the `if` node has at least one `elsif` branch
|
104
111
|
def elsif_conditional?
|
105
|
-
else_branch&.if_type? && else_branch
|
112
|
+
else_branch&.if_type? && else_branch.elsif?
|
106
113
|
end
|
107
114
|
|
108
115
|
# Returns the branch of the `if` node that gets evaluated when its
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module AST
|
5
|
+
# A node extension for `kwbegin` nodes. This will be used in place of a plain
|
6
|
+
# node when the builder constructs the AST, making its methods available
|
7
|
+
# to all `kwbegin` nodes within RuboCop.
|
8
|
+
class KeywordBeginNode < Node
|
9
|
+
# Returns the body of the `kwbegin` block. Returns `self` if the `kwbegin` contains
|
10
|
+
# multiple nodes.
|
11
|
+
#
|
12
|
+
# @return [Node, nil] The body of the `kwbegin`.
|
13
|
+
def body
|
14
|
+
return unless node_parts.any?
|
15
|
+
|
16
|
+
if rescue_node
|
17
|
+
rescue_node.body
|
18
|
+
elsif ensure_node
|
19
|
+
ensure_node.node_parts[0]
|
20
|
+
elsif node_parts.one?
|
21
|
+
node_parts[0]
|
22
|
+
else
|
23
|
+
self
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the `rescue` node of the `kwbegin` block, if one is present.
|
28
|
+
#
|
29
|
+
# @return [Node, nil] The `rescue` node within `kwbegin`.
|
30
|
+
def ensure_node
|
31
|
+
node_parts[0] if node_parts[0]&.ensure_type?
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns the `rescue` node of the `kwbegin` block, if one is present.
|
35
|
+
#
|
36
|
+
# @return [Node, nil] The `rescue` node within `kwbegin`.
|
37
|
+
def rescue_node
|
38
|
+
return ensure_node&.rescue_node if ensure_node&.rescue_node
|
39
|
+
|
40
|
+
node_parts[0] if node_parts[0]&.rescue_type?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module AST
|
5
|
+
# A node extension for `masgn` nodes.
|
6
|
+
# This will be used in place of a plain node when the builder constructs
|
7
|
+
# the AST, making its methods available to all assignment nodes within RuboCop.
|
8
|
+
class MasgnNode < Node
|
9
|
+
# @return [MlhsNode] the `mlhs` node
|
10
|
+
def lhs
|
11
|
+
# The first child is a `mlhs` node
|
12
|
+
node_parts[0]
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Array<Node>] the assignment nodes of the multiple assignment
|
16
|
+
def assignments
|
17
|
+
lhs.assignments
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Array<Symbol>] names of all the variables being assigned
|
21
|
+
def names
|
22
|
+
assignments.map do |assignment|
|
23
|
+
if assignment.type?(:send, :indexasgn)
|
24
|
+
assignment.method_name
|
25
|
+
else
|
26
|
+
assignment.name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# The RHS (right hand side) of the multiple assignment. This returns
|
32
|
+
# the nodes as parsed: either a single node if the RHS has a single value,
|
33
|
+
# or an `array` node containing multiple nodes.
|
34
|
+
#
|
35
|
+
# NOTE: Due to how parsing works, `expression` will return the same for
|
36
|
+
# `a, b = x, y` and `a, b = [x, y]`.
|
37
|
+
#
|
38
|
+
# @return [Node] the right hand side of a multiple assignment.
|
39
|
+
def expression
|
40
|
+
node_parts[1]
|
41
|
+
end
|
42
|
+
alias rhs expression
|
43
|
+
|
44
|
+
# In contrast to `expression`, `values` always returns a Ruby array
|
45
|
+
# containing all the nodes being assigned on the RHS.
|
46
|
+
#
|
47
|
+
# Literal arrays are considered a singular value; but unlike `expression`,
|
48
|
+
# implied `array` nodes from assigning multiple values on the RHS are treated
|
49
|
+
# as separate.
|
50
|
+
#
|
51
|
+
# @return [Array<Node>] individual values being assigned on the RHS of the multiple assignment
|
52
|
+
def values
|
53
|
+
multiple_rhs? ? expression.children : [expression]
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def multiple_rhs?
|
59
|
+
expression.array_type? && !expression.bracketed?
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module AST
|
5
|
+
# Common functionality for nodes that deal with constants:
|
6
|
+
# `const`, `casgn`.
|
7
|
+
module ConstantNode
|
8
|
+
# @return [Node, nil] the node associated with the scope (e.g. cbase, const, ...)
|
9
|
+
def namespace
|
10
|
+
children[0]
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [Symbol] the demodulized name of the constant: "::Foo::Bar" => :Bar
|
14
|
+
def short_name
|
15
|
+
children[1]
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [Boolean] if the constant is a Module / Class, according to the standard convention.
|
19
|
+
# Note: some classes might have uppercase in which case this method
|
20
|
+
# returns false
|
21
|
+
def module_name?
|
22
|
+
short_name.match?(/[[:lower:]]/)
|
23
|
+
end
|
24
|
+
alias class_name? module_name?
|
25
|
+
|
26
|
+
# @return [Boolean] if the constant starts with `::` (aka s(:cbase))
|
27
|
+
def absolute?
|
28
|
+
return false unless namespace
|
29
|
+
|
30
|
+
each_path.first.cbase_type?
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Boolean] if the constant does not start with `::` (aka s(:cbase))
|
34
|
+
def relative?
|
35
|
+
!absolute?
|
36
|
+
end
|
37
|
+
|
38
|
+
# Yield nodes for the namespace
|
39
|
+
#
|
40
|
+
# For `::Foo::Bar::BAZ` => yields:
|
41
|
+
# s(:cbase), then
|
42
|
+
# s(:const, :Foo), then
|
43
|
+
# s(:const, s(:const, :Foo), :Bar)
|
44
|
+
def each_path(&block)
|
45
|
+
return to_enum(__method__) unless block
|
46
|
+
|
47
|
+
descendants = []
|
48
|
+
last = self
|
49
|
+
loop do
|
50
|
+
last = last.children.first
|
51
|
+
break if last.nil?
|
52
|
+
|
53
|
+
descendants << last
|
54
|
+
break unless last.const_type?
|
55
|
+
end
|
56
|
+
descendants.reverse_each(&block)
|
57
|
+
|
58
|
+
self
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -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
|
|
@@ -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
|
|
@@ -117,7 +117,7 @@ module RuboCop
|
|
117
117
|
#
|
118
118
|
# @return [Boolean] whether the method was called with a connecting dot
|
119
119
|
def dot?
|
120
|
-
|
120
|
+
loc_is?(:dot, '.')
|
121
121
|
end
|
122
122
|
|
123
123
|
# Checks whether the dispatched method uses a double colon to connect the
|
@@ -125,7 +125,7 @@ module RuboCop
|
|
125
125
|
#
|
126
126
|
# @return [Boolean] whether the method was called with a connecting dot
|
127
127
|
def double_colon?
|
128
|
-
|
128
|
+
loc_is?(:dot, '::')
|
129
129
|
end
|
130
130
|
|
131
131
|
# Checks whether the dispatched method uses a safe navigation operator to
|
@@ -133,7 +133,7 @@ module RuboCop
|
|
133
133
|
#
|
134
134
|
# @return [Boolean] whether the method was called with a connecting dot
|
135
135
|
def safe_navigation?
|
136
|
-
|
136
|
+
loc_is?(:dot, '&.')
|
137
137
|
end
|
138
138
|
|
139
139
|
# Checks whether the *explicit* receiver of this method dispatch is
|
@@ -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
|
@@ -281,7 +281,7 @@ module RuboCop
|
|
281
281
|
|
282
282
|
# @!method non_bare_access_modifier_declaration?(node = self)
|
283
283
|
def_node_matcher :non_bare_access_modifier_declaration?, <<~PATTERN
|
284
|
-
(send nil? {:public :protected :private :module_function} _)
|
284
|
+
(send nil? {:public :protected :private :module_function} _+)
|
285
285
|
PATTERN
|
286
286
|
end
|
287
287
|
end
|
@@ -13,7 +13,7 @@ module RuboCop
|
|
13
13
|
# @return [Boolean] whether this node's arguments are
|
14
14
|
# wrapped in parentheses
|
15
15
|
def parenthesized?
|
16
|
-
|
16
|
+
loc_is?(:end, ')')
|
17
17
|
end
|
18
18
|
|
19
19
|
# A shorthand for getting the first argument of the node.
|
@@ -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
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module AST
|
5
|
+
# A node extension for `mlhs` nodes.
|
6
|
+
# This will be used in place of a plain node when the builder constructs
|
7
|
+
# the AST, making its methods available to all assignment nodes within RuboCop.
|
8
|
+
class MlhsNode < Node
|
9
|
+
# Returns all the assignment nodes on the left hand side (LHS) of a multiple assignment.
|
10
|
+
# These are generally assignment nodes (`lvasgn`, `ivasgn`, `cvasgn`, `gvasgn`, `casgn`)
|
11
|
+
# but can also be `send` nodes in case of `foo.bar, ... =` or `foo[:bar], ... =`,
|
12
|
+
# or a `splat` node for `*, ... =`.
|
13
|
+
#
|
14
|
+
# @return [Array<Node>] the assignment nodes of the multiple assignment LHS
|
15
|
+
def assignments
|
16
|
+
child_nodes.flat_map do |node|
|
17
|
+
if node.splat_type?
|
18
|
+
# Anonymous splats have no children
|
19
|
+
node.child_nodes.first || node
|
20
|
+
elsif node.mlhs_type?
|
21
|
+
node.assignments
|
22
|
+
else
|
23
|
+
node
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -10,12 +10,13 @@ module RuboCop
|
|
10
10
|
def assignment_node
|
11
11
|
node_parts[0]
|
12
12
|
end
|
13
|
+
alias lhs assignment_node
|
13
14
|
|
14
15
|
# The name of the variable being assigned as a symbol.
|
15
16
|
#
|
16
17
|
# @return [Symbol] the name of the variable being assigned
|
17
18
|
def name
|
18
|
-
assignment_node.name
|
19
|
+
assignment_node.call_type? ? assignment_node.method_name : assignment_node.name
|
19
20
|
end
|
20
21
|
|
21
22
|
# The operator being used for assignment as a symbol.
|
@@ -31,6 +32,7 @@ module RuboCop
|
|
31
32
|
def expression
|
32
33
|
node_parts.last
|
33
34
|
end
|
35
|
+
alias rhs expression
|
34
36
|
end
|
35
37
|
end
|
36
38
|
end
|