rubocop 1.71.2 → 1.75.2
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 +118 -21
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +3 -1
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/comment_config.rb +1 -1
- data/lib/rubocop/config.rb +39 -6
- data/lib/rubocop/config_loader.rb +48 -9
- data/lib/rubocop/config_loader_resolver.rb +24 -9
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +46 -2
- data/lib/rubocop/config_validator.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +7 -3
- 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/node_pattern_groups.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
- data/lib/rubocop/cop/internal_affairs.rb +2 -16
- data/lib/rubocop/cop/layout/block_alignment.rb +2 -0
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +3 -3
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +27 -1
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
- 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/indentation_width.rb +1 -0
- data/lib/rubocop/cop/layout/line_length.rb +8 -4
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +9 -5
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -5
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +4 -1
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
- data/lib/rubocop/cop/lint/debugger.rb +2 -2
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -17
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- 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 +103 -9
- data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
- data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
- data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +8 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +12 -1
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -0
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
- data/lib/rubocop/cop/lint/void.rb +7 -0
- data/lib/rubocop/cop/metrics/block_length.rb +1 -0
- data/lib/rubocop/cop/metrics/method_length.rb +1 -0
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- 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/check_line_breakable.rb +2 -2
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +0 -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/method_complexity.rb +1 -0
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +15 -3
- data/lib/rubocop/cop/mixin/string_help.rb +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.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/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +64 -8
- data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
- data/lib/rubocop/cop/naming/variable_name.rb +51 -6
- data/lib/rubocop/cop/registry.rb +9 -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/array_intersect.rb +39 -28
- data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
- data/lib/rubocop/cop/style/class_and_module_children.rb +29 -7
- data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
- data/lib/rubocop/cop/style/collection_methods.rb +1 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +1 -0
- data/lib/rubocop/cop/style/commented_keyword.rb +10 -3
- data/lib/rubocop/cop/style/comparable_between.rb +75 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +3 -0
- data/lib/rubocop/cop/style/double_negation.rb +2 -2
- data/lib/rubocop/cop/style/empty_literal.rb +4 -0
- data/lib/rubocop/cop/style/endless_method.rb +163 -18
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
- data/lib/rubocop/cop/style/exponential_notation.rb +2 -2
- data/lib/rubocop/cop/style/for.rb +1 -0
- data/lib/rubocop/cop/style/format_string_token.rb +38 -11
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
- data/lib/rubocop/cop/style/guard_clause.rb +2 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -2
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +105 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +3 -0
- data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
- data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +9 -5
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
- data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
- data/lib/rubocop/cop/style/it_block_parameter.rb +100 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +13 -7
- data/lib/rubocop/cop/style/lambda.rb +1 -0
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/map_into_array.rb +1 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +4 -4
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
- data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/object_then.rb +1 -0
- data/lib/rubocop/cop/style/proc.rb +1 -0
- data/lib/rubocop/cop/style/raise_args.rb +8 -8
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +57 -0
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +14 -4
- data/lib/rubocop/cop/style/redundant_format.rb +257 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +20 -5
- data/lib/rubocop/cop/style/redundant_self.rb +1 -0
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/select_by_regexp.rb +4 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +3 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -3
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +41 -106
- data/lib/rubocop/cop/style/string_concatenation.rb +1 -1
- data/lib/rubocop/cop/style/super_arguments.rb +1 -2
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -0
- 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 +2 -2
- data/lib/rubocop/cop/utils/format_string.rb +10 -5
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +2 -7
- data/lib/rubocop/cop/variable_force.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +12 -1
- data/lib/rubocop/directive_comment.rb +36 -3
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/lsp/runtime.rb +6 -4
- data/lib/rubocop/lsp/server.rb +0 -2
- data/lib/rubocop/lsp/stdin_runner.rb +3 -1
- data/lib/rubocop/magic_comment.rb +8 -0
- 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 +13 -1
- data/lib/rubocop/rspec/shared_contexts.rb +35 -0
- data/lib/rubocop/rspec/support.rb +3 -0
- data/lib/rubocop/runner.rb +5 -1
- data/lib/rubocop/server/cache.rb +47 -11
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +30 -8
- data/lib/rubocop.rb +10 -1
- data/lib/ruby_lsp/rubocop/addon.rb +7 -10
- data/lib/ruby_lsp/rubocop/{wraps_built_in_lsp_runtime.rb → runtime_adapter.rb} +25 -10
- metadata +43 -12
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
@@ -97,34 +97,31 @@ module RuboCop
|
|
97
97
|
else
|
98
98
|
correct_to_elsif_from_if_inside_else_form(corrector, node, node.condition)
|
99
99
|
end
|
100
|
-
|
101
|
-
corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
|
102
|
-
return unless (if_branch = node.if_branch)
|
103
|
-
|
104
|
-
range = range_by_whole_lines(if_branch.source_range, include_final_newline: true)
|
105
|
-
corrector.remove(range)
|
106
100
|
end
|
107
101
|
|
108
102
|
def correct_to_elsif_from_modifier_form(corrector, node)
|
109
|
-
corrector.replace(node.parent.loc.else,
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
103
|
+
corrector.replace(node.parent.loc.else, "elsif #{node.condition.source}")
|
104
|
+
|
105
|
+
condition_range = range_between(
|
106
|
+
node.if_branch.source_range.end_pos, node.condition.source_range.end_pos
|
107
|
+
)
|
108
|
+
corrector.remove(condition_range)
|
114
109
|
end
|
115
110
|
|
116
|
-
def correct_to_elsif_from_if_inside_else_form(corrector, node, condition)
|
111
|
+
def correct_to_elsif_from_if_inside_else_form(corrector, node, condition) # rubocop:disable Metrics/AbcSize
|
117
112
|
corrector.replace(node.parent.loc.else, "elsif #{condition.source}")
|
118
113
|
|
119
114
|
if_condition_range = if_condition_range(node, condition)
|
120
115
|
|
121
116
|
if (if_branch = node.if_branch)
|
122
|
-
corrector.replace(if_condition_range, if_branch.source)
|
117
|
+
corrector.replace(if_condition_range, range_with_comments(if_branch).source)
|
118
|
+
corrector.remove(range_with_comments_and_lines(if_branch))
|
123
119
|
else
|
124
120
|
corrector.remove(range_by_whole_lines(if_condition_range, include_final_newline: true))
|
125
121
|
end
|
126
122
|
|
127
123
|
corrector.remove(condition)
|
124
|
+
corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
|
128
125
|
end
|
129
126
|
|
130
127
|
def then?(node)
|
@@ -164,8 +164,8 @@ module RuboCop
|
|
164
164
|
|
165
165
|
def too_long_due_to_comment_after_modifier?(node, comment)
|
166
166
|
source_length = processed_source.lines[node.first_line - 1].length
|
167
|
-
|
168
|
-
|
167
|
+
|
168
|
+
max_line_length.between?(source_length - comment.source_range.length, source_length)
|
169
169
|
end
|
170
170
|
|
171
171
|
def allowed_patterns
|
@@ -46,6 +46,7 @@ module RuboCop
|
|
46
46
|
|
47
47
|
MSG = 'Use `%<inverse>s` instead of inverting `%<method>s`.'
|
48
48
|
CLASS_COMPARISON_METHODS = %i[<= >= < >].freeze
|
49
|
+
SAFE_NAVIGATION_INCOMPATIBLE_METHODS = (CLASS_COMPARISON_METHODS + %i[any? none?]).freeze
|
49
50
|
EQUALITY_METHODS = %i[== != =~ !~ <= >= < >].freeze
|
50
51
|
NEGATED_EQUALITY_METHODS = %i[!= !~].freeze
|
51
52
|
CAMEL_CASE = /[A-Z]+[a-z]+/.freeze
|
@@ -77,7 +78,7 @@ module RuboCop
|
|
77
78
|
def on_send(node)
|
78
79
|
inverse_candidate?(node) do |method_call, lhs, method, rhs|
|
79
80
|
return unless inverse_methods.key?(method)
|
80
|
-
return if negated?(node) ||
|
81
|
+
return if negated?(node) || safe_navigation_incompatible?(method_call)
|
81
82
|
return if part_of_ignored_node?(node)
|
82
83
|
return if possible_class_hierarchy_check?(lhs, rhs, method)
|
83
84
|
|
@@ -105,6 +106,7 @@ module RuboCop
|
|
105
106
|
end
|
106
107
|
|
107
108
|
alias on_numblock on_block
|
109
|
+
alias on_itblock on_block
|
108
110
|
|
109
111
|
private
|
110
112
|
|
@@ -154,10 +156,6 @@ module RuboCop
|
|
154
156
|
node.parent.respond_to?(:method?) && node.parent.method?(:!)
|
155
157
|
end
|
156
158
|
|
157
|
-
def relational_comparison_with_safe_navigation?(node)
|
158
|
-
node.csend_type? && CLASS_COMPARISON_METHODS.include?(node.method_name)
|
159
|
-
end
|
160
|
-
|
161
159
|
def not_to_receiver(node, method_call)
|
162
160
|
node.loc.selector.begin.join(method_call.source_range.begin)
|
163
161
|
end
|
@@ -166,6 +164,12 @@ module RuboCop
|
|
166
164
|
method_call.source_range.end.join(node.source_range.end)
|
167
165
|
end
|
168
166
|
|
167
|
+
def safe_navigation_incompatible?(node)
|
168
|
+
return false unless node.csend_type?
|
169
|
+
|
170
|
+
SAFE_NAVIGATION_INCOMPATIBLE_METHODS.include?(node.method_name)
|
171
|
+
end
|
172
|
+
|
169
173
|
# When comparing classes, `!(Integer < Numeric)` is not the same as
|
170
174
|
# `Integer > Numeric`.
|
171
175
|
def possible_class_hierarchy_check?(lhs, rhs, method)
|
@@ -89,8 +89,8 @@ module RuboCop
|
|
89
89
|
|
90
90
|
def inheritance_check?(node)
|
91
91
|
argument = node.first_argument
|
92
|
-
node.method?(:<) &&
|
93
|
-
|
92
|
+
node.method?(:<) && argument.const_type? &&
|
93
|
+
argument.short_name.to_s.upcase != argument.short_name.to_s
|
94
94
|
end
|
95
95
|
|
96
96
|
def preferred_condition(node)
|
@@ -32,7 +32,7 @@ module RuboCop
|
|
32
32
|
|
33
33
|
# To try to avoid doing two regex checks on every string,
|
34
34
|
# shortcut out if the string does not look like an IP address
|
35
|
-
return false unless
|
35
|
+
return false unless potential_ip?(contents)
|
36
36
|
|
37
37
|
::Resolv::IPv4::Regex.match?(contents) || ::Resolv::IPv6::Regex.match?(contents)
|
38
38
|
end
|
@@ -52,7 +52,7 @@ module RuboCop
|
|
52
52
|
Array(allowed_addresses).map(&:downcase)
|
53
53
|
end
|
54
54
|
|
55
|
-
def
|
55
|
+
def potential_ip?(str)
|
56
56
|
# If the string is too long, it can't be an IP
|
57
57
|
return false if too_long?(str)
|
58
58
|
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for blocks with one argument where `it` block parameter can be used.
|
7
|
+
#
|
8
|
+
# It provides three `EnforcedStyle` options:
|
9
|
+
#
|
10
|
+
# 1. `only_numbered_parameters` (default) ... Detects only numbered block parameters.
|
11
|
+
# 2. `always` ... Always uses the `it` block parameter.
|
12
|
+
# 3. `disallow` ... Disallows the `it` block parameter.
|
13
|
+
#
|
14
|
+
# A single numbered parameter is detected when `only_numbered_parameters` or `always`.
|
15
|
+
#
|
16
|
+
# @example EnforcedStyle: only_numbered_parameters (default)
|
17
|
+
# # bad
|
18
|
+
# block { do_something(_1) }
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# block { do_something(it) }
|
22
|
+
# block { |named_param| do_something(named_param) }
|
23
|
+
#
|
24
|
+
# @example EnforcedStyle: always
|
25
|
+
# # bad
|
26
|
+
# block { do_something(_1) }
|
27
|
+
# block { |named_param| do_something(named_param) }
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# block { do_something(it) }
|
31
|
+
#
|
32
|
+
# @example EnforcedStyle: disallow
|
33
|
+
# # bad
|
34
|
+
# block { do_something(it) }
|
35
|
+
#
|
36
|
+
# # good
|
37
|
+
# block { do_something(_1) }
|
38
|
+
# block { |named_param| do_something(named_param) }
|
39
|
+
#
|
40
|
+
class ItBlockParameter < Base
|
41
|
+
include ConfigurableEnforcedStyle
|
42
|
+
extend TargetRubyVersion
|
43
|
+
extend AutoCorrector
|
44
|
+
|
45
|
+
MSG_USE_IT_BLOCK_PARAMETER = 'Use `it` block parameter.'
|
46
|
+
MSG_AVOID_IT_BLOCK_PARAMETER = 'Avoid using `it` block parameter.'
|
47
|
+
|
48
|
+
minimum_target_ruby_version 3.4
|
49
|
+
|
50
|
+
def on_block(node)
|
51
|
+
return unless style == :always
|
52
|
+
return unless node.arguments.one?
|
53
|
+
|
54
|
+
# `restarg`, `kwrestarg`, `blockarg` nodes can return early.
|
55
|
+
return unless node.first_argument.arg_type?
|
56
|
+
|
57
|
+
variables = find_block_variables(node, node.first_argument.source)
|
58
|
+
|
59
|
+
variables.each do |variable|
|
60
|
+
add_offense(variable, message: MSG_USE_IT_BLOCK_PARAMETER) do |corrector|
|
61
|
+
corrector.remove(node.arguments)
|
62
|
+
corrector.replace(variable, 'it')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def on_numblock(node)
|
68
|
+
return if style == :disallow
|
69
|
+
return unless node.children[1] == 1
|
70
|
+
|
71
|
+
variables = find_block_variables(node, '_1')
|
72
|
+
|
73
|
+
variables.each do |variable|
|
74
|
+
add_offense(variable, message: MSG_USE_IT_BLOCK_PARAMETER) do |corrector|
|
75
|
+
corrector.replace(variable, 'it')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def on_itblock(node)
|
81
|
+
return unless style == :disallow
|
82
|
+
|
83
|
+
variables = find_block_variables(node, 'it')
|
84
|
+
|
85
|
+
variables.each do |variable|
|
86
|
+
add_offense(variable, message: MSG_AVOID_IT_BLOCK_PARAMETER)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def find_block_variables(node, block_argument_name)
|
93
|
+
node.each_descendant(:lvar).select do |descendant|
|
94
|
+
descendant.source == block_argument_name
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -42,19 +42,25 @@ module RuboCop
|
|
42
42
|
return if kwarg_nodes.empty?
|
43
43
|
|
44
44
|
add_offense(node) do |corrector|
|
45
|
-
|
46
|
-
|
45
|
+
defining_node = node.each_ancestor(:any_def, :block).first
|
46
|
+
next if processed_source.contains_comment?(arguments_range(defining_node))
|
47
|
+
next unless node.parent.find(&:kwoptarg_type?) == node
|
47
48
|
|
48
|
-
|
49
|
-
append_newline_to_last_kwoptarg(arguments, corrector) unless parentheses?(arguments)
|
50
|
-
|
51
|
-
remove_kwargs(kwarg_nodes, corrector)
|
52
|
-
end
|
49
|
+
autocorrect(corrector, node, defining_node, kwarg_nodes)
|
53
50
|
end
|
54
51
|
end
|
55
52
|
|
56
53
|
private
|
57
54
|
|
55
|
+
def autocorrect(corrector, node, defining_node, kwarg_nodes)
|
56
|
+
corrector.insert_before(node, "#{kwarg_nodes.map(&:source).join(', ')}, ")
|
57
|
+
|
58
|
+
arguments = defining_node.arguments
|
59
|
+
append_newline_to_last_kwoptarg(arguments, corrector) unless parentheses?(arguments)
|
60
|
+
|
61
|
+
remove_kwargs(kwarg_nodes, corrector)
|
62
|
+
end
|
63
|
+
|
58
64
|
def append_newline_to_last_kwoptarg(arguments, corrector)
|
59
65
|
last_argument = arguments.last
|
60
66
|
return if last_argument.type?(:kwrestarg, :blockarg)
|
@@ -36,7 +36,7 @@ module RuboCop
|
|
36
36
|
include RangeHelp
|
37
37
|
extend AutoCorrector
|
38
38
|
|
39
|
-
MSG = 'Use `\\` instead of
|
39
|
+
MSG = 'Use `\\` instead of `%<operator>s` to concatenate multiline strings.'
|
40
40
|
CONCAT_TOKEN_TYPES = %i[tPLUS tLSHFT].freeze
|
41
41
|
SIMPLE_STRING_TOKEN_TYPE = :tSTRING
|
42
42
|
COMPLEX_STRING_BEGIN_TOKEN = :tSTRING_BEG
|
@@ -61,14 +61,20 @@ module RuboCop
|
|
61
61
|
successor = tokens[index + 2]
|
62
62
|
|
63
63
|
return unless eligible_token_set?(predecessor, operator, successor)
|
64
|
-
|
65
64
|
return if same_line?(operator, successor)
|
66
65
|
|
67
66
|
next_successor = token_after_last_string(successor, index)
|
68
|
-
|
69
67
|
return unless eligible_next_successor?(next_successor)
|
70
68
|
|
71
|
-
|
69
|
+
register_offense(operator)
|
70
|
+
end
|
71
|
+
|
72
|
+
def register_offense(operator)
|
73
|
+
message = format(MSG, operator: operator.text)
|
74
|
+
|
75
|
+
add_offense(operator.pos, message: message) do |corrector|
|
76
|
+
autocorrect(corrector, operator.pos)
|
77
|
+
end
|
72
78
|
end
|
73
79
|
|
74
80
|
def autocorrect(corrector, operator_range)
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
49
49
|
|
50
50
|
def inside_endless_method_def?(node)
|
51
51
|
# parens are required around arguments inside an endless method
|
52
|
-
node.each_ancestor(:
|
52
|
+
node.each_ancestor(:any_def).any?(&:endless?) && node.arguments.any?
|
53
53
|
end
|
54
54
|
|
55
55
|
def require_parentheses_for_hash_value_omission?(node) # rubocop:disable Metrics/PerceivedComplexity
|
@@ -108,7 +108,7 @@ module RuboCop
|
|
108
108
|
end
|
109
109
|
|
110
110
|
def call_in_literals?(node)
|
111
|
-
parent = node.parent&.
|
111
|
+
parent = node.parent&.any_block_type? ? node.parent.parent : node.parent
|
112
112
|
return false unless parent
|
113
113
|
|
114
114
|
parent.type?(:pair, :array, :range) ||
|
@@ -117,7 +117,7 @@ module RuboCop
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def call_in_logical_operators?(node)
|
120
|
-
parent = node.parent&.
|
120
|
+
parent = node.parent&.any_block_type? ? node.parent.parent : node.parent
|
121
121
|
return false unless parent
|
122
122
|
|
123
123
|
logical_operator?(parent) ||
|
@@ -153,7 +153,7 @@ module RuboCop
|
|
153
153
|
end
|
154
154
|
|
155
155
|
def call_in_argument_with_block?(node)
|
156
|
-
parent = node.parent&.
|
156
|
+
parent = node.parent&.any_block_type? && node.parent.parent
|
157
157
|
return false unless parent
|
158
158
|
|
159
159
|
parent.type?(:call, :super, :yield)
|
@@ -36,12 +36,13 @@ module RuboCop
|
|
36
36
|
end
|
37
37
|
|
38
38
|
alias on_numblock on_block
|
39
|
+
alias on_itblock on_block
|
39
40
|
|
40
41
|
def on_send(node)
|
41
42
|
return if ignored_node?(node)
|
42
43
|
|
43
44
|
return unless (receiver = node.receiver)
|
44
|
-
return unless receiver.any_block_type? && receiver.
|
45
|
+
return unless receiver.any_block_type? && receiver.keywords?
|
45
46
|
|
46
47
|
range = range_between(receiver.loc.end.begin_pos, node.source_range.end_pos)
|
47
48
|
|
@@ -28,7 +28,7 @@ module RuboCop
|
|
28
28
|
MSG = 'Avoid multi-line chains of blocks.'
|
29
29
|
|
30
30
|
def on_block(node)
|
31
|
-
node.send_node.each_node(:
|
31
|
+
node.send_node.each_node(:call) do |send_node|
|
32
32
|
receiver = send_node.receiver
|
33
33
|
|
34
34
|
next unless receiver&.any_block_type? && receiver.multiline?
|
@@ -44,6 +44,7 @@ module RuboCop
|
|
44
44
|
end
|
45
45
|
|
46
46
|
alias on_numblock on_block
|
47
|
+
alias on_itblock on_block
|
47
48
|
end
|
48
49
|
end
|
49
50
|
end
|
@@ -50,7 +50,7 @@ module RuboCop
|
|
50
50
|
corrector.remove(range_by_whole_lines(arguments.loc.end, include_final_newline: true))
|
51
51
|
end
|
52
52
|
|
53
|
-
arguments_range = arguments_range(node)
|
53
|
+
arguments_range = range_with_surrounding_space(arguments_range(node), side: :left)
|
54
54
|
# If the method name isn't on the same line as def, move it directly after def
|
55
55
|
if arguments_range.first_line != opening_line(node)
|
56
56
|
corrector.remove(node.loc.name)
|
@@ -66,14 +66,6 @@ module RuboCop
|
|
66
66
|
processed_source[arguments.last_line - 1].strip
|
67
67
|
end
|
68
68
|
|
69
|
-
def arguments_range(node)
|
70
|
-
range = range_between(
|
71
|
-
node.first_argument.source_range.begin_pos, node.last_argument.source_range.end_pos
|
72
|
-
)
|
73
|
-
|
74
|
-
range_with_surrounding_space(range, side: :left)
|
75
|
-
end
|
76
|
-
|
77
69
|
def opening_line(node)
|
78
70
|
node.first_line
|
79
71
|
end
|
@@ -46,6 +46,38 @@ module RuboCop
|
|
46
46
|
# next unless a == 1
|
47
47
|
# puts a
|
48
48
|
# end
|
49
|
+
#
|
50
|
+
# @example AllowConsecutiveConditionals: false (default)
|
51
|
+
# # bad
|
52
|
+
# [1, 2].each do |a|
|
53
|
+
# if a == 1
|
54
|
+
# puts a
|
55
|
+
# end
|
56
|
+
# if a == 2
|
57
|
+
# puts a
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# # good
|
62
|
+
# [1, 2].each do |a|
|
63
|
+
# if a == 1
|
64
|
+
# puts a
|
65
|
+
# end
|
66
|
+
# next unless a == 2
|
67
|
+
# puts a
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# @example AllowConsecutiveConditionals: true
|
71
|
+
# # good
|
72
|
+
# [1, 2].each do |a|
|
73
|
+
# if a == 1
|
74
|
+
# puts a
|
75
|
+
# end
|
76
|
+
# if a == 2
|
77
|
+
# puts a
|
78
|
+
# end
|
79
|
+
# end
|
80
|
+
#
|
49
81
|
class Next < Base
|
50
82
|
include ConfigurableEnforcedStyle
|
51
83
|
include MinBodyLength
|
@@ -72,6 +104,7 @@ module RuboCop
|
|
72
104
|
end
|
73
105
|
|
74
106
|
alias on_numblock on_block
|
107
|
+
alias on_itblock on_block
|
75
108
|
|
76
109
|
def on_while(node)
|
77
110
|
check(node)
|
@@ -86,6 +119,9 @@ module RuboCop
|
|
86
119
|
|
87
120
|
offending_node = offense_node(node.body)
|
88
121
|
|
122
|
+
return if allowed_consecutive_conditionals? &&
|
123
|
+
consecutive_conditionals?(offending_node)
|
124
|
+
|
89
125
|
add_offense(offense_location(offending_node)) do |corrector|
|
90
126
|
if offending_node.modifier_form?
|
91
127
|
autocorrect_modifier(corrector, offending_node)
|
@@ -227,6 +263,14 @@ module RuboCop
|
|
227
263
|
|
228
264
|
corrector.remove_leading(buffer.line_range(lineno), adjustment) if adjustment.positive?
|
229
265
|
end
|
266
|
+
|
267
|
+
def consecutive_conditionals?(if_node)
|
268
|
+
if_node.parent&.begin_type? && if_node.left_sibling&.if_type?
|
269
|
+
end
|
270
|
+
|
271
|
+
def allowed_consecutive_conditionals?
|
272
|
+
cop_config.fetch('AllowConsecutiveConditionals', false)
|
273
|
+
end
|
230
274
|
end
|
231
275
|
end
|
232
276
|
end
|
@@ -3,15 +3,15 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Checks the args passed to `fail` and `raise`.
|
7
|
-
# style (default), it recommends passing the exception class and message
|
8
|
-
# to `raise`, rather than construct an instance of the error. It will
|
9
|
-
# still allow passing just a message, or the construction of an error
|
10
|
-
# with more than one argument.
|
6
|
+
# Checks the args passed to `fail` and `raise`.
|
11
7
|
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
8
|
+
# Exploded style (default) enforces passing the exception class and message
|
9
|
+
# arguments separately, rather than constructing an instance of the error.
|
10
|
+
#
|
11
|
+
# Compact style enforces constructing an error instance.
|
12
|
+
#
|
13
|
+
# Both styles allow passing just a message, or an error instance when there is more
|
14
|
+
# than one argument.
|
15
15
|
#
|
16
16
|
# The exploded style has an `AllowedCompactTypes` configuration
|
17
17
|
# option that takes an `Array` of exception name Strings.
|
@@ -42,7 +42,28 @@ module RuboCop
|
|
42
42
|
# c
|
43
43
|
# end
|
44
44
|
#
|
45
|
+
# # bad
|
46
|
+
# a.nil? ? true : a
|
47
|
+
#
|
48
|
+
# # good
|
49
|
+
# a.nil? || a
|
50
|
+
#
|
51
|
+
# # bad
|
52
|
+
# if a.nil?
|
53
|
+
# true
|
54
|
+
# else
|
55
|
+
# a
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# # good
|
59
|
+
# a.nil? || a
|
60
|
+
#
|
61
|
+
# @example AllowedMethods: ['nonzero?'] (default)
|
62
|
+
# # good
|
63
|
+
# num.nonzero? ? true : false
|
64
|
+
#
|
45
65
|
class RedundantCondition < Base
|
66
|
+
include AllowedMethods
|
46
67
|
include CommentsHelp
|
47
68
|
include RangeHelp
|
48
69
|
extend AutoCorrector
|
@@ -128,6 +149,16 @@ module RuboCop
|
|
128
149
|
# end
|
129
150
|
return true if condition == if_branch
|
130
151
|
|
152
|
+
# e.g.
|
153
|
+
# a.nil? ? true : a
|
154
|
+
# or
|
155
|
+
# if a.nil?
|
156
|
+
# true
|
157
|
+
# else
|
158
|
+
# a
|
159
|
+
# end
|
160
|
+
return true if if_branch_is_true_type_and_else_is_not?(node)
|
161
|
+
|
131
162
|
# e.g.
|
132
163
|
# if foo
|
133
164
|
# @value = foo
|
@@ -146,6 +177,18 @@ module RuboCop
|
|
146
177
|
!use_hash_key_access?(if_branch)
|
147
178
|
end
|
148
179
|
|
180
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
181
|
+
def if_branch_is_true_type_and_else_is_not?(node)
|
182
|
+
return false unless node.ternary? || node.if?
|
183
|
+
|
184
|
+
cond = node.condition
|
185
|
+
return false unless cond.call_type?
|
186
|
+
return false if !cond.predicate_method? || allowed_method?(cond.method_name)
|
187
|
+
|
188
|
+
node.if_branch&.true_type? && node.else_branch && !node.else_branch.true_type?
|
189
|
+
end
|
190
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
191
|
+
|
149
192
|
def branches_have_assignment?(node)
|
150
193
|
_condition, if_branch, else_branch = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
151
194
|
|
@@ -187,6 +230,14 @@ module RuboCop
|
|
187
230
|
node.type?(:kwsplat, :forwarded_kwrestarg)
|
188
231
|
end
|
189
232
|
|
233
|
+
def wrap_arguments_with_parens(condition)
|
234
|
+
method = condition.source_range.begin.join(condition.loc.selector.end)
|
235
|
+
arguments = condition.first_argument.source_range.begin.join(condition.source_range.end)
|
236
|
+
|
237
|
+
"#{method.source}(#{arguments.source})"
|
238
|
+
end
|
239
|
+
|
240
|
+
# rubocop:disable Metrics/AbcSize
|
190
241
|
def if_source(if_branch, arithmetic_operation)
|
191
242
|
if branches_have_method?(if_branch.parent) && if_branch.parenthesized?
|
192
243
|
if_branch.source.delete_suffix(')')
|
@@ -194,10 +245,16 @@ module RuboCop
|
|
194
245
|
argument_source = if_branch.first_argument.source
|
195
246
|
|
196
247
|
"#{if_branch.receiver.source} #{if_branch.method_name} (#{argument_source}"
|
248
|
+
elsif if_branch.true_type?
|
249
|
+
condition = if_branch.parent.condition
|
250
|
+
return condition.source if condition.arguments.empty?
|
251
|
+
|
252
|
+
wrap_arguments_with_parens(condition)
|
197
253
|
else
|
198
254
|
if_branch.source
|
199
255
|
end
|
200
256
|
end
|
257
|
+
# rubocop:enable Metrics/AbcSize
|
201
258
|
|
202
259
|
def else_source(else_branch, arithmetic_operation) # rubocop:disable Metrics/AbcSize
|
203
260
|
if arithmetic_operation
|