rubocop 1.59.0 → 1.60.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|