rubocop-ast 0.1.0 → 0.4.2
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/README.md +9 -5
- data/lib/rubocop/ast.rb +5 -1
- data/lib/rubocop/ast/builder.rb +5 -1
- data/lib/rubocop/ast/ext/range.rb +28 -0
- data/lib/rubocop/ast/ext/set.rb +12 -0
- data/lib/rubocop/ast/node.rb +63 -8
- data/lib/rubocop/ast/node/array_node.rb +2 -8
- data/lib/rubocop/ast/node/block_node.rb +1 -1
- data/lib/rubocop/ast/node/break_node.rb +1 -6
- data/lib/rubocop/ast/node/case_match_node.rb +3 -9
- data/lib/rubocop/ast/node/case_node.rb +13 -9
- data/lib/rubocop/ast/node/const_node.rb +65 -0
- data/lib/rubocop/ast/node/def_node.rb +4 -23
- data/lib/rubocop/ast/node/defined_node.rb +2 -0
- data/lib/rubocop/ast/node/float_node.rb +1 -0
- data/lib/rubocop/ast/node/hash_node.rb +21 -8
- data/lib/rubocop/ast/node/if_node.rb +7 -14
- data/lib/rubocop/ast/node/index_node.rb +5 -3
- data/lib/rubocop/ast/node/indexasgn_node.rb +5 -3
- data/lib/rubocop/ast/node/int_node.rb +1 -0
- data/lib/rubocop/ast/node/lambda_node.rb +10 -3
- data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +0 -7
- data/lib/rubocop/ast/node/mixin/parameterized_node.rb +55 -0
- data/lib/rubocop/ast/node/next_node.rb +12 -0
- data/lib/rubocop/ast/node/pair_node.rb +2 -2
- data/lib/rubocop/ast/node/resbody_node.rb +21 -0
- data/lib/rubocop/ast/node/rescue_node.rb +49 -0
- data/lib/rubocop/ast/node/return_node.rb +1 -13
- data/lib/rubocop/ast/node/send_node.rb +7 -1
- data/lib/rubocop/ast/node/super_node.rb +2 -0
- data/lib/rubocop/ast/node/when_node.rb +3 -9
- data/lib/rubocop/ast/node/yield_node.rb +2 -0
- data/lib/rubocop/ast/node_pattern.rb +99 -86
- data/lib/rubocop/ast/processed_source.rb +94 -16
- data/lib/rubocop/ast/traversal.rb +2 -2
- data/lib/rubocop/ast/version.rb +1 -1
- metadata +12 -8
- data/lib/rubocop/ast/node/retry_node.rb +0 -17
@@ -8,6 +8,9 @@ module RuboCop
|
|
8
8
|
class HashNode < Node
|
9
9
|
# Returns an array of all the key value pairs in the `hash` literal.
|
10
10
|
#
|
11
|
+
# @note this may be different from children as `kwsplat` nodes are
|
12
|
+
# ignored.
|
13
|
+
#
|
11
14
|
# @return [Array<PairNode>] an array of `pair` nodes
|
12
15
|
def pairs
|
13
16
|
each_pair.to_a
|
@@ -23,6 +26,8 @@ module RuboCop
|
|
23
26
|
# Calls the given block for each `pair` node in the `hash` literal.
|
24
27
|
# If no block is given, an `Enumerator` is returned.
|
25
28
|
#
|
29
|
+
# @note `kwsplat` nodes are ignored.
|
30
|
+
#
|
26
31
|
# @return [self] if a block is given
|
27
32
|
# @return [Enumerator] if no block is given
|
28
33
|
def each_pair
|
@@ -37,6 +42,8 @@ module RuboCop
|
|
37
42
|
|
38
43
|
# Returns an array of all the keys in the `hash` literal.
|
39
44
|
#
|
45
|
+
# @note `kwsplat` nodes are ignored.
|
46
|
+
#
|
40
47
|
# @return [Array<Node>] an array of keys in the `hash` literal
|
41
48
|
def keys
|
42
49
|
each_key.to_a
|
@@ -45,20 +52,22 @@ module RuboCop
|
|
45
52
|
# Calls the given block for each `key` node in the `hash` literal.
|
46
53
|
# If no block is given, an `Enumerator` is returned.
|
47
54
|
#
|
55
|
+
# @note `kwsplat` nodes are ignored.
|
56
|
+
#
|
48
57
|
# @return [self] if a block is given
|
49
58
|
# @return [Enumerator] if no block is given
|
50
|
-
def each_key
|
59
|
+
def each_key(&block)
|
51
60
|
return pairs.map(&:key).to_enum unless block_given?
|
52
61
|
|
53
|
-
pairs.map(&:key).each
|
54
|
-
yield key
|
55
|
-
end
|
62
|
+
pairs.map(&:key).each(&block)
|
56
63
|
|
57
64
|
self
|
58
65
|
end
|
59
66
|
|
60
67
|
# Returns an array of all the values in the `hash` literal.
|
61
68
|
#
|
69
|
+
# @note `kwsplat` nodes are ignored.
|
70
|
+
#
|
62
71
|
# @return [Array<Node>] an array of values in the `hash` literal
|
63
72
|
def values
|
64
73
|
each_pair.map(&:value)
|
@@ -67,14 +76,14 @@ module RuboCop
|
|
67
76
|
# Calls the given block for each `value` node in the `hash` literal.
|
68
77
|
# If no block is given, an `Enumerator` is returned.
|
69
78
|
#
|
79
|
+
# @note `kwsplat` nodes are ignored.
|
80
|
+
#
|
70
81
|
# @return [self] if a block is given
|
71
82
|
# @return [Enumerator] if no block is given
|
72
|
-
def each_value
|
83
|
+
def each_value(&block)
|
73
84
|
return pairs.map(&:value).to_enum unless block_given?
|
74
85
|
|
75
|
-
pairs.map(&:value).each
|
76
|
-
yield value
|
77
|
-
end
|
86
|
+
pairs.map(&:value).each(&block)
|
78
87
|
|
79
88
|
self
|
80
89
|
end
|
@@ -85,6 +94,8 @@ module RuboCop
|
|
85
94
|
# @note A multiline `pair` is considered to be on the same line if it
|
86
95
|
# shares any of its lines with another `pair`
|
87
96
|
#
|
97
|
+
# @note `kwsplat` nodes are ignored.
|
98
|
+
#
|
88
99
|
# @return [Boolean] whether any `pair` nodes are on the same line
|
89
100
|
def pairs_on_same_line?
|
90
101
|
pairs.each_cons(2).any? { |first, second| first.same_line?(second) }
|
@@ -93,6 +104,8 @@ module RuboCop
|
|
93
104
|
# Checks whether this `hash` uses a mix of hash rocket and colon
|
94
105
|
# delimiters for its pairs.
|
95
106
|
#
|
107
|
+
# @note `kwsplat` nodes are ignored.
|
108
|
+
#
|
96
109
|
# @return [Boolean] whether the `hash` uses mixed delimiters
|
97
110
|
def mixed_delimiters?
|
98
111
|
pairs.map(&:delimiter).uniq.size > 1
|
@@ -64,10 +64,9 @@ module RuboCop
|
|
64
64
|
#
|
65
65
|
# @return [String] the inverse keyword of the `if` statement
|
66
66
|
def inverse_keyword
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
'if'
|
67
|
+
case keyword
|
68
|
+
when 'if' then 'unless'
|
69
|
+
when 'unless' then 'if'
|
71
70
|
else
|
72
71
|
''
|
73
72
|
end
|
@@ -148,7 +147,7 @@ module RuboCop
|
|
148
147
|
def branches
|
149
148
|
branches = [if_branch]
|
150
149
|
|
151
|
-
return branches unless
|
150
|
+
return branches unless else?
|
152
151
|
|
153
152
|
other_branches = if elsif_conditional?
|
154
153
|
else_branch.branches
|
@@ -158,17 +157,11 @@ module RuboCop
|
|
158
157
|
branches.concat(other_branches)
|
159
158
|
end
|
160
159
|
|
161
|
-
#
|
162
|
-
|
163
|
-
#
|
164
|
-
# @return [self] if a block is given
|
165
|
-
# @return [Enumerator] if no block is given
|
166
|
-
def each_branch
|
160
|
+
# @deprecated Use `branches.each`
|
161
|
+
def each_branch(&block)
|
167
162
|
return branches.to_enum(__method__) unless block_given?
|
168
163
|
|
169
|
-
branches.each
|
170
|
-
yield branch
|
171
|
-
end
|
164
|
+
branches.each(&block)
|
172
165
|
end
|
173
166
|
end
|
174
167
|
end
|
@@ -17,7 +17,7 @@ module RuboCop
|
|
17
17
|
# The main RuboCop runs in legacy mode; this node is only used
|
18
18
|
# if user `AST::Builder.modernize` or `AST::Builder.emit_index=true`
|
19
19
|
class IndexNode < Node
|
20
|
-
include ParameterizedNode
|
20
|
+
include ParameterizedNode::RestArguments
|
21
21
|
include MethodDispatchNode
|
22
22
|
|
23
23
|
# For similarity with legacy mode
|
@@ -35,11 +35,13 @@ module RuboCop
|
|
35
35
|
:[]
|
36
36
|
end
|
37
37
|
|
38
|
+
private
|
39
|
+
|
38
40
|
# An array containing the arguments of the dispatched method.
|
39
41
|
#
|
40
42
|
# @return [Array<Node>] the arguments of the dispatched method
|
41
|
-
def
|
42
|
-
|
43
|
+
def first_argument_index
|
44
|
+
1
|
43
45
|
end
|
44
46
|
end
|
45
47
|
end
|
@@ -19,7 +19,7 @@ module RuboCop
|
|
19
19
|
# The main RuboCop runs in legacy mode; this node is only used
|
20
20
|
# if user `AST::Builder.modernize` or `AST::Builder.emit_index=true`
|
21
21
|
class IndexasgnNode < Node
|
22
|
-
include ParameterizedNode
|
22
|
+
include ParameterizedNode::RestArguments
|
23
23
|
include MethodDispatchNode
|
24
24
|
|
25
25
|
# For similarity with legacy mode
|
@@ -37,11 +37,13 @@ module RuboCop
|
|
37
37
|
:[]=
|
38
38
|
end
|
39
39
|
|
40
|
+
private
|
41
|
+
|
40
42
|
# An array containing the arguments of the dispatched method.
|
41
43
|
#
|
42
44
|
# @return [Array<Node>] the arguments of the dispatched method
|
43
|
-
def
|
44
|
-
|
45
|
+
def first_argument_index
|
46
|
+
1
|
45
47
|
end
|
46
48
|
end
|
47
49
|
end
|
@@ -21,7 +21,7 @@ module RuboCop
|
|
21
21
|
# The main RuboCop runs in legacy mode; this node is only used
|
22
22
|
# if user `AST::Builder.modernize` or `AST::Builder.emit_lambda=true`
|
23
23
|
class LambdaNode < Node
|
24
|
-
include ParameterizedNode
|
24
|
+
include ParameterizedNode::RestArguments
|
25
25
|
include MethodDispatchNode
|
26
26
|
|
27
27
|
# For similarity with legacy mode
|
@@ -44,14 +44,21 @@ module RuboCop
|
|
44
44
|
false
|
45
45
|
end
|
46
46
|
|
47
|
+
# For similarity with legacy mode
|
48
|
+
def receiver
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
47
52
|
# For similarity with legacy mode
|
48
53
|
def method_name
|
49
54
|
:lambda
|
50
55
|
end
|
51
56
|
|
57
|
+
private
|
58
|
+
|
52
59
|
# For similarity with legacy mode
|
53
|
-
def
|
54
|
-
|
60
|
+
def first_argument_index
|
61
|
+
2
|
55
62
|
end
|
56
63
|
end
|
57
64
|
end
|
@@ -26,13 +26,6 @@ module RuboCop
|
|
26
26
|
node_parts[1]
|
27
27
|
end
|
28
28
|
|
29
|
-
# An array containing the arguments of the dispatched method.
|
30
|
-
#
|
31
|
-
# @return [Array<Node>] the arguments of the dispatched method
|
32
|
-
def arguments
|
33
|
-
node_parts[2..-1]
|
34
|
-
end
|
35
|
-
|
36
29
|
# The `block` node associated with this method dispatch, if any.
|
37
30
|
#
|
38
31
|
# @return [BlockNode, nil] the `block` node associated with this method
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module RuboCop
|
4
4
|
module AST
|
5
|
+
# Requires implementing `arguments`.
|
6
|
+
#
|
5
7
|
# Common functionality for nodes that are parameterized:
|
6
8
|
# `send`, `super`, `zsuper`, `def`, `defs`
|
7
9
|
# and (modern only): `index`, `indexasgn`, `lambda`
|
@@ -57,6 +59,59 @@ module RuboCop
|
|
57
59
|
arguments? &&
|
58
60
|
(last_argument.block_pass_type? || last_argument.blockarg_type?)
|
59
61
|
end
|
62
|
+
|
63
|
+
# A specialized `ParameterizedNode` for node that have a single child
|
64
|
+
# containing either `nil`, an argument, or a `begin` node with all the
|
65
|
+
# arguments
|
66
|
+
module WrappedArguments
|
67
|
+
include ParameterizedNode
|
68
|
+
# @return [Array] The arguments of the node.
|
69
|
+
def arguments
|
70
|
+
first = children.first
|
71
|
+
if first&.begin_type?
|
72
|
+
first.children
|
73
|
+
else
|
74
|
+
children
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# A specialized `ParameterizedNode`.
|
80
|
+
# Requires implementing `first_argument_index`
|
81
|
+
# Implements `arguments` as `children[first_argument_index..-1]`
|
82
|
+
# and optimizes other calls
|
83
|
+
module RestArguments
|
84
|
+
include ParameterizedNode
|
85
|
+
# @return [Array<Node>] arguments, if any
|
86
|
+
def arguments
|
87
|
+
children[first_argument_index..-1].freeze
|
88
|
+
end
|
89
|
+
|
90
|
+
# A shorthand for getting the first argument of the node.
|
91
|
+
# Equivalent to `arguments.first`.
|
92
|
+
#
|
93
|
+
# @return [Node, nil] the first argument of the node,
|
94
|
+
# or `nil` if there are no arguments
|
95
|
+
def first_argument
|
96
|
+
children[first_argument_index]
|
97
|
+
end
|
98
|
+
|
99
|
+
# A shorthand for getting the last argument of the node.
|
100
|
+
# Equivalent to `arguments.last`.
|
101
|
+
#
|
102
|
+
# @return [Node, nil] the last argument of the node,
|
103
|
+
# or `nil` if there are no arguments
|
104
|
+
def last_argument
|
105
|
+
children[-1] if arguments?
|
106
|
+
end
|
107
|
+
|
108
|
+
# Checks whether this node has any arguments.
|
109
|
+
#
|
110
|
+
# @return [Boolean] whether this node has any arguments
|
111
|
+
def arguments?
|
112
|
+
children.size > first_argument_index
|
113
|
+
end
|
114
|
+
end
|
60
115
|
end
|
61
116
|
end
|
62
117
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module AST
|
5
|
+
# A node extension for `next` nodes. This will be used in place of a
|
6
|
+
# plain node when the builder constructs the AST, making its methods
|
7
|
+
# available to all `next` nodes within RuboCop.
|
8
|
+
class NextNode < Node
|
9
|
+
include ParameterizedNode::WrappedArguments
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -32,7 +32,7 @@ module RuboCop
|
|
32
32
|
#
|
33
33
|
# @param [Boolean] with_spacing whether to include spacing
|
34
34
|
# @return [String] the delimiter of the `pair`
|
35
|
-
def delimiter(with_spacing
|
35
|
+
def delimiter(*deprecated, with_spacing: deprecated.first)
|
36
36
|
if with_spacing
|
37
37
|
hash_rocket? ? SPACED_HASH_ROCKET : SPACED_COLON
|
38
38
|
else
|
@@ -44,7 +44,7 @@ module RuboCop
|
|
44
44
|
#
|
45
45
|
# @param [Boolean] with_spacing whether to include spacing
|
46
46
|
# @return [String] the inverse delimiter of the `pair`
|
47
|
-
def inverse_delimiter(with_spacing
|
47
|
+
def inverse_delimiter(*deprecated, with_spacing: deprecated.first)
|
48
48
|
if with_spacing
|
49
49
|
hash_rocket? ? SPACED_COLON : SPACED_HASH_ROCKET
|
50
50
|
else
|
@@ -13,12 +13,33 @@ module RuboCop
|
|
13
13
|
node_parts[2]
|
14
14
|
end
|
15
15
|
|
16
|
+
# Returns an array of all the exceptions in the `rescue` clause.
|
17
|
+
#
|
18
|
+
# @return [Array<Node>] an array of exception nodes
|
19
|
+
def exceptions
|
20
|
+
exceptions_node = node_parts[0]
|
21
|
+
if exceptions_node.nil?
|
22
|
+
[]
|
23
|
+
elsif exceptions_node.array_type?
|
24
|
+
exceptions_node.values
|
25
|
+
else
|
26
|
+
[exceptions_node]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
16
30
|
# Returns the exception variable of the `rescue` clause.
|
17
31
|
#
|
18
32
|
# @return [Node, nil] The exception variable of the `resbody`.
|
19
33
|
def exception_variable
|
20
34
|
node_parts[1]
|
21
35
|
end
|
36
|
+
|
37
|
+
# Returns the index of the `resbody` branch within the exception handling statement.
|
38
|
+
#
|
39
|
+
# @return [Integer] the index of the `resbody` branch
|
40
|
+
def branch_index
|
41
|
+
parent.resbody_branches.index(self)
|
42
|
+
end
|
22
43
|
end
|
23
44
|
end
|
24
45
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module AST
|
5
|
+
# A node extension for `rescue` nodes. This will be used in place of a
|
6
|
+
# plain node when the builder constructs the AST, making its methods
|
7
|
+
# available to all `rescue` nodes within RuboCop.
|
8
|
+
class RescueNode < Node
|
9
|
+
# Returns the body of the rescue node.
|
10
|
+
#
|
11
|
+
# @return [Node, nil] The body of the rescue node.
|
12
|
+
def body
|
13
|
+
node_parts[0]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns an array of all the rescue branches in the exception handling statement.
|
17
|
+
#
|
18
|
+
# @return [Array<ResbodyNode>] an array of `resbody` nodes
|
19
|
+
def resbody_branches
|
20
|
+
node_parts[1...-1]
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns an array of all the rescue branches in the exception handling statement.
|
24
|
+
#
|
25
|
+
# @return [Array<Node, nil>] an array of the bodies of the rescue branches
|
26
|
+
# and the else (if any). Note that these bodies could be nil.
|
27
|
+
def branches
|
28
|
+
bodies = resbody_branches.map(&:body)
|
29
|
+
bodies.push(else_branch) if else?
|
30
|
+
bodies
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the else branch of the exception handling statement, if any.
|
34
|
+
#
|
35
|
+
# @return [Node] the else branch node of the exception handling statement
|
36
|
+
# @return [nil] if the exception handling statement does not have an else branch.
|
37
|
+
def else_branch
|
38
|
+
node_parts[-1]
|
39
|
+
end
|
40
|
+
|
41
|
+
# Checks whether this exception handling statement has an `else` branch.
|
42
|
+
#
|
43
|
+
# @return [Boolean] whether the exception handling statement has an `else` branch
|
44
|
+
def else?
|
45
|
+
loc.else
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -6,19 +6,7 @@ module RuboCop
|
|
6
6
|
# plain node when the builder constructs the AST, making its methods
|
7
7
|
# available to all `return` nodes within RuboCop.
|
8
8
|
class ReturnNode < Node
|
9
|
-
include
|
10
|
-
include ParameterizedNode
|
11
|
-
|
12
|
-
# Returns the arguments of the `return`.
|
13
|
-
#
|
14
|
-
# @return [Array] The arguments of the `return`.
|
15
|
-
def arguments
|
16
|
-
if node_parts.one? && node_parts.first.begin_type?
|
17
|
-
node_parts.first.children
|
18
|
-
else
|
19
|
-
node_parts
|
20
|
-
end
|
21
|
-
end
|
9
|
+
include ParameterizedNode::WrappedArguments
|
22
10
|
end
|
23
11
|
end
|
24
12
|
end
|