rubocop 1.53.1 → 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 +25 -3
- 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 +20 -2
- 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
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for uses of `rescue` in its modifier form is added for following
|
|
6
|
+
# Checks for uses of `rescue` in its modifier form. It is added for the following
|
|
7
7
|
# reasons:
|
|
8
8
|
#
|
|
9
9
|
# * The syntax of modifier form `rescue` can be misleading because it
|
|
10
10
|
# might lead us to believe that `rescue` handles the given exception
|
|
11
|
-
# but it actually
|
|
11
|
+
# but it actually rescues all exceptions to return the given rescue
|
|
12
12
|
# block. In this case, value returned by handle_error or
|
|
13
13
|
# SomeException.
|
|
14
14
|
#
|
|
15
15
|
# * Modifier form `rescue` would rescue all the exceptions. It would
|
|
16
|
-
# silently skip all
|
|
16
|
+
# silently skip all exceptions or errors and handle the error.
|
|
17
17
|
# Example: If `NoMethodError` is raised, modifier form rescue would
|
|
18
18
|
# handle the exception.
|
|
19
19
|
#
|
|
@@ -67,18 +67,19 @@ module RuboCop
|
|
|
67
67
|
node.parent && parentheses?(node.parent)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
70
71
|
def correct_rescue_block(corrector, node, parenthesized)
|
|
71
|
-
operation
|
|
72
|
-
*_, rescue_args = *rescue_modifier
|
|
72
|
+
operation = node.body
|
|
73
73
|
|
|
74
74
|
node_indentation, node_offset = indentation_and_offset(node, parenthesized)
|
|
75
75
|
|
|
76
|
+
corrector.wrap(operation, '[', ']') if operation.array_type? && !operation.bracketed?
|
|
76
77
|
corrector.remove(range_between(operation.source_range.end_pos, node.source_range.end_pos))
|
|
77
78
|
corrector.insert_before(operation, "begin\n#{node_indentation}")
|
|
78
|
-
corrector.insert_after(operation, <<~RESCUE_CLAUSE.chop)
|
|
79
|
+
corrector.insert_after(heredoc_end(operation) || operation, <<~RESCUE_CLAUSE.chop)
|
|
79
80
|
|
|
80
81
|
#{node_offset}rescue
|
|
81
|
-
#{node_indentation}#{
|
|
82
|
+
#{node_indentation}#{node.resbody_branches.first.body.source}
|
|
82
83
|
#{node_offset}end
|
|
83
84
|
RESCUE_CLAUSE
|
|
84
85
|
end
|
|
@@ -92,6 +93,18 @@ module RuboCop
|
|
|
92
93
|
end
|
|
93
94
|
[node_indentation, node_offset]
|
|
94
95
|
end
|
|
96
|
+
|
|
97
|
+
def heredoc_end(node)
|
|
98
|
+
return unless node.call_type?
|
|
99
|
+
|
|
100
|
+
heredoc = node.arguments.reverse.find do |argument|
|
|
101
|
+
argument.respond_to?(:heredoc?) && argument.heredoc?
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
return unless heredoc
|
|
105
|
+
|
|
106
|
+
heredoc.loc.heredoc_end
|
|
107
|
+
end
|
|
95
108
|
end
|
|
96
109
|
end
|
|
97
110
|
end
|
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Enforces consistency between
|
|
6
|
+
# Enforces consistency between `return nil` and `return`.
|
|
7
7
|
#
|
|
8
|
-
#
|
|
8
|
+
# This cop is disabled by default. Because there seems to be a perceived semantic difference
|
|
9
|
+
# between `return` and `return nil`. The former can be seen as just halting evaluation,
|
|
10
|
+
# while the latter might be used when the return value is of specific concern.
|
|
11
|
+
#
|
|
12
|
+
# Supported styles are `return` and `return_nil`.
|
|
9
13
|
#
|
|
10
14
|
# @example EnforcedStyle: return (default)
|
|
11
15
|
# # bad
|
|
@@ -43,7 +47,7 @@ module RuboCop
|
|
|
43
47
|
|
|
44
48
|
def on_return(node)
|
|
45
49
|
# Check Lint/NonLocalExitFromIterator first before this cop
|
|
46
|
-
node.each_ancestor(:block, :
|
|
50
|
+
node.each_ancestor(:block, :any_def) do |n|
|
|
47
51
|
break if scoped_node?(n)
|
|
48
52
|
|
|
49
53
|
send_node, args_node, _body_node = *n
|
|
@@ -79,7 +83,7 @@ module RuboCop
|
|
|
79
83
|
end
|
|
80
84
|
|
|
81
85
|
def scoped_node?(node)
|
|
82
|
-
node.
|
|
86
|
+
node.any_def_type? || node.lambda?
|
|
83
87
|
end
|
|
84
88
|
|
|
85
89
|
# @!method chained_send?(node)
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks
|
|
6
|
+
# Checks for predicate method definitions that return `nil`.
|
|
7
|
+
# A predicate method should only return a boolean value.
|
|
7
8
|
#
|
|
8
9
|
# @safety
|
|
9
10
|
# Autocorrection is marked as unsafe because the change of the return value
|
|
@@ -31,7 +32,25 @@ module RuboCop
|
|
|
31
32
|
# do_something?
|
|
32
33
|
# end
|
|
33
34
|
#
|
|
34
|
-
#
|
|
35
|
+
# # bad
|
|
36
|
+
# def foo?
|
|
37
|
+
# if condition
|
|
38
|
+
# nil
|
|
39
|
+
# else
|
|
40
|
+
# true
|
|
41
|
+
# end
|
|
42
|
+
# end
|
|
43
|
+
#
|
|
44
|
+
# # good
|
|
45
|
+
# def foo?
|
|
46
|
+
# if condition
|
|
47
|
+
# false
|
|
48
|
+
# else
|
|
49
|
+
# true
|
|
50
|
+
# end
|
|
51
|
+
# end
|
|
52
|
+
#
|
|
53
|
+
# @example AllowedMethods: ['foo?']
|
|
35
54
|
# # good
|
|
36
55
|
# def foo?
|
|
37
56
|
# return if condition
|
|
@@ -39,7 +58,7 @@ module RuboCop
|
|
|
39
58
|
# do_something?
|
|
40
59
|
# end
|
|
41
60
|
#
|
|
42
|
-
# @example
|
|
61
|
+
# @example AllowedPatterns: [/foo/]
|
|
43
62
|
# # good
|
|
44
63
|
# def foo?
|
|
45
64
|
# return if condition
|
|
@@ -52,7 +71,7 @@ module RuboCop
|
|
|
52
71
|
include AllowedMethods
|
|
53
72
|
include AllowedPattern
|
|
54
73
|
|
|
55
|
-
MSG = '
|
|
74
|
+
MSG = 'Return `false` instead of `nil` in predicate methods.'
|
|
56
75
|
|
|
57
76
|
# @!method return_nil?(node)
|
|
58
77
|
def_node_matcher :return_nil?, <<~PATTERN
|
|
@@ -64,17 +83,54 @@ module RuboCop
|
|
|
64
83
|
return if allowed_method?(node.method_name) || matches_allowed_pattern?(node.method_name)
|
|
65
84
|
return unless (body = node.body)
|
|
66
85
|
|
|
67
|
-
body.each_descendant(:return)
|
|
68
|
-
|
|
86
|
+
body.each_descendant(:return) { |return_node| handle_return(return_node) }
|
|
87
|
+
|
|
88
|
+
handle_implicit_return_values(body)
|
|
89
|
+
end
|
|
90
|
+
alias on_defs on_def
|
|
69
91
|
|
|
70
|
-
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
def last_node_of_type(node, type)
|
|
95
|
+
return unless node
|
|
96
|
+
return node if node_type?(node, type)
|
|
97
|
+
return unless node.begin_type?
|
|
98
|
+
return unless (last_child = node.children.last)
|
|
99
|
+
|
|
100
|
+
last_child if last_child.is_a?(AST::Node) && node_type?(last_child, type)
|
|
101
|
+
end
|
|
71
102
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
103
|
+
def node_type?(node, type)
|
|
104
|
+
node.type == type.to_sym
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def register_offense(offense_node, replacement)
|
|
108
|
+
add_offense(offense_node) do |corrector|
|
|
109
|
+
corrector.replace(offense_node, replacement)
|
|
75
110
|
end
|
|
76
111
|
end
|
|
77
|
-
|
|
112
|
+
|
|
113
|
+
def handle_implicit_return_values(node)
|
|
114
|
+
handle_if(last_node_of_type(node, :if))
|
|
115
|
+
handle_nil(last_node_of_type(node, :nil))
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def handle_return(return_node)
|
|
119
|
+
register_offense(return_node, 'return false') if return_nil?(return_node)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def handle_nil(nil_node)
|
|
123
|
+
return unless nil_node
|
|
124
|
+
|
|
125
|
+
register_offense(nil_node, 'false')
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def handle_if(if_node)
|
|
129
|
+
return unless if_node
|
|
130
|
+
|
|
131
|
+
handle_implicit_return_values(if_node.if_branch)
|
|
132
|
+
handle_implicit_return_values(if_node.else_branch)
|
|
133
|
+
end
|
|
78
134
|
end
|
|
79
135
|
end
|
|
80
136
|
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Identifies places where `array.reverse.find` can be replaced by `array.rfind`.
|
|
7
|
+
#
|
|
8
|
+
# @safety
|
|
9
|
+
# This cop is unsafe because it cannot be guaranteed that the receiver
|
|
10
|
+
# is an `Array` or responds to the replacement method.
|
|
11
|
+
#
|
|
12
|
+
# @example
|
|
13
|
+
# # bad
|
|
14
|
+
# array.reverse.find { |item| item.even? }
|
|
15
|
+
# array.reverse.detect { |item| item.even? }
|
|
16
|
+
# array.reverse_each.find { |item| item.even? }
|
|
17
|
+
# array.reverse_each.detect { |item| item.even? }
|
|
18
|
+
#
|
|
19
|
+
# # good
|
|
20
|
+
# array.rfind { |item| item.even? }
|
|
21
|
+
#
|
|
22
|
+
class ReverseFind < Base
|
|
23
|
+
extend AutoCorrector
|
|
24
|
+
extend TargetRubyVersion
|
|
25
|
+
|
|
26
|
+
MSG = 'Use `rfind` instead.'
|
|
27
|
+
RESTRICT_ON_SEND = %i[find detect].freeze
|
|
28
|
+
|
|
29
|
+
minimum_target_ruby_version 4.0
|
|
30
|
+
|
|
31
|
+
# @!method reverse_find?(node)
|
|
32
|
+
def_node_matcher :reverse_find?, <<~PATTERN
|
|
33
|
+
(call
|
|
34
|
+
(call
|
|
35
|
+
_ {:reverse :reverse_each}) {:find :detect} (block_pass sym)?)
|
|
36
|
+
PATTERN
|
|
37
|
+
|
|
38
|
+
def on_send(node)
|
|
39
|
+
return unless reverse_find?(node)
|
|
40
|
+
|
|
41
|
+
range = node.children.first.loc.selector.join(node.loc.selector)
|
|
42
|
+
|
|
43
|
+
add_offense(range) do |corrector|
|
|
44
|
+
corrector.replace(range, 'rfind')
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
alias on_csend on_send
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -17,9 +17,14 @@ module RuboCop
|
|
|
17
17
|
# `foo&.bar` can start returning `nil` as well as what the method
|
|
18
18
|
# returns.
|
|
19
19
|
#
|
|
20
|
-
# The default for `MaxChainLength` is `2
|
|
20
|
+
# The default for `MaxChainLength` is `2`.
|
|
21
21
|
# We have limited the cop to not register an offense for method chains
|
|
22
|
-
# that exceed this option
|
|
22
|
+
# that exceed this option's value.
|
|
23
|
+
#
|
|
24
|
+
# NOTE: This cop will recognize offenses but not autocorrect code when the
|
|
25
|
+
# right hand side (RHS) of the `&&` statement is an `||` statement
|
|
26
|
+
# (eg. `foo && (foo.bar? || foo.baz?)`). It can be corrected
|
|
27
|
+
# manually by removing the `foo &&` and adding `&.` to each `foo` on the RHS.
|
|
23
28
|
#
|
|
24
29
|
# @safety
|
|
25
30
|
# Autocorrection is unsafe because if a value is `false`, the resulting
|
|
@@ -32,6 +37,16 @@ module RuboCop
|
|
|
32
37
|
# x&.foo # raises NoMethodError
|
|
33
38
|
# ----
|
|
34
39
|
#
|
|
40
|
+
# Additionally, when a method chain is converted, a `NoMethodError` that
|
|
41
|
+
# the original code raised for an intermediate `nil` value is suppressed:
|
|
42
|
+
#
|
|
43
|
+
# [source,ruby]
|
|
44
|
+
# ----
|
|
45
|
+
# x = Struct.new(:foo).new(nil)
|
|
46
|
+
# x && x.foo.bar # raises NoMethodError
|
|
47
|
+
# x&.foo&.bar # returns nil
|
|
48
|
+
# ----
|
|
49
|
+
#
|
|
35
50
|
# @example
|
|
36
51
|
# # bad
|
|
37
52
|
# foo.bar if foo
|
|
@@ -81,7 +96,11 @@ module RuboCop
|
|
|
81
96
|
# foo.baz = bar if foo
|
|
82
97
|
# foo.baz + bar if foo
|
|
83
98
|
# foo.bar > 2 if foo
|
|
84
|
-
|
|
99
|
+
#
|
|
100
|
+
# foo ? foo[index] : nil # Ignored `foo&.[](index)` due to unclear readability benefit.
|
|
101
|
+
# foo ? foo[idx] = v : nil # Ignored `foo&.[]=(idx, v)` due to unclear readability benefit.
|
|
102
|
+
# foo ? foo * 42 : nil # Ignored `foo&.*(42)` due to unclear readability benefit.
|
|
103
|
+
class SafeNavigation < Base # rubocop:disable Metrics/ClassLength
|
|
85
104
|
include NilMethods
|
|
86
105
|
include RangeHelp
|
|
87
106
|
extend AutoCorrector
|
|
@@ -121,56 +140,150 @@ module RuboCop
|
|
|
121
140
|
}
|
|
122
141
|
PATTERN
|
|
123
142
|
|
|
143
|
+
# @!method and_with_rhs_or?(node)
|
|
144
|
+
def_node_matcher :and_with_rhs_or?, '(and _ {or (begin or)})'
|
|
145
|
+
|
|
124
146
|
# @!method not_nil_check?(node)
|
|
125
147
|
def_node_matcher :not_nil_check?, '(send (send $_ :nil?) :!)'
|
|
126
148
|
|
|
149
|
+
# @!method and_inside_begin?(node)
|
|
150
|
+
def_node_matcher :and_inside_begin?, '`(begin and ...)'
|
|
151
|
+
|
|
152
|
+
# @!method strip_begin(node)
|
|
153
|
+
def_node_matcher :strip_begin, '{ (begin $!begin) $!(begin) }'
|
|
154
|
+
|
|
155
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
127
156
|
def on_if(node)
|
|
128
157
|
return if allowed_if_condition?(node)
|
|
129
158
|
|
|
130
|
-
|
|
159
|
+
checked_variable, receiver, method_chain, _method = extract_parts_from_if(node)
|
|
160
|
+
return unless offending_node?(node, checked_variable, method_chain, receiver)
|
|
161
|
+
|
|
162
|
+
body = extract_if_body(node)
|
|
163
|
+
method_call = receiver.parent
|
|
164
|
+
return if dotless_operator_call?(method_call) || method_call.double_colon?
|
|
165
|
+
|
|
166
|
+
removal_ranges = [begin_range(node, body), end_range(node, body)]
|
|
167
|
+
|
|
168
|
+
report_offense(node, method_chain, method_call, *removal_ranges) do |corrector|
|
|
169
|
+
corrector.replace(receiver, checked_variable.source) if checked_variable.csend_type?
|
|
170
|
+
corrector.insert_before(method_call.loc.dot, '&') unless method_call.safe_navigation?
|
|
171
|
+
end
|
|
131
172
|
end
|
|
132
173
|
|
|
133
|
-
def on_and(node)
|
|
134
|
-
|
|
174
|
+
def on_and(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
|
175
|
+
collect_and_clauses(node).each do |(lhs, lhs_operator_range), (rhs, _rhs_operator_range)|
|
|
176
|
+
lhs_not_nil_check = not_nil_check?(lhs)
|
|
177
|
+
lhs_receiver = lhs_not_nil_check || lhs
|
|
178
|
+
rhs_receiver = find_matching_receiver_invocation(strip_begin(rhs), lhs_receiver)
|
|
179
|
+
|
|
180
|
+
next if !cop_config['ConvertCodeThatCanStartToReturnNil'] && lhs_not_nil_check
|
|
181
|
+
next unless offending_node?(node, lhs_receiver, rhs, rhs_receiver)
|
|
182
|
+
|
|
183
|
+
# Since we are evaluating every clause in potentially a complex chain of `and` nodes,
|
|
184
|
+
# we need to ensure that there isn't an object check happening
|
|
185
|
+
lhs_method_chain = find_method_chain(lhs_receiver)
|
|
186
|
+
next unless lhs_method_chain == lhs_receiver || lhs_not_nil_check
|
|
187
|
+
|
|
188
|
+
report_offense(
|
|
189
|
+
node,
|
|
190
|
+
rhs, rhs_receiver,
|
|
191
|
+
range_with_surrounding_space(range: lhs.source_range, side: :right),
|
|
192
|
+
range_with_surrounding_space(range: lhs_operator_range, side: :right),
|
|
193
|
+
offense_range: range_between(lhs.source_range.begin_pos, rhs.source_range.end_pos)
|
|
194
|
+
) do |corrector|
|
|
195
|
+
corrector.replace(rhs_receiver, lhs_receiver.source)
|
|
196
|
+
end
|
|
197
|
+
ignore_node(node)
|
|
198
|
+
end
|
|
135
199
|
end
|
|
136
200
|
|
|
137
201
|
private
|
|
138
202
|
|
|
139
|
-
def
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
203
|
+
def report_offense(node, rhs, rhs_receiver, *removal_ranges, offense_range: node)
|
|
204
|
+
add_offense(offense_range) do |corrector|
|
|
205
|
+
next if ignored_node?(node)
|
|
206
|
+
|
|
207
|
+
# If the RHS is an `or` we cannot safely autocorrect because in order to remove
|
|
208
|
+
# the non-nil check we need to add safe-navs to all clauses where the receiver is used
|
|
209
|
+
next if and_with_rhs_or?(node)
|
|
210
|
+
|
|
211
|
+
removal_ranges.each { |range| corrector.remove(range) }
|
|
212
|
+
yield corrector if block_given?
|
|
213
|
+
|
|
214
|
+
handle_comments(corrector, node, rhs)
|
|
146
215
|
|
|
147
|
-
|
|
216
|
+
add_safe_nav_to_all_methods_in_chain(corrector, rhs_receiver, rhs)
|
|
217
|
+
end
|
|
148
218
|
end
|
|
149
219
|
|
|
150
|
-
def
|
|
151
|
-
node
|
|
220
|
+
def find_method_chain(node)
|
|
221
|
+
return node unless node&.parent&.call_type?
|
|
222
|
+
|
|
223
|
+
find_method_chain(node.parent)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def collect_and_clauses(node)
|
|
227
|
+
# Collect the lhs, operator and rhs of all `and` nodes
|
|
228
|
+
# `and` nodes can be nested and can contain `begin` nodes
|
|
229
|
+
# This gives us a source-ordered list of clauses that is then used to look
|
|
230
|
+
# for matching receivers as well as operator locations for offense and corrections
|
|
231
|
+
node.each_descendant(:and)
|
|
232
|
+
.inject(and_parts(node)) { |nodes, and_node| concat_nodes(nodes, and_node) }
|
|
233
|
+
.sort_by { |a| a.is_a?(RuboCop::AST::Node) ? a.source_range.begin_pos : a.begin_pos }
|
|
234
|
+
.each_slice(2)
|
|
235
|
+
.each_cons(2)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def concat_nodes(nodes, and_node)
|
|
239
|
+
return nodes if and_node.each_ancestor(:block).any?
|
|
240
|
+
|
|
241
|
+
nodes.concat(and_parts(and_node))
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def and_parts(node)
|
|
245
|
+
parts = [node.loc.operator]
|
|
246
|
+
parts << node.rhs unless and_inside_begin?(node.rhs)
|
|
247
|
+
parts << node.lhs unless node.lhs.and_type? || and_inside_begin?(node.lhs)
|
|
248
|
+
parts
|
|
152
249
|
end
|
|
153
250
|
|
|
154
|
-
def
|
|
155
|
-
|
|
156
|
-
|
|
251
|
+
def offending_node?(node, lhs_receiver, rhs, rhs_receiver) # rubocop:disable Metrics/CyclomaticComplexity
|
|
252
|
+
return false if !matching_nodes?(lhs_receiver, rhs_receiver) || rhs_receiver.nil?
|
|
253
|
+
return false if use_var_only_in_unless_modifier?(node, lhs_receiver)
|
|
254
|
+
return false if chain_length(rhs, rhs_receiver) > max_chain_length
|
|
255
|
+
return false if unsafe_method_used?(node, rhs, rhs_receiver.parent)
|
|
256
|
+
return false if rhs.send_type? && rhs.method?(:empty?)
|
|
157
257
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
corrector.insert_before(method_call.loc.dot, '&') unless method_call.safe_navigation?
|
|
161
|
-
handle_comments(corrector, node, method_call)
|
|
258
|
+
true
|
|
259
|
+
end
|
|
162
260
|
|
|
163
|
-
|
|
261
|
+
def use_var_only_in_unless_modifier?(node, variable)
|
|
262
|
+
node.if_type? && node.unless? && !method_called?(variable)
|
|
164
263
|
end
|
|
165
264
|
|
|
166
|
-
def
|
|
167
|
-
if node.
|
|
265
|
+
def extract_if_body(node)
|
|
266
|
+
if node.ternary?
|
|
168
267
|
node.branches.find { |branch| !branch.nil_type? }
|
|
169
268
|
else
|
|
170
269
|
node.node_parts[1]
|
|
171
270
|
end
|
|
172
271
|
end
|
|
173
272
|
|
|
273
|
+
def dotless_operator_call?(method_call)
|
|
274
|
+
return true if dotless_operator_method?(method_call)
|
|
275
|
+
|
|
276
|
+
method_call = method_call.parent while method_call.parent.send_type?
|
|
277
|
+
|
|
278
|
+
dotless_operator_method?(method_call)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def dotless_operator_method?(method_call)
|
|
282
|
+
return false if method_call.loc.dot
|
|
283
|
+
|
|
284
|
+
method_call.method?(:[]) || method_call.method?(:[]=) || method_call.operator_method?
|
|
285
|
+
end
|
|
286
|
+
|
|
174
287
|
def handle_comments(corrector, node, method_call)
|
|
175
288
|
comments = comments(node)
|
|
176
289
|
return if comments.empty?
|
|
@@ -201,20 +314,6 @@ module RuboCop
|
|
|
201
314
|
node.else? || node.elsif?
|
|
202
315
|
end
|
|
203
316
|
|
|
204
|
-
def method_call(node)
|
|
205
|
-
_checked_variable, matching_receiver, = extract_parts(node)
|
|
206
|
-
matching_receiver.parent
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def extract_parts(node)
|
|
210
|
-
case node.type
|
|
211
|
-
when :if
|
|
212
|
-
extract_parts_from_if(node)
|
|
213
|
-
when :and
|
|
214
|
-
extract_parts_from_and(node)
|
|
215
|
-
end
|
|
216
|
-
end
|
|
217
|
-
|
|
218
317
|
def extract_parts_from_if(node)
|
|
219
318
|
variable, receiver =
|
|
220
319
|
if node.ternary?
|
|
@@ -230,16 +329,6 @@ module RuboCop
|
|
|
230
329
|
[checked_variable, matching_receiver, receiver, method]
|
|
231
330
|
end
|
|
232
331
|
|
|
233
|
-
def extract_parts_from_and(node)
|
|
234
|
-
checked_variable, rhs = *node
|
|
235
|
-
if cop_config['ConvertCodeThatCanStartToReturnNil']
|
|
236
|
-
checked_variable = not_nil_check?(checked_variable) || checked_variable
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
checked_variable, matching_receiver, method = extract_common_parts(rhs, checked_variable)
|
|
240
|
-
[checked_variable, matching_receiver, rhs, method]
|
|
241
|
-
end
|
|
242
|
-
|
|
243
332
|
def extract_common_parts(method_chain, checked_variable)
|
|
244
333
|
matching_receiver = find_matching_receiver_invocation(method_chain, checked_variable)
|
|
245
334
|
|
|
@@ -249,38 +338,59 @@ module RuboCop
|
|
|
249
338
|
end
|
|
250
339
|
|
|
251
340
|
def find_matching_receiver_invocation(method_chain, checked_variable)
|
|
252
|
-
return nil unless method_chain
|
|
341
|
+
return nil unless method_chain.respond_to?(:receiver)
|
|
253
342
|
|
|
254
343
|
receiver = method_chain.receiver
|
|
255
344
|
|
|
256
|
-
return receiver if receiver
|
|
345
|
+
return receiver if matching_nodes?(receiver, checked_variable)
|
|
257
346
|
|
|
258
347
|
find_matching_receiver_invocation(receiver, checked_variable)
|
|
259
348
|
end
|
|
260
349
|
|
|
350
|
+
def matching_nodes?(left, right)
|
|
351
|
+
left == right || matching_call_nodes?(left, right)
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def matching_call_nodes?(left, right)
|
|
355
|
+
return false unless left && right.respond_to?(:call_type?)
|
|
356
|
+
return false unless left.call_type? && right.call_type?
|
|
357
|
+
|
|
358
|
+
# Compare receiver and method name, but ignore the difference between
|
|
359
|
+
# safe navigation method call (`&.`) and dot method call (`.`).
|
|
360
|
+
left_receiver, left_method, *left_args = left.children
|
|
361
|
+
right_receiver, right_method, *right_args = right.children
|
|
362
|
+
|
|
363
|
+
left_method == right_method &&
|
|
364
|
+
matching_nodes?(left_receiver, right_receiver) &&
|
|
365
|
+
left_args == right_args
|
|
366
|
+
end
|
|
367
|
+
|
|
261
368
|
def chain_length(method_chain, method)
|
|
262
|
-
method.each_ancestor(:
|
|
369
|
+
method.each_ancestor(:call).inject(0) do |total, ancestor|
|
|
263
370
|
break total + 1 if ancestor == method_chain
|
|
264
371
|
|
|
265
372
|
total + 1
|
|
266
373
|
end
|
|
267
374
|
end
|
|
268
375
|
|
|
269
|
-
def unsafe_method_used?(method_chain, method)
|
|
270
|
-
return true if unsafe_method?(method)
|
|
376
|
+
def unsafe_method_used?(node, method_chain, method)
|
|
377
|
+
return true if unsafe_method?(node, method)
|
|
271
378
|
|
|
272
|
-
method.each_ancestor(:send)
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
break false if ancestor == method_chain
|
|
379
|
+
method.each_ancestor(:send) do |ancestor|
|
|
380
|
+
return true unless config.cop_enabled?('Lint/SafeNavigationChain')
|
|
381
|
+
return true if unsafe_method?(node, ancestor)
|
|
382
|
+
return true if nil_methods.include?(ancestor.method_name)
|
|
383
|
+
return false if ancestor == method_chain
|
|
278
384
|
end
|
|
385
|
+
false
|
|
279
386
|
end
|
|
280
387
|
|
|
281
|
-
def unsafe_method?(send_node)
|
|
282
|
-
negated?(send_node)
|
|
283
|
-
|
|
388
|
+
def unsafe_method?(node, send_node)
|
|
389
|
+
return true if negated?(send_node)
|
|
390
|
+
|
|
391
|
+
return false if node.respond_to?(:ternary?) && node.ternary?
|
|
392
|
+
|
|
393
|
+
send_node.assignment? ||
|
|
284
394
|
(!send_node.dot? && !send_node.safe_navigation?)
|
|
285
395
|
end
|
|
286
396
|
|
|
@@ -308,8 +418,8 @@ module RuboCop
|
|
|
308
418
|
start_method,
|
|
309
419
|
method_chain)
|
|
310
420
|
start_method.each_ancestor do |ancestor|
|
|
311
|
-
break unless
|
|
312
|
-
next
|
|
421
|
+
break unless ancestor.type?(:call, :any_block)
|
|
422
|
+
next if !ancestor.send_type? || ancestor.operator_method?
|
|
313
423
|
|
|
314
424
|
corrector.insert_before(ancestor.loc.dot, '&')
|
|
315
425
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Enforces safe navigation chains length to not exceed the configured maximum.
|
|
7
|
+
# The longer the chain is, the harder it becomes to track what on it could be
|
|
8
|
+
# returning `nil`.
|
|
9
|
+
#
|
|
10
|
+
# There is a potential interplay with `Style/SafeNavigation` - if both are enabled
|
|
11
|
+
# and their settings are "incompatible", one of the cops will complain about what
|
|
12
|
+
# the other proposes.
|
|
13
|
+
#
|
|
14
|
+
# E.g. if `Style/SafeNavigation` is configured with `MaxChainLength: 2` (default)
|
|
15
|
+
# and this cop is configured with `Max: 1`, then for `foo.bar.baz if foo` the former
|
|
16
|
+
# will suggest `foo&.bar&.baz`, which is an offense for the latter.
|
|
17
|
+
#
|
|
18
|
+
# @example Max: 2 (default)
|
|
19
|
+
# # bad
|
|
20
|
+
# user&.address&.zip&.upcase
|
|
21
|
+
#
|
|
22
|
+
# # good
|
|
23
|
+
# user&.address&.zip
|
|
24
|
+
# user.address.zip if user
|
|
25
|
+
#
|
|
26
|
+
class SafeNavigationChainLength < Base
|
|
27
|
+
MSG = 'Avoid safe navigation chains longer than %<max>d calls.'
|
|
28
|
+
|
|
29
|
+
def on_csend(node)
|
|
30
|
+
safe_navigation_chains = safe_navigation_chains(node)
|
|
31
|
+
return if safe_navigation_chains.size < max
|
|
32
|
+
|
|
33
|
+
add_offense(safe_navigation_chains.last, message: format(MSG, max: max))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def safe_navigation_chains(node)
|
|
39
|
+
node.each_ancestor.with_object([]) do |parent, chains|
|
|
40
|
+
break chains unless parent.csend_type?
|
|
41
|
+
|
|
42
|
+
chains << parent
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def max
|
|
47
|
+
cop_config['Max'] || 2
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|