rubocop 1.31.0 → 1.32.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/config/default.yml +23 -0
- data/lib/rubocop/cli.rb +1 -0
- data/lib/rubocop/config.rb +1 -1
- data/lib/rubocop/config_loader_resolver.rb +1 -1
- data/lib/rubocop/cop/base.rb +1 -1
- data/lib/rubocop/cop/generator.rb +4 -0
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +60 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +4 -3
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +3 -3
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +57 -13
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +10 -0
- data/lib/rubocop/cop/layout/line_length.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -1
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +45 -0
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +7 -0
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +10 -4
- data/lib/rubocop/cop/lint/literal_as_condition.rb +5 -0
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +60 -24
- data/lib/rubocop/cop/lint/number_conversion.rb +7 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +7 -0
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +57 -0
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +35 -1
- data/lib/rubocop/cop/metrics/block_length.rb +1 -0
- data/lib/rubocop/cop/metrics/method_length.rb +1 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +4 -0
- data/lib/rubocop/cop/mixin/def_node.rb +2 -7
- data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +12 -14
- data/lib/rubocop/cop/mixin/percent_array.rb +60 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +8 -0
- data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -0
- data/lib/rubocop/cop/style/empty_else.rb +37 -0
- data/lib/rubocop/cop/style/empty_heredoc.rb +59 -0
- data/lib/rubocop/cop/style/fetch_env_var.rb +10 -177
- data/lib/rubocop/cop/style/format_string_token.rb +6 -0
- data/lib/rubocop/cop/style/hash_except.rb +1 -1
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +12 -0
- data/lib/rubocop/cop/style/module_function.rb +2 -2
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +9 -0
- data/lib/rubocop/cop/style/numeric_predicate.rb +20 -6
- data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/semicolon.rb +27 -3
- data/lib/rubocop/cop/style/symbol_array.rb +2 -3
- data/lib/rubocop/cop/style/symbol_proc.rb +9 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +3 -0
- data/lib/rubocop/cop/style/word_array.rb +2 -3
- data/lib/rubocop/formatter/simple_text_formatter.rb +2 -0
- data/lib/rubocop/formatter.rb +21 -21
- data/lib/rubocop/options.rb +3 -6
- data/lib/rubocop/rake_task.rb +5 -1
- data/lib/rubocop/rspec/shared_contexts.rb +14 -14
- data/lib/rubocop/rspec/support.rb +14 -0
- data/lib/rubocop/runner.rb +4 -0
- data/lib/rubocop/server/client_command/base.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +4 -1
- metadata +23 -5
@@ -9,32 +9,15 @@ module RuboCop
|
|
9
9
|
# On the other hand, `ENV.fetch` raises KeyError or returns the explicitly
|
10
10
|
# specified default value.
|
11
11
|
#
|
12
|
-
# When an `ENV[]` is the LHS of `||`, the autocorrect makes the RHS
|
13
|
-
# the default value of `ENV.fetch`.
|
14
|
-
#
|
15
12
|
# @example
|
16
13
|
# # bad
|
17
14
|
# ENV['X']
|
18
|
-
# ENV['X'] || 'string literal'
|
19
|
-
# ENV['X'] || some_method
|
20
15
|
# x = ENV['X']
|
21
16
|
#
|
22
|
-
# ENV['X'] || y.map do |a|
|
23
|
-
# puts a * 2
|
24
|
-
# end
|
25
|
-
#
|
26
17
|
# # good
|
27
18
|
# ENV.fetch('X')
|
28
|
-
# ENV.fetch('X', 'string literal')
|
29
|
-
# ENV.fetch('X') { some_method }
|
30
19
|
# x = ENV.fetch('X')
|
31
20
|
#
|
32
|
-
# ENV.fetch('X') do
|
33
|
-
# y.map do |a|
|
34
|
-
# puts a * 2
|
35
|
-
# end
|
36
|
-
# end
|
37
|
-
#
|
38
21
|
# # also good
|
39
22
|
# !ENV['X']
|
40
23
|
# ENV['X'].some_method # (e.g. `.nil?`)
|
@@ -42,48 +25,20 @@ module RuboCop
|
|
42
25
|
class FetchEnvVar < Base
|
43
26
|
extend AutoCorrector
|
44
27
|
|
45
|
-
|
46
|
-
MSG_DEFAULT_NIL = 'Use `ENV.fetch(%<key>s)` or `ENV.fetch(%<key>s, nil)` instead of `ENV[%<key>s]`.'
|
47
|
-
MSG_DEFAULT_RHS_SECOND_ARG_OF_FETCH = 'Use `ENV.fetch(%<key>s, %<default>s)` instead of `ENV[%<key>s] || %<default>s`.'
|
48
|
-
MSG_DEFAULT_RHS_SINGLE_LINE_BLOCK = 'Use `ENV.fetch(%<key>s) { %<default>s }` instead of `ENV[%<key>s] || %<default>s`.'
|
49
|
-
MSG_DEFAULT_RHS_MULTILINE_BLOCK = 'Use `ENV.fetch(%<key>s)` with a block containing `%<default>s ...`'
|
50
|
-
# rubocop:enable Layout/LineLength
|
28
|
+
MSG = 'Use `ENV.fetch(%<key>s)` or `ENV.fetch(%<key>s, nil)` instead of `ENV[%<key>s]`.'
|
51
29
|
|
52
30
|
# @!method env_with_bracket?(node)
|
53
31
|
def_node_matcher :env_with_bracket?, <<~PATTERN
|
54
32
|
(send (const nil? :ENV) :[] $_)
|
55
33
|
PATTERN
|
56
34
|
|
57
|
-
# @!method operand_of_or?(node)
|
58
|
-
def_node_matcher :operand_of_or?, <<~PATTERN
|
59
|
-
(^or ...)
|
60
|
-
PATTERN
|
61
|
-
|
62
|
-
# @!method block_control?(node)
|
63
|
-
def_node_matcher :block_control?, <<~PATTERN
|
64
|
-
({next | break | retry | redo})
|
65
|
-
PATTERN
|
66
|
-
|
67
|
-
# @!method offensive_nodes(node)
|
68
|
-
def_node_search :offensive_nodes, <<~PATTERN
|
69
|
-
[#env_with_bracket? #offensive?]
|
70
|
-
PATTERN
|
71
|
-
|
72
35
|
def on_send(node)
|
73
36
|
env_with_bracket?(node) do |name_node|
|
74
37
|
break unless offensive?(node)
|
75
38
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
if default_to_rhs?(target_node)
|
81
|
-
default_rhs(target_node, target_name_node)
|
82
|
-
else
|
83
|
-
default_nil(target_node, target_name_node)
|
84
|
-
end
|
85
|
-
else
|
86
|
-
default_nil(node, name_node)
|
39
|
+
message = format(MSG, key: name_node.source)
|
40
|
+
add_offense(node, message: message) do |corrector|
|
41
|
+
corrector.replace(node, new_code(name_node))
|
87
42
|
end
|
88
43
|
end
|
89
44
|
end
|
@@ -130,17 +85,6 @@ module RuboCop
|
|
130
85
|
!(allowed_var?(node) || allowable_use?(node))
|
131
86
|
end
|
132
87
|
|
133
|
-
def or_chain_root(node)
|
134
|
-
while operand_of_or?(ancestor_or ||= node.parent)
|
135
|
-
ancestor_or = ancestor_or.parent
|
136
|
-
end
|
137
|
-
ancestor_or
|
138
|
-
end
|
139
|
-
|
140
|
-
def default_to_rhs?(node)
|
141
|
-
operand_of_or?(node) && !right_end_of_or_chains?(node) && rhs_can_be_default_value?(node)
|
142
|
-
end
|
143
|
-
|
144
88
|
# Check if the node is a receiver and receives a message with dot syntax.
|
145
89
|
def message_chained_with_dot?(node)
|
146
90
|
return false if node.root?
|
@@ -157,8 +101,9 @@ module RuboCop
|
|
157
101
|
# it simply checks whether the variable is set.
|
158
102
|
# - Receiving a message with dot syntax, e.g. `ENV['X'].nil?`.
|
159
103
|
# - `ENV['key']` assigned by logical AND/OR assignment.
|
104
|
+
# - `ENV['key']` is the LHS of a `||`.
|
160
105
|
def allowable_use?(node)
|
161
|
-
used_as_flag?(node) || message_chained_with_dot?(node) || assigned?(node)
|
106
|
+
used_as_flag?(node) || message_chained_with_dot?(node) || assigned?(node) || or_lhs?(node)
|
162
107
|
end
|
163
108
|
|
164
109
|
# The following are allowed cases:
|
@@ -172,127 +117,15 @@ module RuboCop
|
|
172
117
|
node == lhs
|
173
118
|
end
|
174
119
|
|
175
|
-
def
|
176
|
-
return false unless
|
177
|
-
|
178
|
-
node.parent.lhs == node
|
179
|
-
end
|
180
|
-
|
181
|
-
def right_end_of_or_chains?(node)
|
182
|
-
!(left_end_of_or_chains?(node) || node.parent&.parent&.or_type?)
|
183
|
-
end
|
184
|
-
|
185
|
-
def conterpart_rhs_of(node)
|
186
|
-
left_end_of_or_chains?(node) ? node.parent.rhs : node.parent.parent.rhs
|
187
|
-
end
|
188
|
-
|
189
|
-
def rhs_can_be_default_value?(node)
|
190
|
-
!rhs_is_block_control?(node)
|
191
|
-
end
|
120
|
+
def or_lhs?(node)
|
121
|
+
return false unless (parent = node.parent)&.or_type?
|
192
122
|
|
193
|
-
|
194
|
-
block_control?(conterpart_rhs_of(node))
|
123
|
+
parent.lhs == node || parent.parent&.or_type?
|
195
124
|
end
|
196
125
|
|
197
|
-
def
|
126
|
+
def new_code(name_node)
|
198
127
|
"ENV.fetch(#{name_node.source}, nil)"
|
199
128
|
end
|
200
|
-
|
201
|
-
def new_code_default_rhs_single_line(node, name_node)
|
202
|
-
parent = node.parent
|
203
|
-
if parent.rhs.basic_literal?
|
204
|
-
"ENV.fetch(#{name_node.source}, #{parent.rhs.source})"
|
205
|
-
else
|
206
|
-
"ENV.fetch(#{name_node.source}) { #{parent.rhs.source} }"
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
def new_code_default_rhs_multiline(node, name_node)
|
211
|
-
env_indent = indent(node.parent)
|
212
|
-
default = node.parent.rhs.source.split("\n").map do |line|
|
213
|
-
"#{env_indent}#{line}"
|
214
|
-
end.join("\n")
|
215
|
-
<<~NEW_CODE.chomp
|
216
|
-
ENV.fetch(#{name_node.source}) do
|
217
|
-
#{configured_indentation}#{default}
|
218
|
-
#{env_indent}end
|
219
|
-
NEW_CODE
|
220
|
-
end
|
221
|
-
|
222
|
-
def new_code_default_rhs(node, name_node)
|
223
|
-
if node.parent.rhs.single_line?
|
224
|
-
new_code_default_rhs_single_line(node, name_node)
|
225
|
-
else
|
226
|
-
new_code_default_rhs_multiline(node, name_node)
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
def default_rhs(node, name_node)
|
231
|
-
if left_end_of_or_chains?(node)
|
232
|
-
default_rhs_in_same_or(node, name_node)
|
233
|
-
else
|
234
|
-
default_rhs_in_outer_or(node, name_node)
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
# Adds an offense and sets `nil` to the default value of `ENV.fetch`.
|
239
|
-
# `ENV['X']` --> `ENV.fetch('X', nil)`
|
240
|
-
def default_nil(node, name_node)
|
241
|
-
message = format(MSG_DEFAULT_NIL, key: name_node.source)
|
242
|
-
|
243
|
-
add_offense(node, message: message) do |corrector|
|
244
|
-
corrector.replace(node, new_code_default_nil(name_node))
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
# Adds an offense and makes the RHS the default value of `ENV.fetch`.
|
249
|
-
# `ENV['X'] || y` --> `ENV.fetch('X') { y }`
|
250
|
-
def default_rhs_in_same_or(node, name_node)
|
251
|
-
template = message_template_for(node.parent.rhs)
|
252
|
-
message = format(template,
|
253
|
-
key: name_node.source,
|
254
|
-
default: first_line_of(node.parent.rhs.source))
|
255
|
-
|
256
|
-
add_offense(node, message: message) do |corrector|
|
257
|
-
corrector.replace(node.parent, new_code_default_rhs(node, name_node))
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
# Adds an offense and makes the RHS the default value of `ENV.fetch`.
|
262
|
-
# `z || ENV['X'] || y` --> `z || ENV.fetch('X') { y }`
|
263
|
-
def default_rhs_in_outer_or(node, name_node)
|
264
|
-
parent = node.parent
|
265
|
-
grand_parent = parent.parent
|
266
|
-
|
267
|
-
template = message_template_for(grand_parent.rhs)
|
268
|
-
message = format(template,
|
269
|
-
key: name_node.source,
|
270
|
-
default: first_line_of(grand_parent.rhs.source))
|
271
|
-
|
272
|
-
add_offense(node, message: message) do |corrector|
|
273
|
-
lhs_code = parent.lhs.source
|
274
|
-
rhs_code = new_code_default_rhs(parent, name_node)
|
275
|
-
corrector.replace(grand_parent, "#{lhs_code} || #{rhs_code}")
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
def message_template_for(rhs)
|
280
|
-
if rhs.multiline?
|
281
|
-
MSG_DEFAULT_RHS_MULTILINE_BLOCK
|
282
|
-
elsif rhs.basic_literal?
|
283
|
-
MSG_DEFAULT_RHS_SECOND_ARG_OF_FETCH
|
284
|
-
else
|
285
|
-
MSG_DEFAULT_RHS_SINGLE_LINE_BLOCK
|
286
|
-
end
|
287
|
-
end
|
288
|
-
|
289
|
-
def configured_indentation
|
290
|
-
' ' * (config.for_cop('Layout/IndentationWidth')['Width'] || 2)
|
291
|
-
end
|
292
|
-
|
293
|
-
def first_line_of(source)
|
294
|
-
source.split("\n").first
|
295
|
-
end
|
296
129
|
end
|
297
130
|
end
|
298
131
|
end
|
@@ -12,6 +12,7 @@ module RuboCop
|
|
12
12
|
# to encoded URLs or Date/Time formatting strings.
|
13
13
|
#
|
14
14
|
# This cop can be customized ignored methods with `IgnoredMethods`.
|
15
|
+
# By default, there are no methods to ignored.
|
15
16
|
#
|
16
17
|
# @example EnforcedStyle: annotated (default)
|
17
18
|
#
|
@@ -61,6 +62,11 @@ module RuboCop
|
|
61
62
|
# # good
|
62
63
|
# format('%06d', 10)
|
63
64
|
#
|
65
|
+
# @example IgnoredMethods: [] (default)
|
66
|
+
#
|
67
|
+
# # bad
|
68
|
+
# redirect('foo/%{bar_id}')
|
69
|
+
#
|
64
70
|
# @example IgnoredMethods: [redirect]
|
65
71
|
#
|
66
72
|
# # good
|
@@ -6,6 +6,8 @@ module RuboCop
|
|
6
6
|
# Checks for redundant `if` with boolean literal branches.
|
7
7
|
# It checks only conditions to return boolean value (`true` or `false`) for safe detection.
|
8
8
|
# The conditions to be checked are comparison methods, predicate methods, and double negative.
|
9
|
+
# `nonzero?` method is allowed by default.
|
10
|
+
# These are customizable with `AllowedMethods` option.
|
9
11
|
#
|
10
12
|
# @safety
|
11
13
|
# Autocorrection is unsafe because there is no guarantee that all predicate methods
|
@@ -5,12 +5,24 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Checks for unwanted parentheses in parameterless method calls.
|
7
7
|
#
|
8
|
+
# This cop can be customized ignored methods with `IgnoredMethods`.
|
9
|
+
# By default, there are no methods to ignored.
|
10
|
+
#
|
8
11
|
# @example
|
9
12
|
# # bad
|
10
13
|
# object.some_method()
|
11
14
|
#
|
12
15
|
# # good
|
13
16
|
# object.some_method
|
17
|
+
#
|
18
|
+
# @example IgnoredMethods: [] (default)
|
19
|
+
# # bad
|
20
|
+
# object.foo()
|
21
|
+
#
|
22
|
+
# @example IgnoredMethods: [foo]
|
23
|
+
# # good
|
24
|
+
# object.foo()
|
25
|
+
#
|
14
26
|
class MethodCallWithoutArgsParentheses < Base
|
15
27
|
include IgnoredMethods
|
16
28
|
extend AutoCorrector
|
@@ -117,10 +117,10 @@ module RuboCop
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def check_module_function(nodes)
|
120
|
-
|
120
|
+
return if nodes.any? { |node| private_directive?(node) }
|
121
121
|
|
122
122
|
nodes.each do |node|
|
123
|
-
yield node if extend_self_node?(node)
|
123
|
+
yield node if extend_self_node?(node)
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
@@ -5,6 +5,10 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Checks for unparenthesized method calls in the argument list
|
7
7
|
# of a parenthesized method call.
|
8
|
+
# `be`, `be_a`, `be_an`, `be_between`, `be_falsey`, `be_kind_of`, `be_instance_of`,
|
9
|
+
# `be_truthy`, `be_within`, `eq`, `eql`, `end_with`, `include`, `match`, `raise_error`,
|
10
|
+
# `respond_to`, and `start_with` methods are allowed by default.
|
11
|
+
# These are customizable with `AllowedMethods` option.
|
8
12
|
#
|
9
13
|
# @example
|
10
14
|
# # good
|
@@ -12,6 +16,11 @@ module RuboCop
|
|
12
16
|
#
|
13
17
|
# # bad
|
14
18
|
# method1(method2 arg)
|
19
|
+
#
|
20
|
+
# @example AllowedMethods: [foo]
|
21
|
+
# # good
|
22
|
+
# method1(foo arg)
|
23
|
+
#
|
15
24
|
class NestedParenthesizedCalls < Base
|
16
25
|
include RangeHelp
|
17
26
|
include AllowedMethods
|
@@ -6,13 +6,16 @@ module RuboCop
|
|
6
6
|
# Checks for usage of comparison operators (`==`,
|
7
7
|
# `>`, `<`) to test numbers as zero, positive, or negative.
|
8
8
|
# These can be replaced by their respective predicate methods.
|
9
|
-
#
|
9
|
+
# This cop can also be configured to do the reverse.
|
10
10
|
#
|
11
|
-
#
|
11
|
+
# This cop can be customized ignored methods with `IgnoredMethods`.
|
12
|
+
# By default, there are no methods to ignored.
|
13
|
+
#
|
14
|
+
# This cop disregards `#nonzero?` as its value is truthy or falsey,
|
12
15
|
# but not `true` and `false`, and thus not always interchangeable with
|
13
16
|
# `!= 0`.
|
14
17
|
#
|
15
|
-
#
|
18
|
+
# This cop ignores comparisons to global variables, since they are often
|
16
19
|
# populated with objects which can be compared with integers, but are
|
17
20
|
# not themselves `Integer` polymorphic.
|
18
21
|
#
|
@@ -23,29 +26,40 @@ module RuboCop
|
|
23
26
|
#
|
24
27
|
# @example EnforcedStyle: predicate (default)
|
25
28
|
# # bad
|
26
|
-
#
|
27
29
|
# foo == 0
|
28
30
|
# 0 > foo
|
29
31
|
# bar.baz > 0
|
30
32
|
#
|
31
33
|
# # good
|
32
|
-
#
|
33
34
|
# foo.zero?
|
34
35
|
# foo.negative?
|
35
36
|
# bar.baz.positive?
|
36
37
|
#
|
37
38
|
# @example EnforcedStyle: comparison
|
38
39
|
# # bad
|
39
|
-
#
|
40
40
|
# foo.zero?
|
41
41
|
# foo.negative?
|
42
42
|
# bar.baz.positive?
|
43
43
|
#
|
44
44
|
# # good
|
45
|
+
# foo == 0
|
46
|
+
# 0 > foo
|
47
|
+
# bar.baz > 0
|
48
|
+
#
|
49
|
+
# @example IgnoredMethods: [] (default) with EnforcedStyle: predicate
|
50
|
+
# # bad
|
51
|
+
# foo == 0
|
52
|
+
# 0 > foo
|
53
|
+
# bar.baz > 0
|
45
54
|
#
|
55
|
+
# @example IgnoredMethods: [==] with EnforcedStyle: predicate
|
56
|
+
# # good
|
46
57
|
# foo == 0
|
58
|
+
#
|
59
|
+
# # bad
|
47
60
|
# 0 > foo
|
48
61
|
# bar.baz > 0
|
62
|
+
#
|
49
63
|
class NumericPredicate < Base
|
50
64
|
include ConfigurableEnforcedStyle
|
51
65
|
include IgnoredMethods
|
@@ -81,7 +81,8 @@ module RuboCop
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def like_method_argument_parentheses?(node)
|
84
|
-
node.send_type? && node.arguments.
|
84
|
+
node.send_type? && node.arguments.one? &&
|
85
|
+
!node.arithmetic_operation? && node.first_argument.begin_type?
|
85
86
|
end
|
86
87
|
|
87
88
|
def empty_parentheses?(node)
|
@@ -64,12 +64,14 @@ module RuboCop
|
|
64
64
|
# Make the obvious check first
|
65
65
|
return unless processed_source.raw_source.include?(';')
|
66
66
|
|
67
|
-
each_semicolon
|
67
|
+
each_semicolon do |line, column, token_before_semicolon|
|
68
|
+
register_semicolon(line, column, false, token_before_semicolon)
|
69
|
+
end
|
68
70
|
end
|
69
71
|
|
70
72
|
def each_semicolon
|
71
73
|
tokens_for_lines.each do |line, tokens|
|
72
|
-
yield line, tokens.last.column if tokens.last.semicolon?
|
74
|
+
yield line, tokens.last.column, tokens[-2] if tokens.last.semicolon?
|
73
75
|
yield line, tokens.first.column if tokens.first.semicolon?
|
74
76
|
end
|
75
77
|
end
|
@@ -78,13 +80,21 @@ module RuboCop
|
|
78
80
|
processed_source.tokens.group_by(&:line)
|
79
81
|
end
|
80
82
|
|
81
|
-
def register_semicolon(line, column, after_expression)
|
83
|
+
def register_semicolon(line, column, after_expression, token_before_semicolon = nil)
|
82
84
|
range = source_range(processed_source.buffer, line, column)
|
83
85
|
|
84
86
|
add_offense(range) do |corrector|
|
85
87
|
if after_expression
|
86
88
|
corrector.replace(range, "\n")
|
87
89
|
else
|
90
|
+
# Prevents becoming one range instance with subsequent line when endless range
|
91
|
+
# without parentheses.
|
92
|
+
# See: https://github.com/rubocop/rubocop/issues/10791
|
93
|
+
if token_before_semicolon&.regexp_dots?
|
94
|
+
range_node = find_range_node(token_before_semicolon)
|
95
|
+
corrector.wrap(range_node, '(', ')') if range_node
|
96
|
+
end
|
97
|
+
|
88
98
|
corrector.remove(range)
|
89
99
|
end
|
90
100
|
end
|
@@ -103,6 +113,20 @@ module RuboCop
|
|
103
113
|
yield Regexp.last_match.begin(0)
|
104
114
|
end
|
105
115
|
end
|
116
|
+
|
117
|
+
def find_range_node(token_before_semicolon)
|
118
|
+
range_nodes.detect do |range_node|
|
119
|
+
range_node.source_range.contains?(token_before_semicolon.pos)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def range_nodes
|
124
|
+
return @range_nodes if instance_variable_defined?(:@range_nodes)
|
125
|
+
|
126
|
+
ast = processed_source.ast
|
127
|
+
@range_nodes = ast.range_type? ? [ast] : []
|
128
|
+
@range_nodes.concat(ast.each_descendant(:irange, :erange).to_a)
|
129
|
+
end
|
106
130
|
end
|
107
131
|
end
|
108
132
|
end
|
@@ -39,7 +39,7 @@ module RuboCop
|
|
39
39
|
minimum_target_ruby_version 2.0
|
40
40
|
|
41
41
|
PERCENT_MSG = 'Use `%i` or `%I` for an array of symbols.'
|
42
|
-
ARRAY_MSG = 'Use
|
42
|
+
ARRAY_MSG = 'Use %<prefer>s for an array of symbols.'
|
43
43
|
|
44
44
|
class << self
|
45
45
|
attr_accessor :largest_brackets
|
@@ -74,8 +74,7 @@ module RuboCop
|
|
74
74
|
to_symbol_literal(c.value.to_s)
|
75
75
|
end
|
76
76
|
end
|
77
|
-
|
78
|
-
"[#{syms.join(', ')}]"
|
77
|
+
build_bracketed_array_with_appropriate_whitespace(elements: syms, node: node)
|
79
78
|
end
|
80
79
|
|
81
80
|
def to_symbol_literal(string)
|
@@ -7,6 +7,8 @@ module RuboCop
|
|
7
7
|
#
|
8
8
|
# If you prefer a style that allows block for method with arguments,
|
9
9
|
# please set `true` to `AllowMethodsWithArguments`.
|
10
|
+
# respond_to , and `define_method?` methods are ignored by default.
|
11
|
+
# These are customizable with `IgnoredMethods` option.
|
10
12
|
#
|
11
13
|
# @safety
|
12
14
|
# This cop is unsafe because `proc`s and blocks work differently
|
@@ -68,6 +70,12 @@ module RuboCop
|
|
68
70
|
# s.upcase # some comment
|
69
71
|
# # some comment
|
70
72
|
# end
|
73
|
+
#
|
74
|
+
# @example IgnoredMethods: [respond_to, define_method] (default)
|
75
|
+
# # good
|
76
|
+
# respond_to { |foo| foo.bar }
|
77
|
+
# define_method(:foo) { |foo| foo.bar }
|
78
|
+
#
|
71
79
|
class SymbolProc < Base
|
72
80
|
include CommentsHelp
|
73
81
|
include RangeHelp
|
@@ -81,7 +89,7 @@ module RuboCop
|
|
81
89
|
def_node_matcher :proc_node?, '(send (const {nil? cbase} :Proc) :new)'
|
82
90
|
|
83
91
|
# @!method symbol_proc_receiver?(node)
|
84
|
-
def_node_matcher :symbol_proc_receiver?, '{(
|
92
|
+
def_node_matcher :symbol_proc_receiver?, '{(call ...) (super ...) zsuper}'
|
85
93
|
|
86
94
|
# @!method symbol_proc?(node)
|
87
95
|
def_node_matcher :symbol_proc?, <<~PATTERN
|
@@ -5,6 +5,9 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Looks for trivial reader/writer methods, that could
|
7
7
|
# have been created with the attr_* family of functions automatically.
|
8
|
+
# `to_ary`, `to_a`, `to_c`, `to_enum`, `to_h`, `to_hash`, `to_i`, `to_int`, `to_io`,
|
9
|
+
# `to_open`, `to_path`, `to_proc`, `to_r`, `to_regexp`, `to_str`, `to_s`, and `to_sym` methods
|
10
|
+
# are allowed by default. These are customizable with `AllowedMethods` option.
|
8
11
|
#
|
9
12
|
# @example
|
10
13
|
# # bad
|
@@ -44,7 +44,7 @@ module RuboCop
|
|
44
44
|
extend AutoCorrector
|
45
45
|
|
46
46
|
PERCENT_MSG = 'Use `%w` or `%W` for an array of words.'
|
47
|
-
ARRAY_MSG = 'Use
|
47
|
+
ARRAY_MSG = 'Use %<prefer>s for an array of words.'
|
48
48
|
|
49
49
|
class << self
|
50
50
|
attr_accessor :largest_brackets
|
@@ -92,8 +92,7 @@ module RuboCop
|
|
92
92
|
to_string_literal(word.children[0])
|
93
93
|
end
|
94
94
|
end
|
95
|
-
|
96
|
-
"[#{words.join(', ')}]"
|
95
|
+
build_bracketed_array_with_appropriate_whitespace(elements: words, node: node)
|
97
96
|
end
|
98
97
|
end
|
99
98
|
end
|
data/lib/rubocop/formatter.rb
CHANGED
@@ -2,30 +2,30 @@
|
|
2
2
|
|
3
3
|
module RuboCop
|
4
4
|
module Formatter
|
5
|
-
|
6
|
-
|
5
|
+
require_relative 'formatter/text_util'
|
6
|
+
|
7
|
+
require_relative 'formatter/base_formatter'
|
8
|
+
require_relative 'formatter/simple_text_formatter'
|
7
9
|
# relies on simple text
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
10
|
+
require_relative 'formatter/clang_style_formatter'
|
11
|
+
require_relative 'formatter/disabled_config_formatter'
|
12
|
+
require_relative 'formatter/emacs_style_formatter'
|
13
|
+
require_relative 'formatter/file_list_formatter'
|
14
|
+
require_relative 'formatter/fuubar_style_formatter'
|
15
|
+
require_relative 'formatter/git_hub_actions_formatter'
|
16
|
+
require_relative 'formatter/html_formatter'
|
17
|
+
require_relative 'formatter/json_formatter'
|
18
|
+
require_relative 'formatter/junit_formatter'
|
19
|
+
require_relative 'formatter/markdown_formatter'
|
20
|
+
require_relative 'formatter/offense_count_formatter'
|
21
|
+
require_relative 'formatter/progress_formatter'
|
22
|
+
require_relative 'formatter/quiet_formatter'
|
23
|
+
require_relative 'formatter/tap_formatter'
|
24
|
+
require_relative 'formatter/worst_offenders_formatter'
|
25
|
+
require_relative 'formatter/pacman_formatter'
|
24
26
|
# relies on progress formatter
|
25
|
-
|
26
|
-
autoload :Colorizable, 'rubocop/formatter/colorizable'
|
27
|
+
require_relative 'formatter/auto_gen_config_formatter'
|
27
28
|
|
28
29
|
require_relative 'formatter/formatter_set'
|
29
|
-
require_relative 'formatter/text_util'
|
30
30
|
end
|
31
31
|
end
|
data/lib/rubocop/options.rb
CHANGED
@@ -421,12 +421,9 @@ module RuboCop
|
|
421
421
|
end
|
422
422
|
|
423
423
|
def invalid_arguments_for_parallel
|
424
|
-
[('--auto-gen-config'
|
425
|
-
('-F/--fail-fast'
|
426
|
-
('
|
427
|
-
('-a/--autocorrect' if @options.key?(:safe_autocorrect)),
|
428
|
-
('-A/--autocorrect-all' if @options.key?(:autocorrect_all)),
|
429
|
-
('--cache false' if @options > { cache: 'false' })].compact
|
424
|
+
[('--auto-gen-config' if @options.key?(:auto_gen_config)),
|
425
|
+
('-F/--fail-fast' if @options.key?(:fail_fast)),
|
426
|
+
('--cache false' if @options > { cache: 'false' })].compact
|
430
427
|
end
|
431
428
|
|
432
429
|
def only_includes_redundant_disable?
|
data/lib/rubocop/rake_task.rb
CHANGED
@@ -73,11 +73,15 @@ module RuboCop
|
|
73
73
|
namespace(name) do
|
74
74
|
# rubocop:todo Naming/InclusiveLanguage
|
75
75
|
task(:auto_correct, *args) do
|
76
|
+
require 'rainbow'
|
76
77
|
warn Rainbow(
|
77
78
|
'rubocop:auto_correct task is deprecated; ' \
|
78
79
|
'use rubocop:autocorrect task or rubocop:autocorrect_all task instead.'
|
79
80
|
).yellow
|
80
|
-
|
81
|
+
RakeFileUtils.verbose(verbose) do
|
82
|
+
yield(*[self, task_args].slice(0, task_block.arity)) if task_block
|
83
|
+
perform('--autocorrect')
|
84
|
+
end
|
81
85
|
end
|
82
86
|
# rubocop:enable Naming/InclusiveLanguage
|
83
87
|
|