rubocop 1.53.0 → 1.90.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/LICENSE.txt +1 -1
- data/README.md +93 -88
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +949 -185
- data/config/internal_affairs.yml +31 -0
- data/config/obsoletion.yml +43 -4
- data/exe/rubocop +2 -8
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cached_data.rb +28 -7
- data/lib/rubocop/cli/command/auto_generate_config.rb +63 -18
- data/lib/rubocop/cli/command/execute_runner.rb +35 -4
- data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
- data/lib/rubocop/cli/command/lsp.rb +4 -4
- data/lib/rubocop/cli/command/mcp.rb +19 -0
- data/lib/rubocop/cli/command/show_cops.rb +26 -4
- data/lib/rubocop/cli/command/show_docs_url.rb +5 -9
- data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
- data/lib/rubocop/cli/command/version.rb +2 -2
- data/lib/rubocop/cli.rb +60 -16
- data/lib/rubocop/comment_config/directive_range.rb +32 -0
- data/lib/rubocop/comment_config/disable_next.rb +97 -0
- data/lib/rubocop/comment_config.rb +123 -49
- data/lib/rubocop/config.rb +180 -35
- data/lib/rubocop/config_finder.rb +15 -5
- data/lib/rubocop/config_loader.rb +83 -59
- data/lib/rubocop/config_loader_resolver.rb +65 -25
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +56 -9
- data/lib/rubocop/config_store.rb +7 -2
- data/lib/rubocop/config_validator.rb +76 -21
- data/lib/rubocop/cop/autocorrect_logic.rb +70 -25
- data/lib/rubocop/cop/badge.rb +8 -0
- data/lib/rubocop/cop/base.rb +151 -30
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -2
- data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
- data/lib/rubocop/cop/bundler/gem_comment.rb +6 -4
- data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
- data/lib/rubocop/cop/bundler/gem_version.rb +32 -33
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
- data/lib/rubocop/cop/bundler/ordered_gems.rb +11 -4
- data/lib/rubocop/cop/bundler.rb +19 -0
- data/lib/rubocop/cop/commissioner.rb +13 -11
- data/lib/rubocop/cop/cop.rb +30 -4
- data/lib/rubocop/cop/corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +80 -22
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +5 -9
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +13 -16
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +14 -5
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +37 -3
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
- data/lib/rubocop/cop/correctors.rb +28 -0
- data/lib/rubocop/cop/documentation.rb +31 -5
- data/lib/rubocop/cop/exclude_limit.rb +32 -6
- data/lib/rubocop/cop/force.rb +12 -0
- data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +3 -4
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +51 -19
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +11 -4
- data/lib/rubocop/cop/gemspec/require_mfa.rb +22 -5
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -3
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +15 -10
- data/lib/rubocop/cop/gemspec.rb +22 -0
- data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
- data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
- data/lib/rubocop/cop/generator.rb +10 -0
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +51 -25
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
- data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +142 -0
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +7 -5
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +54 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +132 -39
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +130 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +233 -0
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
- data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
- data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -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/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
- data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +11 -2
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +23 -2
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +6 -9
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +10 -0
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -2
- data/lib/rubocop/cop/layout/argument_alignment.rb +4 -11
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/block_alignment.rb +89 -17
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +4 -2
- data/lib/rubocop/cop/layout/class_structure.rb +171 -43
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
- data/lib/rubocop/cop/layout/comment_indentation.rb +10 -3
- data/lib/rubocop/cop/layout/condition_position.rb +13 -7
- data/lib/rubocop/cop/layout/def_end_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/dot_position.rb +3 -7
- data/lib/rubocop/cop/layout/else_alignment.rb +2 -15
- data/lib/rubocop/cop/layout/empty_comment.rb +11 -11
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +66 -15
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +75 -10
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +71 -20
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +13 -2
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +17 -3
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +12 -8
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +24 -6
- data/lib/rubocop/cop/layout/extra_spacing.rb +110 -14
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +59 -11
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +20 -11
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +22 -22
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +26 -26
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +3 -3
- data/lib/rubocop/cop/layout/hash_alignment.rb +11 -12
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +6 -5
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +38 -5
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +168 -22
- data/lib/rubocop/cop/layout/leading_comment_space.rb +111 -2
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +28 -11
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +9 -4
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +4 -2
- data/lib/rubocop/cop/layout/line_length.rb +271 -37
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -0
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +3 -2
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +252 -32
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +11 -8
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +117 -42
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +17 -9
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +6 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +3 -3
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +12 -2
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -4
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +3 -3
- data/lib/rubocop/cop/layout/space_around_operators.rb +94 -38
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +20 -10
- data/lib/rubocop/cop/layout/space_before_brackets.rb +8 -41
- data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +48 -36
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +8 -1
- data/lib/rubocop/cop/layout/space_inside_parens.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -5
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -4
- data/lib/rubocop/cop/layout.rb +114 -0
- data/lib/rubocop/cop/lazy_loader.rb +41 -0
- data/lib/rubocop/cop/legacy/corrector.rb +12 -2
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +73 -4
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1 -10
- data/lib/rubocop/cop/lint/ambiguous_range.rb +8 -1
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
- data/lib/rubocop/cop/lint/argument_mismatch.rb +89 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +20 -10
- data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +11 -13
- data/lib/rubocop/cop/lint/boolean_symbol.rb +2 -4
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +49 -17
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +227 -0
- data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +166 -0
- data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
- data/lib/rubocop/cop/lint/debugger.rb +53 -9
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +2 -2
- data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +7 -13
- data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
- data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
- data/lib/rubocop/cop/lint/duplicate_hash_key.rb +0 -4
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +5 -5
- data/lib/rubocop/cop/lint/duplicate_methods.rb +504 -49
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +6 -43
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
- data/lib/rubocop/cop/lint/else_layout.rb +19 -2
- data/lib/rubocop/cop/lint/empty_block.rb +5 -5
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +33 -57
- data/lib/rubocop/cop/lint/empty_ensure.rb +2 -12
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_file.rb +0 -2
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
- data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -5
- data/lib/rubocop/cop/lint/empty_when.rb +9 -4
- data/lib/rubocop/cop/lint/ensure_return.rb +20 -10
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +28 -25
- data/lib/rubocop/cop/lint/float_comparison.rb +59 -15
- data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -8
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -12
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
- data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +22 -12
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -9
- data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +30 -6
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +50 -0
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +133 -12
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +95 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +61 -30
- data/lib/rubocop/cop/lint/loop.rb +6 -12
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +44 -22
- data/lib/rubocop/cop/lint/missing_super.rb +33 -3
- data/lib/rubocop/cop/lint/mixed_case_range.rb +16 -12
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
- data/lib/rubocop/cop/lint/name_typo.rb +270 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -12
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +8 -25
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +22 -7
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +22 -10
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +10 -10
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
- data/lib/rubocop/cop/lint/number_conversion.rb +28 -15
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -3
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +104 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +18 -6
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +9 -24
- data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
- data/lib/rubocop/cop/lint/raise_exception.rb +30 -11
- data/lib/rubocop/cop/lint/rand_one.rb +1 -5
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +126 -30
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +57 -21
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15 -4
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +12 -2
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -21
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +206 -15
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +20 -10
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -6
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +267 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +9 -3
- data/lib/rubocop/cop/lint/redundant_with_object.rb +10 -2
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +9 -2
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -2
- data/lib/rubocop/cop/lint/require_parentheses.rb +13 -8
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +3 -2
- data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
- data/lib/rubocop/cop/lint/rescue_exception.rb +2 -9
- data/lib/rubocop/cop/lint/rescue_type.rb +6 -12
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -13
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +55 -13
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +113 -41
- data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
- data/lib/rubocop/cop/lint/script_permission.rb +7 -3
- data/lib/rubocop/cop/lint/self_assignment.rb +103 -10
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
- data/lib/rubocop/cop/lint/shadowed_argument.rb +8 -7
- data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -2
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +40 -12
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +78 -0
- data/lib/rubocop/cop/lint/struct_new_override.rb +29 -13
- data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +122 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +26 -4
- data/lib/rubocop/cop/lint/syntax.rb +35 -5
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +77 -9
- data/lib/rubocop/cop/lint/to_json.rb +20 -17
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +114 -0
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
- data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +5 -3
- data/lib/rubocop/cop/lint/unreachable_code.rb +68 -15
- data/lib/rubocop/cop/lint/unreachable_loop.rb +14 -8
- data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +28 -2
- data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
- data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +37 -12
- data/lib/rubocop/cop/lint/useless_assignment.rb +92 -34
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +107 -0
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +92 -0
- data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -4
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +79 -0
- data/lib/rubocop/cop/lint/useless_or.rb +111 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +3 -4
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +14 -8
- data/lib/rubocop/cop/lint/useless_setter_call.rb +17 -29
- data/lib/rubocop/cop/lint/useless_times.rb +24 -3
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +201 -0
- data/lib/rubocop/cop/lint/void.rb +127 -29
- data/lib/rubocop/cop/lint.rb +178 -0
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +4 -4
- data/lib/rubocop/cop/metrics/block_length.rb +9 -7
- data/lib/rubocop/cop/metrics/block_nesting.rb +43 -8
- data/lib/rubocop/cop/metrics/class_length.rb +23 -17
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +8 -1
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
- data/lib/rubocop/cop/metrics/method_length.rb +17 -8
- data/lib/rubocop/cop/metrics/module_length.rb +7 -6
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +38 -8
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +5 -4
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +39 -12
- data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/metrics.rb +31 -0
- data/lib/rubocop/cop/migration/department_name.rb +11 -5
- data/lib/rubocop/cop/migration.rb +13 -0
- data/lib/rubocop/cop/mixin/alignment.rb +8 -4
- data/lib/rubocop/cop/mixin/allowed_methods.rb +12 -6
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +20 -4
- data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
- data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +46 -18
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +47 -0
- data/lib/rubocop/cop/mixin/code_length.rb +12 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +22 -14
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/configurable_max.rb +11 -6
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +32 -0
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +20 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +23 -12
- data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +33 -15
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +49 -40
- data/lib/rubocop/cop/mixin/hash_subset.rb +210 -0
- data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +32 -78
- data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
- data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +61 -14
- data/lib/rubocop/cop/mixin/method_complexity.rb +17 -7
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +11 -12
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +120 -39
- data/lib/rubocop/cop/mixin/project_index_help.rb +188 -0
- data/lib/rubocop/cop/mixin/range_help.rb +16 -6
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +171 -0
- data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
- data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +57 -15
- data/lib/rubocop/cop/mixin/string_help.rb +5 -3
- data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +27 -10
- data/lib/rubocop/cop/mixin.rb +91 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +35 -6
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +39 -8
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +7 -9
- data/lib/rubocop/cop/naming/file_name.rb +9 -10
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
- data/lib/rubocop/cop/naming/inclusive_language.rb +21 -7
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +25 -19
- data/lib/rubocop/cop/naming/method_name.rb +190 -15
- data/lib/rubocop/cop/naming/predicate_method.rb +330 -0
- data/lib/rubocop/cop/naming/predicate_prefix.rb +232 -0
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +23 -17
- data/lib/rubocop/cop/naming/variable_name.rb +50 -6
- data/lib/rubocop/cop/naming/variable_number.rb +5 -4
- data/lib/rubocop/cop/naming.rb +31 -0
- data/lib/rubocop/cop/offense.rb +56 -14
- data/lib/rubocop/cop/registry.rb +225 -64
- data/lib/rubocop/cop/security/compound_hash.rb +4 -2
- data/lib/rubocop/cop/security/eval.rb +17 -3
- data/lib/rubocop/cop/security/io_methods.rb +2 -2
- data/lib/rubocop/cop/security/json_load.rb +33 -11
- data/lib/rubocop/cop/security/marshal_load.rb +1 -1
- data/lib/rubocop/cop/security/open.rb +3 -2
- data/lib/rubocop/cop/security/yaml_load.rb +3 -2
- data/lib/rubocop/cop/security.rb +19 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +184 -33
- data/lib/rubocop/cop/style/accessor_grouping.rb +56 -11
- data/lib/rubocop/cop/style/alias.rb +26 -12
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
- data/lib/rubocop/cop/style/and_or.rb +3 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +487 -63
- data/lib/rubocop/cop/style/array_first_last.rb +90 -0
- data/lib/rubocop/cop/style/array_intersect.rb +148 -41
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +50 -0
- data/lib/rubocop/cop/style/array_join.rb +4 -2
- data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
- data/lib/rubocop/cop/style/attr.rb +5 -2
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
- data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
- data/lib/rubocop/cop/style/begin_block.rb +3 -1
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
- data/lib/rubocop/cop/style/bitwise_predicate.rb +106 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +89 -53
- data/lib/rubocop/cop/style/case_equality.rb +29 -15
- data/lib/rubocop/cop/style/case_like_if.rb +16 -21
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +139 -22
- data/lib/rubocop/cop/style/class_check.rb +1 -0
- data/lib/rubocop/cop/style/class_equality_comparison.rb +29 -14
- data/lib/rubocop/cop/style/class_methods_definitions.rb +11 -5
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +53 -23
- data/lib/rubocop/cop/style/collection_methods.rb +4 -1
- data/lib/rubocop/cop/style/collection_querying.rb +167 -0
- data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
- data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +29 -9
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +30 -4
- data/lib/rubocop/cop/style/comparable_between.rb +78 -0
- data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +11 -5
- data/lib/rubocop/cop/style/conditional_assignment.rb +85 -56
- data/lib/rubocop/cop/style/constant_visibility.rb +21 -23
- data/lib/rubocop/cop/style/copyright.rb +49 -24
- data/lib/rubocop/cop/style/data_inheritance.rb +12 -1
- data/lib/rubocop/cop/style/date_time.rb +8 -7
- data/lib/rubocop/cop/style/def_with_parentheses.rb +22 -7
- data/lib/rubocop/cop/style/dig_chain.rb +94 -0
- data/lib/rubocop/cop/style/dir_empty.rb +4 -0
- data/lib/rubocop/cop/style/directive_scope.rb +171 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +77 -13
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
- data/lib/rubocop/cop/style/documentation.rb +76 -29
- data/lib/rubocop/cop/style/documentation_method.rb +24 -0
- data/lib/rubocop/cop/style/double_negation.rb +5 -5
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +12 -16
- data/lib/rubocop/cop/style/each_with_object.rb +5 -4
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +16 -2
- data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
- data/lib/rubocop/cop/style/empty_else.rb +10 -7
- data/lib/rubocop/cop/style/empty_heredoc.rb +5 -14
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +43 -25
- data/lib/rubocop/cop/style/empty_method.rb +0 -6
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +110 -0
- data/lib/rubocop/cop/style/encoding.rb +7 -1
- data/lib/rubocop/cop/style/end_block.rb +3 -1
- data/lib/rubocop/cop/style/endless_method.rb +164 -24
- data/lib/rubocop/cop/style/env_home.rb +4 -0
- data/lib/rubocop/cop/style/eval_with_location.rb +23 -31
- data/lib/rubocop/cop/style/even_odd.rb +11 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +13 -5
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +19 -6
- data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
- data/lib/rubocop/cop/style/fetch_env_var.rb +35 -8
- data/lib/rubocop/cop/style/file_null.rb +91 -0
- data/lib/rubocop/cop/style/file_open.rb +84 -0
- data/lib/rubocop/cop/style/file_read.rb +2 -5
- data/lib/rubocop/cop/style/file_touch.rb +75 -0
- data/lib/rubocop/cop/style/file_write.rb +23 -21
- data/lib/rubocop/cop/style/float_division.rb +23 -5
- data/lib/rubocop/cop/style/for.rb +7 -2
- data/lib/rubocop/cop/style/format_string.rb +47 -13
- data/lib/rubocop/cop/style/format_string_token.rb +86 -16
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +6 -3
- data/lib/rubocop/cop/style/global_std_stream.rb +10 -1
- data/lib/rubocop/cop/style/global_vars.rb +6 -5
- data/lib/rubocop/cop/style/guard_clause.rb +67 -21
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
- data/lib/rubocop/cop/style/hash_conversion.rb +38 -13
- data/lib/rubocop/cop/style/hash_each_methods.rb +109 -12
- data/lib/rubocop/cop/style/hash_except.rb +38 -146
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_lookup_method.rb +102 -0
- data/lib/rubocop/cop/style/hash_slice.rb +96 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +36 -7
- data/lib/rubocop/cop/style/hash_transform_keys.rb +19 -9
- data/lib/rubocop/cop/style/hash_transform_values.rb +19 -9
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +62 -9
- data/lib/rubocop/cop/style/if_inside_else.rb +26 -22
- data/lib/rubocop/cop/style/if_unless_modifier.rb +72 -47
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +15 -19
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +12 -9
- data/lib/rubocop/cop/style/if_with_semicolon.rb +75 -11
- data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inline_comment.rb +5 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +22 -18
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +71 -9
- data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
- data/lib/rubocop/cop/style/it_assignment.rb +93 -0
- data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +71 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +20 -10
- data/lib/rubocop/cop/style/lambda.rb +16 -5
- data/lib/rubocop/cop/style/lambda_call.rb +33 -11
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/magic_comment_format.rb +4 -4
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +93 -50
- data/lib/rubocop/cop/style/map_into_array.rb +236 -0
- data/lib/rubocop/cop/style/map_join.rb +123 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +28 -10
- data/lib/rubocop/cop/style/map_to_set.rb +4 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +77 -28
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +38 -9
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +37 -15
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +8 -6
- data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
- data/lib/rubocop/cop/style/missing_else.rb +2 -4
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +75 -12
- data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
- data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
- data/lib/rubocop/cop/style/module_function.rb +4 -2
- data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
- data/lib/rubocop/cop/style/multiline_memoization.rb +9 -3
- data/lib/rubocop/cop/style/multiline_method_signature.rb +18 -13
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +6 -4
- data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
- data/lib/rubocop/cop/style/multiple_comparison.rb +63 -59
- data/lib/rubocop/cop/style/mutable_constant.rb +117 -19
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +6 -5
- data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
- data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -2
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +8 -15
- data/lib/rubocop/cop/style/next.rb +45 -1
- data/lib/rubocop/cop/style/nil_comparison.rb +12 -10
- data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
- data/lib/rubocop/cop/style/not.rb +3 -1
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
- data/lib/rubocop/cop/style/numeric_predicate.rb +13 -5
- data/lib/rubocop/cop/style/object_then.rb +16 -14
- data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +50 -16
- data/lib/rubocop/cop/style/open_struct_use.rb +6 -6
- data/lib/rubocop/cop/style/operator_method_call.rb +40 -8
- data/lib/rubocop/cop/style/option_hash.rb +1 -1
- data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
- data/lib/rubocop/cop/style/or_assignment.rb +3 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +69 -48
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +5 -1
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
- data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
- data/lib/rubocop/cop/style/proc.rb +5 -4
- data/lib/rubocop/cop/style/quoted_symbols.rb +2 -4
- data/lib/rubocop/cop/style/raise_args.rb +19 -14
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +37 -4
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- data/lib/rubocop/cop/style/redundant_assignment.rb +21 -3
- data/lib/rubocop/cop/style/redundant_begin.rb +53 -6
- data/lib/rubocop/cop/style/redundant_condition.rb +98 -25
- data/lib/rubocop/cop/style/redundant_conditional.rb +1 -9
- data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +31 -7
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +88 -5
- data/lib/rubocop/cop/style/redundant_each.rb +11 -9
- data/lib/rubocop/cop/style/redundant_exception.rb +39 -13
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +5 -13
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +10 -1
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +23 -6
- data/lib/rubocop/cop/style/redundant_format.rb +319 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
- data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +62 -0
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +92 -72
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +203 -84
- data/lib/rubocop/cop/style/redundant_percent_q.rb +6 -4
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +33 -4
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +20 -24
- data/lib/rubocop/cop/style/redundant_return.rb +20 -8
- data/lib/rubocop/cop/style/redundant_self.rb +43 -22
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +19 -32
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +9 -9
- data/lib/rubocop/cop/style/redundant_sort.rb +17 -16
- data/lib/rubocop/cop/style/redundant_sort_by.rb +19 -3
- data/lib/rubocop/cop/style/redundant_string_escape.rb +4 -5
- data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +32 -3
- data/lib/rubocop/cop/style/require_order.rb +2 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +20 -7
- data/lib/rubocop/cop/style/return_nil.rb +8 -4
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +67 -11
- data/lib/rubocop/cop/style/reverse_find.rb +51 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +176 -66
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/sample.rb +14 -10
- data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
- data/lib/rubocop/cop/style/select_by_range.rb +197 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +62 -26
- data/lib/rubocop/cop/style/self_assignment.rb +13 -19
- data/lib/rubocop/cop/style/semicolon.rb +53 -17
- data/lib/rubocop/cop/style/send.rb +4 -4
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +105 -0
- data/lib/rubocop/cop/style/signal_exception.rb +2 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +16 -8
- data/lib/rubocop/cop/style/single_line_block_params.rb +3 -3
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +90 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +16 -12
- data/lib/rubocop/cop/style/slicing_with_range.rb +105 -10
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +103 -91
- data/lib/rubocop/cop/style/special_global_vars.rb +8 -4
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +3 -1
- data/lib/rubocop/cop/style/static_class.rb +21 -0
- data/lib/rubocop/cop/style/string_chars.rb +1 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +34 -17
- data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/strip.rb +7 -4
- data/lib/rubocop/cop/style/struct_inheritance.rb +25 -3
- data/lib/rubocop/cop/style/super_arguments.rb +220 -0
- data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
- data/lib/rubocop/cop/style/swap_values.rb +4 -15
- data/lib/rubocop/cop/style/symbol_array.rb +35 -15
- data/lib/rubocop/cop/style/symbol_proc.rb +86 -14
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +37 -5
- data/lib/rubocop/cop/style/time_now.rb +41 -0
- data/lib/rubocop/cop/style/top_level_method_definition.rb +4 -3
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +56 -2
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +2 -2
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +21 -22
- data/lib/rubocop/cop/style/trivial_accessors.rb +3 -3
- data/lib/rubocop/cop/style/unless_else.rb +10 -9
- data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
- data/lib/rubocop/cop/style/unpack_first.rb +11 -14
- data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
- data/lib/rubocop/cop/style/while_until_do.rb +7 -2
- data/lib/rubocop/cop/style/while_until_modifier.rb +16 -2
- data/lib/rubocop/cop/style/word_array.rb +1 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +12 -7
- data/lib/rubocop/cop/style/yoda_expression.rb +11 -9
- data/lib/rubocop/cop/style/zero_length_predicate.rb +38 -27
- data/lib/rubocop/cop/style.rb +312 -0
- data/lib/rubocop/cop/team.rb +188 -46
- data/lib/rubocop/cop/util.rb +23 -13
- data/lib/rubocop/cop/utils/format_string.rb +20 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +35 -7
- data/lib/rubocop/cop/variable_force/branch.rb +31 -7
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +32 -10
- data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
- data/lib/rubocop/cop/variable_force.rb +43 -20
- data/lib/rubocop/cops_documentation_generator.rb +137 -63
- data/lib/rubocop/core_ext/string.rb +2 -6
- data/lib/rubocop/directive_comment.rb +135 -19
- data/lib/rubocop/ext/regexp_node.rb +17 -35
- data/lib/rubocop/ext/regexp_parser.rb +4 -21
- data/lib/rubocop/feature_loader.rb +0 -6
- data/lib/rubocop/file_finder.rb +11 -9
- data/lib/rubocop/file_patterns.rb +9 -1
- data/lib/rubocop/formatter/clang_style_formatter.rb +8 -9
- data/lib/rubocop/formatter/disabled_config_formatter.rb +62 -22
- data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
- data/lib/rubocop/formatter/formatter_set.rb +10 -4
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +38 -17
- data/lib/rubocop/formatter/json_formatter.rb +11 -7
- data/lib/rubocop/formatter/junit_formatter.rb +94 -30
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +14 -5
- data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
- data/lib/rubocop/formatter/tap_formatter.rb +11 -10
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +2 -3
- data/lib/rubocop/formatter.rb +22 -21
- data/lib/rubocop/lockfile.rb +76 -7
- data/lib/rubocop/lsp/diagnostic.rb +170 -0
- data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
- data/lib/rubocop/lsp/logger.rb +3 -3
- data/lib/rubocop/lsp/routes.rb +163 -56
- data/lib/rubocop/lsp/runtime.rb +47 -44
- data/lib/rubocop/lsp/server.rb +18 -6
- data/lib/rubocop/lsp/severity.rb +1 -1
- data/lib/rubocop/lsp/stdin_runner.rb +96 -0
- data/lib/rubocop/lsp.rb +36 -0
- data/lib/rubocop/magic_comment.rb +44 -14
- data/lib/rubocop/mcp/server.rb +199 -0
- data/lib/rubocop/options.rb +88 -32
- data/lib/rubocop/path_util.rb +33 -11
- data/lib/rubocop/pending_cops_reporter.rb +51 -0
- data/lib/rubocop/plugin/configuration_integrator.rb +146 -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/project_index_loader.rb +82 -0
- data/lib/rubocop/rake_task.rb +7 -5
- data/lib/rubocop/remote_config.rb +15 -9
- data/lib/rubocop/result_cache.rb +85 -61
- data/lib/rubocop/rspec/cop_helper.rb +28 -2
- data/lib/rubocop/rspec/expect_offense.rb +29 -12
- data/lib/rubocop/rspec/shared_contexts.rb +165 -24
- data/lib/rubocop/rspec/support.rb +8 -2
- data/lib/rubocop/runner.rb +273 -99
- data/lib/rubocop/server/cache.rb +76 -42
- data/lib/rubocop/server/cli.rb +2 -4
- data/lib/rubocop/server/client_command/base.rb +10 -0
- data/lib/rubocop/server/client_command/exec.rb +4 -4
- data/lib/rubocop/server/client_command/start.rb +11 -1
- data/lib/rubocop/server/core.rb +13 -0
- data/lib/rubocop/server/server_command/exec.rb +0 -1
- data/lib/rubocop/server.rb +14 -0
- data/lib/rubocop/string_interpreter.rb +3 -3
- data/lib/rubocop/target_finder.rb +111 -86
- data/lib/rubocop/target_ruby.rb +131 -89
- data/lib/rubocop/todo_audit.rb +111 -0
- data/lib/rubocop/version.rb +84 -10
- data/lib/rubocop/yaml_duplication_checker.rb +20 -26
- data/lib/rubocop.rb +33 -648
- data/lib/ruby_lsp/rubocop/addon.rb +89 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
- metadata +169 -50
- data/lib/rubocop/cop/naming/predicate_name.rb +0 -134
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -100
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
|
@@ -6,72 +6,214 @@ module RuboCop
|
|
|
6
6
|
# Checks for duplicated instance (or singleton) method
|
|
7
7
|
# definitions.
|
|
8
8
|
#
|
|
9
|
+
# NOTE: Aliasing a method to itself is allowed, as it indicates that
|
|
10
|
+
# the developer intends to suppress Ruby's method redefinition warnings.
|
|
11
|
+
# See https://bugs.ruby-lang.org/issues/13574.
|
|
12
|
+
#
|
|
13
|
+
# By default the cop can only detect duplicates within a single file.
|
|
14
|
+
# When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is installed,
|
|
15
|
+
# the cop additionally consults the project-wide index and reports methods
|
|
16
|
+
# whose duplicate definition lives in another file.
|
|
17
|
+
#
|
|
18
|
+
# NOTE: The project index does not record whether a definition in another
|
|
19
|
+
# file is wrapped in a conditional, so a platform-specific redefinition in
|
|
20
|
+
# another file may still be reported. Aliasing the method to itself (see above)
|
|
21
|
+
# before redefining marks the redefinition as intentional and is respected
|
|
22
|
+
# across files. With `AllCops/ActiveSupportExtensionsEnabled: true`, Active
|
|
23
|
+
# Support's redefinition markers (`silence_redefinition_of_method` and
|
|
24
|
+
# `redefine_method`) are honored the same way.
|
|
25
|
+
#
|
|
26
|
+
# NOTE: Methods defined with `define_method` are not recorded in the project
|
|
27
|
+
# index, so a duplicate whose other definition uses `define_method` cannot
|
|
28
|
+
# be detected across files.
|
|
29
|
+
#
|
|
30
|
+
# Cross-file duplicates whose other definition lives in a file matching one
|
|
31
|
+
# of the `AllowedCrossFilePaths` patterns are not reported. This suits files
|
|
32
|
+
# that redefine application methods but are never loaded together with them,
|
|
33
|
+
# such as standalone scripts. Patterns are matched with the same glob (or
|
|
34
|
+
# regexp) semantics as `Exclude`, against the other file's path relative to
|
|
35
|
+
# the directory of the `.rubocop.yml` that configures the cop; absolute
|
|
36
|
+
# patterns are matched against the absolute path. Offenses inside such files
|
|
37
|
+
# themselves are best silenced with an ordinary per-cop `Exclude`.
|
|
38
|
+
#
|
|
9
39
|
# @example
|
|
10
40
|
#
|
|
11
41
|
# # bad
|
|
42
|
+
# def foo
|
|
43
|
+
# 1
|
|
44
|
+
# end
|
|
45
|
+
#
|
|
46
|
+
# def foo
|
|
47
|
+
# 2
|
|
48
|
+
# end
|
|
12
49
|
#
|
|
50
|
+
# # bad
|
|
13
51
|
# def foo
|
|
14
52
|
# 1
|
|
15
53
|
# end
|
|
16
54
|
#
|
|
55
|
+
# alias foo bar
|
|
56
|
+
#
|
|
57
|
+
# # good
|
|
17
58
|
# def foo
|
|
59
|
+
# 1
|
|
60
|
+
# end
|
|
61
|
+
#
|
|
62
|
+
# def bar
|
|
18
63
|
# 2
|
|
19
64
|
# end
|
|
20
65
|
#
|
|
21
|
-
#
|
|
66
|
+
# # good
|
|
67
|
+
# def foo
|
|
68
|
+
# 1
|
|
69
|
+
# end
|
|
22
70
|
#
|
|
23
|
-
#
|
|
71
|
+
# alias bar foo
|
|
24
72
|
#
|
|
73
|
+
# # good
|
|
74
|
+
# alias foo foo
|
|
25
75
|
# def foo
|
|
26
76
|
# 1
|
|
27
77
|
# end
|
|
28
78
|
#
|
|
29
|
-
#
|
|
79
|
+
# # good
|
|
80
|
+
# alias_method :foo, :foo
|
|
81
|
+
# def foo
|
|
82
|
+
# 1
|
|
83
|
+
# end
|
|
30
84
|
#
|
|
31
|
-
#
|
|
85
|
+
# # bad
|
|
86
|
+
# class MyClass
|
|
87
|
+
# extend Forwardable
|
|
88
|
+
#
|
|
89
|
+
# # or with: `def_instance_delegator`, `def_delegators`, `def_instance_delegators`
|
|
90
|
+
# def_delegator :delegation_target, :delegated_method_name
|
|
91
|
+
#
|
|
92
|
+
# def delegated_method_name
|
|
93
|
+
# end
|
|
94
|
+
# end
|
|
32
95
|
#
|
|
33
96
|
# # good
|
|
97
|
+
# class MyClass
|
|
98
|
+
# extend Forwardable
|
|
99
|
+
#
|
|
100
|
+
# def_delegator :delegation_target, :delegated_method_name
|
|
101
|
+
#
|
|
102
|
+
# def non_duplicated_delegated_method_name
|
|
103
|
+
# end
|
|
104
|
+
# end
|
|
105
|
+
#
|
|
106
|
+
# @example AllCops:ActiveSupportExtensionsEnabled: false (default)
|
|
34
107
|
#
|
|
108
|
+
# # good
|
|
35
109
|
# def foo
|
|
36
110
|
# 1
|
|
37
111
|
# end
|
|
38
112
|
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
113
|
+
# delegate :foo, to: :bar
|
|
114
|
+
#
|
|
115
|
+
# @example AllCops:ActiveSupportExtensionsEnabled: true
|
|
116
|
+
#
|
|
117
|
+
# # bad
|
|
118
|
+
# def foo
|
|
119
|
+
# 1
|
|
41
120
|
# end
|
|
42
121
|
#
|
|
43
|
-
#
|
|
122
|
+
# delegate :foo, to: :bar
|
|
44
123
|
#
|
|
45
124
|
# # good
|
|
125
|
+
# def foo
|
|
126
|
+
# 1
|
|
127
|
+
# end
|
|
128
|
+
#
|
|
129
|
+
# delegate :baz, to: :bar
|
|
46
130
|
#
|
|
131
|
+
# # good - delegate with splat arguments is ignored
|
|
47
132
|
# def foo
|
|
48
133
|
# 1
|
|
49
134
|
# end
|
|
50
135
|
#
|
|
51
|
-
#
|
|
52
|
-
|
|
136
|
+
# delegate :foo, **options
|
|
137
|
+
#
|
|
138
|
+
# # good - delegate inside a condition is ignored
|
|
139
|
+
# def foo
|
|
140
|
+
# 1
|
|
141
|
+
# end
|
|
142
|
+
#
|
|
143
|
+
# if cond
|
|
144
|
+
# delegate :foo, to: :bar
|
|
145
|
+
# end
|
|
146
|
+
#
|
|
147
|
+
# # good - Active Support's redefinition markers signal an intentional
|
|
148
|
+
# # redefinition of a method defined in another file
|
|
149
|
+
# silence_redefinition_of_method :foo
|
|
150
|
+
# def foo
|
|
151
|
+
# 1
|
|
152
|
+
# end
|
|
153
|
+
#
|
|
154
|
+
# @example AllowedCrossFilePaths: ['script/**/*'] (default: [])
|
|
155
|
+
# # Cross-file duplicates whose other definition lives in a file
|
|
156
|
+
# # matching one of the patterns are not reported.
|
|
157
|
+
#
|
|
158
|
+
# # good - assuming `AppHelper#format` is also defined in
|
|
159
|
+
# # `script/backfill.rb`, which is never loaded with this file
|
|
160
|
+
# class AppHelper
|
|
161
|
+
# def format
|
|
162
|
+
# end
|
|
163
|
+
# end
|
|
164
|
+
#
|
|
165
|
+
# @example DelegatingMethods: ['delegate', 'expose'] (default: ['delegate'])
|
|
166
|
+
# # A project's own `delegate`-shaped macros can be registered so the
|
|
167
|
+
# # methods they define are recognized (with
|
|
168
|
+
# # `AllCops/ActiveSupportExtensionsEnabled: true`).
|
|
169
|
+
#
|
|
170
|
+
# # bad
|
|
171
|
+
# def foo
|
|
172
|
+
# 1
|
|
173
|
+
# end
|
|
174
|
+
#
|
|
175
|
+
# expose :foo, to: :bar
|
|
176
|
+
#
|
|
177
|
+
class DuplicateMethods < Base # rubocop:disable Metrics/ClassLength
|
|
178
|
+
include ProjectIndexHelp
|
|
179
|
+
|
|
53
180
|
MSG = 'Method `%<method>s` is defined at both %<defined>s and %<current>s.'
|
|
54
|
-
|
|
55
|
-
|
|
181
|
+
|
|
182
|
+
# Method names the cop registers that can be looked up in the project index:
|
|
183
|
+
# a fully qualified namespace followed by `#` (instance) or `.` (singleton)
|
|
184
|
+
# and the method name.
|
|
185
|
+
INDEXABLE_METHOD_NAME =
|
|
186
|
+
/\A(?<owner>[A-Z]\w*(?:::[A-Z]\w*)*)(?<separator>[#.])(?<name>[^#.]+)\z/.freeze
|
|
187
|
+
# No `RESTRICT_ON_SEND`: the delegating method names are configurable
|
|
188
|
+
# (`DelegatingMethods`), so `on_send` must see every call. The handler
|
|
189
|
+
# returns quickly for calls that are not method definitions, and
|
|
190
|
+
# benchmarks show no measurable cost over the previous fixed list.
|
|
56
191
|
|
|
57
192
|
def initialize(config = nil, options = nil)
|
|
58
193
|
super
|
|
59
194
|
@definitions = {}
|
|
60
195
|
@scopes = Hash.new { |hash, key| hash[key] = [] }
|
|
196
|
+
@intentionally_redefined = Set.new
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def on_new_investigation
|
|
200
|
+
# The self-alias trick and Active Support's redefinition markers declare
|
|
201
|
+
# an intentional redefinition only within the file that uses them, so the
|
|
202
|
+
# tracked names do not carry over.
|
|
203
|
+
@intentionally_redefined = Set.new
|
|
204
|
+
super
|
|
61
205
|
end
|
|
62
206
|
|
|
63
207
|
def on_def(node)
|
|
64
208
|
# if a method definition is inside an if, it is very likely
|
|
65
209
|
# that a different definition is used depending on platform, etc.
|
|
66
210
|
return if node.each_ancestor.any?(&:if_type?)
|
|
67
|
-
return if possible_dsl?(node)
|
|
68
211
|
|
|
69
212
|
found_instance_method(node, node.method_name)
|
|
70
213
|
end
|
|
71
214
|
|
|
72
215
|
def on_defs(node)
|
|
73
216
|
return if node.each_ancestor.any?(&:if_type?)
|
|
74
|
-
return if possible_dsl?(node)
|
|
75
217
|
|
|
76
218
|
if node.receiver.const_type?
|
|
77
219
|
_, const_name = *node.receiver
|
|
@@ -83,32 +225,113 @@ module RuboCop
|
|
|
83
225
|
|
|
84
226
|
# @!method method_alias?(node)
|
|
85
227
|
def_node_matcher :method_alias?, <<~PATTERN
|
|
86
|
-
(alias (sym $_name) sym)
|
|
228
|
+
(alias (sym $_name) (sym $_original_name))
|
|
87
229
|
PATTERN
|
|
88
230
|
|
|
89
231
|
def on_alias(node)
|
|
90
|
-
|
|
232
|
+
name, original_name = method_alias?(node)
|
|
233
|
+
return unless name && original_name
|
|
234
|
+
|
|
235
|
+
if name == original_name
|
|
236
|
+
track_intentional_redefinition(node, name)
|
|
237
|
+
return
|
|
238
|
+
end
|
|
91
239
|
return if node.ancestors.any?(&:if_type?)
|
|
92
|
-
return if possible_dsl?(node)
|
|
93
240
|
|
|
94
241
|
found_instance_method(node, name)
|
|
95
242
|
end
|
|
96
243
|
|
|
97
244
|
# @!method alias_method?(node)
|
|
98
245
|
def_node_matcher :alias_method?, <<~PATTERN
|
|
99
|
-
(send nil? :alias_method (sym $_name)
|
|
246
|
+
(send nil? :alias_method (sym $_name) (sym $_original_name))
|
|
247
|
+
PATTERN
|
|
248
|
+
|
|
249
|
+
# Matches the argument shape of an Active Support `delegate` call
|
|
250
|
+
# (`delegate :a, :b, to: :target`), regardless of the method name; the
|
|
251
|
+
# name is checked separately against `DelegatingMethods`.
|
|
252
|
+
# @!method delegate_args(node)
|
|
253
|
+
def_node_matcher :delegate_args, <<~PATTERN
|
|
254
|
+
(send nil? _
|
|
255
|
+
({sym str} $_)+
|
|
256
|
+
(hash <(pair (sym :to) {sym str}) ...>)
|
|
257
|
+
)
|
|
258
|
+
PATTERN
|
|
259
|
+
|
|
260
|
+
# @!method delegator?(node)
|
|
261
|
+
def_node_matcher :delegator?, <<~PATTERN
|
|
262
|
+
(send nil? {:def_delegator :def_instance_delegator}
|
|
263
|
+
{
|
|
264
|
+
{sym str} ({sym str} $_) |
|
|
265
|
+
{sym str} {sym str} ({sym str} $_)
|
|
266
|
+
}
|
|
267
|
+
)
|
|
268
|
+
PATTERN
|
|
269
|
+
|
|
270
|
+
# @!method delegators?(node)
|
|
271
|
+
def_node_matcher :delegators?, <<~PATTERN
|
|
272
|
+
(send nil? {:def_delegators :def_instance_delegators}
|
|
273
|
+
{sym str}
|
|
274
|
+
({sym str} $_)+
|
|
275
|
+
)
|
|
276
|
+
PATTERN
|
|
277
|
+
|
|
278
|
+
# Matches Active Support's markers of an intentional method redefinition:
|
|
279
|
+
# `silence_redefinition_of_method :name` suppresses Ruby's redefinition
|
|
280
|
+
# warning for a subsequent definition of `name`, and
|
|
281
|
+
# `redefine_method(:name) { ... }` both silences the warning and redefines.
|
|
282
|
+
# @!method active_support_redefinition_marker(node)
|
|
283
|
+
def_node_matcher :active_support_redefinition_marker, <<~PATTERN
|
|
284
|
+
(send nil? {:silence_redefinition_of_method :redefine_method} ({sym str} $_) ...)
|
|
100
285
|
PATTERN
|
|
101
286
|
|
|
102
287
|
# @!method sym_name(node)
|
|
103
288
|
def_node_matcher :sym_name, '(sym $_name)'
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
289
|
+
|
|
290
|
+
# @!method class_or_module_new_block?(node)
|
|
291
|
+
def_node_matcher :class_or_module_new_block?, <<~PATTERN
|
|
292
|
+
(block
|
|
293
|
+
(send (const _ {:Class :Module}) :new ...)
|
|
294
|
+
...)
|
|
295
|
+
PATTERN
|
|
296
|
+
|
|
297
|
+
# @!method class_new_block?(node)
|
|
298
|
+
def_node_matcher :class_new_block?, <<~PATTERN
|
|
299
|
+
(block
|
|
300
|
+
(send (const _ :Class) :new ...)
|
|
301
|
+
...)
|
|
302
|
+
PATTERN
|
|
303
|
+
|
|
304
|
+
def on_send(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
305
|
+
name, original_name = alias_method?(node)
|
|
306
|
+
|
|
307
|
+
if name && original_name
|
|
308
|
+
if name == original_name
|
|
309
|
+
track_intentional_redefinition(node, name)
|
|
310
|
+
return
|
|
311
|
+
end
|
|
312
|
+
return if inside_condition?(node)
|
|
108
313
|
|
|
109
314
|
found_instance_method(node, name)
|
|
110
315
|
elsif (attr = node.attribute_accessor?)
|
|
111
316
|
on_attr(node, *attr)
|
|
317
|
+
elsif delegating_method?(node) && (names = delegate_args(node))
|
|
318
|
+
return if inside_condition?(node)
|
|
319
|
+
|
|
320
|
+
on_delegate(node, names)
|
|
321
|
+
elsif (name = delegator?(node))
|
|
322
|
+
return if inside_condition?(node)
|
|
323
|
+
|
|
324
|
+
found_instance_method(node, name)
|
|
325
|
+
elsif (names = delegators?(node))
|
|
326
|
+
return if inside_condition?(node)
|
|
327
|
+
|
|
328
|
+
names.each { |name| found_instance_method(node, name) }
|
|
329
|
+
elsif (name = active_support_redefinition_marker(node))
|
|
330
|
+
# `redefine_method` takes a block; scope resolution must start from the
|
|
331
|
+
# block node, since `parent_module_name` cannot see through a block
|
|
332
|
+
# ancestor that is not a module constructor.
|
|
333
|
+
track_intentional_redefinition(node.block_node || node, name) if
|
|
334
|
+
active_support_extensions_enabled?
|
|
112
335
|
end
|
|
113
336
|
end
|
|
114
337
|
|
|
@@ -123,9 +346,16 @@ module RuboCop
|
|
|
123
346
|
|
|
124
347
|
def check_self_receiver(node, name)
|
|
125
348
|
enclosing = node.parent_module_name
|
|
126
|
-
|
|
349
|
+
if enclosing
|
|
350
|
+
found_method(node, "#{enclosing}.#{name}")
|
|
351
|
+
elsif (anon_block = anonymous_class_block(node))
|
|
352
|
+
scope = qualified_name(anon_block.parent_module_name, nil, 'Object')
|
|
353
|
+
found_method(node, "#{scope}.#{name}", scope_id: anon_block_scope_id(anon_block))
|
|
354
|
+
end
|
|
355
|
+
end
|
|
127
356
|
|
|
128
|
-
|
|
357
|
+
def inside_condition?(node)
|
|
358
|
+
node.ancestors.any?(&:if_type?)
|
|
129
359
|
end
|
|
130
360
|
|
|
131
361
|
def message_for_dup(node, method_name, key)
|
|
@@ -133,17 +363,104 @@ module RuboCop
|
|
|
133
363
|
current: source_location(node))
|
|
134
364
|
end
|
|
135
365
|
|
|
366
|
+
# Recognizing a delegating call as a method definition is Active
|
|
367
|
+
# Support behavior, so it stays gated on `ActiveSupportExtensionsEnabled`
|
|
368
|
+
# as it was when only `delegate` was supported. `DelegatingMethods` lets
|
|
369
|
+
# a project register its own `delegate`-shaped macros.
|
|
370
|
+
def delegating_method?(node)
|
|
371
|
+
active_support_extensions_enabled? &&
|
|
372
|
+
delegating_methods.include?(node.method_name.to_s)
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
def delegating_methods
|
|
376
|
+
cop_config.fetch('DelegatingMethods', ['delegate'])
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
def on_delegate(node, method_names)
|
|
380
|
+
name_prefix = delegate_prefix(node)
|
|
381
|
+
|
|
382
|
+
method_names.each do |name|
|
|
383
|
+
name = "#{name_prefix}_#{name}" if name_prefix
|
|
384
|
+
|
|
385
|
+
found_instance_method(node, name)
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
def delegate_prefix(node)
|
|
390
|
+
kwargs_node = node.last_argument
|
|
391
|
+
|
|
392
|
+
return unless (prefix = hash_value(kwargs_node, :prefix))
|
|
393
|
+
|
|
394
|
+
if prefix.true_type?
|
|
395
|
+
hash_value(kwargs_node, :to).value
|
|
396
|
+
elsif prefix.type?(:sym, :str)
|
|
397
|
+
prefix.value
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def hash_value(node, key)
|
|
402
|
+
node.pairs.find { |pair| pair.key.value == key }&.value
|
|
403
|
+
end
|
|
404
|
+
|
|
136
405
|
def found_instance_method(node, name)
|
|
137
|
-
|
|
406
|
+
if (scope = node.parent_module_name)
|
|
407
|
+
found_method(node, "#{humanize_scope(scope)}#{name}")
|
|
408
|
+
elsif (anon_block = anonymous_class_block(node))
|
|
409
|
+
base = qualified_name(anon_block.parent_module_name, nil, 'Object')
|
|
410
|
+
scope = node.each_ancestor(:sclass).any? ? "#<Class:#{base}>" : base
|
|
411
|
+
found_method(
|
|
412
|
+
node, "#{humanize_scope(scope)}#{name}", scope_id: anon_block_scope_id(anon_block)
|
|
413
|
+
)
|
|
414
|
+
else
|
|
415
|
+
found_sclass_method(node, name)
|
|
416
|
+
end
|
|
417
|
+
end
|
|
138
418
|
|
|
139
|
-
|
|
419
|
+
def humanize_scope(scope)
|
|
140
420
|
scope = scope.sub(
|
|
141
421
|
/(?:(?<name>.*)::)#<Class:\k<name>>|#<Class:(?<name>.*)>(?:::)?/,
|
|
142
422
|
'\k<name>.'
|
|
143
423
|
)
|
|
144
|
-
scope
|
|
424
|
+
scope.end_with?('.') ? scope : "#{scope}#"
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def anonymous_class_block(node)
|
|
428
|
+
first_block = node.each_ancestor(:block).first
|
|
429
|
+
return unless class_or_module_new_block?(first_block)
|
|
430
|
+
return if first_block.parent&.type?(:lvasgn)
|
|
431
|
+
return if node.each_ancestor(:sclass).any? { |s| !s.children.first.self_type? }
|
|
432
|
+
|
|
433
|
+
first_block
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def anon_block_scope_id(anon_block)
|
|
437
|
+
parent = anon_block.parent
|
|
438
|
+
return unless parent&.type?(:any_block, :begin, :call, :casgn, :any_def)
|
|
439
|
+
|
|
440
|
+
if (receiver = scope_receiver(parent, anon_block))
|
|
441
|
+
"#{receiver.source}.#{parent.method_name}"
|
|
442
|
+
elsif !parent.begin_type? || parent.parent&.any_block_type?
|
|
443
|
+
anon_block_identity(anon_block)
|
|
444
|
+
end
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
# When a Class.new block is passed as an argument to a named-receiver
|
|
448
|
+
# method call (e.g. T.cast(Class.new(Base) do ... end, ...)), the
|
|
449
|
+
# receiver-based scope id (e.g. "T.cast") is the same for every call,
|
|
450
|
+
# causing false positives for methods defined in distinct anonymous
|
|
451
|
+
# classes. Return nil so the block falls through to the unique
|
|
452
|
+
# source-location-based scope id.
|
|
453
|
+
# Module.new blocks are excluded because they may be intentionally
|
|
454
|
+
# mixed into the same target via prepend/include/extend.
|
|
455
|
+
def scope_receiver(parent, anon_block)
|
|
456
|
+
return if class_new_block?(anon_block) && parent.call_type?
|
|
457
|
+
|
|
458
|
+
named_receiver(parent)
|
|
459
|
+
end
|
|
145
460
|
|
|
146
|
-
|
|
461
|
+
def named_receiver(node)
|
|
462
|
+
receiver = node.receiver
|
|
463
|
+
receiver unless class_or_module_new_block?(receiver)
|
|
147
464
|
end
|
|
148
465
|
|
|
149
466
|
def found_sclass_method(node, name)
|
|
@@ -156,27 +473,60 @@ module RuboCop
|
|
|
156
473
|
found_method(node, "#{singleton_receiver_node.method_name}.#{name}")
|
|
157
474
|
end
|
|
158
475
|
|
|
159
|
-
def found_method(node, method_name)
|
|
476
|
+
def found_method(node, method_name, scope_id: nil)
|
|
160
477
|
key = method_key(node, method_name)
|
|
478
|
+
key = "#{key}@#{scope_id}" if scope_id
|
|
161
479
|
scope = node.each_ancestor(:rescue, :ensure).first&.type
|
|
162
480
|
|
|
163
481
|
if @definitions.key?(key)
|
|
164
|
-
|
|
165
|
-
@definitions[key] = node
|
|
166
|
-
@scopes[scope] << key
|
|
167
|
-
return
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
message = message_for_dup(node, method_name, key)
|
|
171
|
-
|
|
172
|
-
add_offense(location(node), message: message)
|
|
482
|
+
found_redefinition(node, method_name, key, scope)
|
|
173
483
|
else
|
|
174
484
|
@definitions[key] = node
|
|
485
|
+
check_cross_file_duplicate(node, method_name) if scope_id.nil? && scope.nil?
|
|
175
486
|
end
|
|
176
487
|
end
|
|
177
488
|
|
|
489
|
+
def found_redefinition(node, method_name, key, scope)
|
|
490
|
+
if scope && !@scopes[scope].include?(key)
|
|
491
|
+
@definitions[key] = node
|
|
492
|
+
@scopes[scope] << key
|
|
493
|
+
elsif intentional_cross_file_redefinition?(node, method_name, key) ||
|
|
494
|
+
allowed_cross_file_redefinition?(node, key)
|
|
495
|
+
@definitions[key] = node
|
|
496
|
+
else
|
|
497
|
+
add_offense(location(node), message: message_for_dup(node, method_name, key))
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
# `AllowedCrossFilePaths` also covers duplicates detected without the index,
|
|
502
|
+
# when the cop instance carries definitions over from an earlier file of the
|
|
503
|
+
# same run.
|
|
504
|
+
def allowed_cross_file_redefinition?(node, key)
|
|
505
|
+
other_path = @definitions[key].source_range.source_buffer.name
|
|
506
|
+
return false if other_path == node.source_range.source_buffer.name
|
|
507
|
+
|
|
508
|
+
allowed_cross_file_path?(other_path)
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
# The self-alias trick (`alias foo foo` or `alias_method :foo, :foo` right before
|
|
512
|
+
# a `def`) suppresses Ruby's method redefinition warning, signaling an intentional
|
|
513
|
+
# redefinition of a method defined in another file. Active Support's redefinition
|
|
514
|
+
# markers (tracked when `ActiveSupportExtensionsEnabled` is on) signal the same.
|
|
515
|
+
def intentional_cross_file_redefinition?(node, method_name, key)
|
|
516
|
+
@intentionally_redefined.include?(method_name) &&
|
|
517
|
+
@definitions[key].source_range.source_buffer.name !=
|
|
518
|
+
node.source_range.source_buffer.name
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
def track_intentional_redefinition(node, name)
|
|
522
|
+
scope = node.parent_module_name
|
|
523
|
+
return unless scope
|
|
524
|
+
|
|
525
|
+
@intentionally_redefined << "#{humanize_scope(scope)}#{name}"
|
|
526
|
+
end
|
|
527
|
+
|
|
178
528
|
def method_key(node, method_name)
|
|
179
|
-
if (ancestor_def = node.each_ancestor(
|
|
529
|
+
if (ancestor_def = node.each_ancestor(:any_def).first)
|
|
180
530
|
"#{ancestor_def.method_name}.#{method_name}"
|
|
181
531
|
else
|
|
182
532
|
method_name
|
|
@@ -184,7 +534,7 @@ module RuboCop
|
|
|
184
534
|
end
|
|
185
535
|
|
|
186
536
|
def location(node)
|
|
187
|
-
if
|
|
537
|
+
if node.any_def_type?
|
|
188
538
|
node.loc.keyword.join(node.loc.name)
|
|
189
539
|
else
|
|
190
540
|
node.source_range
|
|
@@ -247,21 +597,126 @@ module RuboCop
|
|
|
247
597
|
end
|
|
248
598
|
end
|
|
249
599
|
|
|
250
|
-
def possible_dsl?(node)
|
|
251
|
-
# DSL methods may evaluate a block in the context of a newly created
|
|
252
|
-
# class or module
|
|
253
|
-
# Assume that if a method definition is inside any block call which
|
|
254
|
-
# we can't identify, it could be a DSL
|
|
255
|
-
node.each_ancestor(:block).any? do |ancestor|
|
|
256
|
-
ancestor.method_name != :class_eval && !ancestor.class_constructor?
|
|
257
|
-
end
|
|
258
|
-
end
|
|
259
|
-
|
|
260
600
|
def source_location(node)
|
|
261
601
|
range = node.source_range
|
|
262
602
|
path = smart_path(range.source_buffer.name)
|
|
263
603
|
"#{path}:#{range.line}"
|
|
264
604
|
end
|
|
605
|
+
|
|
606
|
+
def check_cross_file_duplicate(node, method_name)
|
|
607
|
+
return unless project_index
|
|
608
|
+
return if @intentionally_redefined.include?(method_name)
|
|
609
|
+
return if node.each_ancestor(:any_def).any?
|
|
610
|
+
return unless (prior = cross_file_prior_definition(method_name))
|
|
611
|
+
|
|
612
|
+
message = format(MSG, method: method_name,
|
|
613
|
+
defined: index_source_location(prior),
|
|
614
|
+
current: source_location(node))
|
|
615
|
+
add_offense(location(node), message: message)
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
def cross_file_prior_definition(method_name)
|
|
619
|
+
return unless (match = INDEXABLE_METHOD_NAME.match(method_name))
|
|
620
|
+
|
|
621
|
+
definitions = definitions_in_other_files(
|
|
622
|
+
indexed_definitions(match[:owner], match[:separator], match[:name])
|
|
623
|
+
).reject { |definition| allowed_cross_file_path?(definition.location.to_file_path) }
|
|
624
|
+
return if definitions.empty? || cross_file_self_alias_trick?(definitions)
|
|
625
|
+
return if cross_file_redefinition_marker?(definitions, match[:name])
|
|
626
|
+
|
|
627
|
+
first_indexed_definition(definitions)
|
|
628
|
+
end
|
|
629
|
+
|
|
630
|
+
# Cross-file duplicates whose other definition site matches one of the
|
|
631
|
+
# `AllowedCrossFilePaths` patterns are skipped (e.g. standalone scripts that
|
|
632
|
+
# are never loaded together with the code they redefine). Patterns are
|
|
633
|
+
# matched like `Exclude` patterns, against the path relative to the
|
|
634
|
+
# directory of the config file that configures the cop; absolute patterns
|
|
635
|
+
# are matched against the absolute path.
|
|
636
|
+
def allowed_cross_file_path?(path)
|
|
637
|
+
patterns = cop_config.fetch('AllowedCrossFilePaths', [])
|
|
638
|
+
return false if patterns.empty?
|
|
639
|
+
|
|
640
|
+
relative = config.path_relative_to_config(path)
|
|
641
|
+
patterns.any? { |pattern| match_path?(pattern, relative) || match_path?(pattern, path) }
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
def indexed_definitions(owner, separator, name)
|
|
645
|
+
namespace = separator == '.' ? "#{owner}::<#{owner.split('::').last}>" : owner
|
|
646
|
+
|
|
647
|
+
if name.match?(/\A\w+=\z/)
|
|
648
|
+
# Rubydex indexes `attr_writer :foo` under `foo` rather than `foo=`, so
|
|
649
|
+
# writer definitions come from both the `foo=` and the `foo` declarations.
|
|
650
|
+
indexed_declaration_definitions(namespace, name) +
|
|
651
|
+
indexed_declaration_definitions(namespace, name.delete_suffix('='))
|
|
652
|
+
.select { |definition| writer_attr_definition?(definition) }
|
|
653
|
+
else
|
|
654
|
+
indexed_declaration_definitions(namespace, name).grep_v(Rubydex::AttrWriterDefinition)
|
|
655
|
+
end
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
def indexed_declaration_definitions(namespace, name)
|
|
659
|
+
project_index["#{namespace}##{name}()"]&.definitions.to_a
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
def writer_attr_definition?(definition)
|
|
663
|
+
definition.is_a?(Rubydex::AttrWriterDefinition) ||
|
|
664
|
+
definition.is_a?(Rubydex::AttrAccessorDefinition)
|
|
665
|
+
end
|
|
666
|
+
|
|
667
|
+
# An alias of the method alongside one of its definitions in another file may be
|
|
668
|
+
# the self-alias trick marking an intentional redefinition there, so no offense
|
|
669
|
+
# is registered. A genuine `alias` duplicate is still reported when the alias
|
|
670
|
+
# itself is inspected.
|
|
671
|
+
def cross_file_self_alias_trick?(definitions)
|
|
672
|
+
aliases, others = definitions.partition do |definition|
|
|
673
|
+
definition.is_a?(Rubydex::MethodAliasDefinition)
|
|
674
|
+
end
|
|
675
|
+
alias_paths = aliases.map { |definition| definition.location.to_file_path }
|
|
676
|
+
|
|
677
|
+
others.any? { |definition| alias_paths.include?(definition.location.to_file_path) }
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
# An Active Support redefinition marker alongside one of the definitions in
|
|
681
|
+
# another file marks the redefinition there as intentional, like the
|
|
682
|
+
# self-alias trick. The index does not record the marker's method-name
|
|
683
|
+
# argument, so the other file's source is searched for a marker naming
|
|
684
|
+
# the method.
|
|
685
|
+
def cross_file_redefinition_marker?(definitions, name)
|
|
686
|
+
return false unless active_support_extensions_enabled?
|
|
687
|
+
|
|
688
|
+
definitions.map { |definition| definition.location.to_file_path }.uniq.any? do |path|
|
|
689
|
+
redefinition_marker_in_file?(path, name)
|
|
690
|
+
end
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
def redefinition_marker_in_file?(path, name)
|
|
694
|
+
return false unless File.readable?(path)
|
|
695
|
+
|
|
696
|
+
escaped = Regexp.escape(name)
|
|
697
|
+
marker = /\b(?:silence_redefinition_of_method|redefine_method)\s*\(?\s*
|
|
698
|
+
(?::#{escaped}|(["'])#{escaped}\1)(?![\w=!?])/x
|
|
699
|
+
File.read(path).scrub.match?(marker)
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
def first_indexed_definition(definitions)
|
|
703
|
+
definitions.find { |definition| !definition.is_a?(Rubydex::MethodAliasDefinition) }
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
def index_source_location(definition)
|
|
707
|
+
location = definition.location
|
|
708
|
+
"#{smart_path(location.to_file_path)}:#{location.to_display.start_line}"
|
|
709
|
+
end
|
|
710
|
+
|
|
711
|
+
# Internal identity for an anonymous block, used as a scope key.
|
|
712
|
+
# Includes the source range's begin position to distinguish blocks
|
|
713
|
+
# that share the same line (e.g. two Class.new calls separated by `;`).
|
|
714
|
+
# The user-facing offense message still uses `source_location`, which
|
|
715
|
+
# shows only `path:line`.
|
|
716
|
+
def anon_block_identity(anon_block)
|
|
717
|
+
range = anon_block.source_range
|
|
718
|
+
"#{smart_path(range.source_buffer.name)}:#{range.line}:#{range.begin_pos}"
|
|
719
|
+
end
|
|
265
720
|
end
|
|
266
721
|
end
|
|
267
722
|
end
|