rubocop-ast 1.17.0 → 1.29.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 +71 -70
- data/lib/rubocop/ast/ext/range.rb +3 -3
- data/lib/rubocop/ast/node/csend_node.rb +14 -0
- data/lib/rubocop/ast/node/keyword_splat_node.rb +10 -3
- data/lib/rubocop/ast/node/mixin/descendence.rb +7 -2
- data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +20 -9
- data/lib/rubocop/ast/node/mixin/parameterized_node.rb +9 -1
- data/lib/rubocop/ast/node/regexp_node.rb +6 -0
- data/lib/rubocop/ast/node/send_node.rb +4 -0
- data/lib/rubocop/ast/node/str_node.rb +4 -0
- data/lib/rubocop/ast/node.rb +27 -11
- data/lib/rubocop/ast/node_pattern/compiler/atom_subcompiler.rb +1 -1
- data/lib/rubocop/ast/node_pattern/compiler/binding.rb +2 -2
- data/lib/rubocop/ast/node_pattern/compiler/debug.rb +1 -1
- data/lib/rubocop/ast/node_pattern/compiler/sequence_subcompiler.rb +2 -2
- data/lib/rubocop/ast/node_pattern/node.rb +7 -3
- data/lib/rubocop/ast/node_pattern/parser.racc.rb +1 -1
- data/lib/rubocop/ast/node_pattern/with_meta.rb +3 -4
- data/lib/rubocop/ast/node_pattern.rb +16 -16
- data/lib/rubocop/ast/processed_source.rb +24 -6
- data/lib/rubocop/ast/sexp.rb +2 -1
- data/lib/rubocop/ast/token.rb +15 -1
- data/lib/rubocop/ast/traversal.rb +4 -3
- data/lib/rubocop/ast/version.rb +1 -1
- data/lib/rubocop/ast.rb +3 -2
- metadata +7 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b08ce67ff41a6d40d8385735fe36ebe6fd90513f3cbafbd21afa4f9393a66f9a
|
4
|
+
data.tar.gz: 24e6a84531e66531bcf5c358cfbed40815d1fd3f1d91e598a5b884a1971bb3c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20a8ea979cb2335691b7b39c9986962edc2fe61667e712187e3904e2a984fc3327b38034eca64028a362724964e982d053a093432d3f7994edae592cd8f6fb83
|
7
|
+
data.tar.gz: 59ab4c65c59d3407224147391e8b253c930da8add826c50553b433039057865aa1211d13e90061bb4e3a40ebb97184ea8d5698f3b4f5d0ff7c3c343d14a566bd
|
data/lib/rubocop/ast/builder.rb
CHANGED
@@ -19,76 +19,77 @@ module RuboCop
|
|
19
19
|
|
20
20
|
# @api private
|
21
21
|
NODE_MAP = {
|
22
|
-
and:
|
23
|
-
and_asgn:
|
24
|
-
alias:
|
25
|
-
arg:
|
26
|
-
blockarg:
|
27
|
-
forward_arg:
|
28
|
-
kwarg:
|
29
|
-
kwoptarg:
|
30
|
-
kwrestarg:
|
31
|
-
optarg:
|
32
|
-
restarg:
|
33
|
-
shadowarg:
|
34
|
-
args:
|
35
|
-
array:
|
36
|
-
lvasgn:
|
37
|
-
ivasgn:
|
38
|
-
cvasgn:
|
39
|
-
gvasgn:
|
40
|
-
block:
|
41
|
-
numblock:
|
42
|
-
break:
|
43
|
-
case_match:
|
44
|
-
casgn:
|
45
|
-
case:
|
46
|
-
class:
|
47
|
-
const:
|
48
|
-
def:
|
49
|
-
defined?:
|
50
|
-
defs:
|
51
|
-
dstr:
|
52
|
-
ensure:
|
53
|
-
for:
|
54
|
-
forward_args:
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
22
|
+
and: AndNode,
|
23
|
+
and_asgn: AndAsgnNode,
|
24
|
+
alias: AliasNode,
|
25
|
+
arg: ArgNode,
|
26
|
+
blockarg: ArgNode,
|
27
|
+
forward_arg: ArgNode,
|
28
|
+
kwarg: ArgNode,
|
29
|
+
kwoptarg: ArgNode,
|
30
|
+
kwrestarg: ArgNode,
|
31
|
+
optarg: ArgNode,
|
32
|
+
restarg: ArgNode,
|
33
|
+
shadowarg: ArgNode,
|
34
|
+
args: ArgsNode,
|
35
|
+
array: ArrayNode,
|
36
|
+
lvasgn: AsgnNode,
|
37
|
+
ivasgn: AsgnNode,
|
38
|
+
cvasgn: AsgnNode,
|
39
|
+
gvasgn: AsgnNode,
|
40
|
+
block: BlockNode,
|
41
|
+
numblock: BlockNode,
|
42
|
+
break: BreakNode,
|
43
|
+
case_match: CaseMatchNode,
|
44
|
+
casgn: CasgnNode,
|
45
|
+
case: CaseNode,
|
46
|
+
class: ClassNode,
|
47
|
+
const: ConstNode,
|
48
|
+
def: DefNode,
|
49
|
+
defined?: DefinedNode,
|
50
|
+
defs: DefNode,
|
51
|
+
dstr: DstrNode,
|
52
|
+
ensure: EnsureNode,
|
53
|
+
for: ForNode,
|
54
|
+
forward_args: ForwardArgsNode,
|
55
|
+
forwarded_kwrestarg: KeywordSplatNode,
|
56
|
+
float: FloatNode,
|
57
|
+
hash: HashNode,
|
58
|
+
if: IfNode,
|
59
|
+
in_pattern: InPatternNode,
|
60
|
+
int: IntNode,
|
61
|
+
index: IndexNode,
|
62
|
+
indexasgn: IndexasgnNode,
|
63
|
+
irange: RangeNode,
|
64
|
+
erange: RangeNode,
|
65
|
+
kwargs: HashNode,
|
66
|
+
kwsplat: KeywordSplatNode,
|
67
|
+
lambda: LambdaNode,
|
68
|
+
module: ModuleNode,
|
69
|
+
next: NextNode,
|
70
|
+
op_asgn: OpAsgnNode,
|
71
|
+
or_asgn: OrAsgnNode,
|
72
|
+
or: OrNode,
|
73
|
+
pair: PairNode,
|
74
|
+
procarg0: Procarg0Node,
|
75
|
+
regexp: RegexpNode,
|
76
|
+
rescue: RescueNode,
|
77
|
+
resbody: ResbodyNode,
|
78
|
+
return: ReturnNode,
|
79
|
+
csend: CsendNode,
|
80
|
+
send: SendNode,
|
81
|
+
str: StrNode,
|
82
|
+
xstr: StrNode,
|
83
|
+
sclass: SelfClassNode,
|
84
|
+
super: SuperNode,
|
85
|
+
zsuper: SuperNode,
|
86
|
+
sym: SymbolNode,
|
87
|
+
until: UntilNode,
|
88
|
+
until_post: UntilNode,
|
89
|
+
when: WhenNode,
|
90
|
+
while: WhileNode,
|
91
|
+
while_post: WhileNode,
|
92
|
+
yield: YieldNode
|
92
93
|
}.freeze
|
93
94
|
|
94
95
|
# Generates {Node} from the given information.
|
@@ -15,8 +15,8 @@ module RuboCop
|
|
15
15
|
# :bar
|
16
16
|
# ]
|
17
17
|
#
|
18
|
-
# node.loc.begin.line_span
|
19
|
-
# node.
|
18
|
+
# node.loc.begin.line_span # => 1..1
|
19
|
+
# node.source_range.line_span(exclude_end: true) # => 1...4
|
20
20
|
def line_span(exclude_end: false)
|
21
21
|
::Range.new(first_line, last_line, exclude_end)
|
22
22
|
end
|
@@ -25,4 +25,4 @@ module RuboCop
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
Parser::Source::Range.include RuboCop::AST::Ext::Range
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module AST
|
5
|
+
# A node extension for `csend` 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 `csend` nodes within RuboCop.
|
8
|
+
class CsendNode < SendNode
|
9
|
+
def send_type?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module RuboCop
|
4
4
|
module AST
|
5
|
-
# A node extension for `kwsplat` nodes. This will be used in
|
6
|
-
# plain
|
7
|
-
#
|
5
|
+
# A node extension for `kwsplat` and `forwarded_kwrestarg` nodes. This will be used in
|
6
|
+
# place of a plain node when the builder constructs the AST, making its methods available to
|
7
|
+
# all `kwsplat` and `forwarded_kwrestarg` nodes within RuboCop.
|
8
8
|
class KeywordSplatNode < Node
|
9
9
|
include HashElementNode
|
10
10
|
|
@@ -41,6 +41,13 @@ module RuboCop
|
|
41
41
|
def node_parts
|
42
42
|
[self, self]
|
43
43
|
end
|
44
|
+
|
45
|
+
# This provides `forwarded_kwrestarg` node to return true to be compatible with `kwsplat` node.
|
46
|
+
#
|
47
|
+
# @return [true]
|
48
|
+
def kwsplat_type?
|
49
|
+
true
|
50
|
+
end
|
44
51
|
end
|
45
52
|
end
|
46
53
|
end
|
@@ -36,7 +36,10 @@ module RuboCop
|
|
36
36
|
#
|
37
37
|
# @return [Array<Node>] an array of child nodes
|
38
38
|
def child_nodes
|
39
|
-
|
39
|
+
# Iterate child nodes directly to avoid allocating an Enumerator.
|
40
|
+
nodes = []
|
41
|
+
each_child_node { |node| nodes << node }
|
42
|
+
nodes
|
40
43
|
end
|
41
44
|
|
42
45
|
# Calls the given block for each descendant node with depth first order.
|
@@ -102,7 +105,9 @@ module RuboCop
|
|
102
105
|
protected
|
103
106
|
|
104
107
|
def visit_descendants(types, &block)
|
105
|
-
|
108
|
+
children.each do |child|
|
109
|
+
next unless child.is_a?(::AST::Node)
|
110
|
+
|
106
111
|
yield child if types.empty? || types.include?(child.type)
|
107
112
|
child.visit_descendants(types, &block)
|
108
113
|
end
|
@@ -5,7 +5,7 @@ module RuboCop
|
|
5
5
|
# Common functionality for nodes that are a kind of method dispatch:
|
6
6
|
# `send`, `csend`, `super`, `zsuper`, `yield`, `defined?`,
|
7
7
|
# and (modern only): `index`, `indexasgn`, `lambda`
|
8
|
-
module MethodDispatchNode
|
8
|
+
module MethodDispatchNode # rubocop:disable Metrics/ModuleLength
|
9
9
|
extend NodePattern::Macros
|
10
10
|
include MethodIdentifierPredicates
|
11
11
|
|
@@ -28,6 +28,17 @@ module RuboCop
|
|
28
28
|
node_parts[1]
|
29
29
|
end
|
30
30
|
|
31
|
+
# The source range for the method name or keyword that dispatches this call.
|
32
|
+
#
|
33
|
+
# @return [Parser::Source::Range] the source range for the method name or keyword
|
34
|
+
def selector
|
35
|
+
if loc.respond_to? :keyword
|
36
|
+
loc.keyword
|
37
|
+
else
|
38
|
+
loc.selector
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
31
42
|
# The `block` or `numblock` node associated with this method dispatch, if any.
|
32
43
|
#
|
33
44
|
# @return [BlockNode, nil] the `block` or `numblock` node associated with this method
|
@@ -147,7 +158,7 @@ module RuboCop
|
|
147
158
|
#
|
148
159
|
# @return [Boolean] whether the method is the implicit form of `#call`
|
149
160
|
def implicit_call?
|
150
|
-
method?(:call) && !
|
161
|
+
method?(:call) && !selector
|
151
162
|
end
|
152
163
|
|
153
164
|
# Whether this method dispatch has an explicit block.
|
@@ -211,7 +222,7 @@ module RuboCop
|
|
211
222
|
#
|
212
223
|
# @return [Boolean] whether this method is a lambda literal
|
213
224
|
def lambda_literal?
|
214
|
-
|
225
|
+
loc.expression.source == '->' && block_literal?
|
215
226
|
end
|
216
227
|
|
217
228
|
# Checks whether this is a unary operation.
|
@@ -222,9 +233,9 @@ module RuboCop
|
|
222
233
|
#
|
223
234
|
# @return [Boolean] whether this method is a unary operation
|
224
235
|
def unary_operation?
|
225
|
-
return false unless
|
236
|
+
return false unless selector
|
226
237
|
|
227
|
-
operator_method? && loc.expression.begin_pos ==
|
238
|
+
operator_method? && loc.expression.begin_pos == selector.begin_pos
|
228
239
|
end
|
229
240
|
|
230
241
|
# Checks whether this is a binary operation.
|
@@ -233,11 +244,11 @@ module RuboCop
|
|
233
244
|
#
|
234
245
|
# foo + bar
|
235
246
|
#
|
236
|
-
# @return [
|
247
|
+
# @return [Boolean] whether this method is a binary operation
|
237
248
|
def binary_operation?
|
238
|
-
return false unless
|
249
|
+
return false unless selector
|
239
250
|
|
240
|
-
operator_method? && loc.expression.begin_pos !=
|
251
|
+
operator_method? && loc.expression.begin_pos != selector.begin_pos
|
241
252
|
end
|
242
253
|
|
243
254
|
private
|
@@ -249,7 +260,7 @@ module RuboCop
|
|
249
260
|
^{ # or the parent is...
|
250
261
|
sclass class module class_constructor? # a class-like node
|
251
262
|
[ { # or some "wrapper"
|
252
|
-
kwbegin begin block
|
263
|
+
kwbegin begin block numblock
|
253
264
|
(if _condition <%0 _>) # note: we're excluding the condition of `if` nodes
|
254
265
|
}
|
255
266
|
#in_macro_scope? # that is itself in a macro scope
|
@@ -82,9 +82,17 @@ module RuboCop
|
|
82
82
|
# and optimizes other calls
|
83
83
|
module RestArguments
|
84
84
|
include ParameterizedNode
|
85
|
+
|
86
|
+
EMPTY_ARGUMENTS = [].freeze
|
87
|
+
|
85
88
|
# @return [Array<Node>] arguments, if any
|
86
89
|
def arguments
|
87
|
-
|
90
|
+
if arguments?
|
91
|
+
children.drop(first_argument_index).freeze
|
92
|
+
else
|
93
|
+
# Skip unneeded Array allocation.
|
94
|
+
EMPTY_ARGUMENTS
|
95
|
+
end
|
88
96
|
end
|
89
97
|
|
90
98
|
# A shorthand for getting the first argument of the node.
|
@@ -11,6 +11,7 @@ module RuboCop
|
|
11
11
|
i: Regexp::IGNORECASE,
|
12
12
|
m: Regexp::MULTILINE,
|
13
13
|
n: Regexp::NOENCODING,
|
14
|
+
u: Regexp::FIXEDENCODING,
|
14
15
|
o: 0
|
15
16
|
}.freeze
|
16
17
|
private_constant :OPTIONS
|
@@ -87,6 +88,11 @@ module RuboCop
|
|
87
88
|
regopt_include?(:n)
|
88
89
|
end
|
89
90
|
|
91
|
+
# @return [Bool] if regexp uses the fixed-encoding regopt
|
92
|
+
def fixed_encoding?
|
93
|
+
regopt_include?(:u)
|
94
|
+
end
|
95
|
+
|
90
96
|
private
|
91
97
|
|
92
98
|
def regopt_include?(option)
|
data/lib/rubocop/ast/node.rb
CHANGED
@@ -84,8 +84,12 @@ module RuboCop
|
|
84
84
|
LITERAL_RECURSIVE_TYPES = (OPERATOR_KEYWORDS + COMPOSITE_LITERALS + %i[begin pair]).freeze
|
85
85
|
private_constant :LITERAL_RECURSIVE_METHODS, :LITERAL_RECURSIVE_TYPES
|
86
86
|
|
87
|
+
EMPTY_CHILDREN = [].freeze
|
88
|
+
EMPTY_PROPERTIES = {}.freeze
|
89
|
+
private_constant :EMPTY_CHILDREN, :EMPTY_PROPERTIES
|
90
|
+
|
87
91
|
# @see https://www.rubydoc.info/gems/ast/AST/Node:initialize
|
88
|
-
def initialize(type, children =
|
92
|
+
def initialize(type, children = EMPTY_CHILDREN, properties = EMPTY_PROPERTIES)
|
89
93
|
@mutable_attributes = {}
|
90
94
|
|
91
95
|
# ::AST::Node#initialize freezes itself.
|
@@ -101,11 +105,19 @@ module RuboCop
|
|
101
105
|
end
|
102
106
|
end
|
103
107
|
|
104
|
-
Parser::Meta::NODE_TYPES.each do |node_type|
|
108
|
+
(Parser::Meta::NODE_TYPES - [:send]).each do |node_type|
|
105
109
|
method_name = "#{node_type.to_s.gsub(/\W/, '')}_type?"
|
106
|
-
|
107
|
-
|
108
|
-
|
110
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
111
|
+
def #{method_name} # def block_type?
|
112
|
+
@type == :#{node_type} # @type == :block
|
113
|
+
end # end
|
114
|
+
RUBY
|
115
|
+
end
|
116
|
+
|
117
|
+
# Most nodes are of 'send' type, so this method is defined
|
118
|
+
# separately to make this check as fast as possible.
|
119
|
+
def send_type?
|
120
|
+
false
|
109
121
|
end
|
110
122
|
|
111
123
|
# Returns the parent node, or `nil` if the receiver is a root node.
|
@@ -194,7 +206,7 @@ module RuboCop
|
|
194
206
|
def right_siblings
|
195
207
|
return [].freeze unless parent
|
196
208
|
|
197
|
-
parent.children[sibling_index + 1
|
209
|
+
parent.children[sibling_index + 1..].freeze
|
198
210
|
end
|
199
211
|
|
200
212
|
# Common destructuring method. This can be used to normalize
|
@@ -203,9 +215,7 @@ module RuboCop
|
|
203
215
|
# destructuring method.
|
204
216
|
#
|
205
217
|
# @return [Array<Node>] the different parts of the ndde
|
206
|
-
|
207
|
-
to_a
|
208
|
-
end
|
218
|
+
alias node_parts to_a
|
209
219
|
|
210
220
|
# Calls the given block for each ancestor node from parent to root.
|
211
221
|
# If no block is given, an `Enumerator` is returned.
|
@@ -500,8 +510,14 @@ module RuboCop
|
|
500
510
|
|
501
511
|
# @!method class_constructor?(node = self)
|
502
512
|
def_node_matcher :class_constructor?, <<~PATTERN
|
503
|
-
{
|
504
|
-
|
513
|
+
{
|
514
|
+
(send #global_const?({:Class :Module :Struct}) :new ...)
|
515
|
+
(send #global_const?(:Data) :define ...)
|
516
|
+
({block numblock} {
|
517
|
+
(send #global_const?({:Class :Module :Struct}) :new ...)
|
518
|
+
(send #global_const?(:Data) :define ...)
|
519
|
+
} ...)
|
520
|
+
}
|
505
521
|
PATTERN
|
506
522
|
|
507
523
|
# @deprecated Use `:class_constructor?`
|
@@ -20,8 +20,8 @@ module RuboCop
|
|
20
20
|
end
|
21
21
|
|
22
22
|
if var == :forbidden_unification
|
23
|
-
raise Invalid, "Wildcard #{name} was first seen in a subset of a" \
|
24
|
-
"
|
23
|
+
raise Invalid, "Wildcard #{name} was first seen in a subset of a " \
|
24
|
+
"union and can't be used outside that union"
|
25
25
|
end
|
26
26
|
var
|
27
27
|
end
|
@@ -47,7 +47,7 @@ module RuboCop
|
|
47
47
|
# @return [String] a Rainbow colorized version of ruby
|
48
48
|
def colorize(color_scheme = COLOR_SCHEME)
|
49
49
|
map = color_map(color_scheme)
|
50
|
-
ast.
|
50
|
+
ast.source_range.source_buffer.source.chars.map.with_index do |char, i|
|
51
51
|
Rainbow(char).color(map[i])
|
52
52
|
end.join
|
53
53
|
end
|
@@ -371,13 +371,13 @@ module RuboCop
|
|
371
371
|
|
372
372
|
# @return [Hash] of {subcompiler => code}
|
373
373
|
def compile_union_forks
|
374
|
-
compiler.each_union(node.children).
|
374
|
+
compiler.each_union(node.children).to_h do |child|
|
375
375
|
subsequence_terms = child.is_a?(Node::Subsequence) ? child.children : [child]
|
376
376
|
fork = dup
|
377
377
|
code = fork.compile_terms(subsequence_terms, @remaining_arity)
|
378
378
|
@in_sync = false if @cur_index != :variadic_mode
|
379
379
|
[fork, code]
|
380
|
-
end
|
380
|
+
end
|
381
381
|
end
|
382
382
|
|
383
383
|
# Modifies in place `forks` to insure that `cur_{child|index}_var` are ok
|
@@ -75,6 +75,10 @@ module RuboCop
|
|
75
75
|
self.class.new(type, children, { location: location })
|
76
76
|
end
|
77
77
|
|
78
|
+
def source_range
|
79
|
+
loc.expression
|
80
|
+
end
|
81
|
+
|
78
82
|
INT_TO_RANGE = Hash.new { |h, k| h[k] = k..k }
|
79
83
|
private_constant :INT_TO_RANGE
|
80
84
|
|
@@ -116,7 +120,7 @@ module RuboCop
|
|
116
120
|
|
117
121
|
def initialize(type, children = [], properties = {})
|
118
122
|
if (replace = children.first.in_sequence_head)
|
119
|
-
children = [*replace, *children[1
|
123
|
+
children = [*replace, *children[1..]]
|
120
124
|
end
|
121
125
|
|
122
126
|
super
|
@@ -130,7 +134,7 @@ module RuboCop
|
|
130
134
|
end
|
131
135
|
|
132
136
|
def arg_list
|
133
|
-
children[1
|
137
|
+
children[1..]
|
134
138
|
end
|
135
139
|
end
|
136
140
|
FunctionCall = Predicate
|
@@ -212,7 +216,7 @@ module RuboCop
|
|
212
216
|
|
213
217
|
return unless (replace = children.first.in_sequence_head)
|
214
218
|
|
215
|
-
[with(children: [*replace, *children[1
|
219
|
+
[with(children: [*replace, *children[1..]])]
|
216
220
|
end
|
217
221
|
end
|
218
222
|
|
@@ -48,12 +48,12 @@ module RuboCop
|
|
48
48
|
|
49
49
|
def emit_unary_op(type, operator_t = nil, *children)
|
50
50
|
children[-1] = children[-1].first if children[-1].is_a?(Array) # token?
|
51
|
-
map = source_map(children.first.
|
51
|
+
map = source_map(children.first.source_range, operator_t: operator_t)
|
52
52
|
n(type, children, map)
|
53
53
|
end
|
54
54
|
|
55
55
|
def emit_list(type, begin_t, children, end_t)
|
56
|
-
expr = children.first.
|
56
|
+
expr = children.first.source_range.join(children.last.source_range)
|
57
57
|
map = source_map(expr, begin_t: begin_t, end_t: end_t)
|
58
58
|
n(type, children, map)
|
59
59
|
end
|
@@ -79,8 +79,7 @@ module RuboCop
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def join_exprs(left_expr, right_expr)
|
82
|
-
left_expr.
|
83
|
-
.join(right_expr.loc.expression)
|
82
|
+
left_expr.source_range.join(right_expr.source_range)
|
84
83
|
end
|
85
84
|
|
86
85
|
def source_map(token_or_range, begin_t: nil, end_t: nil, operator_t: nil, selector_t: nil)
|
@@ -54,6 +54,22 @@ module RuboCop
|
|
54
54
|
|
55
55
|
VAR = 'node'
|
56
56
|
|
57
|
+
# Yields its argument and any descendants, depth-first.
|
58
|
+
#
|
59
|
+
def self.descend(element, &block)
|
60
|
+
return to_enum(__method__, element) unless block
|
61
|
+
|
62
|
+
yield element
|
63
|
+
|
64
|
+
if element.is_a?(::RuboCop::AST::Node)
|
65
|
+
element.children.each do |child|
|
66
|
+
descend(child, &block)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
|
57
73
|
attr_reader :pattern, :ast, :match_code
|
58
74
|
|
59
75
|
def_delegators :@compiler, :captures, :named_parameters, :positional_parameters
|
@@ -100,22 +116,6 @@ module RuboCop
|
|
100
116
|
initialize(coder['pattern'])
|
101
117
|
end
|
102
118
|
|
103
|
-
# Yields its argument and any descendants, depth-first.
|
104
|
-
#
|
105
|
-
def self.descend(element, &block)
|
106
|
-
return to_enum(__method__, element) unless block
|
107
|
-
|
108
|
-
yield element
|
109
|
-
|
110
|
-
if element.is_a?(::RuboCop::AST::Node)
|
111
|
-
element.children.each do |child|
|
112
|
-
descend(child, &block)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
nil
|
117
|
-
end
|
118
|
-
|
119
119
|
def freeze
|
120
120
|
@match_code.freeze
|
121
121
|
@compiler.freeze
|
@@ -12,6 +12,9 @@ module RuboCop
|
|
12
12
|
# @api private
|
13
13
|
STRING_SOURCE_NAME = '(string)'
|
14
14
|
|
15
|
+
INVALID_LEVELS = %i[error fatal].freeze
|
16
|
+
private_constant :INVALID_LEVELS
|
17
|
+
|
15
18
|
attr_reader :path, :buffer, :ast, :comments, :tokens, :diagnostics,
|
16
19
|
:parser_error, :raw_source, :ruby_version
|
17
20
|
|
@@ -20,14 +23,11 @@ module RuboCop
|
|
20
23
|
new(file, ruby_version, path)
|
21
24
|
end
|
22
25
|
|
23
|
-
INVALID_LEVELS = %i[error fatal].freeze
|
24
|
-
private_constant :INVALID_LEVELS
|
25
|
-
|
26
26
|
def initialize(source, ruby_version, path = nil)
|
27
27
|
# Defaults source encoding to UTF-8, regardless of the encoding it has
|
28
28
|
# been read with, which could be non-utf8 depending on the default
|
29
29
|
# external encoding.
|
30
|
-
source.force_encoding(Encoding::UTF_8) unless source.encoding == Encoding::UTF_8
|
30
|
+
(+source).force_encoding(Encoding::UTF_8) unless source.encoding == Encoding::UTF_8
|
31
31
|
|
32
32
|
@raw_source = source
|
33
33
|
@path = path
|
@@ -226,9 +226,24 @@ module RuboCop
|
|
226
226
|
[ast, comments, tokens]
|
227
227
|
end
|
228
228
|
|
229
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
229
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
230
230
|
def parser_class(ruby_version)
|
231
231
|
case ruby_version
|
232
|
+
when 1.9
|
233
|
+
require 'parser/ruby19'
|
234
|
+
Parser::Ruby19
|
235
|
+
when 2.0
|
236
|
+
require 'parser/ruby20'
|
237
|
+
Parser::Ruby20
|
238
|
+
when 2.1
|
239
|
+
require 'parser/ruby21'
|
240
|
+
Parser::Ruby21
|
241
|
+
when 2.2
|
242
|
+
require 'parser/ruby22'
|
243
|
+
Parser::Ruby22
|
244
|
+
when 2.3
|
245
|
+
require 'parser/ruby23'
|
246
|
+
Parser::Ruby23
|
232
247
|
when 2.4
|
233
248
|
require 'parser/ruby24'
|
234
249
|
Parser::Ruby24
|
@@ -250,12 +265,15 @@ module RuboCop
|
|
250
265
|
when 3.2
|
251
266
|
require 'parser/ruby32'
|
252
267
|
Parser::Ruby32
|
268
|
+
when 3.3
|
269
|
+
require 'parser/ruby33'
|
270
|
+
Parser::Ruby33
|
253
271
|
else
|
254
272
|
raise ArgumentError,
|
255
273
|
"RuboCop found unknown Ruby version: #{ruby_version.inspect}"
|
256
274
|
end
|
257
275
|
end
|
258
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
276
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
259
277
|
|
260
278
|
def create_parser(ruby_version)
|
261
279
|
builder = RuboCop::AST::Builder.new
|
data/lib/rubocop/ast/sexp.rb
CHANGED
data/lib/rubocop/ast/token.rb
CHANGED
@@ -4,6 +4,8 @@ module RuboCop
|
|
4
4
|
module AST
|
5
5
|
# A basic wrapper around Parser's tokens.
|
6
6
|
class Token
|
7
|
+
LEFT_PAREN_TYPES = %i[tLPAREN tLPAREN2].freeze
|
8
|
+
|
7
9
|
attr_reader :pos, :type, :text
|
8
10
|
|
9
11
|
def self.from_parser_token(parser_token)
|
@@ -89,7 +91,7 @@ module RuboCop
|
|
89
91
|
end
|
90
92
|
|
91
93
|
def left_parens?
|
92
|
-
|
94
|
+
LEFT_PAREN_TYPES.include?(type)
|
93
95
|
end
|
94
96
|
|
95
97
|
def right_parens?
|
@@ -100,6 +102,14 @@ module RuboCop
|
|
100
102
|
type == :tCOMMA
|
101
103
|
end
|
102
104
|
|
105
|
+
def dot?
|
106
|
+
type == :tDOT
|
107
|
+
end
|
108
|
+
|
109
|
+
def regexp_dots?
|
110
|
+
%i[tDOT2 tDOT3].include?(type)
|
111
|
+
end
|
112
|
+
|
103
113
|
def rescue_modifier?
|
104
114
|
type == :kRESCUE_MOD
|
105
115
|
end
|
@@ -111,6 +121,10 @@ module RuboCop
|
|
111
121
|
def equal_sign?
|
112
122
|
%i[tEQL tOP_ASGN].include?(type)
|
113
123
|
end
|
124
|
+
|
125
|
+
def new_line?
|
126
|
+
type == :tNL
|
127
|
+
end
|
114
128
|
end
|
115
129
|
end
|
116
130
|
end
|
@@ -34,7 +34,7 @@ module RuboCop
|
|
34
34
|
|
35
35
|
def def_callback(type, *signature,
|
36
36
|
arity: signature.size..signature.size,
|
37
|
-
arity_check: ENV
|
37
|
+
arity_check: ENV.fetch('RUBOCOP_DEBUG', nil) && self.arity_check(arity),
|
38
38
|
body: self.body(signature, arity_check))
|
39
39
|
type, *aliases = type
|
40
40
|
lineno = caller_locations(1, 1).first.lineno
|
@@ -75,7 +75,8 @@ module RuboCop
|
|
75
75
|
### arity == 0
|
76
76
|
no_children = %i[true false nil self cbase zsuper redo retry
|
77
77
|
forward_args forwarded_args match_nil_pattern
|
78
|
-
forward_arg
|
78
|
+
forward_arg forwarded_restarg forwarded_kwrestarg
|
79
|
+
lambda empty_else kwnilarg
|
79
80
|
__FILE__ __LINE__ __ENCODING__]
|
80
81
|
|
81
82
|
### arity == 0..1
|
@@ -162,7 +163,7 @@ module RuboCop
|
|
162
163
|
### generic processing of any other node (forward compatibility)
|
163
164
|
defined = instance_methods(false)
|
164
165
|
.grep(/^on_/)
|
165
|
-
.map { |s| s.to_s[3
|
166
|
+
.map { |s| s.to_s[3..].to_sym } # :on_foo => :foo
|
166
167
|
|
167
168
|
to_define = ::Parser::Meta::NODE_TYPES.to_a
|
168
169
|
to_define -= defined
|
data/lib/rubocop/ast/version.rb
CHANGED
data/lib/rubocop/ast.rb
CHANGED
@@ -76,6 +76,7 @@ require_relative 'ast/node/resbody_node'
|
|
76
76
|
require_relative 'ast/node/return_node'
|
77
77
|
require_relative 'ast/node/self_class_node'
|
78
78
|
require_relative 'ast/node/send_node'
|
79
|
+
require_relative 'ast/node/csend_node'
|
79
80
|
require_relative 'ast/node/str_node'
|
80
81
|
require_relative 'ast/node/dstr_node'
|
81
82
|
require_relative 'ast/node/super_node'
|
@@ -91,5 +92,5 @@ require_relative 'ast/token'
|
|
91
92
|
require_relative 'ast/traversal'
|
92
93
|
require_relative 'ast/version'
|
93
94
|
|
94
|
-
|
95
|
-
|
95
|
+
RuboCop::AST::NodePattern::Parser.autoload :WithMeta, "#{__dir__}/ast/node_pattern/with_meta"
|
96
|
+
RuboCop::AST::NodePattern::Compiler.autoload :Debug, "#{__dir__}/ast/node_pattern/compiler/debug"
|
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.29.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: 2023-06-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: parser
|
@@ -18,34 +18,14 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 3.
|
21
|
+
version: 3.2.1.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 3.
|
29
|
-
- !ruby/object:Gem::Dependency
|
30
|
-
name: bundler
|
31
|
-
requirement: !ruby/object:Gem::Requirement
|
32
|
-
requirements:
|
33
|
-
- - ">="
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version: 1.15.0
|
36
|
-
- - "<"
|
37
|
-
- !ruby/object:Gem::Version
|
38
|
-
version: '3.0'
|
39
|
-
type: :development
|
40
|
-
prerelease: false
|
41
|
-
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
requirements:
|
43
|
-
- - ">="
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: 1.15.0
|
46
|
-
- - "<"
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
version: '3.0'
|
28
|
+
version: 3.2.1.0
|
49
29
|
description: " RuboCop's Node and NodePattern classes.\n"
|
50
30
|
email: rubocop@googlegroups.com
|
51
31
|
executables: []
|
@@ -76,6 +56,7 @@ files:
|
|
76
56
|
- lib/rubocop/ast/node/casgn_node.rb
|
77
57
|
- lib/rubocop/ast/node/class_node.rb
|
78
58
|
- lib/rubocop/ast/node/const_node.rb
|
59
|
+
- lib/rubocop/ast/node/csend_node.rb
|
79
60
|
- lib/rubocop/ast/node/def_node.rb
|
80
61
|
- lib/rubocop/ast/node/defined_node.rb
|
81
62
|
- lib/rubocop/ast/node/dstr_node.rb
|
@@ -168,14 +149,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
168
149
|
requirements:
|
169
150
|
- - ">="
|
170
151
|
- !ruby/object:Gem::Version
|
171
|
-
version: 2.
|
152
|
+
version: 2.6.0
|
172
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
173
154
|
requirements:
|
174
155
|
- - ">="
|
175
156
|
- !ruby/object:Gem::Version
|
176
157
|
version: '0'
|
177
158
|
requirements: []
|
178
|
-
rubygems_version: 3.
|
159
|
+
rubygems_version: 3.4.1
|
179
160
|
signing_key:
|
180
161
|
specification_version: 4
|
181
162
|
summary: RuboCop tools to deal with Ruby code AST.
|