rubocop 1.59.0 → 1.60.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/LICENSE.txt +1 -1
- data/README.md +3 -3
- data/config/default.yml +3 -1
- data/lib/rubocop/config.rb +0 -2
- data/lib/rubocop/config_loader.rb +0 -1
- data/lib/rubocop/config_validator.rb +0 -2
- data/lib/rubocop/cop/base.rb +6 -0
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +5 -1
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +16 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +12 -5
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/naming/block_forwarding.rb +10 -2
- data/lib/rubocop/cop/registry.rb +4 -4
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +16 -3
- data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
- data/lib/rubocop/cop/style/eval_with_location.rb +0 -11
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +4 -1
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +39 -2
- data/lib/rubocop/cop/style/map_to_hash.rb +9 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +13 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -3
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -3
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +8 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +10 -1
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/symbol_proc.rb +36 -0
- data/lib/rubocop/cops_documentation_generator.rb +11 -1
- data/lib/rubocop/ext/regexp_node.rb +9 -4
- data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +1 -1
- data/lib/rubocop/options.rb +0 -8
- data/lib/rubocop/rspec/shared_contexts.rb +6 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/server/cache.rb +0 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +11 -11
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8154c812a06c819d2014cca8c0967d9b9eb01ff0481b33318accfb61781b04ce
|
|
4
|
+
data.tar.gz: d39b524c83cd84df683815b59ac1377fb9dc235dcce337507a56bf611eaa90af
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0787d7ca9354c20ef1fbbee33dc551cd2e45e8c3ea4aac96a51f8348b3a03a3ae1cc5262e0e6d00f61591f48ce4ffbf9140d7f1ddd19b9716d0596df3bbaa55c'
|
|
7
|
+
data.tar.gz: de7a48105e8126e9f2c323dc516d4c9862b8c239d881e8285496eb3e79cefdecf487a37e0cb3e0b98fc25264f33c3a2d104fb1e6a4e382d1619f21dace50cc99
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://raw.githubusercontent.com/rubocop/rubocop/master/logo/rubo-logo-horizontal.png" alt="RuboCop Logo"/>
|
|
2
|
+
<img src="https://raw.githubusercontent.com/rubocop/rubocop/master/logo/rubo-logo-horizontal-white.png" alt="RuboCop Logo"/>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
----------
|
|
@@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
|
53
53
|
in your `Gemfile`:
|
|
54
54
|
|
|
55
55
|
```rb
|
|
56
|
-
gem 'rubocop', '~> 1.
|
|
56
|
+
gem 'rubocop', '~> 1.60', require: false
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
|
@@ -248,5 +248,5 @@ RuboCop's changelog is available [here](CHANGELOG.md).
|
|
|
248
248
|
|
|
249
249
|
## Copyright
|
|
250
250
|
|
|
251
|
-
Copyright (c) 2012-
|
|
251
|
+
Copyright (c) 2012-2024 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for
|
|
252
252
|
further details.
|
data/config/default.yml
CHANGED
|
@@ -4712,6 +4712,7 @@ Style/OperatorMethodCall:
|
|
|
4712
4712
|
|
|
4713
4713
|
Style/OptionHash:
|
|
4714
4714
|
Description: "Don't use option hashes when you can use keyword arguments."
|
|
4715
|
+
StyleGuide: '#keyword-arguments-vs-option-hashes'
|
|
4715
4716
|
Enabled: false
|
|
4716
4717
|
VersionAdded: '0.33'
|
|
4717
4718
|
VersionChanged: '0.34'
|
|
@@ -5237,7 +5238,8 @@ Style/SingleLineMethods:
|
|
|
5237
5238
|
AllowIfMethodIsEmpty: true
|
|
5238
5239
|
|
|
5239
5240
|
Style/SlicingWithRange:
|
|
5240
|
-
Description: 'Checks array slicing is done with endless ranges when suitable.'
|
|
5241
|
+
Description: 'Checks array slicing is done with redundant, endless, and beginless ranges when suitable.'
|
|
5242
|
+
StyleGuide: '#slicing-with-ranges'
|
|
5241
5243
|
Enabled: true
|
|
5242
5244
|
VersionAdded: '0.83'
|
|
5243
5245
|
Safe: false
|
data/lib/rubocop/config.rb
CHANGED
data/lib/rubocop/cop/base.rb
CHANGED
|
@@ -8,7 +8,7 @@ module RuboCop
|
|
|
8
8
|
# The parameter name given is transformed into a method name (eg. `Max`
|
|
9
9
|
# becomes `self.max=` and `MinDigits` becomes `self.min_digits=`).
|
|
10
10
|
def exclude_limit(parameter_name, method_name: transform(parameter_name))
|
|
11
|
-
define_method("#{method_name}=") do |value|
|
|
11
|
+
define_method(:"#{method_name}=") do |value|
|
|
12
12
|
cfg = config_to_allow_offenses
|
|
13
13
|
cfg[:exclude_limit] ||= {}
|
|
14
14
|
current_max = cfg[:exclude_limit][parameter_name]
|
|
@@ -5,7 +5,10 @@ module RuboCop
|
|
|
5
5
|
module Layout
|
|
6
6
|
# Checks the indentation of the first element in an array literal
|
|
7
7
|
# where the opening bracket and the first element are on separate lines.
|
|
8
|
-
# The other elements' indentations are handled by
|
|
8
|
+
# The other elements' indentations are handled by `Layout/ArrayAlignment` cop.
|
|
9
|
+
#
|
|
10
|
+
# This cop will respect `Layout/ArrayAlignment` and will not work when
|
|
11
|
+
# `EnforcedStyle: with_fixed_indentation` is specified for `Layout/ArrayAlignment`.
|
|
9
12
|
#
|
|
10
13
|
# By default, array literals that are arguments in a method call with
|
|
11
14
|
# parentheses, and where the opening square bracket of the array is on the
|
|
@@ -93,6 +96,8 @@ module RuboCop
|
|
|
93
96
|
end
|
|
94
97
|
|
|
95
98
|
def on_send(node)
|
|
99
|
+
return if style != :consistent && enforce_first_argument_with_fixed_indentation?
|
|
100
|
+
|
|
96
101
|
each_argument_node(node, :array) do |array_node, left_parenthesis|
|
|
97
102
|
check(array_node, left_parenthesis)
|
|
98
103
|
end
|
|
@@ -174,6 +179,16 @@ module RuboCop
|
|
|
174
179
|
'where the left bracket is.'
|
|
175
180
|
end
|
|
176
181
|
end
|
|
182
|
+
|
|
183
|
+
def enforce_first_argument_with_fixed_indentation?
|
|
184
|
+
return false unless array_alignment_config['Enabled']
|
|
185
|
+
|
|
186
|
+
array_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def array_alignment_config
|
|
190
|
+
config.for_cop('Layout/ArrayAlignment')
|
|
191
|
+
end
|
|
177
192
|
end
|
|
178
193
|
end
|
|
179
194
|
end
|
|
@@ -107,7 +107,7 @@ module RuboCop
|
|
|
107
107
|
return false unless line.end_with?("\\\n")
|
|
108
108
|
|
|
109
109
|
# Ensure backslash isn't part of a token spanning to the next line.
|
|
110
|
-
node.children.none? { |c| c.first_line
|
|
110
|
+
node.children.none? { |c| (c.first_line...c.last_line).cover?(line_num) && c.multiline? }
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
def autocorrect(corrector, offense_range, insert_pos, spaces)
|
|
@@ -41,7 +41,7 @@ module RuboCop
|
|
|
41
41
|
next unless asgn_node.loc.operator
|
|
42
42
|
|
|
43
43
|
rhs = asgn_node.to_a.last
|
|
44
|
-
next if !
|
|
44
|
+
next if !all_literals?(rhs) || parallel_assignment_with_splat_operator?(rhs)
|
|
45
45
|
|
|
46
46
|
range = offense_range(asgn_node, rhs)
|
|
47
47
|
|
|
@@ -59,10 +59,17 @@ module RuboCop
|
|
|
59
59
|
node.each_child_node { |child| traverse_node(child, &block) }
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
def
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
def all_literals?(node)
|
|
63
|
+
case node.type
|
|
64
|
+
when :dstr, :xstr
|
|
65
|
+
false
|
|
66
|
+
when :array
|
|
67
|
+
node.values.all? { |value| all_literals?(value) }
|
|
68
|
+
when :hash
|
|
69
|
+
(node.values + node.keys).all? { |item| all_literals?(item) }
|
|
70
|
+
else
|
|
71
|
+
node.respond_to?(:literal?) && node.literal?
|
|
72
|
+
end
|
|
66
73
|
end
|
|
67
74
|
|
|
68
75
|
def parallel_assignment_with_splat_operator?(node)
|
|
@@ -123,6 +123,7 @@ module RuboCop
|
|
|
123
123
|
|
|
124
124
|
# Shorthand assignments always use their arguments
|
|
125
125
|
next false if assignment_node.shorthand_asgn?
|
|
126
|
+
next false unless assignment_node.parent
|
|
126
127
|
|
|
127
128
|
node_within_block_or_conditional =
|
|
128
129
|
node_within_block_or_conditional?(assignment_node.parent, argument.scope.node)
|
|
@@ -17,9 +17,12 @@ module RuboCop
|
|
|
17
17
|
private
|
|
18
18
|
|
|
19
19
|
def add_offense_from_diagnostic(diagnostic, ruby_version)
|
|
20
|
-
message =
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
message = if lsp_mode?
|
|
21
|
+
diagnostic.message
|
|
22
|
+
else
|
|
23
|
+
"#{diagnostic.message}\n(Using Ruby #{ruby_version} parser; " \
|
|
24
|
+
'configure using `TargetRubyVersion` parameter, under `AllCops`)'
|
|
25
|
+
end
|
|
23
26
|
add_offense(diagnostic.location, message: message, severity: diagnostic.level)
|
|
24
27
|
end
|
|
25
28
|
|
|
@@ -51,21 +51,29 @@ module RuboCop
|
|
|
51
51
|
[Lint::AmbiguousOperator, Style::ArgumentsForwarding]
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
54
55
|
def on_def(node)
|
|
55
56
|
return if node.arguments.empty?
|
|
56
57
|
|
|
57
58
|
last_argument = node.last_argument
|
|
58
59
|
return if expected_block_forwarding_style?(node, last_argument)
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
invalid_syntax = false
|
|
62
62
|
node.each_descendant(:block_pass) do |block_pass_node|
|
|
63
63
|
next if block_pass_node.children.first&.sym_type? ||
|
|
64
64
|
last_argument.source != block_pass_node.source
|
|
65
65
|
|
|
66
|
+
if block_pass_node.each_ancestor(:block, :numblock).any?
|
|
67
|
+
invalid_syntax = true
|
|
68
|
+
next
|
|
69
|
+
end
|
|
70
|
+
|
|
66
71
|
register_offense(block_pass_node, node)
|
|
67
72
|
end
|
|
73
|
+
|
|
74
|
+
register_offense(last_argument, node) unless invalid_syntax
|
|
68
75
|
end
|
|
76
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
69
77
|
alias on_defs on_def
|
|
70
78
|
|
|
71
79
|
private
|
data/lib/rubocop/cop/registry.rb
CHANGED
|
@@ -240,12 +240,12 @@ module RuboCop
|
|
|
240
240
|
self
|
|
241
241
|
end
|
|
242
242
|
|
|
243
|
-
def select(
|
|
244
|
-
cops.select(
|
|
243
|
+
def select(...)
|
|
244
|
+
cops.select(...)
|
|
245
245
|
end
|
|
246
246
|
|
|
247
|
-
def each(
|
|
248
|
-
cops.each(
|
|
247
|
+
def each(...)
|
|
248
|
+
cops.each(...)
|
|
249
249
|
end
|
|
250
250
|
|
|
251
251
|
# @param [String] cop_name
|
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
|
23
23
|
# # bad
|
|
24
24
|
# open(something)
|
|
25
25
|
# open("| #{something}")
|
|
26
|
+
# open("| foo")
|
|
26
27
|
# URI.open(something)
|
|
27
28
|
#
|
|
28
29
|
# # good
|
|
@@ -32,7 +33,6 @@ module RuboCop
|
|
|
32
33
|
#
|
|
33
34
|
# # good (literal strings)
|
|
34
35
|
# open("foo.text")
|
|
35
|
-
# open("| foo")
|
|
36
36
|
# URI.open("http://example.com")
|
|
37
37
|
class Open < Base
|
|
38
38
|
MSG = 'The use of `%<receiver>sopen` is a serious security risk.'
|
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
|
40
40
|
|
|
41
41
|
# @!method open?(node)
|
|
42
42
|
def_node_matcher :open?, <<~PATTERN
|
|
43
|
-
(send ${nil? (const {nil? cbase} :URI)} :open
|
|
43
|
+
(send ${nil? (const {nil? cbase} :URI)} :open $_ ...)
|
|
44
44
|
PATTERN
|
|
45
45
|
|
|
46
46
|
def on_send(node)
|
|
@@ -186,12 +186,12 @@ module RuboCop
|
|
|
186
186
|
rest_arg, kwrest_arg, _block_arg = *forwardable_args
|
|
187
187
|
|
|
188
188
|
send_classifications.each do |send_node, _c, forward_rest, forward_kwrest|
|
|
189
|
-
if forward_rest
|
|
189
|
+
if outside_block?(forward_rest)
|
|
190
190
|
register_forward_args_offense(def_node.arguments, rest_arg)
|
|
191
191
|
register_forward_args_offense(send_node, forward_rest)
|
|
192
192
|
end
|
|
193
193
|
|
|
194
|
-
if forward_kwrest
|
|
194
|
+
if outside_block?(forward_kwrest)
|
|
195
195
|
register_forward_kwargs_offense(!forward_rest, def_node.arguments, kwrest_arg)
|
|
196
196
|
register_forward_kwargs_offense(!forward_rest, send_node, forward_kwrest)
|
|
197
197
|
end
|
|
@@ -250,6 +250,12 @@ module RuboCop
|
|
|
250
250
|
redundant_arg_names.include?(arg.source) ? arg : nil
|
|
251
251
|
end
|
|
252
252
|
|
|
253
|
+
def outside_block?(node)
|
|
254
|
+
return false unless node
|
|
255
|
+
|
|
256
|
+
node.each_ancestor(:block, :numblock).none?
|
|
257
|
+
end
|
|
258
|
+
|
|
253
259
|
def register_forward_args_offense(def_arguments_or_send, rest_arg_or_splat)
|
|
254
260
|
add_offense(rest_arg_or_splat, message: ARGS_MSG) do |corrector|
|
|
255
261
|
add_parens_if_missing(def_arguments_or_send, corrector)
|
|
@@ -340,7 +346,7 @@ module RuboCop
|
|
|
340
346
|
end
|
|
341
347
|
|
|
342
348
|
def classification
|
|
343
|
-
return nil unless forwarded_rest_arg || forwarded_kwrest_arg
|
|
349
|
+
return nil unless forwarded_rest_arg || forwarded_kwrest_arg || forwarded_block_arg
|
|
344
350
|
|
|
345
351
|
if can_forward_all?
|
|
346
352
|
:all
|
|
@@ -424,9 +430,16 @@ module RuboCop
|
|
|
424
430
|
def no_additional_args?
|
|
425
431
|
forwardable_count = [@rest_arg, @kwrest_arg, @block_arg].compact.size
|
|
426
432
|
|
|
433
|
+
return false if missing_rest_arg_or_kwrest_arg?
|
|
434
|
+
|
|
427
435
|
@def_node.arguments.size == forwardable_count &&
|
|
428
436
|
@send_node.arguments.size == forwardable_count
|
|
429
437
|
end
|
|
438
|
+
|
|
439
|
+
def missing_rest_arg_or_kwrest_arg?
|
|
440
|
+
(@rest_arg_name && !forwarded_rest_arg) ||
|
|
441
|
+
(@kwrest_arg_name && !forwarded_kwrest_arg)
|
|
442
|
+
end
|
|
430
443
|
end
|
|
431
444
|
end
|
|
432
445
|
end
|
|
@@ -32,27 +32,27 @@ module RuboCop
|
|
|
32
32
|
|
|
33
33
|
send_node = node.send_node
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
add_offense(range) do |corrector|
|
|
35
|
+
add_offense(send_node) do |corrector|
|
|
38
36
|
range_type, min, max = each_range(node)
|
|
39
37
|
|
|
40
38
|
max += 1 if range_type == :irange
|
|
41
39
|
|
|
42
|
-
corrector.replace(
|
|
40
|
+
corrector.replace(send_node, "#{max - min}.times")
|
|
43
41
|
end
|
|
44
42
|
end
|
|
45
43
|
|
|
46
44
|
private
|
|
47
45
|
|
|
48
46
|
def offending?(node)
|
|
47
|
+
return false unless node.arguments.empty?
|
|
48
|
+
|
|
49
49
|
each_range_with_zero_origin?(node) || each_range_without_block_argument?(node)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# @!method each_range(node)
|
|
53
53
|
def_node_matcher :each_range, <<~PATTERN
|
|
54
54
|
(block
|
|
55
|
-
(
|
|
55
|
+
(call
|
|
56
56
|
(begin
|
|
57
57
|
(${irange erange}
|
|
58
58
|
(int $_) (int $_)))
|
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
|
64
64
|
# @!method each_range_with_zero_origin?(node)
|
|
65
65
|
def_node_matcher :each_range_with_zero_origin?, <<~PATTERN
|
|
66
66
|
(block
|
|
67
|
-
(
|
|
67
|
+
(call
|
|
68
68
|
(begin
|
|
69
69
|
({irange erange}
|
|
70
70
|
(int 0) (int _)))
|
|
@@ -76,7 +76,7 @@ module RuboCop
|
|
|
76
76
|
# @!method each_range_without_block_argument?(node)
|
|
77
77
|
def_node_matcher :each_range_without_block_argument?, <<~PATTERN
|
|
78
78
|
(block
|
|
79
|
-
(
|
|
79
|
+
(call
|
|
80
80
|
(begin
|
|
81
81
|
({irange erange}
|
|
82
82
|
(int _) (int _)))
|
|
@@ -128,17 +128,6 @@ module RuboCop
|
|
|
128
128
|
node.method?(:eval) ? node.arguments.size >= 2 : true
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
-
# FIXME: It's a Style/ConditionalAssignment's false positive.
|
|
132
|
-
# rubocop:disable Style/ConditionalAssignment
|
|
133
|
-
def with_lineno?(node)
|
|
134
|
-
if node.method?(:eval)
|
|
135
|
-
node.arguments.size == 4
|
|
136
|
-
else
|
|
137
|
-
node.arguments.size == 3
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
# rubocop:enable Style/ConditionalAssignment
|
|
141
|
-
|
|
142
131
|
def add_offense_for_incorrect_line(method_name, line_node, sign, line_diff)
|
|
143
132
|
expected = expected_line(sign, line_diff)
|
|
144
133
|
message = format(MSG_INCORRECT_LINE,
|
|
@@ -111,11 +111,11 @@ module RuboCop
|
|
|
111
111
|
lvar_sources = node.body.each_descendant(:lvar).map(&:source)
|
|
112
112
|
|
|
113
113
|
if block_arg.mlhs_type?
|
|
114
|
-
block_arg.each_descendant(:arg).all? do |block_arg|
|
|
115
|
-
lvar_sources.none?(block_arg.source)
|
|
114
|
+
block_arg.each_descendant(:arg, :restarg).all? do |block_arg|
|
|
115
|
+
lvar_sources.none?(block_arg.source.delete_prefix('*'))
|
|
116
116
|
end
|
|
117
117
|
else
|
|
118
|
-
lvar_sources.none?(block_arg.source)
|
|
118
|
+
lvar_sources.none?(block_arg.source.delete_prefix('*'))
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
|
|
@@ -158,7 +158,10 @@ module RuboCop
|
|
|
158
158
|
if head.assignment?
|
|
159
159
|
# The `send` node is used instead of the `indexasgn` node, so `name` cannot be used.
|
|
160
160
|
# https://github.com/rubocop/rubocop-ast/blob/v1.29.0/lib/rubocop/ast/node/indexasgn_node.rb
|
|
161
|
-
|
|
161
|
+
#
|
|
162
|
+
# FIXME: It would be better to update `RuboCop::AST::OpAsgnNode` or its subclasses to
|
|
163
|
+
# handle `self.foo ||= value` as a solution, instead of using `head.node_parts[0].to_s`.
|
|
164
|
+
assigned_value = head.send_type? ? head.receiver.source : head.node_parts[0].to_s
|
|
162
165
|
|
|
163
166
|
return if condition_variable == assigned_value
|
|
164
167
|
end
|
|
@@ -51,7 +51,7 @@ module RuboCop
|
|
|
51
51
|
class InvertibleUnlessCondition < Base
|
|
52
52
|
extend AutoCorrector
|
|
53
53
|
|
|
54
|
-
MSG = '
|
|
54
|
+
MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
|
|
55
55
|
|
|
56
56
|
def on_if(node)
|
|
57
57
|
return unless node.unless?
|
|
@@ -59,7 +59,10 @@ module RuboCop
|
|
|
59
59
|
condition = node.condition
|
|
60
60
|
return unless invertible?(condition)
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
message = format(MSG, prefer: "#{node.inverse_keyword} #{preferred_condition(condition)}",
|
|
63
|
+
current: "#{node.keyword} #{condition.source}")
|
|
64
|
+
|
|
65
|
+
add_offense(node, message: message) do |corrector|
|
|
63
66
|
corrector.replace(node.loc.keyword, node.inverse_keyword)
|
|
64
67
|
autocorrect(corrector, condition)
|
|
65
68
|
end
|
|
@@ -88,6 +91,40 @@ module RuboCop
|
|
|
88
91
|
(argument.const_type? && argument.short_name.to_s.upcase != argument.short_name.to_s)
|
|
89
92
|
end
|
|
90
93
|
|
|
94
|
+
def preferred_condition(node)
|
|
95
|
+
case node.type
|
|
96
|
+
when :begin then "(#{preferred_condition(node.children.first)})"
|
|
97
|
+
when :send then preferred_send_condition(node)
|
|
98
|
+
when :or, :and then preferred_logical_condition(node)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def preferred_send_condition(node)
|
|
103
|
+
receiver_source = node.receiver.source
|
|
104
|
+
return receiver_source if node.method?(:!)
|
|
105
|
+
|
|
106
|
+
inverse_method_name = inverse_methods[node.method_name]
|
|
107
|
+
return "#{receiver_source}.#{inverse_method_name}" unless node.arguments?
|
|
108
|
+
|
|
109
|
+
argument_list = node.arguments.map(&:source).join(', ')
|
|
110
|
+
if node.operator_method?
|
|
111
|
+
return "#{receiver_source} #{inverse_method_name} #{argument_list}"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
if node.parenthesized?
|
|
115
|
+
return "#{receiver_source}.#{inverse_method_name}(#{argument_list})"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
"#{receiver_source}.#{inverse_method_name} #{argument_list}"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def preferred_logical_condition(node)
|
|
122
|
+
preferred_lhs = preferred_condition(node.lhs)
|
|
123
|
+
preferred_rhs = preferred_condition(node.rhs)
|
|
124
|
+
|
|
125
|
+
"#{preferred_lhs} #{node.inverse_operator} #{preferred_rhs}"
|
|
126
|
+
end
|
|
127
|
+
|
|
91
128
|
def autocorrect(corrector, node)
|
|
92
129
|
case node.type
|
|
93
130
|
when :begin
|
|
@@ -37,8 +37,8 @@ module RuboCop
|
|
|
37
37
|
MSG = 'Pass a block to `to_h` instead of calling `%<method>s%<dot>sto_h`.'
|
|
38
38
|
RESTRICT_ON_SEND = %i[to_h].freeze
|
|
39
39
|
|
|
40
|
-
# @!method map_to_h
|
|
41
|
-
def_node_matcher :map_to_h
|
|
40
|
+
# @!method map_to_h(node)
|
|
41
|
+
def_node_matcher :map_to_h, <<~PATTERN
|
|
42
42
|
{
|
|
43
43
|
$(call ({block numblock} $(call _ {:map :collect}) ...) :to_h)
|
|
44
44
|
$(call $(call _ {:map :collect} (block_pass sym)) :to_h)
|
|
@@ -50,9 +50,9 @@ module RuboCop
|
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def on_send(node)
|
|
53
|
-
return unless (to_h_node, map_node = map_to_h
|
|
53
|
+
return unless (to_h_node, map_node = map_to_h(node))
|
|
54
54
|
|
|
55
|
-
message = format(MSG, method: map_node.loc.selector.source, dot:
|
|
55
|
+
message = format(MSG, method: map_node.loc.selector.source, dot: to_h_node.loc.dot.source)
|
|
56
56
|
add_offense(map_node.loc.selector, message: message) do |corrector|
|
|
57
57
|
# If the `to_h` call already has a block, do not autocorrect.
|
|
58
58
|
next if to_h_node.block_node
|
|
@@ -64,13 +64,17 @@ module RuboCop
|
|
|
64
64
|
|
|
65
65
|
private
|
|
66
66
|
|
|
67
|
+
# rubocop:disable Metrics/AbcSize
|
|
67
68
|
def autocorrect(corrector, to_h, map)
|
|
68
69
|
removal_range = range_between(to_h.loc.dot.begin_pos, to_h.loc.selector.end_pos)
|
|
69
70
|
|
|
70
71
|
corrector.remove(range_with_surrounding_space(removal_range, side: :left))
|
|
71
|
-
|
|
72
|
+
if (map_dot = map.loc.dot)
|
|
73
|
+
corrector.replace(map_dot, to_h.loc.dot.source)
|
|
74
|
+
end
|
|
72
75
|
corrector.replace(map.loc.selector, 'to_h')
|
|
73
76
|
end
|
|
77
|
+
# rubocop:enable Metrics/AbcSize
|
|
74
78
|
end
|
|
75
79
|
end
|
|
76
80
|
end
|
|
@@ -127,23 +127,31 @@ module RuboCop
|
|
|
127
127
|
|
|
128
128
|
def call_with_ambiguous_arguments?(node) # rubocop:disable Metrics/PerceivedComplexity
|
|
129
129
|
call_with_braced_block?(node) ||
|
|
130
|
+
call_in_argument_with_block?(node) ||
|
|
130
131
|
call_as_argument_or_chain?(node) ||
|
|
131
132
|
call_in_match_pattern?(node) ||
|
|
132
133
|
hash_literal_in_arguments?(node) ||
|
|
133
134
|
node.descendants.any? do |n|
|
|
134
|
-
n.forwarded_args_type? ||
|
|
135
|
-
|
|
135
|
+
n.forwarded_args_type? || n.block_type? ||
|
|
136
|
+
ambiguous_literal?(n) || logical_operator?(n)
|
|
136
137
|
end
|
|
137
138
|
end
|
|
138
139
|
|
|
139
140
|
def call_with_braced_block?(node)
|
|
140
|
-
(node.
|
|
141
|
+
(node.call_type? || node.super_type?) && node.block_node&.braces?
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def call_in_argument_with_block?(node)
|
|
145
|
+
parent = node.parent&.block_type? && node.parent&.parent
|
|
146
|
+
return false unless parent
|
|
147
|
+
|
|
148
|
+
parent.call_type? || parent.super_type? || parent.yield_type?
|
|
141
149
|
end
|
|
142
150
|
|
|
143
151
|
def call_as_argument_or_chain?(node)
|
|
144
152
|
node.parent &&
|
|
145
|
-
(
|
|
146
|
-
|
|
153
|
+
(node.parent.call_type? || node.parent.super_type? || node.parent.yield_type?) &&
|
|
154
|
+
!assigned_before?(node.parent, node)
|
|
147
155
|
end
|
|
148
156
|
|
|
149
157
|
def call_in_match_pattern?(node)
|
|
@@ -218,15 +218,13 @@ module RuboCop
|
|
|
218
218
|
send(style, node) # call require_parentheses or omit_parentheses
|
|
219
219
|
end
|
|
220
220
|
alias on_csend on_send
|
|
221
|
-
alias on_super on_send
|
|
222
221
|
alias on_yield on_send
|
|
223
222
|
|
|
224
223
|
private
|
|
225
224
|
|
|
226
225
|
def args_begin(node)
|
|
227
226
|
loc = node.loc
|
|
228
|
-
selector =
|
|
229
|
-
node.super_type? || node.yield_type? ? loc.keyword : loc.selector
|
|
227
|
+
selector = node.yield_type? ? loc.keyword : loc.selector
|
|
230
228
|
|
|
231
229
|
resize_by = args_parenthesized?(node) ? 2 : 1
|
|
232
230
|
selector.end.resize(resize_by)
|
|
@@ -54,12 +54,10 @@ module RuboCop
|
|
|
54
54
|
private
|
|
55
55
|
|
|
56
56
|
def offense?(node)
|
|
57
|
-
node.ternary? && node.multiline?
|
|
57
|
+
node.ternary? && node.multiline? && node.source != replacement(node)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def autocorrect(corrector, node)
|
|
61
|
-
return unless offense?(node)
|
|
62
|
-
|
|
63
61
|
corrector.replace(node, replacement(node))
|
|
64
62
|
return unless (parent = node.parent)
|
|
65
63
|
return unless (comments_in_condition = comments_in_condition(node))
|
|
@@ -81,6 +81,7 @@ module RuboCop
|
|
|
81
81
|
cond = node.condition
|
|
82
82
|
|
|
83
83
|
control_op_condition(cond) do |first_child, rest_children|
|
|
84
|
+
return if require_parentheses?(node, first_child)
|
|
84
85
|
return if semicolon_separated_expressions?(first_child, rest_children)
|
|
85
86
|
return if modifier_op?(first_child)
|
|
86
87
|
return if parens_allowed?(cond)
|
|
@@ -92,6 +93,13 @@ module RuboCop
|
|
|
92
93
|
end
|
|
93
94
|
end
|
|
94
95
|
|
|
96
|
+
def require_parentheses?(node, condition_body)
|
|
97
|
+
return false if !node.while_type? && !node.until_type?
|
|
98
|
+
return false if !condition_body.block_type? && !condition_body.numblock_type?
|
|
99
|
+
|
|
100
|
+
condition_body.send_node.block_literal? && condition_body.keywords?
|
|
101
|
+
end
|
|
102
|
+
|
|
95
103
|
def semicolon_separated_expressions?(first_exp, rest_exps)
|
|
96
104
|
return false unless (second_exp = rest_exps.first)
|
|
97
105
|
|
|
@@ -56,6 +56,7 @@ module RuboCop
|
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
|
+
alias on_csend on_send
|
|
59
60
|
|
|
60
61
|
private
|
|
61
62
|
|
|
@@ -64,7 +65,7 @@ module RuboCop
|
|
|
64
65
|
return if node.last_argument&.block_pass_type?
|
|
65
66
|
|
|
66
67
|
if node.method?(:each) && !node.parent&.block_type?
|
|
67
|
-
ancestor_node = node.each_ancestor(:send).detect do |ancestor|
|
|
68
|
+
ancestor_node = node.each_ancestor(:send, :csend).detect do |ancestor|
|
|
68
69
|
ancestor.receiver == node &&
|
|
69
70
|
(RESTRICT_ON_SEND.include?(ancestor.method_name) || ancestor.method?(:reverse_each))
|
|
70
71
|
end
|
|
@@ -83,10 +84,12 @@ module RuboCop
|
|
|
83
84
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
84
85
|
|
|
85
86
|
def range(node)
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
return node.selector unless node.method?(:each)
|
|
88
|
+
|
|
89
|
+
if node.parent.call_type?
|
|
90
|
+
node.selector.join(node.parent.loc.dot)
|
|
88
91
|
else
|
|
89
|
-
node.loc.selector
|
|
92
|
+
node.loc.dot.join(node.selector)
|
|
90
93
|
end
|
|
91
94
|
end
|
|
92
95
|
|
|
@@ -94,7 +94,8 @@ module RuboCop
|
|
|
94
94
|
!ends_with_backslash_without_comment?(range.source_line) ||
|
|
95
95
|
string_concatenation?(range.source_line) ||
|
|
96
96
|
start_with_arithmetic_operator?(processed_source[range.line]) ||
|
|
97
|
-
inside_string_literal_or_method_with_argument?(range)
|
|
97
|
+
inside_string_literal_or_method_with_argument?(range) ||
|
|
98
|
+
leading_dot_method_chain_with_blank_line?(range)
|
|
98
99
|
end
|
|
99
100
|
|
|
100
101
|
def ends_with_backslash_without_comment?(source_line)
|
|
@@ -113,6 +114,12 @@ module RuboCop
|
|
|
113
114
|
end
|
|
114
115
|
end
|
|
115
116
|
|
|
117
|
+
def leading_dot_method_chain_with_blank_line?(range)
|
|
118
|
+
return false unless range.source_line.strip.start_with?('.', '&.')
|
|
119
|
+
|
|
120
|
+
processed_source[range.line].strip.empty?
|
|
121
|
+
end
|
|
122
|
+
|
|
116
123
|
def redundant_line_continuation?(range)
|
|
117
124
|
return true unless (node = find_node_for_line(range.line))
|
|
118
125
|
return false if argument_newline?(node)
|
|
@@ -53,7 +53,7 @@ module RuboCop
|
|
|
53
53
|
def ignore_syntax?(node)
|
|
54
54
|
return false unless (parent = node.parent)
|
|
55
55
|
|
|
56
|
-
parent.while_post_type? || parent.until_post_type? ||
|
|
56
|
+
parent.while_post_type? || parent.until_post_type? || parent.match_with_lvasgn_type? ||
|
|
57
57
|
like_method_argument_parentheses?(parent)
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -150,6 +150,8 @@ module RuboCop
|
|
|
150
150
|
return if begin_node.chained?
|
|
151
151
|
|
|
152
152
|
if node.and_type? || node.or_type?
|
|
153
|
+
return if node.semantic_operator? && begin_node.parent
|
|
154
|
+
return if node.multiline? && allow_in_multiline_conditions?
|
|
153
155
|
return if ALLOWED_NODE_TYPES.include?(begin_node.parent&.type)
|
|
154
156
|
return if begin_node.parent&.if_type? && begin_node.parent&.ternary?
|
|
155
157
|
|
|
@@ -165,6 +167,13 @@ module RuboCop
|
|
|
165
167
|
# @!method interpolation?(node)
|
|
166
168
|
def_node_matcher :interpolation?, '[^begin ^^dstr]'
|
|
167
169
|
|
|
170
|
+
def allow_in_multiline_conditions?
|
|
171
|
+
parentheses_around_condition_config = config.for_cop('Style/ParenthesesAroundCondition')
|
|
172
|
+
return false unless parentheses_around_condition_config['Enabled']
|
|
173
|
+
|
|
174
|
+
!!parentheses_around_condition_config['AllowInMultilineConditions']
|
|
175
|
+
end
|
|
176
|
+
|
|
168
177
|
def check_send(begin_node, node)
|
|
169
178
|
return check_unary(begin_node, node) if node.unary_operation?
|
|
170
179
|
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks that arrays are sliced with
|
|
7
|
-
# `ary[start..-1]` on Ruby 2.6
|
|
6
|
+
# Checks that arrays are not sliced with the redundant `ary[0..-1]`, replacing it with `ary`,
|
|
7
|
+
# and ensures arrays are sliced with endless ranges instead of `ary[start..-1]` on Ruby 2.6+,
|
|
8
|
+
# and with beginless ranges instead of `ary[nil..end]` on Ruby 2.7+.
|
|
8
9
|
#
|
|
9
10
|
# @safety
|
|
10
11
|
# This cop is unsafe because `x..-1` and `x..` are only guaranteed to
|
|
@@ -21,29 +22,94 @@ module RuboCop
|
|
|
21
22
|
#
|
|
22
23
|
# @example
|
|
23
24
|
# # bad
|
|
24
|
-
# items[
|
|
25
|
+
# items[0..-1]
|
|
26
|
+
# items[0..nil]
|
|
27
|
+
# items[0...nil]
|
|
25
28
|
#
|
|
26
29
|
# # good
|
|
27
|
-
# items
|
|
30
|
+
# items
|
|
31
|
+
#
|
|
32
|
+
# # bad
|
|
33
|
+
# items[1..-1] # Ruby 2.6+
|
|
34
|
+
# items[1..nil] # Ruby 2.6+
|
|
35
|
+
#
|
|
36
|
+
# # good
|
|
37
|
+
# items[1..] # Ruby 2.6+
|
|
38
|
+
#
|
|
39
|
+
# # bad
|
|
40
|
+
# items[nil..42] # Ruby 2.7+
|
|
41
|
+
#
|
|
42
|
+
# # good
|
|
43
|
+
# items[..42] # Ruby 2.7+
|
|
44
|
+
# items[0..42] # Ruby 2.7+
|
|
45
|
+
#
|
|
28
46
|
class SlicingWithRange < Base
|
|
29
47
|
extend AutoCorrector
|
|
30
48
|
extend TargetRubyVersion
|
|
31
49
|
|
|
32
50
|
minimum_target_ruby_version 2.6
|
|
33
51
|
|
|
34
|
-
MSG = 'Prefer
|
|
52
|
+
MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
|
|
53
|
+
MSG_USELESS_RANGE = 'Remove the useless `%<prefer>s`.'
|
|
35
54
|
RESTRICT_ON_SEND = %i[[]].freeze
|
|
36
55
|
|
|
56
|
+
# @!method range_from_zero_till_minus_one?(node)
|
|
57
|
+
def_node_matcher :range_from_zero_till_minus_one?, <<~PATTERN
|
|
58
|
+
{
|
|
59
|
+
(irange (int 0) {(int -1) nil})
|
|
60
|
+
(erange (int 0) nil)
|
|
61
|
+
}
|
|
62
|
+
PATTERN
|
|
63
|
+
|
|
37
64
|
# @!method range_till_minus_one?(node)
|
|
38
|
-
def_node_matcher :range_till_minus_one?,
|
|
65
|
+
def_node_matcher :range_till_minus_one?, <<~PATTERN
|
|
66
|
+
{
|
|
67
|
+
(irange !nil? {(int -1) nil})
|
|
68
|
+
(erange !nil? nil)
|
|
69
|
+
}
|
|
70
|
+
PATTERN
|
|
71
|
+
|
|
72
|
+
# @!method range_from_zero?(node)
|
|
73
|
+
def_node_matcher :range_from_zero?, <<~PATTERN
|
|
74
|
+
(irange nil !nil?)
|
|
75
|
+
PATTERN
|
|
39
76
|
|
|
40
77
|
def on_send(node)
|
|
41
|
-
return unless node.arguments.
|
|
42
|
-
return unless range_till_minus_one?(node.first_argument)
|
|
78
|
+
return unless node.arguments.one?
|
|
43
79
|
|
|
44
|
-
|
|
45
|
-
|
|
80
|
+
range_node = node.first_argument
|
|
81
|
+
selector = node.loc.selector
|
|
82
|
+
unless (message, removal_range = offense_message_with_removal_range(range_node, selector))
|
|
83
|
+
return
|
|
46
84
|
end
|
|
85
|
+
|
|
86
|
+
add_offense(selector, message: message) do |corrector|
|
|
87
|
+
corrector.remove(removal_range)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
def offense_message_with_removal_range(range_node, selector)
|
|
94
|
+
if range_from_zero_till_minus_one?(range_node)
|
|
95
|
+
[format(MSG_USELESS_RANGE, prefer: selector.source), selector]
|
|
96
|
+
elsif range_till_minus_one?(range_node)
|
|
97
|
+
[
|
|
98
|
+
format(MSG, prefer: endless(range_node), current: selector.source), range_node.end
|
|
99
|
+
]
|
|
100
|
+
elsif range_from_zero?(range_node) && target_ruby_version >= 2.7
|
|
101
|
+
[
|
|
102
|
+
format(MSG, prefer: beginless(range_node), current: selector.source), range_node.begin
|
|
103
|
+
]
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def endless(range_node)
|
|
108
|
+
"[#{range_node.begin.source}#{range_node.loc.operator.source}]"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def beginless(range_node)
|
|
112
|
+
"[#{range_node.loc.operator.source}#{range_node.end.source}]"
|
|
47
113
|
end
|
|
48
114
|
end
|
|
49
115
|
end
|
|
@@ -37,6 +37,42 @@ module RuboCop
|
|
|
37
37
|
# # ArgumentError: wrong number of arguments (given 1, expected 0)
|
|
38
38
|
# ----
|
|
39
39
|
#
|
|
40
|
+
# It is also unsafe because `Symbol#to_proc` does not work with
|
|
41
|
+
# `protected` methods which would otherwise be accessible.
|
|
42
|
+
#
|
|
43
|
+
# For example:
|
|
44
|
+
#
|
|
45
|
+
# [source,ruby]
|
|
46
|
+
# ----
|
|
47
|
+
# class Box
|
|
48
|
+
# def initialize
|
|
49
|
+
# @secret = rand
|
|
50
|
+
# end
|
|
51
|
+
#
|
|
52
|
+
# def normal_matches?(*others)
|
|
53
|
+
# others.map { |other| other.secret }.any?(secret)
|
|
54
|
+
# end
|
|
55
|
+
#
|
|
56
|
+
# def symbol_to_proc_matches?(*others)
|
|
57
|
+
# others.map(&:secret).any?(secret)
|
|
58
|
+
# end
|
|
59
|
+
#
|
|
60
|
+
# protected
|
|
61
|
+
#
|
|
62
|
+
# attr_reader :secret
|
|
63
|
+
# end
|
|
64
|
+
#
|
|
65
|
+
# boxes = [Box.new, Box.new]
|
|
66
|
+
# Box.new.normal_matches?(*boxes)
|
|
67
|
+
# # => false
|
|
68
|
+
# boxes.first.normal_matches?(*boxes)
|
|
69
|
+
# # => true
|
|
70
|
+
# Box.new.symbol_to_proc_matches?(*boxes)
|
|
71
|
+
# # => NoMethodError: protected method `secret' called for #<Box...>
|
|
72
|
+
# boxes.first.symbol_to_proc_matches?(*boxes)
|
|
73
|
+
# # => NoMethodError: protected method `secret' called for #<Box...>
|
|
74
|
+
# ----
|
|
75
|
+
#
|
|
40
76
|
# @example
|
|
41
77
|
# # bad
|
|
42
78
|
# something.map { |s| s.upcase }
|
|
@@ -251,9 +251,18 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
|
251
251
|
"\ninclude::../partials/#{filename}[]\n"
|
|
252
252
|
end
|
|
253
253
|
|
|
254
|
+
# rubocop:disable Metrics/MethodLength
|
|
254
255
|
def print_cops_of_department(department)
|
|
255
256
|
selected_cops = cops_of_department(department)
|
|
256
|
-
content =
|
|
257
|
+
content = +<<~HEADER
|
|
258
|
+
////
|
|
259
|
+
Do NOT edit this file by hand directly, as it is automatically generated.
|
|
260
|
+
|
|
261
|
+
Please make any necessary changes to the cop documentation within the source files themselves.
|
|
262
|
+
////
|
|
263
|
+
|
|
264
|
+
= #{department}
|
|
265
|
+
HEADER
|
|
257
266
|
selected_cops.each { |cop| content << print_cop_with_doc(cop) }
|
|
258
267
|
content << footer_for_department(department)
|
|
259
268
|
file_name = "#{docs_path}/#{department_to_basename(department)}.adoc"
|
|
@@ -262,6 +271,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
|
262
271
|
file.write("#{content.strip}\n")
|
|
263
272
|
end
|
|
264
273
|
end
|
|
274
|
+
# rubocop:enable Metrics/MethodLength
|
|
265
275
|
|
|
266
276
|
def print_cop_with_doc(cop) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
|
|
267
277
|
cop_config = config.for_cop(cop)
|
|
@@ -54,10 +54,7 @@ module RuboCop
|
|
|
54
54
|
return enum_for(__method__, named: named) unless block_given?
|
|
55
55
|
|
|
56
56
|
parsed_tree&.traverse do |event, exp, _index|
|
|
57
|
-
yield(exp) if event
|
|
58
|
-
named == exp.respond_to?(:name) &&
|
|
59
|
-
exp.respond_to?(:capturing?) &&
|
|
60
|
-
exp.capturing?
|
|
57
|
+
yield(exp) if named_capturing?(exp, event, named)
|
|
61
58
|
end
|
|
62
59
|
|
|
63
60
|
self
|
|
@@ -65,6 +62,14 @@ module RuboCop
|
|
|
65
62
|
|
|
66
63
|
private
|
|
67
64
|
|
|
65
|
+
def named_capturing?(exp, event, named)
|
|
66
|
+
event == :enter &&
|
|
67
|
+
named == exp.respond_to?(:name) &&
|
|
68
|
+
!exp.text.start_with?('(?<=') &&
|
|
69
|
+
exp.respond_to?(:capturing?) &&
|
|
70
|
+
exp.capturing?
|
|
71
|
+
end
|
|
72
|
+
|
|
68
73
|
def with_interpolations_blanked
|
|
69
74
|
# Ignore the trailing regopt node
|
|
70
75
|
children[0...-1].map do |child|
|
|
@@ -30,7 +30,8 @@ module RuboCop
|
|
|
30
30
|
@files_with_offenses ||= {}
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
def file_started(_file,
|
|
33
|
+
def file_started(_file, options)
|
|
34
|
+
@config_for_pwd = options[:config_store].for_pwd
|
|
34
35
|
@exclude_limit_option = @options[:exclude_limit]
|
|
35
36
|
@exclude_limit = Integer(@exclude_limit_option ||
|
|
36
37
|
RuboCop::Options::DEFAULT_MAXIMUM_EXCLUSION_ITEMS)
|
|
@@ -115,9 +116,13 @@ module RuboCop
|
|
|
115
116
|
def set_max(cfg, cop_name)
|
|
116
117
|
return unless cfg[:exclude_limit]
|
|
117
118
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if
|
|
119
|
+
max_set_in_user_config =
|
|
120
|
+
@config_for_pwd.for_cop(cop_name)['Max'] != default_config(cop_name)['Max']
|
|
121
|
+
if !max_set_in_user_config &&
|
|
122
|
+
# In case auto_gen_only_exclude is set, only modify the maximum if the files are not
|
|
123
|
+
# excluded one by one.
|
|
124
|
+
(!@options[:auto_gen_only_exclude] ||
|
|
125
|
+
@files_with_offenses[cop_name].size > @exclude_limit)
|
|
121
126
|
cfg.merge!(cfg[:exclude_limit])
|
|
122
127
|
end
|
|
123
128
|
|
|
@@ -192,8 +197,8 @@ module RuboCop
|
|
|
192
197
|
# 'Enabled' option will be put into file only if exclude
|
|
193
198
|
# limit is exceeded.
|
|
194
199
|
rejected_keys = ['Enabled']
|
|
195
|
-
rejected_keys <<
|
|
196
|
-
cfg.reject { |key|
|
|
200
|
+
rejected_keys << /\AEnforcedStyle\w*/ unless auto_gen_enforced_style?
|
|
201
|
+
cfg.reject { |key| include_or_match?(rejected_keys, key) }
|
|
197
202
|
end
|
|
198
203
|
|
|
199
204
|
def output_offending_files(output_buffer, cfg, cop_name)
|
|
@@ -262,6 +267,12 @@ module RuboCop
|
|
|
262
267
|
def no_exclude_limit?
|
|
263
268
|
@options[:no_exclude_limit] == false
|
|
264
269
|
end
|
|
270
|
+
|
|
271
|
+
# Returns true if the given arr include the given elm or if any of the
|
|
272
|
+
# given arr is a regexp that matches the given elm.
|
|
273
|
+
def include_or_match?(arr, elm)
|
|
274
|
+
arr.include?(elm) || arr.any? { |x| x.is_a?(Regexp) && x.match?(elm) }
|
|
275
|
+
end
|
|
265
276
|
end
|
|
266
277
|
end
|
|
267
278
|
end
|
data/lib/rubocop/formatter.rb
CHANGED
|
@@ -14,7 +14,7 @@ module RuboCop
|
|
|
14
14
|
require_relative 'formatter/emacs_style_formatter'
|
|
15
15
|
require_relative 'formatter/file_list_formatter'
|
|
16
16
|
require_relative 'formatter/fuubar_style_formatter'
|
|
17
|
-
require_relative 'formatter/
|
|
17
|
+
require_relative 'formatter/github_actions_formatter'
|
|
18
18
|
require_relative 'formatter/html_formatter'
|
|
19
19
|
require_relative 'formatter/json_formatter'
|
|
20
20
|
require_relative 'formatter/junit_formatter'
|
data/lib/rubocop/lsp/routes.rb
CHANGED
data/lib/rubocop/options.rb
CHANGED
|
@@ -364,10 +364,6 @@ module RuboCop
|
|
|
364
364
|
raise OptionArgumentError, '-C/--cache argument must be true or false'
|
|
365
365
|
end
|
|
366
366
|
|
|
367
|
-
if display_only_fail_level_offenses_with_autocorrect?
|
|
368
|
-
raise OptionArgumentError, '--autocorrect cannot be used with ' \
|
|
369
|
-
'--display-only-fail-level-offenses.'
|
|
370
|
-
end
|
|
371
367
|
validate_auto_gen_config
|
|
372
368
|
validate_autocorrect
|
|
373
369
|
validate_display_only_failed
|
|
@@ -460,10 +456,6 @@ module RuboCop
|
|
|
460
456
|
(@options[:only] & %w[Lint/RedundantCopDisableDirective RedundantCopDisableDirective]).any?
|
|
461
457
|
end
|
|
462
458
|
|
|
463
|
-
def display_only_fail_level_offenses_with_autocorrect?
|
|
464
|
-
@options.key?(:display_only_fail_level_offenses) && @options.key?(:autocorrect)
|
|
465
|
-
end
|
|
466
|
-
|
|
467
459
|
def except_syntax?
|
|
468
460
|
@options.key?(:except) && (@options[:except] & %w[Lint/Syntax Syntax]).any?
|
|
469
461
|
end
|
|
@@ -128,6 +128,12 @@ RSpec.shared_context 'mock console output' do
|
|
|
128
128
|
end
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
+
RSpec.shared_context 'lsp mode' do
|
|
132
|
+
before do
|
|
133
|
+
allow(cop).to receive(:lsp_mode?).and_return(true)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
131
137
|
RSpec.shared_context 'ruby 2.0' do
|
|
132
138
|
let(:ruby_version) { 2.0 }
|
|
133
139
|
end
|
|
@@ -13,6 +13,7 @@ RSpec.configure do |config|
|
|
|
13
13
|
config.include HostEnvironmentSimulatorHelper
|
|
14
14
|
config.include_context 'config', :config
|
|
15
15
|
config.include_context 'isolated environment', :isolated_environment
|
|
16
|
+
config.include_context 'lsp mode', :lsp_mode
|
|
16
17
|
config.include_context 'maintain registry', :restore_registry
|
|
17
18
|
config.include_context 'ruby 2.0', :ruby20
|
|
18
19
|
config.include_context 'ruby 2.1', :ruby21
|
data/lib/rubocop/server/cache.rb
CHANGED
data/lib/rubocop/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubocop
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.60.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bozhidar Batsov
|
|
8
8
|
- Jonas Arvidsson
|
|
9
9
|
- Yuji Nakayama
|
|
10
|
-
autorequire:
|
|
10
|
+
autorequire:
|
|
11
11
|
bindir: exe
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date:
|
|
13
|
+
date: 2024-01-15 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: json
|
|
@@ -60,14 +60,14 @@ dependencies:
|
|
|
60
60
|
requirements:
|
|
61
61
|
- - ">="
|
|
62
62
|
- !ruby/object:Gem::Version
|
|
63
|
-
version: 3.
|
|
63
|
+
version: 3.3.0.2
|
|
64
64
|
type: :runtime
|
|
65
65
|
prerelease: false
|
|
66
66
|
version_requirements: !ruby/object:Gem::Requirement
|
|
67
67
|
requirements:
|
|
68
68
|
- - ">="
|
|
69
69
|
- !ruby/object:Gem::Version
|
|
70
|
-
version: 3.
|
|
70
|
+
version: 3.3.0.2
|
|
71
71
|
- !ruby/object:Gem::Dependency
|
|
72
72
|
name: rainbow
|
|
73
73
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -964,7 +964,7 @@ files:
|
|
|
964
964
|
- lib/rubocop/formatter/file_list_formatter.rb
|
|
965
965
|
- lib/rubocop/formatter/formatter_set.rb
|
|
966
966
|
- lib/rubocop/formatter/fuubar_style_formatter.rb
|
|
967
|
-
- lib/rubocop/formatter/
|
|
967
|
+
- lib/rubocop/formatter/github_actions_formatter.rb
|
|
968
968
|
- lib/rubocop/formatter/html_formatter.rb
|
|
969
969
|
- lib/rubocop/formatter/json_formatter.rb
|
|
970
970
|
- lib/rubocop/formatter/junit_formatter.rb
|
|
@@ -1028,12 +1028,12 @@ licenses:
|
|
|
1028
1028
|
- MIT
|
|
1029
1029
|
metadata:
|
|
1030
1030
|
homepage_uri: https://rubocop.org/
|
|
1031
|
-
changelog_uri: https://github.com/rubocop/rubocop/
|
|
1031
|
+
changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.60.0
|
|
1032
1032
|
source_code_uri: https://github.com/rubocop/rubocop/
|
|
1033
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
|
1033
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.60/
|
|
1034
1034
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
|
1035
1035
|
rubygems_mfa_required: 'true'
|
|
1036
|
-
post_install_message:
|
|
1036
|
+
post_install_message:
|
|
1037
1037
|
rdoc_options: []
|
|
1038
1038
|
require_paths:
|
|
1039
1039
|
- lib
|
|
@@ -1048,8 +1048,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
1048
1048
|
- !ruby/object:Gem::Version
|
|
1049
1049
|
version: '0'
|
|
1050
1050
|
requirements: []
|
|
1051
|
-
rubygems_version: 3.
|
|
1052
|
-
signing_key:
|
|
1051
|
+
rubygems_version: 3.4.22
|
|
1052
|
+
signing_key:
|
|
1053
1053
|
specification_version: 4
|
|
1054
1054
|
summary: Automatic Ruby code style checking tool.
|
|
1055
1055
|
test_files: []
|
|
File without changes
|