rubocop 1.71.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 +51 -11
- data/config/internal_affairs.yml +16 -0
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/comment_config.rb +1 -1
- data/lib/rubocop/config.rb +4 -0
- data/lib/rubocop/config_loader.rb +44 -8
- data/lib/rubocop/config_loader_resolver.rb +23 -9
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +4 -2
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
- data/lib/rubocop/cop/internal_affairs.rb +1 -16
- data/lib/rubocop/cop/layout/block_alignment.rb +2 -0
- data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +26 -1
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +3 -3
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
- 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/format_parameter_mismatch.rb +1 -1
- 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 +252 -0
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +80 -0
- data/lib/rubocop/cop/lint/void.rb +6 -0
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/mixin/alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +18 -18
- data/lib/rubocop/cop/mixin/hash_subset.rb +19 -4
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +3 -3
- data/lib/rubocop/cop/mixin/string_help.rb +1 -1
- 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/predicate_name.rb +44 -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/arguments_forwarding.rb +3 -3
- 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 +250 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +18 -4
- 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/cop/util.rb +1 -1
- data/lib/rubocop/cop/utils/format_string.rb +7 -5
- data/lib/rubocop/cops_documentation_generator.rb +12 -1
- data/lib/rubocop/directive_comment.rb +35 -2
- data/lib/rubocop/lsp/runtime.rb +2 -0
- data/lib/rubocop/lsp/server.rb +0 -2
- data/lib/rubocop/options.rb +26 -11
- data/lib/rubocop/path_util.rb +4 -0
- data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
- data/lib/rubocop/plugin/load_error.rb +26 -0
- data/lib/rubocop/plugin/loader.rb +100 -0
- data/lib/rubocop/plugin/not_supported_error.rb +29 -0
- data/lib/rubocop/plugin.rb +46 -0
- data/lib/rubocop/rake_task.rb +4 -1
- data/lib/rubocop/rspec/cop_helper.rb +9 -0
- data/lib/rubocop/rspec/shared_contexts.rb +15 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/server/cache.rb +35 -2
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/version.rb +17 -2
- data/lib/rubocop.rb +5 -1
- data/lib/ruby_lsp/rubocop/addon.rb +7 -10
- data/lib/ruby_lsp/rubocop/{wraps_built_in_lsp_runtime.rb → runtime_adapter.rb} +5 -8
- metadata +35 -10
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
@@ -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
|
@@ -27,9 +27,14 @@ module RuboCop
|
|
27
27
|
KIND = 'method'
|
28
28
|
|
29
29
|
def on_def(node)
|
30
|
-
|
30
|
+
if node.endless?
|
31
|
+
return unless offending_endless_method?(node)
|
31
32
|
|
32
|
-
|
33
|
+
register_offense_for_endless_method(node)
|
34
|
+
else
|
35
|
+
first_line = node.arguments.source_range&.last_line
|
36
|
+
check(node, node.body, adjusted_first_line: first_line)
|
37
|
+
end
|
33
38
|
end
|
34
39
|
alias on_defs on_def
|
35
40
|
|
@@ -38,6 +43,21 @@ module RuboCop
|
|
38
43
|
def style
|
39
44
|
:no_empty_lines
|
40
45
|
end
|
46
|
+
|
47
|
+
def offending_endless_method?(node)
|
48
|
+
node.body.first_line > node.loc.assignment.line + 1 &&
|
49
|
+
processed_source.lines[node.loc.assignment.line].empty?
|
50
|
+
end
|
51
|
+
|
52
|
+
def register_offense_for_endless_method(node)
|
53
|
+
range = processed_source.buffer.line_range(node.loc.assignment.line + 1).resize(1)
|
54
|
+
|
55
|
+
msg = message(MSG_EXTRA, 'beginning')
|
56
|
+
|
57
|
+
add_offense(range, message: msg) do |corrector|
|
58
|
+
corrector.remove(range)
|
59
|
+
end
|
60
|
+
end
|
41
61
|
end
|
42
62
|
end
|
43
63
|
end
|
@@ -162,7 +162,7 @@ module RuboCop
|
|
162
162
|
|
163
163
|
def end_keyword_before_closing_parenthesis?(parenthesized_send_node)
|
164
164
|
parenthesized_send_node.ancestors.any? do |ancestor|
|
165
|
-
ancestor.
|
165
|
+
ancestor.loc_is?(:end, 'end')
|
166
166
|
end
|
167
167
|
end
|
168
168
|
|
@@ -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
|
@@ -216,7 +216,7 @@ module RuboCop
|
|
216
216
|
|
217
217
|
def get_dot_right_above(node)
|
218
218
|
node.each_ancestor.find do |a|
|
219
|
-
dot = a.loc.
|
219
|
+
dot = a.loc.dot if a.loc?(:dot)
|
220
220
|
next unless dot
|
221
221
|
|
222
222
|
dot.line == node.loc.dot.line - 1 && dot.column == node.loc.dot.column
|
@@ -239,7 +239,7 @@ module RuboCop
|
|
239
239
|
node = node.receiver while node.receiver
|
240
240
|
# ascend to first call which has a dot
|
241
241
|
node = node.parent
|
242
|
-
node = node.parent until node.loc
|
242
|
+
node = node.parent until node.loc?(:dot)
|
243
243
|
|
244
244
|
node
|
245
245
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Lint/RedundantCopDisableDirective
|
4
|
+
# rubocop:disable Style/DoubleCopDisableDirective
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module Lint
|
8
|
+
# Checks that `# rubocop:enable ...` and `# rubocop:disable ...` statements
|
9
|
+
# are strictly formatted.
|
10
|
+
#
|
11
|
+
# A comment can be added to the directive by prefixing it with `--`.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# # bad
|
15
|
+
# # rubocop:disable Layout/LineLength Style/Encoding
|
16
|
+
# # ^ missing comma
|
17
|
+
#
|
18
|
+
# # bad
|
19
|
+
# # rubocop:disable
|
20
|
+
#
|
21
|
+
# # bad
|
22
|
+
# # rubocop:disable Layout/LineLength # rubocop:disable Style/Encoding
|
23
|
+
#
|
24
|
+
# # bad
|
25
|
+
# # rubocop:wrongmode Layout/LineLength
|
26
|
+
#
|
27
|
+
# # good
|
28
|
+
# # rubocop:disable Layout/LineLength
|
29
|
+
#
|
30
|
+
# # good
|
31
|
+
# # rubocop:disable Layout/LineLength, Style/Encoding
|
32
|
+
#
|
33
|
+
# # good
|
34
|
+
# # rubocop:disable all
|
35
|
+
#
|
36
|
+
# # good
|
37
|
+
# # rubocop:disable Layout/LineLength -- This is a good comment.
|
38
|
+
#
|
39
|
+
class CopDirectiveSyntax < Base
|
40
|
+
COMMON_MSG = 'Malformed directive comment detected.'
|
41
|
+
|
42
|
+
MISSING_MODE_NAME_MSG = 'The mode name is missing.'
|
43
|
+
INVALID_MODE_NAME_MSG = 'The mode name must be one of `enable`, `disable`, or `todo`.'
|
44
|
+
MISSING_COP_NAME_MSG = 'The cop name is missing.'
|
45
|
+
MALFORMED_COP_NAMES_MSG = 'Cop names must be separated by commas. ' \
|
46
|
+
'Comment in the directive must start with `--`.'
|
47
|
+
|
48
|
+
def on_new_investigation
|
49
|
+
processed_source.comments.each do |comment|
|
50
|
+
directive_comment = DirectiveComment.new(comment)
|
51
|
+
next unless directive_comment.start_with_marker?
|
52
|
+
next unless directive_comment.malformed?
|
53
|
+
|
54
|
+
message = offense_message(directive_comment)
|
55
|
+
add_offense(comment, message: message)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# rubocop:disable Metrics/MethodLength
|
62
|
+
def offense_message(directive_comment)
|
63
|
+
comment = directive_comment.comment
|
64
|
+
after_marker = comment.text.sub(DirectiveComment::DIRECTIVE_MARKER_REGEXP, '')
|
65
|
+
mode = after_marker.split(' ', 2).first
|
66
|
+
additional_msg = if mode.nil?
|
67
|
+
MISSING_MODE_NAME_MSG
|
68
|
+
elsif !DirectiveComment::AVAILABLE_MODES.include?(mode)
|
69
|
+
INVALID_MODE_NAME_MSG
|
70
|
+
elsif directive_comment.missing_cop_name?
|
71
|
+
MISSING_COP_NAME_MSG
|
72
|
+
else
|
73
|
+
MALFORMED_COP_NAMES_MSG
|
74
|
+
end
|
75
|
+
|
76
|
+
"#{COMMON_MSG} #{additional_msg}"
|
77
|
+
end
|
78
|
+
# rubocop:enable Metrics/MethodLength
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
# rubocop:enable Lint/RedundantCopDisableDirective
|
84
|
+
# rubocop:enable Style/DoubleCopDisableDirective
|
@@ -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
|
@@ -7,7 +7,7 @@ module RuboCop
|
|
7
7
|
# expected fields for format/sprintf/#% and what is actually
|
8
8
|
# passed as arguments.
|
9
9
|
#
|
10
|
-
# In addition it checks whether different formats are used in the same
|
10
|
+
# In addition, it checks whether different formats are used in the same
|
11
11
|
# format string. Do not mix numbered, unnumbered, and named formats in
|
12
12
|
# the same format string.
|
13
13
|
#
|
@@ -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
|