rubocop 1.72.1 → 1.73.1
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 +26 -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/internal_affairs/example_description.rb +4 -2
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
- 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/empty_conditional_body.rb +10 -5
- data/lib/rubocop/cop/lint/float_comparison.rb +1 -6
- data/lib/rubocop/cop/lint/literal_as_condition.rb +99 -9
- data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
- 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/useless_constant_scoping.rb +7 -1
- data/lib/rubocop/cop/lint/void.rb +6 -0
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
- 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/block_forwarding.rb +3 -3
- 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/arguments_forwarding.rb +3 -3
- data/lib/rubocop/cop/style/commented_keyword.rb +1 -1
- 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 +46 -0
- data/lib/rubocop/cop/style/redundant_format.rb +39 -11
- data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -3
- 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/configuration_integrator.rb +2 -0
- data/lib/rubocop/plugin/load_error.rb +1 -1
- data/lib/rubocop/plugin.rb +9 -2
- data/lib/rubocop/rspec/cop_helper.rb +2 -0
- 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: a4215b7d095dfd177a36af3bdf5d5aecd786877a6feca3480078d9cb1a5917ad
|
4
|
+
data.tar.gz: fc20be6f63f1a0e3c06cd2fc13f8619f872e9a81642dfa833f90f88f70997857
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aee7de1fa54b8b7108f5ad7f29c3fbc1818547f28507010dca91adc0f648b02ce519c96846d2ad98407d8f8847047cd8f88547e7d5c81028d0f54cfafb44500b
|
7
|
+
data.tar.gz: afc90ab7e887e183ddfac0bf49e9f644c04564e7fd605423d29f2848f6cc509f2394fd642eccd8870d105b21055a5cb4d0dea051b92ba47ef3befbf5b7d3dad5
|
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']`."
|
@@ -5104,6 +5108,9 @@ Style/RedundantCondition:
|
|
5104
5108
|
Description: 'Checks for unnecessary conditional expressions.'
|
5105
5109
|
Enabled: true
|
5106
5110
|
VersionAdded: '0.76'
|
5111
|
+
VersionChanged: '1.73'
|
5112
|
+
AllowedMethods:
|
5113
|
+
- nonzero?
|
5107
5114
|
|
5108
5115
|
Style/RedundantConditional:
|
5109
5116
|
Description: "Don't return true/false from a conditional."
|
@@ -5171,7 +5178,9 @@ Style/RedundantFilterChain:
|
|
5171
5178
|
Style/RedundantFormat:
|
5172
5179
|
Description: 'Checks for usages of `Kernel#format` or `Kernel#sprintf` with only a single argument.'
|
5173
5180
|
Enabled: pending
|
5181
|
+
SafeAutoCorrect: false
|
5174
5182
|
VersionAdded: '1.72'
|
5183
|
+
VersionChanged: '1.72'
|
5175
5184
|
|
5176
5185
|
Style/RedundantFreeze:
|
5177
5186
|
Description: "Checks usages of Object#freeze on immutable objects."
|
@@ -5699,14 +5708,17 @@ Style/TrailingCommaInArrayLiteral:
|
|
5699
5708
|
StyleGuide: '#no-trailing-array-commas'
|
5700
5709
|
Enabled: true
|
5701
5710
|
VersionAdded: '0.53'
|
5702
|
-
# If `comma`, the cop requires a comma after the last item in an array,
|
5703
|
-
#
|
5704
|
-
# If `consistent_comma`, the cop requires a comma after the last item of all
|
5705
|
-
#
|
5711
|
+
# If `comma`, the cop requires a comma after the last item in an array, but only when each item is
|
5712
|
+
# on its own line.
|
5713
|
+
# If `consistent_comma`, the cop requires a comma after the last item of all non-empty, multiline
|
5714
|
+
# array literals.
|
5715
|
+
# If `diff_comma`, the cop requires a comma after the last item of all non-empty, multiline array
|
5716
|
+
# literals, but only when that last item immediately precedes a newline.
|
5706
5717
|
EnforcedStyleForMultiline: no_comma
|
5707
5718
|
SupportedStylesForMultiline:
|
5708
5719
|
- comma
|
5709
5720
|
- consistent_comma
|
5721
|
+
- diff_comma
|
5710
5722
|
- no_comma
|
5711
5723
|
|
5712
5724
|
Style/TrailingCommaInBlockArgs:
|
@@ -5718,14 +5730,17 @@ Style/TrailingCommaInBlockArgs:
|
|
5718
5730
|
Style/TrailingCommaInHashLiteral:
|
5719
5731
|
Description: 'Checks for trailing comma in hash literals.'
|
5720
5732
|
Enabled: true
|
5721
|
-
# If `comma`, the cop requires a comma after the last item in a hash,
|
5722
|
-
#
|
5723
|
-
# If `consistent_comma`, the cop requires a comma after the last item of all
|
5724
|
-
#
|
5733
|
+
# If `comma`, the cop requires a comma after the last item in a hash, but only when each item is
|
5734
|
+
# on its own line.
|
5735
|
+
# If `consistent_comma`, the cop requires a comma after the last item of all non-empty, multiline
|
5736
|
+
# hash literals.
|
5737
|
+
# If `diff_comma`, the cop requires a comma after the last item of all non-empty, multiline hash
|
5738
|
+
# literals, but only when that last item immediately precedes a newline.
|
5725
5739
|
EnforcedStyleForMultiline: no_comma
|
5726
5740
|
SupportedStylesForMultiline:
|
5727
5741
|
- comma
|
5728
5742
|
- consistent_comma
|
5743
|
+
- diff_comma
|
5729
5744
|
- no_comma
|
5730
5745
|
VersionAdded: '0.53'
|
5731
5746
|
|
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
|
@@ -90,8 +90,10 @@ module RuboCop
|
|
90
90
|
description_text = string_contents(current_description)
|
91
91
|
return unless (new_description = correct_description(description_text, description_map))
|
92
92
|
|
93
|
+
quote = current_description.dstr_type? ? '"' : "'"
|
94
|
+
|
93
95
|
add_offense(current_description, message: message) do |corrector|
|
94
|
-
corrector.replace(current_description, "
|
96
|
+
corrector.replace(current_description, "#{quote}#{new_description}#{quote}")
|
95
97
|
end
|
96
98
|
end
|
97
99
|
|
@@ -106,7 +108,7 @@ module RuboCop
|
|
106
108
|
end
|
107
109
|
|
108
110
|
def string_contents(node)
|
109
|
-
node.
|
111
|
+
node.type?(:str, :dstr) ? node.value : node.source
|
110
112
|
end
|
111
113
|
end
|
112
114
|
end
|
@@ -155,10 +155,10 @@ module RuboCop
|
|
155
155
|
end
|
156
156
|
|
157
157
|
def all_elements_aligned?(elements)
|
158
|
-
elements.
|
159
|
-
|
160
|
-
|
161
|
-
|
158
|
+
if elements.first.hash_type?
|
159
|
+
elements.first.each_child_node.map { |child| child.loc.column }
|
160
|
+
else
|
161
|
+
elements.flat_map do |e|
|
162
162
|
e.loc.column
|
163
163
|
end
|
164
164
|
end.uniq.count == 1
|
@@ -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)
|
@@ -67,7 +67,6 @@ module RuboCop
|
|
67
67
|
|
68
68
|
MSG = 'Avoid `%<keyword>s` branches without a body.'
|
69
69
|
|
70
|
-
# rubocop:disable Metrics/AbcSize
|
71
70
|
def on_if(node)
|
72
71
|
return if node.body || same_line?(node.loc.begin, node.loc.end)
|
73
72
|
return if cop_config['AllowComments'] && contains_comments?(node)
|
@@ -75,15 +74,21 @@ module RuboCop
|
|
75
74
|
range = offense_range(node)
|
76
75
|
|
77
76
|
add_offense(range, message: format(MSG, keyword: node.keyword)) do |corrector|
|
78
|
-
|
79
|
-
|
80
|
-
autocorrect(corrector, node)
|
77
|
+
autocorrect(corrector, node) if do_autocorrect?(node)
|
81
78
|
end
|
82
79
|
end
|
83
|
-
# rubocop:enable Metrics/AbcSize
|
84
80
|
|
85
81
|
private
|
86
82
|
|
83
|
+
def do_autocorrect?(node)
|
84
|
+
# if condition; end.do_something
|
85
|
+
return false if (parent = node.parent)&.call_type?
|
86
|
+
# x = if condition; end
|
87
|
+
return false if (parent&.assignment? || parent&.operator_keyword?) && node.children.one?
|
88
|
+
|
89
|
+
true
|
90
|
+
end
|
91
|
+
|
87
92
|
def offense_range(node)
|
88
93
|
if node.loc.else
|
89
94
|
node.source_range.begin.join(node.loc.else.begin)
|
@@ -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
|
@@ -18,12 +18,15 @@ module RuboCop
|
|
18
18
|
# end
|
19
19
|
#
|
20
20
|
# # bad
|
21
|
-
#
|
21
|
+
# # We're only interested in the left hand side being a truthy literal,
|
22
|
+
# # because it affects the evaluation of the &&, whereas the right hand
|
23
|
+
# # side will be conditionally executed/called and can be a literal.
|
24
|
+
# if true && some_var
|
22
25
|
# do_something
|
23
26
|
# end
|
24
27
|
#
|
25
28
|
# # good
|
26
|
-
# if some_var
|
29
|
+
# if some_var
|
27
30
|
# do_something
|
28
31
|
# end
|
29
32
|
#
|
@@ -34,27 +37,90 @@ module RuboCop
|
|
34
37
|
# end
|
35
38
|
class LiteralAsCondition < Base
|
36
39
|
include RangeHelp
|
40
|
+
extend AutoCorrector
|
37
41
|
|
38
42
|
MSG = 'Literal `%<literal>s` appeared as a condition.'
|
39
43
|
RESTRICT_ON_SEND = [:!].freeze
|
40
44
|
|
45
|
+
def on_and(node)
|
46
|
+
return unless node.lhs.truthy_literal?
|
47
|
+
|
48
|
+
add_offense(node.lhs) do |corrector|
|
49
|
+
corrector.replace(node, node.rhs.source)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
41
53
|
def on_if(node)
|
42
|
-
|
54
|
+
cond = condition(node)
|
55
|
+
|
56
|
+
if node.unless?
|
57
|
+
correct_if_node(node, cond, true) if cond.falsey_literal?
|
58
|
+
correct_if_node(node, cond, false) if cond.truthy_literal?
|
59
|
+
else
|
60
|
+
correct_if_node(node, cond, true) if cond.truthy_literal?
|
61
|
+
correct_if_node(node, cond, false) if cond.falsey_literal?
|
62
|
+
end
|
43
63
|
end
|
44
64
|
|
45
65
|
def on_while(node)
|
46
|
-
return if
|
66
|
+
return if node.condition.source == 'true'
|
47
67
|
|
48
|
-
|
68
|
+
if node.condition.truthy_literal?
|
69
|
+
add_offense(node.condition) do |corrector|
|
70
|
+
corrector.replace(node.condition, 'true')
|
71
|
+
end
|
72
|
+
elsif node.condition.falsey_literal?
|
73
|
+
add_offense(node.condition) do |corrector|
|
74
|
+
corrector.remove(node)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# rubocop:disable Metrics/AbcSize
|
80
|
+
def on_while_post(node)
|
81
|
+
return if node.condition.source == 'true'
|
82
|
+
|
83
|
+
if node.condition.truthy_literal?
|
84
|
+
add_offense(node.condition) do |corrector|
|
85
|
+
corrector.replace(node, node.source.sub(node.condition.source, 'true'))
|
86
|
+
end
|
87
|
+
elsif node.condition.falsey_literal?
|
88
|
+
add_offense(node.condition) do |corrector|
|
89
|
+
corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
|
90
|
+
end
|
91
|
+
end
|
49
92
|
end
|
50
|
-
|
93
|
+
# rubocop:enable Metrics/AbcSize
|
51
94
|
|
52
95
|
def on_until(node)
|
53
|
-
return if
|
96
|
+
return if node.condition.source == 'false'
|
54
97
|
|
55
|
-
|
98
|
+
if node.condition.falsey_literal?
|
99
|
+
add_offense(node.condition) do |corrector|
|
100
|
+
corrector.replace(node.condition, 'false')
|
101
|
+
end
|
102
|
+
elsif node.condition.truthy_literal?
|
103
|
+
add_offense(node.condition) do |corrector|
|
104
|
+
corrector.remove(node)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# rubocop:disable Metrics/AbcSize
|
110
|
+
def on_until_post(node)
|
111
|
+
return if node.condition.source == 'false'
|
112
|
+
|
113
|
+
if node.condition.falsey_literal?
|
114
|
+
add_offense(node.condition) do |corrector|
|
115
|
+
corrector.replace(node, node.source.sub(node.condition.source, 'false'))
|
116
|
+
end
|
117
|
+
elsif node.condition.truthy_literal?
|
118
|
+
add_offense(node.condition) do |corrector|
|
119
|
+
corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
|
120
|
+
end
|
121
|
+
end
|
56
122
|
end
|
57
|
-
|
123
|
+
# rubocop:enable Metrics/AbcSize
|
58
124
|
|
59
125
|
def on_case(case_node)
|
60
126
|
if case_node.condition
|
@@ -130,6 +196,8 @@ module RuboCop
|
|
130
196
|
|
131
197
|
def handle_node(node)
|
132
198
|
if node.literal?
|
199
|
+
return if node.parent.and_type?
|
200
|
+
|
133
201
|
add_offense(node)
|
134
202
|
elsif %i[send and or begin].include?(node.type)
|
135
203
|
check_node(node)
|
@@ -159,6 +227,28 @@ module RuboCop
|
|
159
227
|
when_node.conditions.last.source_range.end_pos
|
160
228
|
)
|
161
229
|
end
|
230
|
+
|
231
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
232
|
+
def correct_if_node(node, cond, result)
|
233
|
+
if result
|
234
|
+
add_offense(cond) do |corrector|
|
235
|
+
corrector.replace(node, node.if_branch.source)
|
236
|
+
end
|
237
|
+
elsif node.elsif_conditional?
|
238
|
+
add_offense(cond) do |corrector|
|
239
|
+
corrector.replace(node, "#{node.else_branch.source.sub('elsif', 'if')}\nend")
|
240
|
+
end
|
241
|
+
elsif node.else? || node.ternary?
|
242
|
+
add_offense(cond) do |corrector|
|
243
|
+
corrector.replace(node, node.else_branch.source)
|
244
|
+
end
|
245
|
+
else
|
246
|
+
add_offense(cond) do |corrector|
|
247
|
+
corrector.remove(node)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
162
252
|
end
|
163
253
|
end
|
164
254
|
end
|
@@ -79,7 +79,7 @@ module RuboCop
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def range_pairs(expr)
|
82
|
-
|
82
|
+
expr.expressions.filter_map { |e| [e.expressions[0], e.expressions[1]] if e.type == :set }
|
83
83
|
end
|
84
84
|
|
85
85
|
def unsafe_range?(range_start, range_end)
|
@@ -94,7 +94,7 @@ module RuboCop
|
|
94
94
|
|
95
95
|
def skip_range?(range_start, range_end)
|
96
96
|
[range_start, range_end].any? do |bound|
|
97
|
-
bound
|
97
|
+
bound&.type != :literal
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
@@ -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
|