rubocop 1.26.1 → 1.27.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 +15 -2
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +3 -1
- data/lib/rubocop/cop/autocorrect_logic.rb +4 -0
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -5
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +1 -5
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -2
- data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -4
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +6 -6
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +3 -1
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +3 -1
- data/lib/rubocop/cop/lint/empty_when.rb +3 -1
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +11 -4
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +8 -1
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +51 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +10 -0
- data/lib/rubocop/cop/lint/syntax.rb +1 -2
- data/lib/rubocop/cop/lint/unused_method_argument.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
- data/lib/rubocop/cop/mixin/comments_help.rb +22 -2
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +1 -2
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -2
- data/lib/rubocop/cop/mixin/surrounding_space.rb +4 -2
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +32 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +1 -2
- data/lib/rubocop/cop/style/file_write.rb +12 -0
- data/lib/rubocop/cop/style/raise_args.rb +5 -2
- data/lib/rubocop/cop/style/redundant_capital_w.rb +1 -2
- data/lib/rubocop/cop/style/redundant_initialize.rb +119 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +12 -7
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -2
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -4
- data/lib/rubocop/formatter/offense_count_formatter.rb +6 -2
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -2
- data/lib/rubocop/result_cache.rb +9 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +2 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d48fd91bc57ba3589a331c3c0141d3e168c7631e5db47238a88cecbd10b12292
|
4
|
+
data.tar.gz: 9393d3cab7e09e86a9276ca4614f8f2c4fc2895f2070bd3364096569c2cd5828
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13d85485214ca48904b07a6da11f89d2e2ef33fceab05912fb4c4f4c1e025da4be79139845d13724a749f97eb837b943eef5515639a5116299b6a164d7517944
|
7
|
+
data.tar.gz: 668abbcaedb1f06c43a2e5f61774909d684767659979bc3787c0827ca22adf42be0edf1d30544909a74fc6aac18bcd3758c7c5f77352cb97b51fd96acd24ab18
|
data/README.md
CHANGED
@@ -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.27', require: false
|
57
57
|
```
|
58
58
|
|
59
59
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
data/config/default.yml
CHANGED
@@ -2058,6 +2058,12 @@ Lint/RedundantWithObject:
|
|
2058
2058
|
Enabled: true
|
2059
2059
|
VersionAdded: '0.51'
|
2060
2060
|
|
2061
|
+
Lint/RefinementImportMethods:
|
2062
|
+
Description: 'Use `Refinement#import_methods` when using `include` or `prepend` in `refine` block.'
|
2063
|
+
Enabled: pending
|
2064
|
+
SafeAutoCorrect: false
|
2065
|
+
VersionAdded: '1.27'
|
2066
|
+
|
2061
2067
|
Lint/RegexpAsCondition:
|
2062
2068
|
Description: >-
|
2063
2069
|
Do not use regexp literal as a condition.
|
@@ -2327,8 +2333,8 @@ Lint/UselessMethodDefinition:
|
|
2327
2333
|
Description: 'Checks for useless method definitions.'
|
2328
2334
|
Enabled: true
|
2329
2335
|
VersionAdded: '0.90'
|
2336
|
+
VersionChanged: '0.91'
|
2330
2337
|
Safe: false
|
2331
|
-
AllowComments: true
|
2332
2338
|
|
2333
2339
|
Lint/UselessRuby2Keywords:
|
2334
2340
|
Description: 'Finds unnecessary uses of `ruby2_keywords`.'
|
@@ -4524,6 +4530,11 @@ Style/RedundantFreeze:
|
|
4524
4530
|
VersionAdded: '0.34'
|
4525
4531
|
VersionChanged: '0.66'
|
4526
4532
|
|
4533
|
+
Style/RedundantInitialize:
|
4534
|
+
Description: 'Checks for redundant `initialize` methods.'
|
4535
|
+
Enabled: pending
|
4536
|
+
VersionAdded: '1.27'
|
4537
|
+
|
4527
4538
|
Style/RedundantInterpolation:
|
4528
4539
|
Description: 'Checks for strings that are just an interpolated expression.'
|
4529
4540
|
Enabled: true
|
@@ -4645,7 +4656,7 @@ Style/SafeNavigation:
|
|
4645
4656
|
be `nil` or truthy, but never `false`.
|
4646
4657
|
Enabled: true
|
4647
4658
|
VersionAdded: '0.43'
|
4648
|
-
VersionChanged: '
|
4659
|
+
VersionChanged: '1.27'
|
4649
4660
|
# Safe navigation may cause a statement to start returning `nil` in addition
|
4650
4661
|
# to whatever it used to return.
|
4651
4662
|
ConvertCodeThatCanStartToReturnNil: false
|
@@ -4656,6 +4667,8 @@ Style/SafeNavigation:
|
|
4656
4667
|
- try
|
4657
4668
|
- try!
|
4658
4669
|
SafeAutoCorrect: false
|
4670
|
+
# Maximum length of method chains for register an offense.
|
4671
|
+
MaxChainLength: 2
|
4659
4672
|
|
4660
4673
|
Style/Sample:
|
4661
4674
|
Description: >-
|
@@ -33,7 +33,9 @@ module RuboCop
|
|
33
33
|
return old_name unless old_name.end_with?('*')
|
34
34
|
|
35
35
|
# Handle whole departments (expressed as `Department/*`)
|
36
|
-
config.keys.
|
36
|
+
config.keys.select do |key|
|
37
|
+
key == department || key.start_with?("#{department}/")
|
38
|
+
end
|
37
39
|
end
|
38
40
|
|
39
41
|
def feature_loaded?
|
@@ -8,6 +8,10 @@ module RuboCop
|
|
8
8
|
autocorrect_requested? && correctable? && autocorrect_enabled?
|
9
9
|
end
|
10
10
|
|
11
|
+
def autocorrect_with_disable_uncorrectable?
|
12
|
+
autocorrect_requested? && disable_uncorrectable? && autocorrect_enabled?
|
13
|
+
end
|
14
|
+
|
11
15
|
def autocorrect_requested?
|
12
16
|
@options.fetch(:auto_correct, false)
|
13
17
|
end
|
@@ -46,11 +46,7 @@ module RuboCop
|
|
46
46
|
|
47
47
|
duplicated_gem_nodes.each do |nodes|
|
48
48
|
nodes[1..-1].each do |node|
|
49
|
-
register_offense(
|
50
|
-
node,
|
51
|
-
node.first_argument.to_a.first,
|
52
|
-
nodes.first.first_line
|
53
|
-
)
|
49
|
+
register_offense(node, node.first_argument.to_a.first, nodes.first.first_line)
|
54
50
|
end
|
55
51
|
end
|
56
52
|
end
|
@@ -52,11 +52,7 @@ module RuboCop
|
|
52
52
|
|
53
53
|
duplicated_assignment_method_nodes.each do |nodes|
|
54
54
|
nodes[1..-1].each do |node|
|
55
|
-
register_offense(
|
56
|
-
node,
|
57
|
-
node.method_name,
|
58
|
-
nodes.first.first_line
|
59
|
-
)
|
55
|
+
register_offense(node, node.method_name, nodes.first.first_line)
|
60
56
|
end
|
61
57
|
end
|
62
58
|
end
|
@@ -185,8 +185,7 @@ module RuboCop
|
|
185
185
|
|
186
186
|
def check_members_for_indented_internal_methods_style(members)
|
187
187
|
each_member(members) do |member, previous_modifier|
|
188
|
-
check_indentation(previous_modifier, member,
|
189
|
-
indentation_consistency_style)
|
188
|
+
check_indentation(previous_modifier, member, indentation_consistency_style)
|
190
189
|
end
|
191
190
|
end
|
192
191
|
|
@@ -105,10 +105,9 @@ module RuboCop
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def convertible_block?(node)
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
send_node.parenthesized? || !send_node.arguments?
|
108
|
+
parent = node.parent
|
109
|
+
parent&.block_type? && node == parent.send_node &&
|
110
|
+
(node.parenthesized? || !node.arguments?)
|
112
111
|
end
|
113
112
|
|
114
113
|
def comment_within?(node)
|
@@ -24,11 +24,11 @@ module RuboCop
|
|
24
24
|
extend AutoCorrector
|
25
25
|
|
26
26
|
AMBIGUITIES = {
|
27
|
-
'+' => { actual: 'positive number', possible: 'addition' },
|
28
|
-
'-' => { actual: 'negative number', possible: 'subtraction' },
|
29
|
-
'*' => { actual: 'splat', possible: 'multiplication' },
|
30
|
-
'&' => { actual: 'block', possible: 'binary AND' },
|
31
|
-
'**' => { actual: 'keyword splat', possible: 'exponent' }
|
27
|
+
'+' => { actual: 'positive number', possible: 'an addition' },
|
28
|
+
'-' => { actual: 'negative number', possible: 'a subtraction' },
|
29
|
+
'*' => { actual: 'splat', possible: 'a multiplication' },
|
30
|
+
'&' => { actual: 'block', possible: 'a binary AND' },
|
31
|
+
'**' => { actual: 'keyword splat', possible: 'an exponent' }
|
32
32
|
}.each do |key, hash|
|
33
33
|
hash[:operator] = key
|
34
34
|
end
|
@@ -36,7 +36,7 @@ module RuboCop
|
|
36
36
|
MSG_FORMAT = 'Ambiguous %<actual>s operator. Parenthesize the method ' \
|
37
37
|
"arguments if it's surely a %<actual>s operator, or add " \
|
38
38
|
'a whitespace to the right of the `%<operator>s` if it ' \
|
39
|
-
'should be
|
39
|
+
'should be %<possible>s.'
|
40
40
|
|
41
41
|
def on_new_investigation
|
42
42
|
processed_source.diagnostics.each do |diagnostic|
|
@@ -53,11 +53,13 @@ module RuboCop
|
|
53
53
|
# end
|
54
54
|
#
|
55
55
|
class EmptyConditionalBody < Base
|
56
|
+
include CommentsHelp
|
57
|
+
|
56
58
|
MSG = 'Avoid `%<keyword>s` branches without a body.'
|
57
59
|
|
58
60
|
def on_if(node)
|
59
61
|
return if node.body
|
60
|
-
return if cop_config['AllowComments'] &&
|
62
|
+
return if cop_config['AllowComments'] && contains_comments?(node)
|
61
63
|
|
62
64
|
add_offense(node, message: format(MSG, keyword: node.keyword))
|
63
65
|
end
|
@@ -44,6 +44,7 @@ module RuboCop
|
|
44
44
|
#
|
45
45
|
class EmptyInPattern < Base
|
46
46
|
extend TargetRubyVersion
|
47
|
+
include CommentsHelp
|
47
48
|
|
48
49
|
MSG = 'Avoid `in` branches without a body.'
|
49
50
|
|
@@ -51,7 +52,8 @@ module RuboCop
|
|
51
52
|
|
52
53
|
def on_case_match(node)
|
53
54
|
node.in_pattern_branches.each do |branch|
|
54
|
-
next if branch.body
|
55
|
+
next if branch.body
|
56
|
+
next if cop_config['AllowComments'] && contains_comments?(branch)
|
55
57
|
|
56
58
|
add_offense(branch)
|
57
59
|
end
|
@@ -45,12 +45,14 @@ module RuboCop
|
|
45
45
|
# end
|
46
46
|
#
|
47
47
|
class EmptyWhen < Base
|
48
|
+
include CommentsHelp
|
49
|
+
|
48
50
|
MSG = 'Avoid `when` branches without a body.'
|
49
51
|
|
50
52
|
def on_case(node)
|
51
53
|
node.each_when do |when_node|
|
52
54
|
next if when_node.body
|
53
|
-
next if cop_config['AllowComments'] &&
|
55
|
+
next if cop_config['AllowComments'] && contains_comments?(when_node)
|
54
56
|
|
55
57
|
add_offense(when_node)
|
56
58
|
end
|
@@ -6,6 +6,15 @@ module RuboCop
|
|
6
6
|
#
|
7
7
|
# This cop checks for `IO.select` that is incompatible with Fiber Scheduler since Ruby 3.0.
|
8
8
|
#
|
9
|
+
# NOTE: When the method is successful the return value of `IO.select` is `[[IO]]`,
|
10
|
+
# and the return value of `io.wait_readable` and `io.wait_writable` are `self`.
|
11
|
+
# They are not auto-corrected when assigning a return value because these types are different.
|
12
|
+
# It's up to user how to handle the return value.
|
13
|
+
#
|
14
|
+
# @safety
|
15
|
+
# This cop's autocorrection is unsafe because `NoMethodError` occurs
|
16
|
+
# if `require 'io/wait'` is not called.
|
17
|
+
#
|
9
18
|
# @example
|
10
19
|
#
|
11
20
|
# # bad
|
@@ -20,10 +29,6 @@ module RuboCop
|
|
20
29
|
# # good
|
21
30
|
# io.wait_writable(timeout)
|
22
31
|
#
|
23
|
-
# @safety
|
24
|
-
# This cop's autocorrection is unsafe because `NoMethodError` occurs
|
25
|
-
# if `require 'io/wait'` is not called.
|
26
|
-
#
|
27
32
|
class IncompatibleIoSelectWithFiberScheduler < Base
|
28
33
|
extend AutoCorrector
|
29
34
|
|
@@ -45,6 +50,8 @@ module RuboCop
|
|
45
50
|
message = format(MSG, preferred: preferred, current: node.source)
|
46
51
|
|
47
52
|
add_offense(node, message: message) do |corrector|
|
53
|
+
next if node.parent&.assignment?
|
54
|
+
|
48
55
|
corrector.replace(node, preferred)
|
49
56
|
end
|
50
57
|
end
|
@@ -31,8 +31,15 @@ module RuboCop
|
|
31
31
|
MSG = 'lambda without a literal block is deprecated; use the proc without lambda instead.'
|
32
32
|
RESTRICT_ON_SEND = %i[lambda].freeze
|
33
33
|
|
34
|
+
# @!method lambda_with_symbol_proc?(node)
|
35
|
+
def_node_matcher :lambda_with_symbol_proc?, <<~PATTERN
|
36
|
+
(send nil? :lambda (block_pass (sym _)))
|
37
|
+
PATTERN
|
38
|
+
|
34
39
|
def on_send(node)
|
35
|
-
|
40
|
+
if node.parent&.block_type? || !node.first_argument || lambda_with_symbol_proc?(node)
|
41
|
+
return
|
42
|
+
end
|
36
43
|
|
37
44
|
add_offense(node) do |corrector|
|
38
45
|
corrector.replace(node, node.first_argument.source.delete('&'))
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks if `include` or `prepend` is called in `refine` block.
|
7
|
+
# These methods are deprecated and should be replaced with `Refinement#import_methods`.
|
8
|
+
#
|
9
|
+
# It emulates deprecation warnings in Ruby 3.1.
|
10
|
+
#
|
11
|
+
# @safety
|
12
|
+
# This cop's autocorrection is unsafe because `include M` will affect the included class
|
13
|
+
# if any changes are made to module `M`.
|
14
|
+
# On the other hand, `import_methods M` uses a snapshot of method definitions,
|
15
|
+
# thus it will not be affected if module `M` changes.
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
#
|
19
|
+
# # bad
|
20
|
+
# refine Foo do
|
21
|
+
# include Bar
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# # bad
|
25
|
+
# refine Foo do
|
26
|
+
# prepend Bar
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# refine Foo do
|
31
|
+
# import_methods Bar
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
class RefinementImportMethods < Base
|
35
|
+
extend TargetRubyVersion
|
36
|
+
|
37
|
+
MSG = 'Use `import_methods` instead of `%<current>s` because it is deprecated in Ruby 3.1.'
|
38
|
+
RESTRICT_ON_SEND = %i[include prepend].freeze
|
39
|
+
|
40
|
+
minimum_target_ruby_version 3.1
|
41
|
+
|
42
|
+
def on_send(node)
|
43
|
+
return if node.receiver
|
44
|
+
return unless node.parent.block_type? && node.parent.method?(:refine)
|
45
|
+
|
46
|
+
add_offense(node.loc.selector, message: format(MSG, current: node.method_name))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -57,10 +57,20 @@ module RuboCop
|
|
57
57
|
|
58
58
|
outer_local_variable = variable_table.find_variable(variable.name)
|
59
59
|
return unless outer_local_variable
|
60
|
+
return if same_conditions_node_different_branch?(variable, outer_local_variable)
|
60
61
|
|
61
62
|
message = format(MSG, variable: variable.name)
|
62
63
|
add_offense(variable.declaration_node, message: message)
|
63
64
|
end
|
65
|
+
|
66
|
+
def same_conditions_node_different_branch?(variable, outer_local_variable)
|
67
|
+
variable_node = variable.scope.node.parent
|
68
|
+
return false unless variable_node.conditional?
|
69
|
+
|
70
|
+
outer_local_variable_node = outer_local_variable.scope.node
|
71
|
+
|
72
|
+
outer_local_variable_node.conditional? && variable_node == outer_local_variable_node
|
73
|
+
end
|
64
74
|
end
|
65
75
|
end
|
66
76
|
end
|
@@ -9,8 +9,7 @@ module RuboCop
|
|
9
9
|
def on_other_file
|
10
10
|
add_offense_from_error(processed_source.parser_error) if processed_source.parser_error
|
11
11
|
processed_source.diagnostics.each do |diagnostic|
|
12
|
-
add_offense_from_diagnostic(diagnostic,
|
13
|
-
processed_source.ruby_version)
|
12
|
+
add_offense_from_diagnostic(diagnostic, processed_source.ruby_version)
|
14
13
|
end
|
15
14
|
super
|
16
15
|
end
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
64
64
|
|
65
65
|
# @!method not_implemented?(node)
|
66
66
|
def_node_matcher :not_implemented?, <<~PATTERN
|
67
|
-
{(send nil? :raise (const {nil? cbase} :NotImplementedError))
|
67
|
+
{(send nil? :raise (const {nil? cbase} :NotImplementedError) ...)
|
68
68
|
(send nil? :fail ...)}
|
69
69
|
PATTERN
|
70
70
|
|
@@ -101,8 +101,7 @@ module RuboCop
|
|
101
101
|
children = node.masgn_type? ? node.children[0].children : node.children
|
102
102
|
|
103
103
|
will_be_miscounted = children.count do |child|
|
104
|
-
child.respond_to?(:setter_method?) &&
|
105
|
-
!child.setter_method?
|
104
|
+
child.respond_to?(:setter_method?) && !child.setter_method?
|
106
105
|
end
|
107
106
|
@assignment += will_be_miscounted
|
108
107
|
|
@@ -4,8 +4,6 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
# Help methods for working with nodes containing comments.
|
6
6
|
module CommentsHelp
|
7
|
-
include VisibilityHelp
|
8
|
-
|
9
7
|
def source_range_with_comment(node)
|
10
8
|
begin_pos = begin_pos_with_comment(node)
|
11
9
|
end_pos = end_position_for(node)
|
@@ -13,6 +11,13 @@ module RuboCop
|
|
13
11
|
Parser::Source::Range.new(buffer, begin_pos, end_pos)
|
14
12
|
end
|
15
13
|
|
14
|
+
def contains_comments?(node)
|
15
|
+
start_line = node.source_range.line
|
16
|
+
end_line = find_end_line(node)
|
17
|
+
|
18
|
+
processed_source.each_comment_in_lines(start_line...end_line).any?
|
19
|
+
end
|
20
|
+
|
16
21
|
private
|
17
22
|
|
18
23
|
def end_position_for(node)
|
@@ -37,6 +42,21 @@ module RuboCop
|
|
37
42
|
def buffer
|
38
43
|
processed_source.buffer
|
39
44
|
end
|
45
|
+
|
46
|
+
# Returns the end line of a node, which might be a comment and not part of the AST
|
47
|
+
# End line is considered either the line at which another node starts, or
|
48
|
+
# the line at which the parent node ends.
|
49
|
+
def find_end_line(node)
|
50
|
+
if node.if_type? && node.loc.else
|
51
|
+
node.loc.else.line
|
52
|
+
elsif (next_sibling = node.right_sibling)
|
53
|
+
next_sibling.loc.line
|
54
|
+
elsif (parent = node.parent)
|
55
|
+
parent.loc.end.line
|
56
|
+
else
|
57
|
+
node.loc.end.line
|
58
|
+
end
|
59
|
+
end
|
40
60
|
end
|
41
61
|
end
|
42
62
|
end
|
@@ -65,9 +65,8 @@ module RuboCop
|
|
65
65
|
|
66
66
|
def use_modifier_form_without_parenthesized_method_call?(ancestor)
|
67
67
|
return false if ancestor.respond_to?(:parenthesized?) && ancestor.parenthesized?
|
68
|
-
return false unless (parent = ancestor.parent)
|
69
68
|
|
70
|
-
|
69
|
+
ancestor.ancestors.any? { |node| node.respond_to?(:modifier_form?) && node.modifier_form? }
|
71
70
|
end
|
72
71
|
|
73
72
|
def without_parentheses_call_expr_follows?(ancestor)
|
@@ -196,8 +196,7 @@ module RuboCop
|
|
196
196
|
|
197
197
|
def not_for_this_cop?(node)
|
198
198
|
node.ancestors.any? do |ancestor|
|
199
|
-
grouped_expression?(ancestor) ||
|
200
|
-
inside_arg_list_parentheses?(node, ancestor)
|
199
|
+
grouped_expression?(ancestor) || inside_arg_list_parentheses?(node, ancestor)
|
201
200
|
end
|
202
201
|
end
|
203
202
|
|
@@ -44,7 +44,8 @@ module RuboCop
|
|
44
44
|
if extra_space?(left_token, :left) && !start_ok
|
45
45
|
space_offense(node, left_token, :right, message, NO_SPACE_COMMAND)
|
46
46
|
end
|
47
|
-
return if !extra_space?(right_token, :right) || end_ok
|
47
|
+
return if (!extra_space?(right_token, :right) || end_ok) ||
|
48
|
+
(autocorrect_with_disable_uncorrectable? && !start_ok)
|
48
49
|
|
49
50
|
space_offense(node, right_token, :left, message, NO_SPACE_COMMAND)
|
50
51
|
end
|
@@ -58,7 +59,8 @@ module RuboCop
|
|
58
59
|
unless extra_space?(left_token, :left) || start_ok
|
59
60
|
space_offense(node, left_token, :none, message, SPACE_COMMAND)
|
60
61
|
end
|
61
|
-
return if extra_space?(right_token, :right) || end_ok
|
62
|
+
return if (extra_space?(right_token, :right) || end_ok) ||
|
63
|
+
(autocorrect_with_disable_uncorrectable? && !start_ok)
|
62
64
|
|
63
65
|
space_offense(node, right_token, :none, message, SPACE_COMMAND)
|
64
66
|
end
|
@@ -107,7 +107,7 @@ module RuboCop
|
|
107
107
|
def use_block_argument_as_local_variable?(node, last_argument)
|
108
108
|
return if node.body.nil?
|
109
109
|
|
110
|
-
node.body.each_descendant(:lvar).any? do |lvar|
|
110
|
+
node.body.each_descendant(:lvar, :lvasgn).any? do |lvar|
|
111
111
|
!lvar.parent.block_pass_type? && lvar.source == last_argument
|
112
112
|
end
|
113
113
|
end
|
@@ -72,9 +72,14 @@ module RuboCop
|
|
72
72
|
def end_of_method_definition?(node)
|
73
73
|
return false unless (def_node = find_def_node_from_ascendant(node))
|
74
74
|
|
75
|
+
conditional_node = find_conditional_node_from_ascendant(node)
|
75
76
|
last_child = find_last_child(def_node.body)
|
76
77
|
|
77
|
-
|
78
|
+
if conditional_node
|
79
|
+
double_negative_condition_return_value?(node, last_child, conditional_node)
|
80
|
+
else
|
81
|
+
last_child.last_line == node.last_line
|
82
|
+
end
|
78
83
|
end
|
79
84
|
|
80
85
|
def find_def_node_from_ascendant(node)
|
@@ -84,6 +89,13 @@ module RuboCop
|
|
84
89
|
find_def_node_from_ascendant(node.parent)
|
85
90
|
end
|
86
91
|
|
92
|
+
def find_conditional_node_from_ascendant(node)
|
93
|
+
return unless (parent = node.parent)
|
94
|
+
return parent if parent.conditional?
|
95
|
+
|
96
|
+
find_conditional_node_from_ascendant(parent)
|
97
|
+
end
|
98
|
+
|
87
99
|
def find_last_child(node)
|
88
100
|
case node.type
|
89
101
|
when :rescue
|
@@ -94,6 +106,25 @@ module RuboCop
|
|
94
106
|
node.child_nodes.last
|
95
107
|
end
|
96
108
|
end
|
109
|
+
|
110
|
+
def double_negative_condition_return_value?(node, last_child, conditional_node)
|
111
|
+
parent = find_parent_not_enumerable(node)
|
112
|
+
if parent.begin_type?
|
113
|
+
node.loc.line == parent.loc.last_line
|
114
|
+
else
|
115
|
+
last_child.last_line <= conditional_node.last_line
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def find_parent_not_enumerable(node)
|
120
|
+
return unless (parent = node.parent)
|
121
|
+
|
122
|
+
if parent.pair_type? || parent.hash_type? || parent.array_type?
|
123
|
+
find_parent_not_enumerable(parent)
|
124
|
+
else
|
125
|
+
parent
|
126
|
+
end
|
127
|
+
end
|
97
128
|
end
|
98
129
|
end
|
99
130
|
end
|
@@ -47,8 +47,7 @@ module RuboCop
|
|
47
47
|
branch_bodies = [*case_node.when_branches.map(&:body), case_node.else_branch].compact
|
48
48
|
|
49
49
|
return if branch_bodies.any? do |body|
|
50
|
-
body.return_type? ||
|
51
|
-
body.each_descendant.any?(&:return_type?)
|
50
|
+
body.return_type? || body.each_descendant.any?(&:return_type?)
|
52
51
|
end
|
53
52
|
|
54
53
|
add_offense(case_node.loc.keyword) { |corrector| autocorrect(corrector, case_node) }
|
@@ -5,6 +5,17 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Favor `File.(bin)write` convenience methods.
|
7
7
|
#
|
8
|
+
# NOTE: There are different method signatures between `File.write` (class method)
|
9
|
+
# and `File#write` (instance method). The following case will be allowed because
|
10
|
+
# static analysis does not know the contents of the splat argument:
|
11
|
+
#
|
12
|
+
# [source,ruby]
|
13
|
+
# ----
|
14
|
+
# File.open(filename, 'w') do |f|
|
15
|
+
# f.write(*objects)
|
16
|
+
# end
|
17
|
+
# ----
|
18
|
+
#
|
8
19
|
# @example
|
9
20
|
# ## text mode
|
10
21
|
# # bad
|
@@ -85,6 +96,7 @@ module RuboCop
|
|
85
96
|
content = send_write?(node) || block_write?(node) do |block_arg, lvar, write_arg|
|
86
97
|
write_arg if block_arg == lvar
|
87
98
|
end
|
99
|
+
return false if content&.splat_type?
|
88
100
|
|
89
101
|
yield(content) if content
|
90
102
|
end
|
@@ -107,8 +107,7 @@ module RuboCop
|
|
107
107
|
|
108
108
|
first_arg = node.first_argument
|
109
109
|
|
110
|
-
return
|
111
|
-
return if acceptable_exploded_args?(first_arg.arguments)
|
110
|
+
return if !use_new_method?(first_arg) || acceptable_exploded_args?(first_arg.arguments)
|
112
111
|
|
113
112
|
return if allowed_non_exploded_type?(first_arg)
|
114
113
|
|
@@ -120,6 +119,10 @@ module RuboCop
|
|
120
119
|
end
|
121
120
|
end
|
122
121
|
|
122
|
+
def use_new_method?(first_arg)
|
123
|
+
first_arg.send_type? && first_arg.receiver && first_arg.method?(:new)
|
124
|
+
end
|
125
|
+
|
123
126
|
def acceptable_exploded_args?(args)
|
124
127
|
# Allow code like `raise Ex.new(arg1, arg2)`.
|
125
128
|
return true if args.size > 1
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for `initialize` methods that are redundant.
|
7
|
+
#
|
8
|
+
# An initializer is redundant if it does not do anything, or if it only
|
9
|
+
# calls `super` with the same arguments given to it. If the initializer takes
|
10
|
+
# an argument that accepts multiple values (`restarg`, `kwrestarg`, etc.) it
|
11
|
+
# will not register an offense, because it allows the initializer to take a different
|
12
|
+
# number of arguments as its superclass potentially does.
|
13
|
+
#
|
14
|
+
# NOTE: If an initializer argument has a default value, RuboCop assumes it
|
15
|
+
# to *not* be redundant.
|
16
|
+
#
|
17
|
+
# NOTE: Empty initializers are registered as offenses, but it is possible
|
18
|
+
# to purposely create an empty `initialize` method to override a superclass's
|
19
|
+
# initializer.
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# # bad
|
23
|
+
# def initialize
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # bad
|
27
|
+
# def initialize
|
28
|
+
# super
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# # bad
|
32
|
+
# def initialize(a, b)
|
33
|
+
# super
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# # bad
|
37
|
+
# def initialize(a, b)
|
38
|
+
# super(a, b)
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# # good
|
42
|
+
# def initialize
|
43
|
+
# do_something
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# # good
|
47
|
+
# def initialize
|
48
|
+
# do_something
|
49
|
+
# super
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# # good (different number of parameters)
|
53
|
+
# def initialize(a, b)
|
54
|
+
# super(a)
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# # good (default value)
|
58
|
+
# def initialize(a, b = 5)
|
59
|
+
# super
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# # good (default value)
|
63
|
+
# def initialize(a, b: 5)
|
64
|
+
# super
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# # good (changes the parameter requirements)
|
68
|
+
# def initialize(*)
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# # good (changes the parameter requirements)
|
72
|
+
# def initialize(**)
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# # good (changes the parameter requirements)
|
76
|
+
# def initialize(...)
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
class RedundantInitialize < Base
|
80
|
+
MSG = 'Remove unnecessary `initialize` method.'
|
81
|
+
MSG_EMPTY = 'Remove unnecessary empty `initialize` method.'
|
82
|
+
|
83
|
+
# @!method initialize_forwards?(node)
|
84
|
+
def_node_matcher :initialize_forwards?, <<~PATTERN
|
85
|
+
(def _ (args $arg*) $({super zsuper} ...))
|
86
|
+
PATTERN
|
87
|
+
|
88
|
+
def on_def(node)
|
89
|
+
return unless node.method?(:initialize)
|
90
|
+
return if forwards?(node)
|
91
|
+
|
92
|
+
if node.body.nil?
|
93
|
+
add_offense(node, message: MSG_EMPTY)
|
94
|
+
else
|
95
|
+
return if node.body.begin_type?
|
96
|
+
|
97
|
+
if (args, super_node = initialize_forwards?(node))
|
98
|
+
return unless same_args?(super_node, args)
|
99
|
+
|
100
|
+
add_offense(node)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def forwards?(node)
|
108
|
+
node.arguments.each_child_node(:restarg, :kwrestarg, :forward_args, :forward_arg).any?
|
109
|
+
end
|
110
|
+
|
111
|
+
def same_args?(super_node, args)
|
112
|
+
return true if super_node.zsuper_type?
|
113
|
+
|
114
|
+
args.map(&:name) == super_node.arguments.map { |a| a.children[0] }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -7,8 +7,7 @@ module RuboCop
|
|
7
7
|
# check for the variable whose method is being called to
|
8
8
|
# safe navigation (`&.`). If there is a method chain, all of the methods
|
9
9
|
# in the chain need to be checked for safety, and all of the methods will
|
10
|
-
# need to be changed to use safe navigation.
|
11
|
-
# not register an offense for method chains that exceed 2 methods.
|
10
|
+
# need to be changed to use safe navigation.
|
12
11
|
#
|
13
12
|
# The default for `ConvertCodeThatCanStartToReturnNil` is `false`.
|
14
13
|
# When configured to `true`, this will
|
@@ -18,6 +17,10 @@ module RuboCop
|
|
18
17
|
# `foo&.bar` can start returning `nil` as well as what the method
|
19
18
|
# returns.
|
20
19
|
#
|
20
|
+
# The default for `MaxChainLength` is `2`
|
21
|
+
# We have limited the cop to not register an offense for method chains
|
22
|
+
# that exceed this option is set.
|
23
|
+
#
|
21
24
|
# @safety
|
22
25
|
# Autocorrection is unsafe because if a value is `false`, the resulting
|
23
26
|
# code will have different behaviour or raise an error.
|
@@ -116,9 +119,7 @@ module RuboCop
|
|
116
119
|
checked_variable, receiver, method_chain, method = extract_parts(node)
|
117
120
|
return unless receiver == checked_variable
|
118
121
|
return if use_var_only_in_unless_modifier?(node, checked_variable)
|
119
|
-
|
120
|
-
# chain greater than 2
|
121
|
-
return if chain_size(method_chain, method) > 1
|
122
|
+
return if chain_length(method_chain, method) > max_chain_length
|
122
123
|
return if unsafe_method_used?(method_chain, method)
|
123
124
|
return if method_chain.method?(:empty?)
|
124
125
|
|
@@ -225,8 +226,8 @@ module RuboCop
|
|
225
226
|
find_matching_receiver_invocation(receiver, checked_variable)
|
226
227
|
end
|
227
228
|
|
228
|
-
def
|
229
|
-
method.each_ancestor(:send).inject(
|
229
|
+
def chain_length(method_chain, method)
|
230
|
+
method.each_ancestor(:send).inject(1) do |total, ancestor|
|
230
231
|
break total + 1 if ancestor == method_chain
|
231
232
|
|
232
233
|
total + 1
|
@@ -281,6 +282,10 @@ module RuboCop
|
|
281
282
|
break if ancestor == method_chain
|
282
283
|
end
|
283
284
|
end
|
285
|
+
|
286
|
+
def max_chain_length
|
287
|
+
cop_config.fetch('MaxChainLength', 2)
|
288
|
+
end
|
284
289
|
end
|
285
290
|
end
|
286
291
|
end
|
@@ -184,8 +184,7 @@ module RuboCop
|
|
184
184
|
|
185
185
|
def unsafe_autocorrect?(condition)
|
186
186
|
condition.children.any? do |child|
|
187
|
-
unparenthesized_method_call?(child) ||
|
188
|
-
below_ternary_precedence?(child)
|
187
|
+
unparenthesized_method_call?(child) || below_ternary_precedence?(child)
|
189
188
|
end
|
190
189
|
end
|
191
190
|
|
@@ -42,10 +42,7 @@ module RuboCop
|
|
42
42
|
return if node.endless? || !trailing_end?(node)
|
43
43
|
|
44
44
|
add_offense(node.loc.end) do |corrector|
|
45
|
-
corrector.insert_before(
|
46
|
-
node.loc.end,
|
47
|
-
"\n#{' ' * node.loc.keyword.column}"
|
48
|
-
)
|
45
|
+
corrector.insert_before(node.loc.end, "\n#{' ' * node.loc.keyword.column}")
|
49
46
|
end
|
50
47
|
end
|
51
48
|
|
@@ -17,6 +17,7 @@ module RuboCop
|
|
17
17
|
def started(target_files)
|
18
18
|
super
|
19
19
|
@offense_counts = Hash.new(0)
|
20
|
+
@style_guide_links = {}
|
20
21
|
|
21
22
|
return unless output.tty?
|
22
23
|
|
@@ -37,6 +38,9 @@ module RuboCop
|
|
37
38
|
|
38
39
|
def file_finished(_file, offenses)
|
39
40
|
offenses.each { |o| @offense_counts[o.cop_name] += 1 }
|
41
|
+
if options[:display_style_guide]
|
42
|
+
offenses.each { |o| @style_guide_links[o.cop_name] ||= o.message[/ \(http\S+\)\Z/] }
|
43
|
+
end
|
40
44
|
@progressbar.increment if instance_variable_defined?(:@progressbar)
|
41
45
|
end
|
42
46
|
|
@@ -52,8 +56,8 @@ module RuboCop
|
|
52
56
|
output.puts
|
53
57
|
|
54
58
|
per_cop_counts.each do |cop_name, count|
|
55
|
-
output.puts "#{count.to_s.ljust(total_count.to_s.length + 2)}" \
|
56
|
-
"#{cop_name}\n"
|
59
|
+
output.puts "#{count.to_s.ljust(total_count.to_s.length + 2)}#{cop_name}" \
|
60
|
+
"#{@style_guide_links[cop_name]}\n"
|
57
61
|
end
|
58
62
|
output.puts '--'
|
59
63
|
output.puts "#{total_count} Total"
|
@@ -40,8 +40,7 @@ module RuboCop
|
|
40
40
|
output.puts
|
41
41
|
|
42
42
|
per_file_counts.each do |file_name, count|
|
43
|
-
output.puts "#{count.to_s.ljust(total_count.to_s.length + 2)}"
|
44
|
-
"#{file_name}\n"
|
43
|
+
output.puts "#{count.to_s.ljust(total_count.to_s.length + 2)}#{file_name}\n"
|
45
44
|
end
|
46
45
|
output.puts '--'
|
47
46
|
output.puts "#{total_count} Total"
|
data/lib/rubocop/result_cache.rb
CHANGED
@@ -73,7 +73,15 @@ module RuboCop
|
|
73
73
|
# access.
|
74
74
|
File.join(ENV['XDG_CACHE_HOME'], Process.uid.to_s)
|
75
75
|
else
|
76
|
-
|
76
|
+
# On FreeBSD, the /home path is a symbolic link to /usr/home
|
77
|
+
# and the $HOME environment variable returns the /home path.
|
78
|
+
#
|
79
|
+
# As $HOME is a built-in environment variable, FreeBSD users
|
80
|
+
# always get a warning message.
|
81
|
+
#
|
82
|
+
# To avoid raising warn log messages on FreeBSD, we retrieve
|
83
|
+
# the real path of the home folder.
|
84
|
+
File.join(File.realpath(ENV['HOME']), '.cache')
|
77
85
|
end
|
78
86
|
File.join(root, 'rubocop_cache')
|
79
87
|
end
|
data/lib/rubocop/version.rb
CHANGED
data/lib/rubocop.rb
CHANGED
@@ -348,6 +348,7 @@ require_relative 'rubocop/cop/lint/redundant_splat_expansion'
|
|
348
348
|
require_relative 'rubocop/cop/lint/redundant_string_coercion'
|
349
349
|
require_relative 'rubocop/cop/lint/redundant_with_index'
|
350
350
|
require_relative 'rubocop/cop/lint/redundant_with_object'
|
351
|
+
require_relative 'rubocop/cop/lint/refinement_import_methods'
|
351
352
|
require_relative 'rubocop/cop/lint/regexp_as_condition'
|
352
353
|
require_relative 'rubocop/cop/lint/require_parentheses'
|
353
354
|
require_relative 'rubocop/cop/lint/require_relative_self_path'
|
@@ -527,6 +528,7 @@ require_relative 'rubocop/cop/style/open_struct_use'
|
|
527
528
|
require_relative 'rubocop/cop/style/redundant_assignment'
|
528
529
|
require_relative 'rubocop/cop/style/redundant_fetch_block'
|
529
530
|
require_relative 'rubocop/cop/style/redundant_file_extension_in_require'
|
531
|
+
require_relative 'rubocop/cop/style/redundant_initialize'
|
530
532
|
require_relative 'rubocop/cop/style/redundant_self_assignment'
|
531
533
|
require_relative 'rubocop/cop/style/redundant_self_assignment_branch'
|
532
534
|
require_relative 'rubocop/cop/style/sole_nested_conditional'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.27.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-
|
13
|
+
date: 2022-04-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: parallel
|
@@ -460,6 +460,7 @@ files:
|
|
460
460
|
- lib/rubocop/cop/lint/redundant_string_coercion.rb
|
461
461
|
- lib/rubocop/cop/lint/redundant_with_index.rb
|
462
462
|
- lib/rubocop/cop/lint/redundant_with_object.rb
|
463
|
+
- lib/rubocop/cop/lint/refinement_import_methods.rb
|
463
464
|
- lib/rubocop/cop/lint/regexp_as_condition.rb
|
464
465
|
- lib/rubocop/cop/lint/require_parentheses.rb
|
465
466
|
- lib/rubocop/cop/lint/require_relative_self_path.rb
|
@@ -778,6 +779,7 @@ files:
|
|
778
779
|
- lib/rubocop/cop/style/redundant_fetch_block.rb
|
779
780
|
- lib/rubocop/cop/style/redundant_file_extension_in_require.rb
|
780
781
|
- lib/rubocop/cop/style/redundant_freeze.rb
|
782
|
+
- lib/rubocop/cop/style/redundant_initialize.rb
|
781
783
|
- lib/rubocop/cop/style/redundant_interpolation.rb
|
782
784
|
- lib/rubocop/cop/style/redundant_parentheses.rb
|
783
785
|
- lib/rubocop/cop/style/redundant_percent_q.rb
|
@@ -913,7 +915,7 @@ metadata:
|
|
913
915
|
homepage_uri: https://rubocop.org/
|
914
916
|
changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
|
915
917
|
source_code_uri: https://github.com/rubocop/rubocop/
|
916
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
918
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.27/
|
917
919
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
918
920
|
rubygems_mfa_required: 'true'
|
919
921
|
post_install_message:
|