rubocop 1.91.0 → 1.92.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 +1 -1
- data/config/default.yml +4 -1
- data/lib/rubocop/cached_data.rb +47 -7
- data/lib/rubocop/changed_files.rb +35 -13
- data/lib/rubocop/cli/command/cop_names.rb +57 -0
- data/lib/rubocop/cli/command/execute_runner.rb +2 -2
- data/lib/rubocop/cli/command/explain.rb +34 -0
- data/lib/rubocop/cli/command/show_cops.rb +6 -0
- data/lib/rubocop/cli/command/show_docs_url.rb +6 -4
- data/lib/rubocop/cli.rb +3 -2
- data/lib/rubocop/comment_config.rb +17 -8
- data/lib/rubocop/config_loader.rb +6 -3
- data/lib/rubocop/config_loader_resolver.rb +37 -12
- data/lib/rubocop/config_obsoletion/removed_cop.rb +1 -1
- data/lib/rubocop/config_validator.rb +11 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +10 -5
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/base.rb +42 -21
- data/lib/rubocop/cop/bundler/gem_comment.rb +0 -1
- data/lib/rubocop/cop/bundler/ordered_gems.rb +0 -8
- data/lib/rubocop/cop/cop_documentation.rb +81 -0
- data/lib/rubocop/cop/cop_explanation.rb +140 -0
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +13 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +37 -7
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +25 -4
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +34 -0
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +45 -8
- data/lib/rubocop/cop/documentation.rb +1 -1
- data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +0 -6
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +2 -5
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +0 -7
- data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
- data/lib/rubocop/cop/layout/argument_alignment.rb +5 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +27 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +25 -9
- data/lib/rubocop/cop/layout/class_structure.rb +29 -7
- data/lib/rubocop/cop/layout/def_end_alignment.rb +4 -0
- data/lib/rubocop/cop/layout/dot_position.rb +25 -15
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +21 -8
- data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +9 -3
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +19 -17
- data/lib/rubocop/cop/layout/extra_spacing.rb +4 -0
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +27 -1
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +15 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +16 -8
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +16 -12
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +7 -3
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +15 -0
- data/lib/rubocop/cop/layout/indentation_consistency.rb +22 -5
- data/lib/rubocop/cop/layout/indentation_style.rb +4 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +8 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
- data/lib/rubocop/cop/layout/line_length.rb +153 -21
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +12 -0
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +8 -1
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +9 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +6 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +30 -5
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +22 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +15 -2
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
- data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +6 -11
- data/lib/rubocop/cop/layout/space_around_keyword.rb +10 -0
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +4 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +15 -2
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +31 -8
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -12
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +2 -1
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +6 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +3 -1
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +4 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +15 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +63 -19
- data/lib/rubocop/cop/lint/loop.rb +24 -2
- data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +71 -11
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +18 -3
- data/lib/rubocop/cop/lint/number_conversion.rb +3 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +12 -1
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +13 -2
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +47 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -0
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +18 -1
- data/lib/rubocop/cop/lint/useless_assignment.rb +14 -7
- data/lib/rubocop/cop/lint/useless_setter_call.rb +7 -4
- data/lib/rubocop/cop/lint/void.rb +8 -1
- data/lib/rubocop/cop/metrics/class_length.rb +4 -2
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
- data/lib/rubocop/cop/metrics/module_length.rb +4 -2
- data/lib/rubocop/cop/mixin/alignment.rb +4 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +23 -19
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +8 -2
- data/lib/rubocop/cop/mixin/code_length.rb +10 -2
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -1
- data/lib/rubocop/cop/mixin/endless_method_body_help.rb +105 -0
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +2 -2
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +24 -5
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +26 -2
- data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +9 -0
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +17 -2
- data/lib/rubocop/cop/mixin/project_index_help.rb +15 -0
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +13 -3
- data/lib/rubocop/cop/mixin/statement_modifier.rb +25 -4
- data/lib/rubocop/cop/mixin/visibility_help.rb +2 -1
- data/lib/rubocop/cop/mixin.rb +2 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +0 -16
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
- data/lib/rubocop/cop/naming/predicate_prefix.rb +7 -22
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
- data/lib/rubocop/cop/offense.rb +59 -3
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/json_load.rb +16 -4
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +37 -2
- data/lib/rubocop/cop/style/alias.rb +18 -5
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
- data/lib/rubocop/cop/style/and_or.rb +6 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +32 -3
- data/lib/rubocop/cop/style/attr.rb +3 -4
- data/lib/rubocop/cop/style/bitwise_predicate.rb +6 -4
- data/lib/rubocop/cop/style/block_delimiters.rb +35 -3
- data/lib/rubocop/cop/style/case_like_if.rb +6 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +56 -16
- data/lib/rubocop/cop/style/class_methods_definitions.rb +15 -0
- data/lib/rubocop/cop/style/collection_querying.rb +79 -46
- data/lib/rubocop/cop/style/combinable_loops.rb +89 -11
- data/lib/rubocop/cop/style/concat_array_literals.rb +58 -7
- data/lib/rubocop/cop/style/conditional_assignment.rb +4 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +65 -9
- data/lib/rubocop/cop/style/double_negation.rb +11 -0
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +3 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +53 -11
- data/lib/rubocop/cop/style/endless_method.rb +71 -6
- data/lib/rubocop/cop/style/exact_regexp_match.rb +45 -8
- data/lib/rubocop/cop/style/explicit_block_argument.rb +50 -10
- data/lib/rubocop/cop/style/float_division.rb +22 -2
- data/lib/rubocop/cop/style/for.rb +53 -2
- data/lib/rubocop/cop/style/format_string.rb +28 -6
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
- data/lib/rubocop/cop/style/guard_clause.rb +31 -22
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +4 -0
- data/lib/rubocop/cop/style/hash_conversion.rb +28 -8
- data/lib/rubocop/cop/style/hash_lookup_method.rb +32 -9
- data/lib/rubocop/cop/style/hash_syntax.rb +16 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +21 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +32 -26
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -0
- data/lib/rubocop/cop/style/if_with_semicolon.rb +47 -4
- data/lib/rubocop/cop/style/inverse_methods.rb +24 -2
- data/lib/rubocop/cop/style/it_block_parameter.rb +94 -4
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +3 -1
- data/lib/rubocop/cop/style/lambda.rb +34 -1
- data/lib/rubocop/cop/style/lambda_call.rb +7 -2
- data/lib/rubocop/cop/style/map_into_array.rb +1 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +80 -13
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -2
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +26 -3
- data/lib/rubocop/cop/style/method_def_parentheses.rb +29 -3
- data/lib/rubocop/cop/style/missing_else.rb +7 -1
- data/lib/rubocop/cop/style/mixin_grouping.rb +12 -3
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +45 -5
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -5
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
- data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
- data/lib/rubocop/cop/style/mutable_constant.rb +52 -7
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +2 -1
- data/lib/rubocop/cop/style/negative_array_index.rb +9 -1
- data/lib/rubocop/cop/style/nested_modifier.rb +27 -8
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
- data/lib/rubocop/cop/style/next.rb +24 -10
- data/lib/rubocop/cop/style/nil_comparison.rb +16 -4
- data/lib/rubocop/cop/style/non_nil_check.rb +1 -1
- data/lib/rubocop/cop/style/not.rb +10 -5
- data/lib/rubocop/cop/style/numeric_predicate.rb +21 -5
- data/lib/rubocop/cop/style/one_line_conditional.rb +13 -2
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +1 -1
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +14 -3
- data/lib/rubocop/cop/style/raise_args.rb +19 -9
- data/lib/rubocop/cop/style/reduce_to_hash.rb +17 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +22 -4
- data/lib/rubocop/cop/style/redundant_condition.rb +30 -13
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -0
- data/lib/rubocop/cop/style/redundant_exception.rb +15 -3
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +9 -1
- data/lib/rubocop/cop/style/redundant_freeze.rb +11 -3
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +24 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +12 -1
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +7 -0
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +20 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +4 -0
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +28 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +38 -4
- data/lib/rubocop/cop/style/regexp_literal.rb +75 -26
- data/lib/rubocop/cop/style/require_order.rb +25 -8
- data/lib/rubocop/cop/style/rescue_modifier.rb +11 -9
- data/lib/rubocop/cop/style/return_nil.rb +17 -2
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
- data/lib/rubocop/cop/style/sample.rb +9 -8
- data/lib/rubocop/cop/style/self_assignment.rb +12 -15
- data/lib/rubocop/cop/style/semicolon.rb +16 -5
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +4 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +21 -4
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +29 -5
- data/lib/rubocop/cop/style/string_concatenation.rb +9 -3
- data/lib/rubocop/cop/style/struct_inheritance.rb +6 -0
- data/lib/rubocop/cop/style/super_arguments.rb +3 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +24 -6
- data/lib/rubocop/cop/style/ternary_parentheses.rb +23 -1
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +23 -19
- data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +24 -9
- data/lib/rubocop/cop/style/yoda_expression.rb +10 -1
- data/lib/rubocop/cop/team.rb +10 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +14 -1
- data/lib/rubocop/formatter/base_formatter.rb +22 -0
- data/lib/rubocop/formatter/formatter_set.rb +4 -0
- data/lib/rubocop/formatter/json_formatter.rb +71 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +3 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +3 -1
- data/lib/rubocop/formatter/sarif_formatter.rb +12 -7
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +3 -1
- data/lib/rubocop/lsp/routes.rb +23 -23
- data/lib/rubocop/lsp/runtime.rb +47 -11
- data/lib/rubocop/lsp/stdin_runner.rb +11 -5
- data/lib/rubocop/lsp.rb +5 -2
- data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
- data/lib/rubocop/mcp/explain_tool.rb +68 -0
- data/lib/rubocop/mcp/scope.rb +65 -0
- data/lib/rubocop/mcp/server.rb +184 -76
- data/lib/rubocop/mcp/source_files.rb +35 -0
- data/lib/rubocop/offense_limit.rb +30 -0
- data/lib/rubocop/options.rb +45 -10
- data/lib/rubocop/plugin/configuration_integrator.rb +12 -5
- data/lib/rubocop/remote_config.rb +4 -1
- data/lib/rubocop/result_cache.rb +20 -13
- data/lib/rubocop/runner.rb +109 -41
- data/lib/rubocop/server/cache.rb +6 -6
- data/lib/rubocop/target_ruby.rb +21 -9
- data/lib/rubocop/util.rb +69 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +5 -0
- metadata +16 -5
|
@@ -96,15 +96,22 @@ module RuboCop
|
|
|
96
96
|
[parenthesized, first_line_comment(node)].compact.join(' ')
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
99
100
|
def if_body_source(if_body)
|
|
100
|
-
if
|
|
101
|
+
if unparenthesized_call_with_omitted_value?(if_body)
|
|
101
102
|
"#{method_source(if_body)}(#{if_body.arguments.map(&:source).join(', ')})"
|
|
103
|
+
elsif (value = wrapped_value(if_body))
|
|
104
|
+
prefix = if_body.source_range.begin.join(value.source_range.begin).source
|
|
105
|
+
suffix = value.source_range.end.join(if_body.source_range.end).source
|
|
106
|
+
|
|
107
|
+
"#{prefix}#{if_body_source(value)}#{suffix}"
|
|
102
108
|
else
|
|
103
109
|
if_body.source
|
|
104
110
|
end
|
|
105
111
|
end
|
|
106
112
|
|
|
107
|
-
def
|
|
113
|
+
def unparenthesized_call_with_omitted_value?(if_body)
|
|
114
|
+
return false if !if_body.call_type? || if_body.method?(:[]=) || if_body.parenthesized?
|
|
108
115
|
return false unless (last_argument = if_body.last_argument)
|
|
109
116
|
|
|
110
117
|
last_argument.hash_type? && last_argument.pairs.last&.value_omission?
|
|
@@ -116,6 +123,14 @@ module RuboCop
|
|
|
116
123
|
if_body.source_range.begin.join(end_range).source
|
|
117
124
|
end
|
|
118
125
|
|
|
126
|
+
def wrapped_value(if_body)
|
|
127
|
+
if if_body.type?(:return, :next, :break)
|
|
128
|
+
if_body.first_argument if if_body.arguments.one?
|
|
129
|
+
elsif if_body.type?(:lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn)
|
|
130
|
+
if_body.expression
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
119
134
|
def first_line_comment(node)
|
|
120
135
|
comment = processed_source.comment_at_line(node.first_line)
|
|
121
136
|
return unless comment
|
|
@@ -137,9 +152,15 @@ module RuboCop
|
|
|
137
152
|
parent = node.parent
|
|
138
153
|
return false if parent.nil?
|
|
139
154
|
return true if parent.assignment? || parent.operator_keyword?
|
|
140
|
-
return true if
|
|
155
|
+
return true if parent.type?(:array, :pair, :call, :yield, :super)
|
|
156
|
+
|
|
157
|
+
ternary_branch_or_endless_method_body?(parent)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def ternary_branch_or_endless_method_body?(parent)
|
|
161
|
+
return parent.ternary? if parent.if_type?
|
|
141
162
|
|
|
142
|
-
|
|
163
|
+
parent.any_def_type? && parent.endless?
|
|
143
164
|
end
|
|
144
165
|
|
|
145
166
|
def comment_disables_cop?(comment)
|
|
@@ -63,9 +63,10 @@ module RuboCop
|
|
|
63
63
|
(send nil? VISIBILITY_SCOPES def)
|
|
64
64
|
PATTERN
|
|
65
65
|
|
|
66
|
+
# A modifier applies to every symbol it is given, not only to a sole argument.
|
|
66
67
|
# @!method visibility_inline_on_method_name?(node, method_name:)
|
|
67
68
|
def_node_matcher :visibility_inline_on_method_name?, <<~PATTERN
|
|
68
|
-
(send nil? VISIBILITY_SCOPES (sym %method_name))
|
|
69
|
+
(send nil? VISIBILITY_SCOPES <(sym %method_name) ...>)
|
|
69
70
|
PATTERN
|
|
70
71
|
end
|
|
71
72
|
end
|
data/lib/rubocop/cop/mixin.rb
CHANGED
|
@@ -32,6 +32,7 @@ module RuboCop
|
|
|
32
32
|
autoload :AnnotationComment, "#{__dir__}/mixin/annotation_comment"
|
|
33
33
|
autoload :EmptyParameter, "#{__dir__}/mixin/empty_parameter"
|
|
34
34
|
autoload :EndKeywordAlignment, "#{__dir__}/mixin/end_keyword_alignment"
|
|
35
|
+
autoload :EndlessMethodBodyHelp, "#{__dir__}/mixin/endless_method_body_help"
|
|
35
36
|
autoload :EndlessMethodRewriter, "#{__dir__}/mixin/endless_method_rewriter"
|
|
36
37
|
autoload :EnforceSuperclass, "#{__dir__}/mixin/enforce_superclass"
|
|
37
38
|
autoload :FirstElementLineBreak, "#{__dir__}/mixin/first_element_line_break"
|
|
@@ -64,6 +65,7 @@ module RuboCop
|
|
|
64
65
|
autoload :OnNormalIfUnless, "#{__dir__}/mixin/on_normal_if_unless"
|
|
65
66
|
autoload :OrderedGemNode, "#{__dir__}/mixin/ordered_gem_node"
|
|
66
67
|
autoload :Parentheses, "#{__dir__}/mixin/parentheses"
|
|
68
|
+
autoload :PatternMatchingHelp, "#{__dir__}/mixin/pattern_matching_help"
|
|
67
69
|
autoload :PercentArray, "#{__dir__}/mixin/percent_array"
|
|
68
70
|
autoload :PercentLiteral, "#{__dir__}/mixin/percent_literal"
|
|
69
71
|
autoload :PrecedingFollowingAlignment, "#{__dir__}/mixin/preceding_following_alignment"
|
|
@@ -80,22 +80,6 @@ module RuboCop
|
|
|
80
80
|
node.arguments.one? &&
|
|
81
81
|
node.first_argument.arg_type?
|
|
82
82
|
end
|
|
83
|
-
|
|
84
|
-
# When `AllCops/UseProjectIndex` is enabled, methods that override a
|
|
85
|
-
# method defined by an ancestor elsewhere in the project are not
|
|
86
|
-
# reported: renaming an override breaks the inherited contract.
|
|
87
|
-
def overrides_inherited_method?(node)
|
|
88
|
-
return false unless project_index
|
|
89
|
-
return false unless (namespace_node = node.each_ancestor(:class, :module).first)
|
|
90
|
-
|
|
91
|
-
declaration = resolve_constant_in_index(namespace_node.identifier)
|
|
92
|
-
return false unless declaration.is_a?(Rubydex::Namespace)
|
|
93
|
-
|
|
94
|
-
scope = node.defs_type? ? indexed_singleton_of(declaration) : declaration
|
|
95
|
-
!scope.nil? && inherited_index_member?(scope, "#{node.method_name}()")
|
|
96
|
-
rescue StandardError
|
|
97
|
-
false
|
|
98
|
-
end
|
|
99
83
|
end
|
|
100
84
|
end
|
|
101
85
|
end
|
|
@@ -63,7 +63,7 @@ module RuboCop
|
|
|
63
63
|
|
|
64
64
|
def self.autocorrect_incompatible_with
|
|
65
65
|
[
|
|
66
|
-
Lint::AmbiguousOperator, Style::ArgumentsForwarding,
|
|
66
|
+
Lint::AmbiguousOperator, Style::ArgumentsForwarding, Style::EndlessMethod,
|
|
67
67
|
Style::ExplicitBlockArgument, Style::MethodDefParentheses
|
|
68
68
|
]
|
|
69
69
|
end
|
|
@@ -35,7 +35,7 @@ module RuboCop
|
|
|
35
35
|
MSG = 'Use %<style>s heredoc delimiters.'
|
|
36
36
|
|
|
37
37
|
def on_heredoc(node)
|
|
38
|
-
return if correct_case_delimiters?(node)
|
|
38
|
+
return if correct_case_delimiters?(node) || corrected_delimiter_in_body?(node)
|
|
39
39
|
|
|
40
40
|
add_offense(node.loc.heredoc_end) do |corrector|
|
|
41
41
|
expr = node.source_range
|
|
@@ -52,7 +52,14 @@ module RuboCop
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def correct_case_delimiters?(node)
|
|
55
|
-
|
|
55
|
+
delimiters = delimiter_string(node)
|
|
56
|
+
delimiters == correct_delimiters(delimiters)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def corrected_delimiter_in_body?(node)
|
|
60
|
+
corrected = correct_delimiters(delimiter_string(node))
|
|
61
|
+
|
|
62
|
+
node.loc.heredoc_body.source.each_line.any? { |line| line.strip == corrected }
|
|
56
63
|
end
|
|
57
64
|
|
|
58
65
|
def correct_delimiters(source)
|
|
@@ -43,9 +43,11 @@ module RuboCop
|
|
|
43
43
|
|
|
44
44
|
return false unless /\w/.match?(delimiters)
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
forbidden_delimiter_regexps.none? { |regexp| regexp.match?(delimiters) }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def forbidden_delimiter_regexps
|
|
50
|
+
@forbidden_delimiter_regexps ||= forbidden_delimiters.map { |d| Regexp.new(d) }
|
|
49
51
|
end
|
|
50
52
|
|
|
51
53
|
def forbidden_delimiters
|
|
@@ -142,12 +142,6 @@ module RuboCop
|
|
|
142
142
|
end
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
def offending_prefixes_for(node, method_name)
|
|
146
|
-
predicate_prefixes.reject do |prefix|
|
|
147
|
-
allowed_method_name?(method_name, prefix) ||
|
|
148
|
-
(use_sorbet_sigs? && !sorbet_sig?(node, return_type: 'T::Boolean'))
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
145
|
alias on_defs on_def
|
|
152
146
|
|
|
153
147
|
def validate_config
|
|
@@ -162,6 +156,13 @@ module RuboCop
|
|
|
162
156
|
|
|
163
157
|
private
|
|
164
158
|
|
|
159
|
+
def offending_prefixes_for(node, method_name)
|
|
160
|
+
prefixes = predicate_prefixes.reject { |p| allowed_method_name?(method_name, p) }
|
|
161
|
+
return prefixes if prefixes.empty? || !use_sorbet_sigs?
|
|
162
|
+
|
|
163
|
+
sorbet_sig?(node, return_type: 'T::Boolean') ? prefixes : []
|
|
164
|
+
end
|
|
165
|
+
|
|
165
166
|
# @!method sorbet_return_type(node)
|
|
166
167
|
def_node_matcher :sorbet_return_type, <<~PATTERN
|
|
167
168
|
(block (send nil? :sig) args (send _ :returns $_type))
|
|
@@ -210,22 +211,6 @@ module RuboCop
|
|
|
210
211
|
def method_definition_macro?(macro_name)
|
|
211
212
|
cop_config['MethodDefinitionMacros'].include?(macro_name.to_s)
|
|
212
213
|
end
|
|
213
|
-
|
|
214
|
-
# When `AllCops/UseProjectIndex` is enabled, methods that override a
|
|
215
|
-
# method defined by an ancestor elsewhere in the project are not
|
|
216
|
-
# reported: renaming an override breaks the inherited contract.
|
|
217
|
-
def overrides_inherited_method?(node)
|
|
218
|
-
return false unless project_index
|
|
219
|
-
return false unless (namespace_node = node.each_ancestor(:class, :module).first)
|
|
220
|
-
|
|
221
|
-
declaration = resolve_constant_in_index(namespace_node.identifier)
|
|
222
|
-
return false unless declaration.is_a?(Rubydex::Namespace)
|
|
223
|
-
|
|
224
|
-
scope = node.defs_type? ? indexed_singleton_of(declaration) : declaration
|
|
225
|
-
!scope.nil? && inherited_index_member?(scope, "#{node.method_name}()")
|
|
226
|
-
rescue StandardError
|
|
227
|
-
false
|
|
228
|
-
end
|
|
229
214
|
end
|
|
230
215
|
end
|
|
231
216
|
end
|
|
@@ -128,7 +128,7 @@ module RuboCop
|
|
|
128
128
|
if child_node.lvar_type?
|
|
129
129
|
parent_node = child_node.parent
|
|
130
130
|
if parent_node.respond_to?(:value_omission?) && parent_node.value_omission?
|
|
131
|
-
corrector.
|
|
131
|
+
corrector.replace(parent_node.loc.operator, ": #{preferred_name}")
|
|
132
132
|
else
|
|
133
133
|
corrector.replace(child_node, preferred_name)
|
|
134
134
|
end
|
data/lib/rubocop/cop/offense.rb
CHANGED
|
@@ -86,6 +86,9 @@ module RuboCop
|
|
|
86
86
|
|
|
87
87
|
NO_LOCATION = PseudoSourceRange.new(1, 0, '', 0, 0).freeze
|
|
88
88
|
|
|
89
|
+
EMPTY_CORRECTIONS = [].freeze
|
|
90
|
+
private_constant :EMPTY_CORRECTIONS
|
|
91
|
+
|
|
89
92
|
# @api public
|
|
90
93
|
#
|
|
91
94
|
# @!attribute [r] justification
|
|
@@ -96,9 +99,43 @@ module RuboCop
|
|
|
96
99
|
# or the directive carries no reason
|
|
97
100
|
attr_reader :justification
|
|
98
101
|
|
|
102
|
+
# @api public
|
|
103
|
+
#
|
|
104
|
+
# @!attribute [r] corrections
|
|
105
|
+
#
|
|
106
|
+
# @return [Array<Correction>]
|
|
107
|
+
# the individual edits that autocorrecting this offense would make, in
|
|
108
|
+
# source order. Empty when the offense has no correction. Unlike
|
|
109
|
+
# {#corrector}, this survives serialization, so it is available on a
|
|
110
|
+
# cache hit and in parallel runs.
|
|
111
|
+
attr_reader :corrections
|
|
112
|
+
|
|
113
|
+
# @api public
|
|
114
|
+
#
|
|
115
|
+
# @!attribute [r] correction_safe
|
|
116
|
+
#
|
|
117
|
+
# @return [Boolean]
|
|
118
|
+
# whether autocorrection would apply {#corrections} in a normal `-a`
|
|
119
|
+
# run. A cop marked `Safe: false` or `SafeAutoCorrect: false` still
|
|
120
|
+
# builds its correction, but only `-A` applies it, so a consumer that
|
|
121
|
+
# applies edits itself has to make the same distinction.
|
|
122
|
+
attr_reader :correction_safe
|
|
123
|
+
|
|
124
|
+
# A single edit of an autocorrection: the source range it replaces and
|
|
125
|
+
# the text it replaces it with. An insertion has an empty range, a
|
|
126
|
+
# removal an empty replacement.
|
|
127
|
+
#
|
|
128
|
+
# @api public
|
|
129
|
+
Correction = Struct.new(:begin_pos, :end_pos, :replacement) do
|
|
130
|
+
def length
|
|
131
|
+
end_pos - begin_pos
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
99
135
|
# @api private
|
|
100
136
|
def initialize(severity, location, message, cop_name, # rubocop:disable Metrics/ParameterLists
|
|
101
|
-
status = :uncorrected, corrector = nil, justification: nil
|
|
137
|
+
status = :uncorrected, corrector = nil, justification: nil,
|
|
138
|
+
corrections: nil, correction_safe: true)
|
|
102
139
|
@severity = RuboCop::Cop::Severity.new(severity)
|
|
103
140
|
@location = location
|
|
104
141
|
|
|
@@ -112,15 +149,21 @@ module RuboCop
|
|
|
112
149
|
@status = status
|
|
113
150
|
@corrector = corrector
|
|
114
151
|
@justification = justification.freeze
|
|
152
|
+
@corrections = (corrections || corrections_from(corrector)).freeze
|
|
153
|
+
@correction_safe = correction_safe
|
|
115
154
|
freeze
|
|
116
155
|
end
|
|
117
156
|
|
|
118
157
|
def marshal_dump
|
|
119
|
-
[@severity, @location, @message, @cop_name, @status, @justification
|
|
158
|
+
[@severity, @location, @message, @cop_name, @status, @justification, @corrections,
|
|
159
|
+
@correction_safe]
|
|
120
160
|
end
|
|
121
161
|
|
|
122
162
|
def marshal_load(array)
|
|
123
|
-
@severity, @location, @message, @cop_name, @status, @justification
|
|
163
|
+
@severity, @location, @message, @cop_name, @status, @justification, @corrections,
|
|
164
|
+
@correction_safe = array
|
|
165
|
+
@corrections ||= EMPTY_CORRECTIONS
|
|
166
|
+
@correction_safe = true if @correction_safe.nil?
|
|
124
167
|
@line = @location.line
|
|
125
168
|
@column = @location.column
|
|
126
169
|
end
|
|
@@ -276,6 +319,19 @@ module RuboCop
|
|
|
276
319
|
end
|
|
277
320
|
0
|
|
278
321
|
end
|
|
322
|
+
|
|
323
|
+
private
|
|
324
|
+
|
|
325
|
+
# Extracted eagerly rather than on demand because the offense is frozen,
|
|
326
|
+
# and because a corrector cannot be serialized - the cache and parallel
|
|
327
|
+
# workers would otherwise hand back offenses that have lost their edits.
|
|
328
|
+
def corrections_from(corrector)
|
|
329
|
+
return EMPTY_CORRECTIONS unless corrector
|
|
330
|
+
|
|
331
|
+
corrector.as_replacements.map do |range, replacement|
|
|
332
|
+
Correction.new(range.begin_pos, range.end_pos, replacement.freeze).freeze
|
|
333
|
+
end
|
|
334
|
+
end
|
|
279
335
|
end
|
|
280
336
|
end
|
|
281
337
|
end
|
data/lib/rubocop/cop/registry.rb
CHANGED
|
@@ -22,6 +22,13 @@ module RuboCop
|
|
|
22
22
|
# passing the `create_additions` keyword argument emits a deprecation warning, with the
|
|
23
23
|
# goal of being secure by default in the next major version 3.0.0.
|
|
24
24
|
#
|
|
25
|
+
# NOTE: Before `json` gem version 2.17.0, `JSON.load` only takes options as its third
|
|
26
|
+
# argument. A hash passed as the second argument is taken as the `proc` argument, so
|
|
27
|
+
# its `create_additions` option is ignored. Which `json` version runs can't be told
|
|
28
|
+
# statically (the lockfile may resolve a newer one than the default gem loaded in
|
|
29
|
+
# production), so options passed as the second argument are always reported. Pass
|
|
30
|
+
# `nil` as the second argument instead.
|
|
31
|
+
#
|
|
25
32
|
# @safety
|
|
26
33
|
# This cop's autocorrection is unsafe because it's potentially dangerous.
|
|
27
34
|
# If using a stream, like `JSON.load(open('file'))`, you will need to call
|
|
@@ -33,13 +40,16 @@ module RuboCop
|
|
|
33
40
|
# JSON.load('{}')
|
|
34
41
|
# JSON.restore('{}')
|
|
35
42
|
#
|
|
43
|
+
# # bad - ignored by `json` older than 2.17.0
|
|
44
|
+
# JSON.load('{}', create_additions: false)
|
|
45
|
+
#
|
|
36
46
|
# # good
|
|
37
47
|
# JSON.parse('{}')
|
|
38
48
|
# JSON.unsafe_load('{}')
|
|
39
49
|
#
|
|
40
50
|
# # good - explicit use of `create_additions` option
|
|
41
|
-
# JSON.load('{}', create_additions: true)
|
|
42
|
-
# JSON.load('{}', create_additions: false)
|
|
51
|
+
# JSON.load('{}', nil, create_additions: true)
|
|
52
|
+
# JSON.load('{}', nil, create_additions: false)
|
|
43
53
|
#
|
|
44
54
|
class JSONLoad < Base
|
|
45
55
|
extend AutoCorrector
|
|
@@ -51,8 +61,10 @@ module RuboCop
|
|
|
51
61
|
def_node_matcher :insecure_json_load, <<~PATTERN
|
|
52
62
|
(
|
|
53
63
|
send (const {nil? cbase} :JSON) ${:load :restore}
|
|
54
|
-
|
|
55
|
-
|
|
64
|
+
{
|
|
65
|
+
_ hash
|
|
66
|
+
| ... !`(pair (sym :create_additions) _)
|
|
67
|
+
}
|
|
56
68
|
)
|
|
57
69
|
PATTERN
|
|
58
70
|
|
|
@@ -132,10 +132,11 @@ module RuboCop
|
|
|
132
132
|
# private alias_method :qux, :foo
|
|
133
133
|
#
|
|
134
134
|
# end
|
|
135
|
-
class AccessModifierDeclarations < Base
|
|
135
|
+
class AccessModifierDeclarations < Base # rubocop:disable Metrics/ClassLength
|
|
136
136
|
extend AutoCorrector
|
|
137
137
|
|
|
138
138
|
include ConfigurableEnforcedStyle
|
|
139
|
+
include EndlessMethodBodyHelp
|
|
139
140
|
include RangeHelp
|
|
140
141
|
|
|
141
142
|
GROUP_STYLE_MESSAGE = [
|
|
@@ -169,6 +170,10 @@ module RuboCop
|
|
|
169
170
|
(send nil? :alias_method _ _))
|
|
170
171
|
PATTERN
|
|
171
172
|
|
|
173
|
+
def self.autocorrect_incompatible_with
|
|
174
|
+
[Style::EndlessMethod, Style::SingleLineMethods]
|
|
175
|
+
end
|
|
176
|
+
|
|
172
177
|
def on_send(node)
|
|
173
178
|
return if allowed?(node)
|
|
174
179
|
|
|
@@ -187,11 +192,18 @@ module RuboCop
|
|
|
187
192
|
def allowed?(node)
|
|
188
193
|
!node.access_modifier? ||
|
|
189
194
|
node.parent&.type?(:pair, :any_block) ||
|
|
195
|
+
dynamic_method_list?(node) ||
|
|
190
196
|
allow_modifiers_on_symbols?(node) ||
|
|
191
197
|
allow_modifiers_on_attrs?(node) ||
|
|
192
198
|
allow_modifiers_on_alias_method?(node)
|
|
193
199
|
end
|
|
194
200
|
|
|
201
|
+
# `private(*names)` with a list computed at runtime names no definition
|
|
202
|
+
# the modifier could be grouped with.
|
|
203
|
+
def dynamic_method_list?(node)
|
|
204
|
+
node.arguments.any?(&:splat_type?) && !access_modifier_with_symbol?(node)
|
|
205
|
+
end
|
|
206
|
+
|
|
195
207
|
def autocorrect(corrector, node)
|
|
196
208
|
case style
|
|
197
209
|
when :group
|
|
@@ -241,10 +253,33 @@ module RuboCop
|
|
|
241
253
|
|
|
242
254
|
access_modifier_is_inlined?(node) && !right_siblings_same_inline_method?(node)
|
|
243
255
|
else
|
|
244
|
-
access_modifier_is_not_inlined?(node) && select_grouped_def_nodes(node)
|
|
256
|
+
access_modifier_is_not_inlined?(node) && inlinable?(select_grouped_def_nodes(node))
|
|
245
257
|
end
|
|
246
258
|
end
|
|
247
259
|
|
|
260
|
+
def inlinable?(def_nodes)
|
|
261
|
+
return false if def_nodes.empty?
|
|
262
|
+
|
|
263
|
+
def_nodes.none? { |def_node| def_node.endless? && body_unsafe_to_inline?(def_node.body) }
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def body_unsafe_to_inline?(body)
|
|
267
|
+
return true if body.each_node(:any_block).any? { |block| do_end_block?(block) }
|
|
268
|
+
|
|
269
|
+
target_ruby_version < 4.0 && command_body?(body)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def do_end_block?(block)
|
|
273
|
+
block.keywords? && !block.send_node.lambda_literal?
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def command_body?(body)
|
|
277
|
+
body = body.body while body.rescue_type?
|
|
278
|
+
return true if body.send_type? && body.prefix_not? && !body.parenthesized?
|
|
279
|
+
|
|
280
|
+
command_call?(body)
|
|
281
|
+
end
|
|
282
|
+
|
|
248
283
|
def correctable_group_offense?(node)
|
|
249
284
|
return false unless group_style?
|
|
250
285
|
return false if allowed?(node)
|
|
@@ -60,7 +60,7 @@ module RuboCop
|
|
|
60
60
|
add_offense(node.loc.keyword, message: MSG_ALIAS) do |corrector|
|
|
61
61
|
autocorrect(corrector, node)
|
|
62
62
|
end
|
|
63
|
-
elsif node.children.
|
|
63
|
+
elsif node.children.all? { |arg| !bareword?(arg) && bareword_symbol?(arg) }
|
|
64
64
|
add_offense_for_args(node) { |corrector| autocorrect(corrector, node) }
|
|
65
65
|
end
|
|
66
66
|
end
|
|
@@ -97,7 +97,7 @@ module RuboCop
|
|
|
97
97
|
|
|
98
98
|
def add_offense_for_args(node, &block)
|
|
99
99
|
existing_args = node.children.map(&:source).join(' ')
|
|
100
|
-
preferred_args = node.children.map { |
|
|
100
|
+
preferred_args = node.children.map { |node| bareword_for(node) }.join(' ')
|
|
101
101
|
arg_ranges = node.children.map(&:source_range)
|
|
102
102
|
msg = format(MSG_SYMBOL_ARGS, prefer: preferred_args, current: existing_args)
|
|
103
103
|
add_offense(arg_ranges.reduce(&:join), message: msg, &block)
|
|
@@ -138,6 +138,15 @@ module RuboCop
|
|
|
138
138
|
!sym_node.source.start_with?(':') || sym_node.dsym_type?
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
+
def bareword_symbol?(sym_node)
|
|
142
|
+
return false unless sym_node.sym_type?
|
|
143
|
+
|
|
144
|
+
value = sym_node.value.to_s
|
|
145
|
+
return true if value.match?(/\A[A-Za-z_]\w*[?!=]?\z/)
|
|
146
|
+
|
|
147
|
+
!sym_node.source.start_with?(':"', ":'") && !value.start_with?('@', '$')
|
|
148
|
+
end
|
|
149
|
+
|
|
141
150
|
def correct_alias_method_to_alias(corrector, send_node)
|
|
142
151
|
new, old = *send_node.arguments
|
|
143
152
|
replacement = "alias #{identifier(new)} #{identifier(old)}"
|
|
@@ -153,17 +162,21 @@ module RuboCop
|
|
|
153
162
|
end
|
|
154
163
|
|
|
155
164
|
def correct_alias_with_symbol_args(corrector, node)
|
|
156
|
-
corrector.replace(node.new_identifier, node.new_identifier
|
|
157
|
-
corrector.replace(node.old_identifier, node.old_identifier
|
|
165
|
+
corrector.replace(node.new_identifier, bareword_for(node.new_identifier))
|
|
166
|
+
corrector.replace(node.old_identifier, bareword_for(node.old_identifier))
|
|
158
167
|
end
|
|
159
168
|
|
|
160
169
|
def identifier(node)
|
|
161
|
-
if node
|
|
170
|
+
if bareword_symbol?(node)
|
|
162
171
|
":#{node.children.first}"
|
|
163
172
|
else
|
|
164
173
|
node.source
|
|
165
174
|
end
|
|
166
175
|
end
|
|
176
|
+
|
|
177
|
+
def bareword_for(sym_node)
|
|
178
|
+
sym_node.value.to_s
|
|
179
|
+
end
|
|
167
180
|
end
|
|
168
181
|
end
|
|
169
182
|
end
|
|
@@ -39,9 +39,9 @@ module RuboCop
|
|
|
39
39
|
# @!method ambiguous_endless_method_body(node)
|
|
40
40
|
def_node_matcher :ambiguous_endless_method_body, <<~PATTERN
|
|
41
41
|
^${
|
|
42
|
-
(if _ <
|
|
43
|
-
({and or}
|
|
44
|
-
({while until} _
|
|
42
|
+
(if _ <any_def _>)
|
|
43
|
+
({and or} any_def _)
|
|
44
|
+
({while until} _ any_def)
|
|
45
45
|
}
|
|
46
46
|
PATTERN
|
|
47
47
|
|
|
@@ -57,6 +57,7 @@ module RuboCop
|
|
|
57
57
|
correct_to_multiline(corrector, node)
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
|
+
alias on_defs on_def
|
|
60
61
|
|
|
61
62
|
private
|
|
62
63
|
|
|
@@ -48,6 +48,10 @@ module RuboCop
|
|
|
48
48
|
|
|
49
49
|
MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
|
|
50
50
|
|
|
51
|
+
def self.autocorrect_incompatible_with
|
|
52
|
+
[Style::MethodCallWithArgsParentheses, Style::ReturnNil, Style::ReturnNilInPredicateMethodDefinition]
|
|
53
|
+
end
|
|
54
|
+
|
|
51
55
|
def on_and(node)
|
|
52
56
|
process_logical_operator(node) if style == :always
|
|
53
57
|
end
|
|
@@ -69,7 +73,7 @@ module RuboCop
|
|
|
69
73
|
message = message(node)
|
|
70
74
|
add_offense(node.loc.operator, message: message) do |corrector|
|
|
71
75
|
node.each_child_node do |expr|
|
|
72
|
-
if expr.
|
|
76
|
+
if expr.call_type?
|
|
73
77
|
correct_send(expr, corrector)
|
|
74
78
|
elsif expr.type?(:return, :next, :break, :yield) || expr.assignment?
|
|
75
79
|
correct_other(expr, corrector)
|
|
@@ -116,7 +120,7 @@ module RuboCop
|
|
|
116
120
|
# however, 'not x' also parses as (send x :!)
|
|
117
121
|
def correct_not(node, receiver, corrector)
|
|
118
122
|
if node.prefix_bang?
|
|
119
|
-
return unless receiver.
|
|
123
|
+
return unless receiver.call_type?
|
|
120
124
|
|
|
121
125
|
correct_send(receiver, corrector)
|
|
122
126
|
elsif node.prefix_not?
|
|
@@ -153,7 +153,7 @@ module RuboCop
|
|
|
153
153
|
BLOCK_MSG = 'Use anonymous block arguments forwarding (`&`).'
|
|
154
154
|
|
|
155
155
|
def self.autocorrect_incompatible_with
|
|
156
|
-
[Naming::BlockForwarding, Style::MethodDefParentheses]
|
|
156
|
+
[Naming::BlockForwarding, Style::EndlessMethod, Style::MethodDefParentheses]
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
def on_def(node)
|
|
@@ -169,7 +169,7 @@ module RuboCop
|
|
|
169
169
|
|
|
170
170
|
return if send_classifications.empty?
|
|
171
171
|
|
|
172
|
-
if
|
|
172
|
+
if forward_all?(send_nodes, send_classifications)
|
|
173
173
|
add_forward_all_offenses(node, send_classifications, forwardable_args)
|
|
174
174
|
elsif target_ruby_version >= 3.2
|
|
175
175
|
add_post_ruby_32_offenses(node, send_classifications, forwardable_args)
|
|
@@ -192,11 +192,33 @@ module RuboCop
|
|
|
192
192
|
[restarg_node, kwrestarg_node, blockarg_node]
|
|
193
193
|
end
|
|
194
194
|
|
|
195
|
+
def forward_all?(send_nodes, send_classifications)
|
|
196
|
+
only_forwards_all?(send_classifications) &&
|
|
197
|
+
!anonymous_forwarding_elsewhere?(send_nodes, send_classifications)
|
|
198
|
+
end
|
|
199
|
+
|
|
195
200
|
def only_forwards_all?(send_classifications)
|
|
196
201
|
all_classifications = %i[all all_anonymous].freeze
|
|
197
202
|
send_classifications.all? { |_, c, _, _| all_classifications.include?(c) }
|
|
198
203
|
end
|
|
199
204
|
|
|
205
|
+
def anonymous_forwarding_elsewhere?(send_nodes, send_classifications)
|
|
206
|
+
classified = send_classifications.map(&:first)
|
|
207
|
+
|
|
208
|
+
send_nodes.any? do |send_node|
|
|
209
|
+
classified.none? { |node| node.equal?(send_node) } &&
|
|
210
|
+
forwards_anonymous_args?(send_node)
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def forwards_anonymous_args?(send_node)
|
|
215
|
+
send_node.arguments.any? do |arg|
|
|
216
|
+
next arg.children.any?(&:forwarded_kwrestarg_type?) if arg.hash_type?
|
|
217
|
+
|
|
218
|
+
arg.forwarded_restarg_type?
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
200
222
|
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
201
223
|
def add_forward_all_offenses(node, send_classifications, forwardable_args)
|
|
202
224
|
rest_arg, kwrest_arg, block_arg = *forwardable_args
|
|
@@ -376,11 +398,16 @@ module RuboCop
|
|
|
376
398
|
|
|
377
399
|
def add_parens_if_missing(node, corrector)
|
|
378
400
|
return if parentheses?(node)
|
|
379
|
-
return if node.
|
|
401
|
+
return if node.call_type? && operator_or_setter_call?(node)
|
|
402
|
+
return unless (@parenthesized_nodes ||= Set.new.compare_by_identity).add?(node)
|
|
380
403
|
|
|
381
404
|
add_parentheses(node, corrector)
|
|
382
405
|
end
|
|
383
406
|
|
|
407
|
+
def operator_or_setter_call?(node)
|
|
408
|
+
node.setter_method? || (node.operator_method? && !node.loc.dot)
|
|
409
|
+
end
|
|
410
|
+
|
|
384
411
|
# Classifies send nodes for possible rest/kwrest/all (including block) forwarding.
|
|
385
412
|
class SendNodeClassifier
|
|
386
413
|
extend NodePattern::Macros
|
|
@@ -499,6 +526,8 @@ module RuboCop
|
|
|
499
526
|
end
|
|
500
527
|
|
|
501
528
|
def offensive_block_forwarding?
|
|
529
|
+
return false if @send_node.block_literal?
|
|
530
|
+
|
|
502
531
|
@block_arg ? forwarded_block_arg : allow_offense_for_no_block?
|
|
503
532
|
end
|
|
504
533
|
|
|
@@ -50,10 +50,9 @@ module RuboCop
|
|
|
50
50
|
def autocorrect(corrector, node)
|
|
51
51
|
attr_name, setter = *node.arguments
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
remove = range_between(attr_expr.end_pos, node_expr.end_pos) if setter&.boolean_type?
|
|
53
|
+
if setter&.boolean_type?
|
|
54
|
+
remove = range_between(attr_name.source_range.end_pos, setter.source_range.end_pos)
|
|
55
|
+
end
|
|
57
56
|
|
|
58
57
|
corrector.replace(node.loc.selector, replacement_method(node))
|
|
59
58
|
corrector.remove(remove) if remove
|