rubocop 1.90.0 → 1.92.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 +1 -1
- data/config/default.yml +241 -11
- data/config/obsoletion.yml +9 -0
- data/lib/rubocop/cached_data.rb +47 -7
- data/lib/rubocop/changed_files.rb +134 -0
- data/lib/rubocop/cli/command/cop_names.rb +57 -0
- data/lib/rubocop/cli/command/execute_runner.rb +23 -3
- 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 +11 -4
- data/lib/rubocop/comment_config/directive_range.rb +3 -1
- data/lib/rubocop/comment_config/disable_next.rb +49 -3
- data/lib/rubocop/comment_config/push_pop.rb +55 -0
- data/lib/rubocop/comment_config.rb +32 -53
- data/lib/rubocop/config.rb +10 -0
- data/lib/rubocop/config_loader.rb +18 -7
- data/lib/rubocop/config_loader_resolver.rb +79 -12
- data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
- data/lib/rubocop/config_obsoletion/removed_cop.rb +9 -1
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_validator.rb +29 -3
- data/lib/rubocop/cop/autocorrect_logic.rb +10 -5
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/base.rb +57 -24
- 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 +22 -7
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +23 -2
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +45 -8
- data/lib/rubocop/cop/correctors.rb +2 -2
- 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/gemspec/require_mfa.rb +1 -1
- data/lib/rubocop/cop/generator.rb +1 -1
- 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/on_send_without_on_csend.rb +1 -1
- 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 +2 -0
- 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 +9 -1
- data/lib/rubocop/cop/layout/comment_indentation.rb +8 -5
- data/lib/rubocop/cop/layout/def_end_alignment.rb +4 -0
- data/lib/rubocop/cop/layout/else_alignment.rb +1 -0
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +14 -5
- data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +16 -10
- data/lib/rubocop/cop/layout/extra_spacing.rb +4 -0
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -0
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +17 -4
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +5 -3
- 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/first_parameter_indentation.rb +11 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +15 -10
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -0
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +15 -0
- data/lib/rubocop/cop/layout/indentation_style.rb +4 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +4 -4
- 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 +71 -19
- 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 +7 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +6 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +14 -0
- 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 +10 -4
- data/lib/rubocop/cop/layout/space_around_keyword.rb +10 -0
- data/lib/rubocop/cop/layout/space_around_operators.rb +5 -1
- 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/lint/ambiguous_operator.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +2 -1
- data/lib/rubocop/cop/lint/argument_mismatch.rb +14 -4
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +88 -14
- data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +3 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +23 -2
- 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 +245 -0
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +19 -4
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +17 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +42 -17
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +13 -2
- 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/void.rb +8 -1
- data/lib/rubocop/cop/lint.rb +1 -0
- 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/migration/department_name.rb +1 -1
- data/lib/rubocop/cop/mixin/alignment.rb +5 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +17 -14
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +5 -1
- 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 +69 -0
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +2 -2
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +26 -2
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +31 -3
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
- 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 +29 -3
- 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 +22 -2
- data/lib/rubocop/cop/mixin.rb +4 -2
- data/lib/rubocop/cop/naming/accessor_method_name.rb +0 -16
- data/lib/rubocop/cop/naming/block_forwarding.rb +4 -1
- data/lib/rubocop/cop/naming/block_parameter_name.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/offense.rb +59 -3
- data/lib/rubocop/cop/registry.rb +10 -2
- data/lib/rubocop/cop/security/json_load.rb +16 -4
- data/lib/rubocop/cop/severity.rb +12 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +10 -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 +4 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +6 -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 +29 -3
- data/lib/rubocop/cop/style/case_like_if.rb +9 -6
- data/lib/rubocop/cop/style/class_and_module_children.rb +54 -16
- data/lib/rubocop/cop/style/class_methods_definitions.rb +8 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +85 -11
- data/lib/rubocop/cop/style/concat_array_literals.rb +46 -7
- data/lib/rubocop/cop/style/conditional_assignment.rb +4 -0
- data/lib/rubocop/cop/style/constant_visibility.rb +6 -2
- data/lib/rubocop/cop/style/data_inheritance.rb +14 -0
- data/lib/rubocop/cop/style/directive_scope.rb +154 -21
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +118 -18
- data/lib/rubocop/cop/style/documentation_method.rb +1 -9
- data/lib/rubocop/cop/style/double_negation.rb +11 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +15 -3
- data/lib/rubocop/cop/style/endless_method.rb +91 -11
- 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/file_null.rb +2 -2
- data/lib/rubocop/cop/style/float_division.rb +28 -14
- data/lib/rubocop/cop/style/for.rb +44 -1
- data/lib/rubocop/cop/style/format_string.rb +28 -6
- data/lib/rubocop/cop/style/format_string_token.rb +1 -1
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
- data/lib/rubocop/cop/style/guard_clause.rb +13 -1
- data/lib/rubocop/cop/style/hash_conversion.rb +28 -8
- data/lib/rubocop/cop/style/hash_lookup_method.rb +35 -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 +19 -20
- 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 +32 -3
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +3 -1
- data/lib/rubocop/cop/style/lambda.rb +18 -0
- data/lib/rubocop/cop/style/lambda_call.rb +7 -2
- data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
- data/lib/rubocop/cop/style/map_into_array.rb +1 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +45 -10
- 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/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 +28 -1
- 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 +36 -12
- 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 +48 -8
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +18 -2
- data/lib/rubocop/cop/style/not.rb +10 -3
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +21 -5
- data/lib/rubocop/cop/style/one_line_conditional.rb +14 -3
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -1
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -1
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +14 -3
- data/lib/rubocop/cop/style/reduce_to_hash.rb +17 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +20 -3
- data/lib/rubocop/cop/style/redundant_condition.rb +34 -17
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +16 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +15 -3
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +10 -2
- data/lib/rubocop/cop/style/redundant_freeze.rb +10 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +23 -2
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +7 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +25 -5
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +4 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +75 -26
- data/lib/rubocop/cop/style/require_order.rb +9 -0
- data/lib/rubocop/cop/style/rescue_modifier.rb +5 -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/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +16 -4
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- 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 +14 -0
- data/lib/rubocop/cop/style/super_arguments.rb +3 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +23 -5
- data/lib/rubocop/cop/style/ternary_parentheses.rb +23 -1
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -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/style.rb +0 -1
- data/lib/rubocop/cop/team.rb +10 -5
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +14 -1
- data/lib/rubocop/cops_documentation_generator.rb +23 -2
- data/lib/rubocop/directive_comment.rb +37 -8
- data/lib/rubocop/formatter/base_formatter.rb +22 -0
- data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -1
- data/lib/rubocop/formatter/formatter_set.rb +6 -1
- data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
- data/lib/rubocop/formatter/html_formatter.rb +2 -2
- data/lib/rubocop/formatter/json_formatter.rb +71 -1
- data/lib/rubocop/formatter/junit_formatter.rb +1 -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 +186 -0
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +3 -1
- data/lib/rubocop/formatter.rb +1 -0
- 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/magic_comment.rb +27 -0
- 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 +97 -4
- data/lib/rubocop/path_util.rb +1 -1
- data/lib/rubocop/plugin/configuration_integrator.rb +12 -5
- data/lib/rubocop/plugin/loader.rb +1 -1
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.rb +8 -5
- data/lib/rubocop/result_cache.rb +36 -18
- data/lib/rubocop/runner.rb +160 -49
- data/lib/rubocop/server/cache.rb +2 -2
- data/lib/rubocop/unified_diff.rb +257 -0
- data/lib/rubocop/util.rb +69 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +9 -1
- metadata +21 -6
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
|
@@ -54,6 +54,10 @@ module RuboCop
|
|
|
54
54
|
|
|
55
55
|
MSG = 'Convert `if-elsif` to `case-when`.'
|
|
56
56
|
|
|
57
|
+
def self.autocorrect_incompatible_with
|
|
58
|
+
[Style::IfInsideElse]
|
|
59
|
+
end
|
|
60
|
+
|
|
57
61
|
def on_if(node)
|
|
58
62
|
return unless should_check?(node)
|
|
59
63
|
|
|
@@ -106,7 +110,7 @@ module RuboCop
|
|
|
106
110
|
when :or
|
|
107
111
|
find_target(node.lhs)
|
|
108
112
|
when :match_with_lvasgn
|
|
109
|
-
lhs, rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
|
113
|
+
lhs, rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring -- `match_with_lvasgn` has no named operand accessors
|
|
110
114
|
if lhs.regexp_type?
|
|
111
115
|
rhs
|
|
112
116
|
elsif rhs.regexp_type?
|
|
@@ -171,7 +175,7 @@ module RuboCop
|
|
|
171
175
|
return collect_conditions(node.lhs, target, conditions) &&
|
|
172
176
|
collect_conditions(node.rhs, target, conditions)
|
|
173
177
|
when :match_with_lvasgn
|
|
174
|
-
lhs, rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
|
178
|
+
lhs, rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring -- `match_with_lvasgn` has no named operand accessors
|
|
175
179
|
condition_from_binary_op(lhs, rhs, target)
|
|
176
180
|
when :send
|
|
177
181
|
condition_from_send_node(node, target)
|
|
@@ -224,10 +228,9 @@ module RuboCop
|
|
|
224
228
|
end
|
|
225
229
|
|
|
226
230
|
def branch_conditions(node)
|
|
227
|
-
conditions = []
|
|
228
|
-
while node&.if_type? &&
|
|
231
|
+
conditions = [node.condition]
|
|
232
|
+
while (node = node.else_branch)&.if_type? && node.elsif?
|
|
229
233
|
conditions << node.condition
|
|
230
|
-
node = node.else_branch
|
|
231
234
|
end
|
|
232
235
|
conditions
|
|
233
236
|
end
|
|
@@ -258,7 +261,7 @@ module RuboCop
|
|
|
258
261
|
def regexp_with_working_captures?(node)
|
|
259
262
|
case node.type
|
|
260
263
|
when :match_with_lvasgn
|
|
261
|
-
lhs, _rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
|
264
|
+
lhs, _rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring -- `match_with_lvasgn` has no named operand accessors
|
|
262
265
|
node.loc.selector.source == '=~' && regexp_with_named_captures?(lhs)
|
|
263
266
|
when :send
|
|
264
267
|
node.method?(:match) &&
|
|
@@ -65,6 +65,12 @@ module RuboCop
|
|
|
65
65
|
NESTED_MSG = 'Use nested module/class definitions instead of compact style.'
|
|
66
66
|
COMPACT_MSG = 'Use compact module/class definition instead of nested style.'
|
|
67
67
|
|
|
68
|
+
# `Style/StructInheritance` turns a class definition into a constant assignment in
|
|
69
|
+
# the same pass, which the compacted `class` keyword would then precede.
|
|
70
|
+
def self.autocorrect_incompatible_with
|
|
71
|
+
[Style::StructInheritance]
|
|
72
|
+
end
|
|
73
|
+
|
|
68
74
|
def on_class(node)
|
|
69
75
|
return if node.parent_class && style_for_classes != :nested
|
|
70
76
|
|
|
@@ -117,7 +123,10 @@ module RuboCop
|
|
|
117
123
|
end
|
|
118
124
|
|
|
119
125
|
def heuristic_namespace_keyword(node)
|
|
120
|
-
|
|
126
|
+
left_sibling = node.left_sibling
|
|
127
|
+
return 'module' unless left_sibling.is_a?(AST::Node)
|
|
128
|
+
|
|
129
|
+
class_definition = left_sibling.each_node(:class).find do |class_node|
|
|
121
130
|
class_node.identifier == node.identifier.namespace
|
|
122
131
|
end
|
|
123
132
|
|
|
@@ -194,33 +203,62 @@ module RuboCop
|
|
|
194
203
|
"#{node.body.children.first.const_name}"
|
|
195
204
|
end
|
|
196
205
|
|
|
197
|
-
# rubocop:disable-next Metrics/AbcSize
|
|
198
206
|
def remove_end(corrector, body)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
adjustment = processed_source.raw_source[remove_begin_pos] == ';' ? 0 : 1
|
|
205
|
-
range = range_between(remove_begin_pos, body.loc.end.end_pos + adjustment)
|
|
207
|
+
range = if same_line?(body.loc.name, body.loc.end)
|
|
208
|
+
single_line_end_range(body)
|
|
209
|
+
else
|
|
210
|
+
multiline_end_range(body)
|
|
211
|
+
end
|
|
206
212
|
|
|
207
213
|
corrector.remove(range)
|
|
208
214
|
end
|
|
209
215
|
|
|
210
|
-
def
|
|
211
|
-
|
|
216
|
+
def single_line_end_range(body)
|
|
217
|
+
raw = processed_source.raw_source
|
|
218
|
+
pos = body.loc.end.begin_pos
|
|
219
|
+
pos -= 1 while raw[pos - 1] == ' '
|
|
220
|
+
pos -= 1 if raw[pos - 1] == ';'
|
|
221
|
+
range_between(pos, body.loc.end.end_pos)
|
|
222
|
+
end
|
|
212
223
|
|
|
213
|
-
|
|
214
|
-
|
|
224
|
+
def multiline_end_range(body)
|
|
225
|
+
remove_begin_pos = body.loc.end.begin_pos - leading_spaces(body).size
|
|
226
|
+
adjustment = processed_source.raw_source[remove_begin_pos] == ';' ? 0 : 1
|
|
227
|
+
range_between(remove_begin_pos, body.loc.end.end_pos + adjustment)
|
|
228
|
+
end
|
|
215
229
|
|
|
216
|
-
|
|
217
|
-
|
|
230
|
+
def unindent(corrector, node)
|
|
231
|
+
column_delta = unindent_column_delta(node)
|
|
232
|
+
return unless column_delta&.negative?
|
|
233
|
+
|
|
234
|
+
range = unindentable_range(node.body)
|
|
235
|
+
return unless range
|
|
218
236
|
|
|
219
237
|
AlignmentCorrector.correct(
|
|
220
|
-
corrector, processed_source,
|
|
238
|
+
corrector, processed_source, range, column_delta, tab_indentation: true
|
|
221
239
|
)
|
|
222
240
|
end
|
|
223
241
|
|
|
242
|
+
def unindent_column_delta(node)
|
|
243
|
+
body = node.body.children.last
|
|
244
|
+
return unless body
|
|
245
|
+
|
|
246
|
+
node_indentation = spaces_size(leading_spaces(node))
|
|
247
|
+
body_indentation = spaces_size(leading_spaces(body))
|
|
248
|
+
|
|
249
|
+
node_indentation + configured_indentation_width - body_indentation
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def unindentable_range(body)
|
|
253
|
+
first_line = body.loc.name.line + 1
|
|
254
|
+
last_line = body.loc.end.line - 1
|
|
255
|
+
return if first_line > last_line
|
|
256
|
+
|
|
257
|
+
buffer = processed_source.buffer
|
|
258
|
+
range_between(buffer.line_range(first_line).begin_pos,
|
|
259
|
+
buffer.line_range(last_line).end_pos)
|
|
260
|
+
end
|
|
261
|
+
|
|
224
262
|
def leading_spaces(node)
|
|
225
263
|
node.source_range.source_line[/\A\s*/]
|
|
226
264
|
end
|
|
@@ -72,6 +72,7 @@ module RuboCop
|
|
|
72
72
|
return unless def_self_style?
|
|
73
73
|
return unless node.identifier.self_type?
|
|
74
74
|
return unless all_methods_public?(node)
|
|
75
|
+
return unless def_nodes(node).all? { |def_node| no_code_after?(def_node.source_range) }
|
|
75
76
|
|
|
76
77
|
add_offense(node, message: MSG_SCLASS) do |corrector|
|
|
77
78
|
autocorrect_sclass(node, corrector)
|
|
@@ -112,6 +113,13 @@ module RuboCop
|
|
|
112
113
|
end
|
|
113
114
|
end
|
|
114
115
|
|
|
116
|
+
def no_code_after?(range)
|
|
117
|
+
trailing = processed_source.lines[range.last_line - 1][range.last_column..].to_s.strip
|
|
118
|
+
trailing = trailing.sub(/\A;+\s*/, '')
|
|
119
|
+
|
|
120
|
+
trailing.empty? || trailing.start_with?('#')
|
|
121
|
+
end
|
|
122
|
+
|
|
115
123
|
def autocorrect_sclass(node, corrector)
|
|
116
124
|
rewritten_defs = []
|
|
117
125
|
|
|
@@ -60,19 +60,18 @@ module RuboCop
|
|
|
60
60
|
# end
|
|
61
61
|
#
|
|
62
62
|
class CombinableLoops < Base
|
|
63
|
+
include RangeHelp
|
|
63
64
|
extend AutoCorrector
|
|
64
65
|
|
|
65
66
|
MSG = 'Combine this loop with the previous loop.'
|
|
66
67
|
|
|
67
|
-
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
68
68
|
def on_block(node)
|
|
69
69
|
return unless node.parent&.begin_type?
|
|
70
70
|
return unless collection_looping_method?(node)
|
|
71
|
-
return unless
|
|
72
|
-
return unless node.body && node.left_sibling.body
|
|
71
|
+
return unless combinable_looping_blocks?(node, node.left_sibling)
|
|
73
72
|
|
|
74
73
|
add_offense(node) do |corrector|
|
|
75
|
-
next unless node
|
|
74
|
+
next unless combinable_blocks?(node, node.left_sibling)
|
|
76
75
|
|
|
77
76
|
combine_with_left_sibling(corrector, node)
|
|
78
77
|
end
|
|
@@ -87,9 +86,7 @@ module RuboCop
|
|
|
87
86
|
return unless node.body && node.left_sibling.body
|
|
88
87
|
|
|
89
88
|
add_offense(node) do |corrector|
|
|
90
|
-
|
|
91
|
-
# body referencing an undefined variable, so only autocorrect when they match.
|
|
92
|
-
next unless node.variable == node.left_sibling.variable
|
|
89
|
+
next unless combinable_fors?(node, node.left_sibling)
|
|
93
90
|
|
|
94
91
|
combine_with_left_sibling(corrector, node)
|
|
95
92
|
end
|
|
@@ -110,25 +107,102 @@ module RuboCop
|
|
|
110
107
|
sibling.send_node.arguments == node.send_node.arguments
|
|
111
108
|
end
|
|
112
109
|
|
|
110
|
+
def combinable_looping_blocks?(node, sibling)
|
|
111
|
+
same_collection_looping_block?(node, sibling) && node.body && sibling.body
|
|
112
|
+
end
|
|
113
|
+
|
|
113
114
|
def same_collection_looping_for?(node, sibling)
|
|
114
115
|
sibling&.for_type? && node.collection == sibling.collection
|
|
115
116
|
end
|
|
116
117
|
|
|
118
|
+
def combinable_blocks?(node, sibling)
|
|
119
|
+
return false unless node.arguments == sibling.arguments
|
|
120
|
+
# Numbered and `it` parameters are implicit, so `arguments` is empty for both.
|
|
121
|
+
return false unless node.argument_list == sibling.argument_list
|
|
122
|
+
return false if directive_after_opening?(node)
|
|
123
|
+
|
|
124
|
+
!node.body.type?(:rescue, :ensure) && !sibling.body.type?(:rescue, :ensure)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Combining loops with different iteration variables would leave the second
|
|
128
|
+
# body referencing an undefined variable, so only autocorrect when they match.
|
|
129
|
+
def combinable_fors?(node, sibling)
|
|
130
|
+
node.variable == sibling.variable && !directive_after_opening?(node)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# The opening is removed, so a directive after it would end up on a line of
|
|
134
|
+
# its own, where it covers the rest of the file instead of a single line.
|
|
135
|
+
def directive_after_opening?(node)
|
|
136
|
+
opening_line = loop_opening(node).line
|
|
137
|
+
return false if opening_line == node.body.first_line
|
|
138
|
+
|
|
139
|
+
comment = processed_source.comment_at_line(opening_line)
|
|
140
|
+
comment && DirectiveComment.new(comment).start_with_marker?
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# The block arguments or `{`/`do` of a block, or the `do` or collection of a `for` loop.
|
|
144
|
+
def loop_opening(node)
|
|
145
|
+
if node.for_type?
|
|
146
|
+
node.loc.begin || node.collection.source_range
|
|
147
|
+
else
|
|
148
|
+
(node.block_type? && node.arguments.source_range) || node.loc.begin
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
117
152
|
def combine_with_left_sibling(corrector, node)
|
|
118
|
-
corrector.remove(node.left_sibling
|
|
119
|
-
corrector.remove(
|
|
153
|
+
corrector.remove(closing_with_preceding_space(node.left_sibling, node))
|
|
154
|
+
corrector.remove(opening_with_following_space(node))
|
|
120
155
|
|
|
121
156
|
correct_end_of_block(corrector, node)
|
|
122
157
|
end
|
|
123
158
|
|
|
159
|
+
# Comments and heredoc bodies before the closing delimiter are kept. When
|
|
160
|
+
# the next loop starts on the delimiter's line, the line break before the
|
|
161
|
+
# delimiter is kept too, so that a comment doesn't swallow the next loop.
|
|
162
|
+
def closing_with_preceding_space(loop, next_loop)
|
|
163
|
+
separate_lines = !same_line?(loop.loc.end, next_loop)
|
|
164
|
+
|
|
165
|
+
range_with_surrounding_space(
|
|
166
|
+
loop.loc.end, side: :left, newlines: separate_lines, whitespace: separate_lines
|
|
167
|
+
)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Comments between the opening and the body are kept.
|
|
171
|
+
def opening_with_following_space(node)
|
|
172
|
+
opening = node.source_range.begin.join(loop_opening(node))
|
|
173
|
+
|
|
174
|
+
range_with_surrounding_space(opening, side: :right, whitespace: true)
|
|
175
|
+
end
|
|
176
|
+
|
|
124
177
|
def correct_end_of_block(corrector, node)
|
|
125
178
|
return unless node.left_sibling.respond_to?(:braces?)
|
|
126
|
-
return if node
|
|
179
|
+
return if combined_with_right_sibling?(node)
|
|
127
180
|
|
|
128
|
-
end_of_block = node.
|
|
181
|
+
end_of_block = first_combined_block(node).braces? ? '}' : ' end'
|
|
129
182
|
corrector.remove(node.loc.end)
|
|
130
183
|
corrector.insert_before(node.source_range.end, end_of_block)
|
|
131
184
|
end
|
|
185
|
+
|
|
186
|
+
def combined_with_right_sibling?(node)
|
|
187
|
+
sibling = node.right_sibling
|
|
188
|
+
return false unless sibling&.any_block_type?
|
|
189
|
+
# A disabled loop isn't corrected, so it doesn't get merged into this one.
|
|
190
|
+
return false unless enabled_lines?(sibling.source_range)
|
|
191
|
+
|
|
192
|
+
same_collection_looping_block?(sibling, node) && sibling.body &&
|
|
193
|
+
combinable_blocks?(sibling, node)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def first_combined_block(node)
|
|
197
|
+
first = node.left_sibling
|
|
198
|
+
|
|
199
|
+
while (previous = first.left_sibling) && enabled_lines?(first.source_range) &&
|
|
200
|
+
combinable_looping_blocks?(first, previous) && combinable_blocks?(first, previous)
|
|
201
|
+
first = previous
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
first
|
|
205
|
+
end
|
|
132
206
|
end
|
|
133
207
|
end
|
|
134
208
|
end
|
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
|
23
23
|
# list.push(qux, quux, corge)
|
|
24
24
|
#
|
|
25
25
|
class ConcatArrayLiterals < Base
|
|
26
|
+
include RangeHelp
|
|
26
27
|
extend AutoCorrector
|
|
27
28
|
|
|
28
29
|
MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
|
|
@@ -30,6 +31,14 @@ module RuboCop
|
|
|
30
31
|
'Use `push` with elements as arguments without array brackets instead of `%<current>s`.'
|
|
31
32
|
RESTRICT_ON_SEND = %i[concat].freeze
|
|
32
33
|
|
|
34
|
+
# `Style/MethodCallWithArgsParentheses` removing the parentheses of the `push(...)`
|
|
35
|
+
# this cop writes in the same pass drops the line continuation a multiline call needs.
|
|
36
|
+
# `Style/TrailingCommaInArguments` adds a comma after the array literal this cop
|
|
37
|
+
# replaces with its elements in the same pass.
|
|
38
|
+
def self.autocorrect_incompatible_with
|
|
39
|
+
[Style::MethodCallWithArgsParentheses, Style::TrailingCommaInArguments]
|
|
40
|
+
end
|
|
41
|
+
|
|
33
42
|
# rubocop:disable-next Metrics
|
|
34
43
|
def on_send(node)
|
|
35
44
|
return if node.arguments.empty?
|
|
@@ -54,17 +63,13 @@ module RuboCop
|
|
|
54
63
|
if use_percent_literal
|
|
55
64
|
next unless prefer
|
|
56
65
|
|
|
57
|
-
corrector
|
|
66
|
+
rebuild_call(corrector, offense, prefer)
|
|
58
67
|
elsif node.arguments.any? { |argument| argument.children.empty? }
|
|
59
68
|
# In-place bracket removal would leave dangling commas (e.g.
|
|
60
69
|
# `concat([], [b])` -> `push(, b)`), so rebuild the call instead.
|
|
61
|
-
corrector
|
|
70
|
+
rebuild_call(corrector, offense, preferred_method(node))
|
|
62
71
|
else
|
|
63
|
-
corrector
|
|
64
|
-
node.arguments.each do |argument|
|
|
65
|
-
corrector.remove(argument.loc.begin)
|
|
66
|
-
corrector.remove(argument.loc.end)
|
|
67
|
-
end
|
|
72
|
+
remove_brackets(corrector, node)
|
|
68
73
|
end
|
|
69
74
|
end
|
|
70
75
|
end
|
|
@@ -94,6 +99,40 @@ module RuboCop
|
|
|
94
99
|
arg.children.all? { |child| child.type?(:str, :sym) }
|
|
95
100
|
end
|
|
96
101
|
end
|
|
102
|
+
|
|
103
|
+
def rebuild_call(corrector, offense, replacement)
|
|
104
|
+
# The comments inside the call would be lost.
|
|
105
|
+
return if comment_in?(offense)
|
|
106
|
+
|
|
107
|
+
corrector.replace(offense, replacement)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def comment_in?(range)
|
|
111
|
+
processed_source.each_comment_in_lines(range.line..range.last_line).any? do |comment|
|
|
112
|
+
range.contains?(comment.source_range)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def remove_brackets(corrector, node)
|
|
117
|
+
closing_ranges = node.arguments.map { |argument| closing_bracket_range(node, argument) }
|
|
118
|
+
# A comment or a heredoc body there can't be moved out of the way.
|
|
119
|
+
return unless closing_ranges.all? { |range| range.source.match?(/\A[\s,]*\]\z/) }
|
|
120
|
+
|
|
121
|
+
corrector.replace(node.loc.selector, 'push')
|
|
122
|
+
node.arguments.zip(closing_ranges) do |argument, closing_range|
|
|
123
|
+
corrector.remove(argument.loc.begin)
|
|
124
|
+
corrector.remove(closing_range)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Whatever sits between the last element and the `]` of an array that isn't the
|
|
129
|
+
# last argument would end up before the following comma (a newline before it is a
|
|
130
|
+
# syntax error), so it's removed along with the `]`.
|
|
131
|
+
def closing_bracket_range(node, argument)
|
|
132
|
+
return argument.loc.end if argument.equal?(node.last_argument)
|
|
133
|
+
|
|
134
|
+
range_between(argument.children.last.source_range.end_pos, argument.loc.end.end_pos)
|
|
135
|
+
end
|
|
97
136
|
end
|
|
98
137
|
end
|
|
99
138
|
end
|
|
@@ -223,6 +223,10 @@ module RuboCop
|
|
|
223
223
|
}
|
|
224
224
|
PATTERN
|
|
225
225
|
|
|
226
|
+
def self.autocorrect_incompatible_with
|
|
227
|
+
[Style::MethodCallWithArgsParentheses]
|
|
228
|
+
end
|
|
229
|
+
|
|
226
230
|
ASSIGNMENT_TYPES.each do |type|
|
|
227
231
|
define_method :"on_#{type}" do |node|
|
|
228
232
|
return if part_of_ignored_node?(node)
|
|
@@ -82,12 +82,16 @@ module RuboCop
|
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
84
|
|
|
85
|
-
# rubocop:disable-next Metrics/AbcSize
|
|
85
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
86
86
|
def visibility_declaration?(node)
|
|
87
87
|
node.parent.each_child_node(:send).any? do |child|
|
|
88
88
|
next false unless (arguments = visibility_declaration_for(child))
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
if (splat = arguments.first)&.splat_type?
|
|
91
|
+
next true unless splat.children.first.array_type?
|
|
92
|
+
|
|
93
|
+
arguments = splat.children.first.children
|
|
94
|
+
end
|
|
91
95
|
constant_values = arguments.map do |argument|
|
|
92
96
|
# `respond_to?(:value)` is too broad: `int`/`float` nodes respond to it
|
|
93
97
|
# but their value is a `Numeric`, which has no `to_sym` (e.g.
|
|
@@ -10,6 +10,10 @@ module RuboCop
|
|
|
10
10
|
# Autocorrection is unsafe because it will change the inheritance
|
|
11
11
|
# tree (e.g. return value of `Module#ancestors`) of the constant.
|
|
12
12
|
#
|
|
13
|
+
# It is also unsafe because constants that the class body resolves through its
|
|
14
|
+
# ancestors (e.g. one provided by an included module) fall out of scope inside
|
|
15
|
+
# the block.
|
|
16
|
+
#
|
|
13
17
|
# @example
|
|
14
18
|
# # bad
|
|
15
19
|
# class Person < Data.define(:first_name, :last_name)
|
|
@@ -42,6 +46,7 @@ module RuboCop
|
|
|
42
46
|
|
|
43
47
|
def on_class(node)
|
|
44
48
|
return unless data_define?(node.parent_class)
|
|
49
|
+
return if defines_constants?(node.body)
|
|
45
50
|
|
|
46
51
|
add_offense(node.parent_class) do |corrector|
|
|
47
52
|
corrector.remove(range_with_surrounding_space(node.loc.keyword, newlines: false))
|
|
@@ -59,6 +64,15 @@ module RuboCop
|
|
|
59
64
|
|
|
60
65
|
private
|
|
61
66
|
|
|
67
|
+
# Constants, including nested classes and modules, are scoped to the class when they
|
|
68
|
+
# are defined in a class body, but leak into the enclosing namespace once moved into a
|
|
69
|
+
# `Data.define` block, so such a class cannot be rewritten as an assignment.
|
|
70
|
+
def defines_constants?(class_body)
|
|
71
|
+
return false unless class_body
|
|
72
|
+
|
|
73
|
+
class_body.each_node(:casgn, :class, :module).any?
|
|
74
|
+
end
|
|
75
|
+
|
|
62
76
|
def correct_parent(parent, corrector)
|
|
63
77
|
if parent.block_type?
|
|
64
78
|
# Convert a brace block to `do`, so the class's own `end` closes it
|