rubocop-ast 1.29.0 → 1.46.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/README.md +1 -1
- data/lib/rubocop/ast/builder.rb +33 -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 +9 -5
- data/lib/rubocop/ast/node/asgn_node.rb +2 -0
- data/lib/rubocop/ast/node/block_node.rb +27 -8
- data/lib/rubocop/ast/node/casgn_node.rb +4 -12
- data/lib/rubocop/ast/node/complex_node.rb +13 -0
- data/lib/rubocop/ast/node/const_node.rb +1 -52
- data/lib/rubocop/ast/node/def_node.rb +1 -1
- data/lib/rubocop/ast/node/ensure_node.rb +36 -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 +11 -4
- 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/basic_literal_node.rb +1 -1
- data/lib/rubocop/ast/node/mixin/collection_node.rb +1 -1
- 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 +12 -13
- data/lib/rubocop/ast/node/mixin/numeric_node.rb +2 -2
- 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/rational_node.rb +13 -0
- 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 +124 -45
- data/lib/rubocop/ast/node_pattern/compiler/binding.rb +3 -3
- data/lib/rubocop/ast/node_pattern/compiler/debug.rb +3 -8
- data/lib/rubocop/ast/node_pattern/compiler/sequence_subcompiler.rb +3 -4
- data/lib/rubocop/ast/node_pattern/compiler.rb +1 -1
- data/lib/rubocop/ast/node_pattern/lexer.rex.rb +1 -2
- data/lib/rubocop/ast/node_pattern/node.rb +11 -6
- data/lib/rubocop/ast/node_pattern/parser.racc.rb +4 -2
- data/lib/rubocop/ast/node_pattern/parser.rb +1 -1
- data/lib/rubocop/ast/node_pattern.rb +1 -1
- data/lib/rubocop/ast/processed_source.rb +158 -60
- data/lib/rubocop/ast/token.rb +2 -1
- data/lib/rubocop/ast/traversal.rb +35 -25
- data/lib/rubocop/ast/utilities/simple_forwardable.rb +27 -0
- data/lib/rubocop/ast/version.rb +1 -1
- data/lib/rubocop/ast.rb +10 -1
- metadata +29 -7
- data/lib/rubocop/ast/ext/range_min_max.rb +0 -18
@@ -2,28 +2,55 @@
|
|
2
2
|
|
3
3
|
require 'digest/sha1'
|
4
4
|
|
5
|
-
# rubocop:disable Metrics/ClassLength
|
6
5
|
module RuboCop
|
7
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
|
+
|
8
28
|
# ProcessedSource contains objects which are generated by Parser
|
9
29
|
# and other information such as disabled lines for cops.
|
10
30
|
# It also provides a convenient way to access source lines.
|
11
|
-
class ProcessedSource
|
31
|
+
class ProcessedSource # rubocop:disable Metrics/ClassLength
|
12
32
|
# @api private
|
13
33
|
STRING_SOURCE_NAME = '(string)'
|
14
34
|
|
15
35
|
INVALID_LEVELS = %i[error fatal].freeze
|
16
36
|
private_constant :INVALID_LEVELS
|
17
37
|
|
38
|
+
PARSER_ENGINES = %i[default parser_whitequark parser_prism].freeze
|
39
|
+
private_constant :PARSER_ENGINES
|
40
|
+
|
18
41
|
attr_reader :path, :buffer, :ast, :comments, :tokens, :diagnostics,
|
19
|
-
:parser_error, :raw_source, :ruby_version
|
42
|
+
:parser_error, :raw_source, :ruby_version, :parser_engine
|
20
43
|
|
21
|
-
def self.from_file(path, ruby_version)
|
44
|
+
def self.from_file(path, ruby_version, parser_engine: :default)
|
22
45
|
file = File.read(path, mode: 'rb')
|
23
|
-
new(file, ruby_version, path)
|
46
|
+
new(file, ruby_version, path, parser_engine: parser_engine)
|
24
47
|
end
|
25
48
|
|
26
|
-
def initialize(
|
49
|
+
def initialize(
|
50
|
+
source, ruby_version, path = nil, parser_engine: :default, prism_result: nil
|
51
|
+
)
|
52
|
+
parser_engine = normalize_parser_engine(parser_engine, ruby_version)
|
53
|
+
|
27
54
|
# Defaults source encoding to UTF-8, regardless of the encoding it has
|
28
55
|
# been read with, which could be non-utf8 depending on the default
|
29
56
|
# external encoding.
|
@@ -33,9 +60,10 @@ module RuboCop
|
|
33
60
|
@path = path
|
34
61
|
@diagnostics = []
|
35
62
|
@ruby_version = ruby_version
|
63
|
+
@parser_engine = parser_engine
|
36
64
|
@parser_error = nil
|
37
65
|
|
38
|
-
parse(source, ruby_version)
|
66
|
+
parse(source, ruby_version, parser_engine, prism_result)
|
39
67
|
end
|
40
68
|
|
41
69
|
def ast_with_comments
|
@@ -193,13 +221,13 @@ module RuboCop
|
|
193
221
|
end
|
194
222
|
end
|
195
223
|
|
196
|
-
def parse(source, ruby_version)
|
224
|
+
def parse(source, ruby_version, parser_engine, prism_result)
|
197
225
|
buffer_name = @path || STRING_SOURCE_NAME
|
198
226
|
@buffer = Parser::Source::Buffer.new(buffer_name, 1)
|
199
227
|
|
200
228
|
begin
|
201
229
|
@buffer.source = source
|
202
|
-
rescue EncodingError => e
|
230
|
+
rescue EncodingError, Parser::UnknownEncodingInMagicComment => e
|
203
231
|
@parser_error = e
|
204
232
|
@ast = nil
|
205
233
|
@comments = []
|
@@ -207,7 +235,9 @@ module RuboCop
|
|
207
235
|
return
|
208
236
|
end
|
209
237
|
|
210
|
-
|
238
|
+
parser = create_parser(ruby_version, parser_engine, prism_result)
|
239
|
+
|
240
|
+
@ast, @comments, @tokens = tokenize(parser)
|
211
241
|
end
|
212
242
|
|
213
243
|
def tokenize(parser)
|
@@ -226,59 +256,102 @@ module RuboCop
|
|
226
256
|
[ast, comments, tokens]
|
227
257
|
end
|
228
258
|
|
229
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
230
|
-
def parser_class(ruby_version)
|
231
|
-
case
|
232
|
-
when
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
259
|
+
# rubocop:disable Lint/FloatComparison, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
260
|
+
def parser_class(ruby_version, parser_engine)
|
261
|
+
case parser_engine
|
262
|
+
when :parser_whitequark
|
263
|
+
case ruby_version
|
264
|
+
when 1.9
|
265
|
+
require 'parser/ruby19'
|
266
|
+
Parser::Ruby19
|
267
|
+
when 2.0
|
268
|
+
require 'parser/ruby20'
|
269
|
+
Parser::Ruby20
|
270
|
+
when 2.1
|
271
|
+
require 'parser/ruby21'
|
272
|
+
Parser::Ruby21
|
273
|
+
when 2.2
|
274
|
+
require 'parser/ruby22'
|
275
|
+
Parser::Ruby22
|
276
|
+
when 2.3
|
277
|
+
require 'parser/ruby23'
|
278
|
+
Parser::Ruby23
|
279
|
+
when 2.4
|
280
|
+
require 'parser/ruby24'
|
281
|
+
Parser::Ruby24
|
282
|
+
when 2.5
|
283
|
+
require 'parser/ruby25'
|
284
|
+
Parser::Ruby25
|
285
|
+
when 2.6
|
286
|
+
require 'parser/ruby26'
|
287
|
+
Parser::Ruby26
|
288
|
+
when 2.7
|
289
|
+
require 'parser/ruby27'
|
290
|
+
Parser::Ruby27
|
291
|
+
when 2.8, 3.0
|
292
|
+
require 'parser/ruby30'
|
293
|
+
Parser::Ruby30
|
294
|
+
when 3.1
|
295
|
+
require 'parser/ruby31'
|
296
|
+
Parser::Ruby31
|
297
|
+
when 3.2
|
298
|
+
require 'parser/ruby32'
|
299
|
+
Parser::Ruby32
|
300
|
+
when 3.3
|
301
|
+
require 'parser/ruby33'
|
302
|
+
Parser::Ruby33
|
303
|
+
when 3.4
|
304
|
+
require 'parser/ruby34'
|
305
|
+
Parser::Ruby34
|
306
|
+
else
|
307
|
+
raise ArgumentError, 'RuboCop supports target Ruby versions 3.4 and below with ' \
|
308
|
+
"`parser`. Specified target Ruby version: #{ruby_version.inspect}"
|
309
|
+
end
|
310
|
+
when :parser_prism
|
311
|
+
case ruby_version
|
312
|
+
when 3.3
|
313
|
+
require 'prism/translation/parser33'
|
314
|
+
Prism::Translation::Parser33
|
315
|
+
when 3.4
|
316
|
+
require 'prism/translation/parser34'
|
317
|
+
Prism::Translation::Parser34
|
318
|
+
when 3.5
|
319
|
+
require 'prism/translation/parser35'
|
320
|
+
Prism::Translation::Parser35
|
321
|
+
else
|
322
|
+
raise ArgumentError, 'RuboCop supports target Ruby versions 3.3 and above with Prism. ' \
|
323
|
+
"Specified target Ruby version: #{ruby_version.inspect}"
|
324
|
+
end
|
274
325
|
end
|
275
326
|
end
|
276
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
327
|
+
# rubocop:enable Lint/FloatComparison, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
277
328
|
|
278
|
-
def
|
279
|
-
|
329
|
+
def builder_class(parser_engine)
|
330
|
+
case parser_engine
|
331
|
+
when :parser_whitequark
|
332
|
+
RuboCop::AST::Builder
|
333
|
+
when :parser_prism
|
334
|
+
RuboCop::AST::BuilderPrism
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
339
|
+
def create_parser(ruby_version, parser_engine, prism_result)
|
340
|
+
builder = builder_class(parser_engine).new
|
341
|
+
|
342
|
+
parser_class = parser_class(ruby_version, parser_engine)
|
343
|
+
|
344
|
+
parser_instance = if parser_engine == :parser_prism && prism_result
|
345
|
+
# NOTE: Since it is intended for use with Ruby LSP, it targets only Prism.
|
346
|
+
# If there is no reuse of a pre-parsed result, such as in Ruby LSP,
|
347
|
+
# regular parsing with Prism occurs, and `else` branch will be executed.
|
348
|
+
prism_reparsed = PrismPreparsed.new(prism_result)
|
349
|
+
parser_class.new(builder, parser: prism_reparsed)
|
350
|
+
else
|
351
|
+
parser_class.new(builder)
|
352
|
+
end
|
280
353
|
|
281
|
-
|
354
|
+
parser_instance.tap do |parser|
|
282
355
|
# On JRuby there's a risk that we hang in tokenize() if we
|
283
356
|
# don't set the all errors as fatal flag. The problem is caused by a bug
|
284
357
|
# in Racc that is discussed in issue #93 of the whitequark/parser
|
@@ -290,6 +363,32 @@ module RuboCop
|
|
290
363
|
end
|
291
364
|
end
|
292
365
|
end
|
366
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
367
|
+
|
368
|
+
def normalize_parser_engine(parser_engine, ruby_version)
|
369
|
+
parser_engine = parser_engine.to_sym
|
370
|
+
unless PARSER_ENGINES.include?(parser_engine)
|
371
|
+
raise ArgumentError, 'The keyword argument `parser_engine` accepts `default`, ' \
|
372
|
+
"`parser_whitequark`, or `parser_prism`, but `#{parser_engine}` " \
|
373
|
+
'was passed.'
|
374
|
+
end
|
375
|
+
if parser_engine == :default
|
376
|
+
default_parser_engine(ruby_version)
|
377
|
+
else
|
378
|
+
parser_engine
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
# The Parser gem does not support Ruby 3.5 or later.
|
383
|
+
# It is also not fully compatible with Ruby 3.4 but for
|
384
|
+
# now respects using parser for backwards compatibility.
|
385
|
+
def default_parser_engine(ruby_version)
|
386
|
+
if ruby_version >= 3.4
|
387
|
+
:parser_prism
|
388
|
+
else
|
389
|
+
:parser_whitequark
|
390
|
+
end
|
391
|
+
end
|
293
392
|
|
294
393
|
def first_token_index(range_or_node)
|
295
394
|
begin_pos = source_range(range_or_node).begin_pos
|
@@ -311,4 +410,3 @@ module RuboCop
|
|
311
410
|
end
|
312
411
|
end
|
313
412
|
end
|
314
|
-
# rubocop:enable Metrics/ClassLength
|
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,39 +26,48 @@ 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
|
-
module_eval(<<~RUBY, __FILE__, lineno)
|
43
|
+
module_eval(<<~RUBY, __FILE__, lineno)
|
42
44
|
def on_#{type}(node) # def on_send(node)
|
43
45
|
#{body} # # body ...
|
44
46
|
nil # nil
|
45
47
|
end # end
|
46
48
|
RUBY
|
47
49
|
aliases.each do |m|
|
48
|
-
alias_method "on_#{m}", "on_#{type}"
|
50
|
+
alias_method :"on_#{m}", :"on_#{type}"
|
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,16 +109,16 @@ 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
|
112
|
-
while_post until_post
|
121
|
+
while_post until_post
|
113
122
|
match_with_lvasgn begin kwbegin return
|
114
123
|
in_match match_alt break next
|
115
124
|
match_as array_pattern array_pattern_with_tail
|
@@ -117,22 +126,22 @@ module RuboCop
|
|
117
126
|
index indexasgn procarg0 kwargs]
|
118
127
|
many_opt_node_children = %i[case rescue resbody ensure for when
|
119
128
|
case_match in_pattern irange erange
|
120
|
-
match_pattern match_pattern_p]
|
129
|
+
match_pattern match_pattern_p iflipflop eflipflop]
|
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
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
# Similar to `Forwardable#def_delegators`, but simpler & faster
|
5
|
+
module SimpleForwardable
|
6
|
+
def def_delegators(accessor, *methods)
|
7
|
+
methods.each do |method|
|
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
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/rubocop/ast/version.rb
CHANGED
data/lib/rubocop/ast.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'parser'
|
4
|
+
require 'prism'
|
4
5
|
require 'forwardable'
|
5
6
|
require 'set'
|
6
7
|
|
7
8
|
require_relative 'ast/ext/range'
|
8
|
-
require_relative 'ast/
|
9
|
+
require_relative 'ast/utilities/simple_forwardable'
|
9
10
|
require_relative 'ast/node_pattern/method_definer'
|
10
11
|
require_relative 'ast/node_pattern'
|
11
12
|
require_relative 'ast/node/mixin/descendence'
|
@@ -27,6 +28,7 @@ require_relative 'ast/node/mixin/method_identifier_predicates'
|
|
27
28
|
require_relative 'ast/node/mixin/binary_operator_node'
|
28
29
|
require_relative 'ast/node/mixin/collection_node'
|
29
30
|
require_relative 'ast/node/mixin/conditional_node'
|
31
|
+
require_relative 'ast/node/mixin/constant_node'
|
30
32
|
require_relative 'ast/node/mixin/hash_element_node'
|
31
33
|
require_relative 'ast/node/mixin/method_dispatch_node'
|
32
34
|
require_relative 'ast/node/mixin/modifier_node'
|
@@ -46,6 +48,7 @@ require_relative 'ast/node/case_match_node'
|
|
46
48
|
require_relative 'ast/node/case_node'
|
47
49
|
require_relative 'ast/node/casgn_node'
|
48
50
|
require_relative 'ast/node/class_node'
|
51
|
+
require_relative 'ast/node/complex_node'
|
49
52
|
require_relative 'ast/node/const_node'
|
50
53
|
require_relative 'ast/node/def_node'
|
51
54
|
require_relative 'ast/node/defined_node'
|
@@ -59,8 +62,11 @@ require_relative 'ast/node/in_pattern_node'
|
|
59
62
|
require_relative 'ast/node/index_node'
|
60
63
|
require_relative 'ast/node/indexasgn_node'
|
61
64
|
require_relative 'ast/node/int_node'
|
65
|
+
require_relative 'ast/node/keyword_begin_node'
|
62
66
|
require_relative 'ast/node/keyword_splat_node'
|
63
67
|
require_relative 'ast/node/lambda_node'
|
68
|
+
require_relative 'ast/node/masgn_node'
|
69
|
+
require_relative 'ast/node/mlhs_node'
|
64
70
|
require_relative 'ast/node/module_node'
|
65
71
|
require_relative 'ast/node/next_node'
|
66
72
|
require_relative 'ast/node/op_asgn_node'
|
@@ -70,6 +76,7 @@ require_relative 'ast/node/or_node'
|
|
70
76
|
require_relative 'ast/node/pair_node'
|
71
77
|
require_relative 'ast/node/procarg0_node'
|
72
78
|
require_relative 'ast/node/range_node'
|
79
|
+
require_relative 'ast/node/rational_node'
|
73
80
|
require_relative 'ast/node/regexp_node'
|
74
81
|
require_relative 'ast/node/rescue_node'
|
75
82
|
require_relative 'ast/node/resbody_node'
|
@@ -82,10 +89,12 @@ require_relative 'ast/node/dstr_node'
|
|
82
89
|
require_relative 'ast/node/super_node'
|
83
90
|
require_relative 'ast/node/symbol_node'
|
84
91
|
require_relative 'ast/node/until_node'
|
92
|
+
require_relative 'ast/node/var_node'
|
85
93
|
require_relative 'ast/node/when_node'
|
86
94
|
require_relative 'ast/node/while_node'
|
87
95
|
require_relative 'ast/node/yield_node'
|
88
96
|
require_relative 'ast/builder'
|
97
|
+
require_relative 'ast/builder_prism'
|
89
98
|
require_relative 'ast/processed_source'
|
90
99
|
require_relative 'ast/rubocop_compatibility'
|
91
100
|
require_relative 'ast/token'
|