rubocop 1.72.2 → 1.73.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 +3 -3
- data/config/default.yml +21 -11
- data/config/internal_affairs.yml +16 -0
- data/lib/rubocop/config_loader_resolver.rb +2 -2
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +26 -1
- data/lib/rubocop/cop/layout/line_length.rb +3 -3
- data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -14
- data/lib/rubocop/cop/lint/float_comparison.rb +1 -6
- data/lib/rubocop/cop/lint/literal_as_condition.rb +104 -7
- data/lib/rubocop/cop/lint/mixed_case_range.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +23 -2
- data/lib/rubocop/cop/lint/void.rb +6 -0
- data/lib/rubocop/cop/mixin/hash_subset.rb +19 -4
- data/lib/rubocop/cop/mixin/trailing_comma.rb +12 -0
- data/lib/rubocop/cop/naming/variable_name.rb +64 -6
- data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
- data/lib/rubocop/cop/style/endless_method.rb +163 -18
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +34 -0
- data/lib/rubocop/cop/style/redundant_format.rb +23 -11
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -3
- data/lib/rubocop/cop/style/string_concatenation.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +12 -1
- data/lib/rubocop/plugin/load_error.rb +1 -1
- data/lib/rubocop/plugin.rb +9 -2
- data/lib/rubocop/rspec/shared_contexts.rb +15 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +0 -1
- metadata +4 -5
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3d6b4b7f7dd2a3128259ff94614da64550ae7c4148106a681987a9ee739b905
|
4
|
+
data.tar.gz: 023ed07c7e4445c1dc44b3062cf0199321e3cc7fc6d4abf55287d281519bdb11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfc82c25468c882682017c7ab8f750970896dcacae270fc00fc6482e4a7d12a20c97f7f56509811fec8c811981be457fc450c977c058d72700490ae72a4aff0a
|
7
|
+
data.tar.gz: 04cfd985c5527d40ba6fd11e33e64278f37b8fcd78a63cfcdf5fef317bef248bfc8771febfa39a05a474372c1ad56190766dc7a188ea9e17bc72031f16d672da
|
data/README.md
CHANGED
@@ -52,7 +52,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
52
52
|
in your `Gemfile`:
|
53
53
|
|
54
54
|
```rb
|
55
|
-
gem 'rubocop', '~> 1.
|
55
|
+
gem 'rubocop', '~> 1.73', require: false
|
56
56
|
```
|
57
57
|
|
58
58
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
@@ -241,9 +241,9 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
|
|
241
241
|
<a href="https://opencollective.com/rubocop/organization/28/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/28/avatar.svg"></a>
|
242
242
|
<a href="https://opencollective.com/rubocop/organization/29/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/29/avatar.svg"></a>
|
243
243
|
|
244
|
-
##
|
244
|
+
## Release Notes
|
245
245
|
|
246
|
-
RuboCop's
|
246
|
+
RuboCop's release notes are available [here](https://github.com/rubocop/rubocop/releases).
|
247
247
|
|
248
248
|
## Copyright
|
249
249
|
|
data/config/default.yml
CHANGED
@@ -2046,6 +2046,7 @@ Lint/LambdaWithoutLiteralBlock:
|
|
2046
2046
|
Lint/LiteralAsCondition:
|
2047
2047
|
Description: 'Checks of literals used in conditions.'
|
2048
2048
|
Enabled: true
|
2049
|
+
AutoCorrect: contextual
|
2049
2050
|
VersionAdded: '0.51'
|
2050
2051
|
|
2051
2052
|
Lint/LiteralAssignmentInCondition:
|
@@ -2259,9 +2260,8 @@ Lint/RedundantRegexpQuantifiers:
|
|
2259
2260
|
Lint/RedundantRequireStatement:
|
2260
2261
|
Description: 'Checks for unnecessary `require` statement.'
|
2261
2262
|
Enabled: true
|
2262
|
-
SafeAutoCorrect: false
|
2263
2263
|
VersionAdded: '0.76'
|
2264
|
-
VersionChanged: '1.
|
2264
|
+
VersionChanged: '1.73'
|
2265
2265
|
|
2266
2266
|
Lint/RedundantSafeNavigation:
|
2267
2267
|
Description: 'Checks for redundant safe navigation calls.'
|
@@ -3081,13 +3081,15 @@ Naming/VariableName:
|
|
3081
3081
|
StyleGuide: '#snake-case-symbols-methods-vars'
|
3082
3082
|
Enabled: true
|
3083
3083
|
VersionAdded: '0.50'
|
3084
|
-
VersionChanged: '1.
|
3084
|
+
VersionChanged: '1.73'
|
3085
3085
|
EnforcedStyle: snake_case
|
3086
3086
|
SupportedStyles:
|
3087
3087
|
- snake_case
|
3088
3088
|
- camelCase
|
3089
3089
|
AllowedIdentifiers: []
|
3090
3090
|
AllowedPatterns: []
|
3091
|
+
ForbiddenIdentifiers: []
|
3092
|
+
ForbiddenPatterns: []
|
3091
3093
|
|
3092
3094
|
Naming/VariableNumber:
|
3093
3095
|
Description: 'Use the configured style when numbering symbols, methods and variables.'
|
@@ -3922,6 +3924,8 @@ Style/EndlessMethod:
|
|
3922
3924
|
- allow_single_line
|
3923
3925
|
- allow_always
|
3924
3926
|
- disallow
|
3927
|
+
- require_single_line
|
3928
|
+
- require_always
|
3925
3929
|
|
3926
3930
|
Style/EnvHome:
|
3927
3931
|
Description: "Checks for consistent usage of `ENV['HOME']`."
|
@@ -5701,14 +5705,17 @@ Style/TrailingCommaInArrayLiteral:
|
|
5701
5705
|
StyleGuide: '#no-trailing-array-commas'
|
5702
5706
|
Enabled: true
|
5703
5707
|
VersionAdded: '0.53'
|
5704
|
-
# If `comma`, the cop requires a comma after the last item in an array,
|
5705
|
-
#
|
5706
|
-
# If `consistent_comma`, the cop requires a comma after the last item of all
|
5707
|
-
#
|
5708
|
+
# If `comma`, the cop requires a comma after the last item in an array, but only when each item is
|
5709
|
+
# on its own line.
|
5710
|
+
# If `consistent_comma`, the cop requires a comma after the last item of all non-empty, multiline
|
5711
|
+
# array literals.
|
5712
|
+
# If `diff_comma`, the cop requires a comma after the last item of all non-empty, multiline array
|
5713
|
+
# literals, but only when that last item immediately precedes a newline.
|
5708
5714
|
EnforcedStyleForMultiline: no_comma
|
5709
5715
|
SupportedStylesForMultiline:
|
5710
5716
|
- comma
|
5711
5717
|
- consistent_comma
|
5718
|
+
- diff_comma
|
5712
5719
|
- no_comma
|
5713
5720
|
|
5714
5721
|
Style/TrailingCommaInBlockArgs:
|
@@ -5720,14 +5727,17 @@ Style/TrailingCommaInBlockArgs:
|
|
5720
5727
|
Style/TrailingCommaInHashLiteral:
|
5721
5728
|
Description: 'Checks for trailing comma in hash literals.'
|
5722
5729
|
Enabled: true
|
5723
|
-
# If `comma`, the cop requires a comma after the last item in a hash,
|
5724
|
-
#
|
5725
|
-
# If `consistent_comma`, the cop requires a comma after the last item of all
|
5726
|
-
#
|
5730
|
+
# If `comma`, the cop requires a comma after the last item in a hash, but only when each item is
|
5731
|
+
# on its own line.
|
5732
|
+
# If `consistent_comma`, the cop requires a comma after the last item of all non-empty, multiline
|
5733
|
+
# hash literals.
|
5734
|
+
# If `diff_comma`, the cop requires a comma after the last item of all non-empty, multiline hash
|
5735
|
+
# literals, but only when that last item immediately precedes a newline.
|
5727
5736
|
EnforcedStyleForMultiline: no_comma
|
5728
5737
|
SupportedStylesForMultiline:
|
5729
5738
|
- comma
|
5730
5739
|
- consistent_comma
|
5740
|
+
- diff_comma
|
5731
5741
|
- no_comma
|
5732
5742
|
VersionAdded: '0.53'
|
5733
5743
|
|
data/config/internal_affairs.yml
CHANGED
@@ -6,6 +6,22 @@ InternalAffairs/CopDescription:
|
|
6
6
|
Include:
|
7
7
|
- 'lib/rubocop/cop/**/*.rb'
|
8
8
|
|
9
|
+
InternalAffairs/ExampleHeredocDelimiter:
|
10
|
+
Include:
|
11
|
+
- 'spec/rubocop/cop/**/*.rb'
|
12
|
+
|
13
|
+
InternalAffairs/ExampleDescription:
|
14
|
+
Include:
|
15
|
+
- 'spec/rubocop/cop/**/*.rb'
|
16
|
+
|
17
|
+
InternalAffairs/OnSendWithoutOnCSend:
|
18
|
+
Include:
|
19
|
+
- 'lib/rubocop/cop/**/*.rb'
|
20
|
+
|
21
|
+
InternalAffairs/UndefinedConfig:
|
22
|
+
Include:
|
23
|
+
- 'lib/rubocop/cop/**/*.rb'
|
24
|
+
|
9
25
|
InternalAffairs/UselessMessageAssertion:
|
10
26
|
Include:
|
11
27
|
- '**/*_spec.rb'
|
@@ -123,7 +123,7 @@ module RuboCop
|
|
123
123
|
elsif merge_hashes?(base_hash, derived_hash, key)
|
124
124
|
result[key] = merge(base_hash[key], derived_hash[key], **opts)
|
125
125
|
elsif should_union?(derived_hash, base_hash, opts[:inherit_mode], key)
|
126
|
-
result[key] = base_hash[key] | derived_hash[key]
|
126
|
+
result[key] = Array(base_hash[key]) | Array(derived_hash[key])
|
127
127
|
elsif opts[:debug]
|
128
128
|
warn_on_duplicate_setting(base_hash, derived_hash, key, **opts)
|
129
129
|
end
|
@@ -205,7 +205,7 @@ module RuboCop
|
|
205
205
|
end
|
206
206
|
|
207
207
|
def should_union?(derived_hash, base_hash, root_mode, key)
|
208
|
-
return false unless base_hash[key].is_a?(Array)
|
208
|
+
return false unless base_hash[key].is_a?(Array) || derived_hash[key].is_a?(Array)
|
209
209
|
|
210
210
|
derived_mode = derived_hash['inherit_mode']
|
211
211
|
return false if should_override?(derived_mode, key)
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
9
9
|
|
10
10
|
# @api private
|
11
11
|
COMMON_PARAMS = %w[Exclude Include Severity inherit_mode AutoCorrect StyleGuide Details
|
12
|
-
Enabled].freeze
|
12
|
+
Enabled Reference].freeze
|
13
13
|
# @api private
|
14
14
|
INTERNAL_PARAMS = %w[Description StyleGuide
|
15
15
|
VersionAdded VersionChanged VersionRemoved
|
@@ -93,7 +93,7 @@ module RuboCop
|
|
93
93
|
add_offense(node, message: message) do |corrector|
|
94
94
|
line = range_by_whole_lines(node.source_range)
|
95
95
|
|
96
|
-
corrector.insert_before(line, "\n")
|
96
|
+
corrector.insert_before(line, "\n") if should_insert_line_before?(node)
|
97
97
|
|
98
98
|
correct_next_line_if_denied_style(corrector, node, line)
|
99
99
|
end
|
@@ -122,6 +122,8 @@ module RuboCop
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def correct_next_line_if_denied_style(corrector, node, line)
|
125
|
+
return unless should_insert_line_after?(node)
|
126
|
+
|
125
127
|
case style
|
126
128
|
when :around
|
127
129
|
corrector.insert_after(line, "\n") unless next_line_empty?(node.last_line)
|
@@ -205,6 +207,29 @@ module RuboCop
|
|
205
207
|
format(MSG_BEFORE_FOR_ONLY_BEFORE, modifier: modifier)
|
206
208
|
end
|
207
209
|
end
|
210
|
+
|
211
|
+
def should_insert_line_before?(node)
|
212
|
+
return false if previous_line_empty?(node.first_line)
|
213
|
+
return true unless inside_block?(node) && no_empty_lines_around_block_body?
|
214
|
+
return true unless node.parent.begin_type?
|
215
|
+
|
216
|
+
node.parent.children.first != node
|
217
|
+
end
|
218
|
+
|
219
|
+
def should_insert_line_after?(node)
|
220
|
+
return true unless inside_block?(node) && no_empty_lines_around_block_body?
|
221
|
+
|
222
|
+
node.parent.children.last != node
|
223
|
+
end
|
224
|
+
|
225
|
+
def inside_block?(node)
|
226
|
+
node.parent.block_type? || (node.parent.begin_type? && node.parent.parent&.block_type?)
|
227
|
+
end
|
228
|
+
|
229
|
+
def no_empty_lines_around_block_body?
|
230
|
+
config.for_enabled_cop('Layout/EmptyLinesAroundBlockBody')['EnforcedStyle'] ==
|
231
|
+
'no_empty_lines'
|
232
|
+
end
|
208
233
|
end
|
209
234
|
end
|
210
235
|
end
|
@@ -209,7 +209,7 @@ module RuboCop
|
|
209
209
|
# are not bisected.
|
210
210
|
# If the string contains spaces, use them to determine a place for a clean break;
|
211
211
|
# otherwise, the string will be broken at the line length limit.
|
212
|
-
def breakable_string_range(node)
|
212
|
+
def breakable_string_range(node)
|
213
213
|
source_range = node.source_range
|
214
214
|
relevant_substr = largest_possible_string(node)
|
215
215
|
|
@@ -221,13 +221,13 @@ module RuboCop
|
|
221
221
|
adjustment = max - source_range.last_column - 3
|
222
222
|
return if adjustment.abs > source_range.size
|
223
223
|
|
224
|
-
source_range.adjust(end_pos:
|
224
|
+
source_range.adjust(end_pos: adjustment)
|
225
225
|
end
|
226
226
|
end
|
227
227
|
|
228
228
|
def breakable_dstr_begin_position(node)
|
229
229
|
source_range = node.source_range
|
230
|
-
source_range.begin_pos if source_range.
|
230
|
+
source_range.begin_pos if source_range.column < max && source_range.last_column >= max
|
231
231
|
end
|
232
232
|
|
233
233
|
def breakable_range_by_line_index
|
@@ -54,14 +54,12 @@ module RuboCop
|
|
54
54
|
# if a method definition is inside an if, it is very likely
|
55
55
|
# that a different definition is used depending on platform, etc.
|
56
56
|
return if node.each_ancestor.any?(&:if_type?)
|
57
|
-
return if possible_dsl?(node)
|
58
57
|
|
59
58
|
found_instance_method(node, node.method_name)
|
60
59
|
end
|
61
60
|
|
62
61
|
def on_defs(node)
|
63
62
|
return if node.each_ancestor.any?(&:if_type?)
|
64
|
-
return if possible_dsl?(node)
|
65
63
|
|
66
64
|
if node.receiver.const_type?
|
67
65
|
_, const_name = *node.receiver
|
@@ -79,7 +77,6 @@ module RuboCop
|
|
79
77
|
def on_alias(node)
|
80
78
|
return unless (name = method_alias?(node))
|
81
79
|
return if node.ancestors.any?(&:if_type?)
|
82
|
-
return if possible_dsl?(node)
|
83
80
|
|
84
81
|
found_instance_method(node, name)
|
85
82
|
end
|
@@ -94,7 +91,6 @@ module RuboCop
|
|
94
91
|
def on_send(node)
|
95
92
|
if (name = alias_method?(node))
|
96
93
|
return if node.ancestors.any?(&:if_type?)
|
97
|
-
return if possible_dsl?(node)
|
98
94
|
|
99
95
|
found_instance_method(node, name)
|
100
96
|
elsif (attr = node.attribute_accessor?)
|
@@ -237,16 +233,6 @@ module RuboCop
|
|
237
233
|
end
|
238
234
|
end
|
239
235
|
|
240
|
-
def possible_dsl?(node)
|
241
|
-
# DSL methods may evaluate a block in the context of a newly created
|
242
|
-
# class or module
|
243
|
-
# Assume that if a method definition is inside any block call which
|
244
|
-
# we can't identify, it could be a DSL
|
245
|
-
node.each_ancestor(:block).any? do |ancestor|
|
246
|
-
!ancestor.method?(:class_eval) && !ancestor.class_constructor?
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
236
|
def source_location(node)
|
251
237
|
range = node.source_range
|
252
238
|
path = smart_path(range.source_buffer.name)
|
@@ -81,21 +81,16 @@ module RuboCop
|
|
81
81
|
(node.numeric_type? && node.value.zero?) || node.nil_type?
|
82
82
|
end
|
83
83
|
|
84
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
85
84
|
def check_send(node)
|
86
85
|
if node.arithmetic_operation?
|
87
86
|
float?(node.receiver) || float?(node.first_argument)
|
88
87
|
elsif FLOAT_RETURNING_METHODS.include?(node.method_name)
|
89
88
|
true
|
90
89
|
elsif node.receiver&.float_type?
|
91
|
-
|
92
|
-
true
|
93
|
-
else
|
90
|
+
FLOAT_INSTANCE_METHODS.include?(node.method_name) ||
|
94
91
|
check_numeric_returning_method(node)
|
95
|
-
end
|
96
92
|
end
|
97
93
|
end
|
98
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
99
94
|
|
100
95
|
def check_numeric_returning_method(node)
|
101
96
|
return false unless node.receiver
|
@@ -34,27 +34,100 @@ module RuboCop
|
|
34
34
|
# end
|
35
35
|
class LiteralAsCondition < Base
|
36
36
|
include RangeHelp
|
37
|
+
extend AutoCorrector
|
37
38
|
|
38
39
|
MSG = 'Literal `%<literal>s` appeared as a condition.'
|
39
40
|
RESTRICT_ON_SEND = [:!].freeze
|
40
41
|
|
42
|
+
# rubocop:disable Metrics/AbcSize
|
43
|
+
def on_and(node)
|
44
|
+
if node.lhs.truthy_literal? && node.rhs.truthy_literal?
|
45
|
+
add_offense(node) do |corrector|
|
46
|
+
corrector.replace(node, 'true')
|
47
|
+
end
|
48
|
+
elsif node.lhs.truthy_literal?
|
49
|
+
add_offense(node.lhs) do |corrector|
|
50
|
+
corrector.replace(node, node.rhs.source)
|
51
|
+
end
|
52
|
+
elsif node.rhs.truthy_literal?
|
53
|
+
add_offense(node.rhs) do |corrector|
|
54
|
+
corrector.replace(node, node.lhs.source)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
# rubocop:enable Metrics/AbcSize
|
59
|
+
|
41
60
|
def on_if(node)
|
42
|
-
|
61
|
+
cond = condition(node)
|
62
|
+
|
63
|
+
if node.unless?
|
64
|
+
correct_if_node(node, cond, true) if cond.falsey_literal?
|
65
|
+
correct_if_node(node, cond, false) if cond.truthy_literal?
|
66
|
+
else
|
67
|
+
correct_if_node(node, cond, true) if cond.truthy_literal?
|
68
|
+
correct_if_node(node, cond, false) if cond.falsey_literal?
|
69
|
+
end
|
43
70
|
end
|
44
71
|
|
45
72
|
def on_while(node)
|
46
|
-
return if
|
73
|
+
return if node.condition.source == 'true'
|
47
74
|
|
48
|
-
|
75
|
+
if node.condition.truthy_literal?
|
76
|
+
add_offense(node.condition) do |corrector|
|
77
|
+
corrector.replace(node.condition, 'true')
|
78
|
+
end
|
79
|
+
elsif node.condition.falsey_literal?
|
80
|
+
add_offense(node.condition) do |corrector|
|
81
|
+
corrector.remove(node)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# rubocop:disable Metrics/AbcSize
|
87
|
+
def on_while_post(node)
|
88
|
+
return if node.condition.source == 'true'
|
89
|
+
|
90
|
+
if node.condition.truthy_literal?
|
91
|
+
add_offense(node.condition) do |corrector|
|
92
|
+
corrector.replace(node, node.source.sub(node.condition.source, 'true'))
|
93
|
+
end
|
94
|
+
elsif node.condition.falsey_literal?
|
95
|
+
add_offense(node.condition) do |corrector|
|
96
|
+
corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
|
97
|
+
end
|
98
|
+
end
|
49
99
|
end
|
50
|
-
|
100
|
+
# rubocop:enable Metrics/AbcSize
|
51
101
|
|
52
102
|
def on_until(node)
|
53
|
-
return if
|
103
|
+
return if node.condition.source == 'false'
|
54
104
|
|
55
|
-
|
105
|
+
if node.condition.falsey_literal?
|
106
|
+
add_offense(node.condition) do |corrector|
|
107
|
+
corrector.replace(node.condition, 'false')
|
108
|
+
end
|
109
|
+
elsif node.condition.truthy_literal?
|
110
|
+
add_offense(node.condition) do |corrector|
|
111
|
+
corrector.remove(node)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# rubocop:disable Metrics/AbcSize
|
117
|
+
def on_until_post(node)
|
118
|
+
return if node.condition.source == 'false'
|
119
|
+
|
120
|
+
if node.condition.falsey_literal?
|
121
|
+
add_offense(node.condition) do |corrector|
|
122
|
+
corrector.replace(node, node.source.sub(node.condition.source, 'false'))
|
123
|
+
end
|
124
|
+
elsif node.condition.truthy_literal?
|
125
|
+
add_offense(node.condition) do |corrector|
|
126
|
+
corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
|
127
|
+
end
|
128
|
+
end
|
56
129
|
end
|
57
|
-
|
130
|
+
# rubocop:enable Metrics/AbcSize
|
58
131
|
|
59
132
|
def on_case(case_node)
|
60
133
|
if case_node.condition
|
@@ -130,6 +203,8 @@ module RuboCop
|
|
130
203
|
|
131
204
|
def handle_node(node)
|
132
205
|
if node.literal?
|
206
|
+
return if node.parent.and_type?
|
207
|
+
|
133
208
|
add_offense(node)
|
134
209
|
elsif %i[send and or begin].include?(node.type)
|
135
210
|
check_node(node)
|
@@ -159,6 +234,28 @@ module RuboCop
|
|
159
234
|
when_node.conditions.last.source_range.end_pos
|
160
235
|
)
|
161
236
|
end
|
237
|
+
|
238
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
239
|
+
def correct_if_node(node, cond, result)
|
240
|
+
if result
|
241
|
+
add_offense(cond) do |corrector|
|
242
|
+
corrector.replace(node, node.if_branch.source)
|
243
|
+
end
|
244
|
+
elsif node.elsif_conditional?
|
245
|
+
add_offense(cond) do |corrector|
|
246
|
+
corrector.replace(node, "#{node.else_branch.source.sub('elsif', 'if')}\nend")
|
247
|
+
end
|
248
|
+
elsif node.else? || node.ternary?
|
249
|
+
add_offense(cond) do |corrector|
|
250
|
+
corrector.replace(node, node.else_branch.source)
|
251
|
+
end
|
252
|
+
else
|
253
|
+
add_offense(cond) do |corrector|
|
254
|
+
corrector.remove(node)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
162
259
|
end
|
163
260
|
end
|
164
261
|
end
|
@@ -17,17 +17,12 @@ module RuboCop
|
|
17
17
|
# * 2.0+ ... `enumerator`
|
18
18
|
# * 2.1+ ... `thread`
|
19
19
|
# * 2.2+ ... Add `rational` and `complex` above
|
20
|
-
# * 2.5+ ... Add `pp` above
|
21
20
|
# * 2.7+ ... Add `ruby2_keywords` above
|
22
21
|
# * 3.1+ ... Add `fiber` above
|
23
22
|
# * 3.2+ ... `set`
|
24
23
|
#
|
25
24
|
# This cop target those features.
|
26
25
|
#
|
27
|
-
# @safety
|
28
|
-
# This cop's autocorrection is unsafe because if `require 'pp'` is removed from one file,
|
29
|
-
# `NameError` can be encountered when another file uses `PP.pp`.
|
30
|
-
#
|
31
26
|
# @example
|
32
27
|
# # bad
|
33
28
|
# require 'unloaded_feature'
|
@@ -42,10 +37,6 @@ module RuboCop
|
|
42
37
|
MSG = 'Remove unnecessary `require` statement.'
|
43
38
|
RESTRICT_ON_SEND = %i[require].freeze
|
44
39
|
RUBY_22_LOADED_FEATURES = %w[rational complex].freeze
|
45
|
-
PRETTY_PRINT_METHODS = %i[
|
46
|
-
pretty_inspect pretty_print pretty_print_cycle
|
47
|
-
pretty_print_inspect pretty_print_instance_variables
|
48
|
-
].freeze
|
49
40
|
|
50
41
|
# @!method redundant_require_statement?(node)
|
51
42
|
def_node_matcher :redundant_require_statement?, <<~PATTERN
|
@@ -53,11 +44,6 @@ module RuboCop
|
|
53
44
|
(str #redundant_feature?))
|
54
45
|
PATTERN
|
55
46
|
|
56
|
-
# @!method pp_const?(node)
|
57
|
-
def_node_matcher :pp_const?, <<~PATTERN
|
58
|
-
(const {nil? cbase} :PP)
|
59
|
-
PATTERN
|
60
|
-
|
61
47
|
def on_send(node)
|
62
48
|
return unless redundant_require_statement?(node)
|
63
49
|
|
@@ -81,18 +67,11 @@ module RuboCop
|
|
81
67
|
feature_name == 'enumerator' ||
|
82
68
|
(target_ruby_version >= 2.1 && feature_name == 'thread') ||
|
83
69
|
(target_ruby_version >= 2.2 && RUBY_22_LOADED_FEATURES.include?(feature_name)) ||
|
84
|
-
(target_ruby_version >= 2.5 && feature_name == 'pp' && !need_to_require_pp?) ||
|
85
70
|
(target_ruby_version >= 2.7 && feature_name == 'ruby2_keywords') ||
|
86
71
|
(target_ruby_version >= 3.1 && feature_name == 'fiber') ||
|
87
72
|
(target_ruby_version >= 3.2 && feature_name == 'set')
|
88
73
|
end
|
89
74
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
90
|
-
|
91
|
-
def need_to_require_pp?
|
92
|
-
processed_source.ast.each_descendant(:send).any? do |node|
|
93
|
-
pp_const?(node.receiver) || PRETTY_PRINT_METHODS.include?(node.method_name)
|
94
|
-
end
|
95
|
-
end
|
96
75
|
end
|
97
76
|
end
|
98
77
|
end
|
@@ -39,7 +39,7 @@ module RuboCop
|
|
39
39
|
# 1i.to_c
|
40
40
|
# [].to_a
|
41
41
|
# {}.to_h
|
42
|
-
# Set.new.
|
42
|
+
# Set.new.to_set
|
43
43
|
#
|
44
44
|
# # good
|
45
45
|
# "text"
|
@@ -52,6 +52,16 @@ module RuboCop
|
|
52
52
|
# {}
|
53
53
|
# Set.new
|
54
54
|
#
|
55
|
+
# # bad
|
56
|
+
# Integer(var).to_i
|
57
|
+
#
|
58
|
+
# # good
|
59
|
+
# Integer(var)
|
60
|
+
#
|
61
|
+
# # good - chaining to a type constructor with exceptions suppressed
|
62
|
+
# # in this case, `Integer()` could return `nil`
|
63
|
+
# Integer(var, exception: false).to_i
|
64
|
+
#
|
55
65
|
# # bad - chaining the same conversion
|
56
66
|
# foo.to_s.to_s
|
57
67
|
#
|
@@ -161,6 +171,11 @@ module RuboCop
|
|
161
171
|
}
|
162
172
|
PATTERN
|
163
173
|
|
174
|
+
# @!method exception_false_keyword_argument?(node)
|
175
|
+
def_node_matcher :exception_false_keyword_argument?, <<~PATTERN
|
176
|
+
(hash (pair (sym :exception) false))
|
177
|
+
PATTERN
|
178
|
+
|
164
179
|
# rubocop:disable Metrics/AbcSize
|
165
180
|
def on_send(node)
|
166
181
|
return if hash_or_set_with_block?(node)
|
@@ -211,7 +226,13 @@ module RuboCop
|
|
211
226
|
matcher = CONSTRUCTOR_MAPPING[node.method_name]
|
212
227
|
return false unless matcher
|
213
228
|
|
214
|
-
public_send(matcher, receiver)
|
229
|
+
public_send(matcher, receiver) && !constructor_suppresses_exceptions?(receiver)
|
230
|
+
end
|
231
|
+
|
232
|
+
def constructor_suppresses_exceptions?(receiver)
|
233
|
+
# If the constructor suppresses exceptions with `exception: false`, it is possible
|
234
|
+
# it could return `nil`, and therefore a chained conversion is not redundant.
|
235
|
+
receiver.arguments.any? { |arg| exception_false_keyword_argument?(arg) }
|
215
236
|
end
|
216
237
|
|
217
238
|
def chained_conversion?(node, receiver)
|
@@ -125,9 +125,14 @@ module RuboCop
|
|
125
125
|
check_nonmutating(expr)
|
126
126
|
end
|
127
127
|
|
128
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
128
129
|
def check_void_op(node, &block)
|
129
130
|
node = node.children.first while node.begin_type?
|
130
131
|
return unless node.call_type? && OPERATORS.include?(node.method_name)
|
132
|
+
if !UNARY_OPERATORS.include?(node.method_name) && node.loc.dot && node.arguments.none?
|
133
|
+
return
|
134
|
+
end
|
135
|
+
|
131
136
|
return if block && yield(node)
|
132
137
|
|
133
138
|
add_offense(node.loc.selector,
|
@@ -135,6 +140,7 @@ module RuboCop
|
|
135
140
|
autocorrect_void_op(corrector, node)
|
136
141
|
end
|
137
142
|
end
|
143
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
138
144
|
|
139
145
|
def check_var(node)
|
140
146
|
return unless node.variable? || node.const_type?
|
@@ -23,7 +23,7 @@ module RuboCop
|
|
23
23
|
(call _ _)
|
24
24
|
(args
|
25
25
|
$(arg _key)
|
26
|
-
(arg _))
|
26
|
+
$(arg _))
|
27
27
|
{
|
28
28
|
$(send
|
29
29
|
{(lvar _key) $_ _ | _ $_ (lvar _key)})
|
@@ -67,7 +67,7 @@ module RuboCop
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def extracts_hash_subset?(block)
|
70
|
-
block_with_first_arg_check?(block) do |key_arg, send_node, method|
|
70
|
+
block_with_first_arg_check?(block) do |key_arg, value_arg, send_node, method|
|
71
71
|
# Only consider methods that have one argument
|
72
72
|
return false unless send_node.arguments.one?
|
73
73
|
|
@@ -76,15 +76,22 @@ module RuboCop
|
|
76
76
|
|
77
77
|
case method
|
78
78
|
when :include?, :exclude?
|
79
|
-
send_node
|
79
|
+
slices_key?(send_node, :first_argument, key_arg, value_arg)
|
80
80
|
when :in?
|
81
|
-
send_node
|
81
|
+
slices_key?(send_node, :receiver, key_arg, value_arg)
|
82
82
|
else
|
83
83
|
true
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
+
def slices_key?(send_node, method, key_arg, value_arg)
|
89
|
+
return false if using_value_variable?(send_node, value_arg)
|
90
|
+
|
91
|
+
node = method == :receiver ? send_node.receiver : send_node.first_argument
|
92
|
+
node.source == key_arg.source
|
93
|
+
end
|
94
|
+
|
88
95
|
def range_include?(send_node)
|
89
96
|
# When checking `include?`, `exclude?` and `in?` for offenses, if the receiver
|
90
97
|
# or first argument is a range, an offense should not be registered.
|
@@ -97,6 +104,14 @@ module RuboCop
|
|
97
104
|
receiver.range_type?
|
98
105
|
end
|
99
106
|
|
107
|
+
def using_value_variable?(send_node, value_arg)
|
108
|
+
# If the receiver of `include?` or `exclude?`, or the first argument of `in?` is the
|
109
|
+
# hash value block argument, an offense should not be registered.
|
110
|
+
# ie. `v.include?(k)` or `k.in?(v)`
|
111
|
+
(send_node.receiver.lvar_type? && send_node.receiver.name == value_arg.name) ||
|
112
|
+
(send_node.first_argument.lvar_type? && send_node.first_argument.name == value_arg.name)
|
113
|
+
end
|
114
|
+
|
100
115
|
def supported_subset_method?(method)
|
101
116
|
if active_support_extensions_enabled?
|
102
117
|
ACTIVE_SUPPORT_SUBSET_METHODS.include?(method)
|