rubocop 1.71.1 → 1.91.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 +23 -19
- data/config/default.yml +883 -168
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +47 -4
- data/exe/rubocop +2 -9
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cached_data.rb +7 -2
- data/lib/rubocop/changed_files.rb +112 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +36 -4
- data/lib/rubocop/cli/command/execute_runner.rb +52 -1
- data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
- data/lib/rubocop/cli/command/lsp.rb +1 -1
- data/lib/rubocop/cli/command/mcp.rb +19 -0
- data/lib/rubocop/cli/command/show_cops.rb +2 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +4 -8
- data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
- data/lib/rubocop/cli.rb +58 -17
- data/lib/rubocop/comment_config/directive_range.rb +34 -0
- data/lib/rubocop/comment_config/disable_next.rb +143 -0
- data/lib/rubocop/comment_config/push_pop.rb +55 -0
- data/lib/rubocop/comment_config.rb +92 -48
- data/lib/rubocop/config.rb +137 -19
- data/lib/rubocop/config_finder.rb +1 -1
- data/lib/rubocop/config_loader.rb +72 -49
- data/lib/rubocop/config_loader_resolver.rb +94 -28
- data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
- data/lib/rubocop/config_obsoletion/removed_cop.rb +8 -0
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +47 -3
- data/lib/rubocop/config_store.rb +7 -2
- data/lib/rubocop/config_validator.rb +64 -12
- data/lib/rubocop/cop/autocorrect_logic.rb +35 -14
- data/lib/rubocop/cop/badge.rb +9 -1
- data/lib/rubocop/cop/base.rb +93 -21
- data/lib/rubocop/cop/bundler/gem_comment.rb +5 -3
- data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
- data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -3
- data/lib/rubocop/cop/bundler.rb +19 -0
- data/lib/rubocop/cop/commissioner.rb +13 -11
- data/lib/rubocop/cop/corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +79 -10
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -1
- 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 +36 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors.rb +28 -0
- data/lib/rubocop/cop/documentation.rb +2 -3
- data/lib/rubocop/cop/exclude_limit.rb +31 -5
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +49 -17
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -3
- data/lib/rubocop/cop/gemspec/require_mfa.rb +22 -5
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
- data/lib/rubocop/cop/gemspec.rb +22 -0
- data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
- data/lib/rubocop/cop/generator.rb +5 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
- 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_line_equality_comparison.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +14 -15
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +6 -2
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +2 -2
- 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_let_rubocop_config_new.rb +5 -3
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +3 -16
- data/lib/rubocop/cop/layout/argument_alignment.rb +4 -2
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +59 -4
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +3 -1
- data/lib/rubocop/cop/layout/class_structure.rb +163 -35
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
- data/lib/rubocop/cop/layout/comment_indentation.rb +17 -7
- data/lib/rubocop/cop/layout/condition_position.rb +13 -3
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +2 -2
- data/lib/rubocop/cop/layout/else_alignment.rb +3 -15
- data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +27 -9
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +46 -21
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +34 -4
- 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_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_method_body.rb +22 -2
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +9 -3
- data/lib/rubocop/cop/layout/extra_spacing.rb +105 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +56 -3
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -5
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +20 -15
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +11 -13
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +3 -3
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +33 -3
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +157 -10
- data/lib/rubocop/cop/layout/leading_comment_space.rb +40 -1
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +2 -3
- data/lib/rubocop/cop/layout/line_length.rb +160 -23
- 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_method_call_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +245 -40
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +9 -5
- data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +89 -6
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +14 -7
- data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +14 -3
- data/lib/rubocop/cop/layout/space_around_keyword.rb +10 -3
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +30 -4
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +6 -39
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +42 -36
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/layout.rb +114 -0
- data/lib/rubocop/cop/lazy_loader.rb +41 -0
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +72 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1 -10
- data/lib/rubocop/cop/lint/ambiguous_range.rb +6 -2
- data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -8
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +94 -15
- data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +240 -0
- data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
- data/lib/rubocop/cop/lint/debugger.rb +13 -4
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +5 -2
- data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +506 -41
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
- data/lib/rubocop/cop/lint/else_layout.rb +19 -0
- data/lib/rubocop/cop/lint/empty_block.rb +4 -4
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +20 -65
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
- data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
- data/lib/rubocop/cop/lint/empty_when.rb +8 -1
- data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -8
- data/lib/rubocop/cop/lint/float_comparison.rb +33 -10
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +25 -6
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +137 -11
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +13 -19
- data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +185 -0
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +44 -22
- data/lib/rubocop/cop/lint/missing_super.rb +31 -1
- data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
- 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 +2 -2
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
- data/lib/rubocop/cop/lint/number_conversion.rb +19 -10
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +11 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +20 -14
- data/lib/rubocop/cop/lint/raise_exception.rb +30 -11
- data/lib/rubocop/cop/lint/rand_one.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +149 -39
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +53 -19
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15 -4
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -25
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +134 -12
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -4
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +267 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +5 -3
- data/lib/rubocop/cop/lint/redundant_with_object.rb +8 -0
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
- data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
- 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 +1 -4
- data/lib/rubocop/cop/lint/rescue_type.rb +2 -2
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +28 -4
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +9 -5
- data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
- data/lib/rubocop/cop/lint/script_permission.rb +5 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +63 -6
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
- data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +14 -1
- data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
- data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +122 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +21 -4
- data/lib/rubocop/cop/lint/syntax.rb +25 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +73 -5
- 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 +36 -10
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +16 -9
- data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
- data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
- 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/useless_access_modifier.rb +31 -6
- data/lib/rubocop/cop/lint/useless_assignment.rb +56 -27
- 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_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +11 -10
- data/lib/rubocop/cop/lint/useless_or.rb +111 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +2 -3
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +13 -7
- data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -1
- data/lib/rubocop/cop/lint/useless_times.rb +22 -1
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +201 -0
- data/lib/rubocop/cop/lint/void.rb +60 -21
- data/lib/rubocop/cop/lint.rb +179 -0
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/block_length.rb +2 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +3 -2
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +37 -7
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
- 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 +3 -3
- data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -5
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +27 -9
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +5 -7
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +2 -3
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
- 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 +1 -2
- data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +44 -16
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +29 -26
- data/lib/rubocop/cop/mixin/hash_subset.rb +28 -6
- 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/indexed_method_arity.rb +94 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +52 -11
- data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -1
- 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_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +62 -6
- data/lib/rubocop/cop/mixin/project_index_help.rb +188 -0
- data/lib/rubocop/cop/mixin/range_help.rb +16 -5
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +171 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +47 -11
- data/lib/rubocop/cop/mixin/string_help.rb +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +23 -6
- data/lib/rubocop/cop/mixin.rb +91 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +24 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +7 -4
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +6 -5
- data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +13 -6
- 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_name.rb → predicate_prefix.rb} +80 -8
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +11 -6
- data/lib/rubocop/cop/naming/variable_name.rb +51 -6
- data/lib/rubocop/cop/naming/variable_number.rb +3 -1
- data/lib/rubocop/cop/naming.rb +31 -0
- data/lib/rubocop/cop/offense.rb +52 -9
- data/lib/rubocop/cop/registry.rb +233 -64
- 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 +1 -0
- data/lib/rubocop/cop/security.rb +19 -0
- data/lib/rubocop/cop/severity.rb +12 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +47 -13
- data/lib/rubocop/cop/style/accessor_grouping.rb +47 -10
- data/lib/rubocop/cop/style/alias.rb +15 -3
- data/lib/rubocop/cop/style/and_or.rb +2 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +49 -37
- data/lib/rubocop/cop/style/array_first_last.rb +13 -3
- data/lib/rubocop/cop/style/array_intersect.rb +136 -38
- 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/bare_percent_literals.rb +4 -3
- data/lib/rubocop/cop/style/begin_block.rb +3 -1
- data/lib/rubocop/cop/style/bitwise_predicate.rb +7 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +43 -38
- data/lib/rubocop/cop/style/case_equality.rb +29 -15
- data/lib/rubocop/cop/style/case_like_if.rb +6 -8
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +135 -21
- data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -14
- data/lib/rubocop/cop/style/class_methods_definitions.rb +11 -5
- data/lib/rubocop/cop/style/collection_compact.rb +37 -17
- data/lib/rubocop/cop/style/collection_methods.rb +1 -0
- 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_loops.rb +7 -2
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
- 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 +8 -3
- data/lib/rubocop/cop/style/conditional_assignment.rb +54 -24
- data/lib/rubocop/cop/style/constant_visibility.rb +23 -12
- data/lib/rubocop/cop/style/copyright.rb +27 -12
- data/lib/rubocop/cop/style/data_inheritance.rb +25 -0
- data/lib/rubocop/cop/style/date_time.rb +4 -4
- data/lib/rubocop/cop/style/def_with_parentheses.rb +22 -5
- data/lib/rubocop/cop/style/dig_chain.rb +6 -1
- data/lib/rubocop/cop/style/dir_empty.rb +4 -0
- data/lib/rubocop/cop/style/directive_scope.rb +304 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +122 -14
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
- data/lib/rubocop/cop/style/documentation.rb +53 -6
- data/lib/rubocop/cop/style/documentation_method.rb +8 -12
- data/lib/rubocop/cop/style/double_negation.rb +3 -3
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +4 -3
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +13 -4
- data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
- data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +11 -2
- data/lib/rubocop/cop/style/empty_method.rb +12 -8
- 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 +191 -19
- data/lib/rubocop/cop/style/env_home.rb +4 -0
- data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
- data/lib/rubocop/cop/style/even_odd.rb +11 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +8 -1
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
- data/lib/rubocop/cop/style/exponential_notation.rb +5 -4
- data/lib/rubocop/cop/style/fetch_env_var.rb +33 -7
- data/lib/rubocop/cop/style/file_null.rb +6 -4
- data/lib/rubocop/cop/style/file_open.rb +84 -0
- data/lib/rubocop/cop/style/file_write.rb +21 -16
- data/lib/rubocop/cop/style/float_division.rb +25 -17
- data/lib/rubocop/cop/style/for.rb +9 -0
- data/lib/rubocop/cop/style/format_string.rb +17 -4
- data/lib/rubocop/cop/style/format_string_token.rb +86 -16
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
- data/lib/rubocop/cop/style/global_vars.rb +5 -2
- data/lib/rubocop/cop/style/guard_clause.rb +32 -23
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
- data/lib/rubocop/cop/style/hash_conversion.rb +28 -12
- data/lib/rubocop/cop/style/hash_each_methods.rb +4 -4
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_lookup_method.rb +105 -0
- data/lib/rubocop/cop/style/hash_slice.rb +16 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +7 -3
- 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 +18 -9
- data/lib/rubocop/cop/style/if_inside_else.rb +25 -20
- data/lib/rubocop/cop/style/if_unless_modifier.rb +71 -46
- 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 +5 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +16 -6
- 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 +10 -6
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +27 -7
- data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
- data/lib/rubocop/cop/style/it_assignment.rb +69 -12
- data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +20 -10
- data/lib/rubocop/cop/style/lambda.rb +12 -1
- data/lib/rubocop/cop/style/lambda_call.rb +26 -10
- 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 +11 -0
- data/lib/rubocop/cop/style/map_into_array.rb +5 -2
- data/lib/rubocop/cop/style/map_join.rb +123 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +13 -5
- data/lib/rubocop/cop/style/map_to_set.rb +1 -3
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +31 -15
- 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 +34 -5
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +12 -7
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
- data/lib/rubocop/cop/style/method_def_parentheses.rb +7 -5
- data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +40 -7
- 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 +2 -1
- 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 +7 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +14 -18
- data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +111 -12
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -2
- data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
- data/lib/rubocop/cop/style/nested_modifier.rb +9 -4
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +41 -13
- data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +21 -11
- data/lib/rubocop/cop/style/not.rb +5 -1
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
- data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
- data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +1 -0
- data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +22 -13
- data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +10 -2
- 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/parallel_assignment.rb +58 -27
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -1
- data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +4 -0
- 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 +4 -2
- data/lib/rubocop/cop/style/raise_args.rb +9 -9
- data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
- 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 +12 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +38 -3
- data/lib/rubocop/cop/style/redundant_condition.rb +63 -5
- data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +26 -4
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +11 -3
- data/lib/rubocop/cop/style/redundant_each.rb +4 -5
- data/lib/rubocop/cop/style/redundant_exception.rb +7 -1
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +2 -10
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +319 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
- data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
- data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +83 -119
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +164 -82
- data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +8 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +8 -8
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +12 -0
- data/lib/rubocop/cop/style/redundant_return.rb +4 -3
- data/lib/rubocop/cop/style/redundant_self.rb +20 -7
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -3
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
- data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
- 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/rescue_modifier.rb +5 -3
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/reverse_find.rb +51 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +76 -20
- data/lib/rubocop/cop/style/sample.rb +11 -6
- 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 +54 -22
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +45 -14
- data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +22 -8
- data/lib/rubocop/cop/style/single_line_methods.rb +13 -8
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +96 -104
- data/lib/rubocop/cop/style/special_global_vars.rb +7 -2
- 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_concatenation.rb +31 -15
- data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +38 -2
- data/lib/rubocop/cop/style/super_arguments.rb +4 -6
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +11 -9
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +11 -0
- data/lib/rubocop/cop/style/time_now.rb +41 -0
- data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -2
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +52 -1
- 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 +18 -19
- data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
- 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/while_until_do.rb +7 -0
- data/lib/rubocop/cop/style/while_until_modifier.rb +16 -1
- data/lib/rubocop/cop/style/word_array.rb +1 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +2 -3
- data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
- data/lib/rubocop/cop/style.rb +311 -0
- data/lib/rubocop/cop/team.rb +163 -45
- data/lib/rubocop/cop/util.rb +7 -10
- data/lib/rubocop/cop/utils/format_string.rb +20 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +7 -3
- data/lib/rubocop/cop/variable_force/branch.rb +30 -6
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +28 -10
- data/lib/rubocop/cop/variable_force.rb +26 -9
- data/lib/rubocop/cops_documentation_generator.rb +49 -15
- data/lib/rubocop/directive_comment.rb +147 -5
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/feature_loader.rb +0 -6
- data/lib/rubocop/file_patterns.rb +9 -1
- data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +57 -14
- data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
- data/lib/rubocop/formatter/formatter_set.rb +3 -2
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
- data/lib/rubocop/formatter/html_formatter.rb +3 -5
- data/lib/rubocop/formatter/json_formatter.rb +11 -6
- data/lib/rubocop/formatter/junit_formatter.rb +27 -10
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +2 -3
- data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
- data/lib/rubocop/formatter/sarif_formatter.rb +181 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
- data/lib/rubocop/formatter/tap_formatter.rb +8 -3
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +2 -3
- data/lib/rubocop/formatter.rb +23 -21
- data/lib/rubocop/lockfile.rb +18 -0
- data/lib/rubocop/lsp/diagnostic.rb +22 -41
- data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
- data/lib/rubocop/lsp/routes.rb +136 -33
- data/lib/rubocop/lsp/runtime.rb +23 -8
- data/lib/rubocop/lsp/server.rb +4 -2
- data/lib/rubocop/lsp/stdin_runner.rb +31 -18
- data/lib/rubocop/magic_comment.rb +55 -0
- data/lib/rubocop/mcp/server.rb +199 -0
- data/lib/rubocop/options.rb +129 -21
- data/lib/rubocop/path_util.rb +20 -5
- 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 +6 -4
- data/lib/rubocop/remote_config.rb +14 -12
- data/lib/rubocop/result_cache.rb +90 -52
- data/lib/rubocop/rspec/cop_helper.rb +21 -1
- data/lib/rubocop/rspec/expect_offense.rb +11 -7
- data/lib/rubocop/rspec/shared_contexts.rb +85 -3
- data/lib/rubocop/rspec/support.rb +4 -0
- data/lib/rubocop/runner.rb +294 -100
- data/lib/rubocop/server/cache.rb +67 -48
- 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 +2 -1
- data/lib/rubocop/server/client_command/start.rb +11 -1
- data/lib/rubocop/server/core.rb +8 -0
- data/lib/rubocop/server.rb +14 -0
- data/lib/rubocop/target_finder.rb +25 -11
- data/lib/rubocop/target_ruby.rb +31 -14
- data/lib/rubocop/todo_audit.rb +111 -0
- data/lib/rubocop/unified_diff.rb +257 -0
- data/lib/rubocop/version.rb +48 -10
- data/lib/rubocop.rb +30 -682
- data/lib/ruby_lsp/rubocop/addon.rb +28 -17
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
- metadata +116 -19
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +0 -50
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Prefer `Enumerable` predicate methods over expressions with `count`.
|
|
7
|
+
#
|
|
8
|
+
# The cop checks calls to `count` without arguments, or with a
|
|
9
|
+
# block. It doesn't register offenses for `count` with a positional
|
|
10
|
+
# argument because its behavior differs from predicate methods (`count`
|
|
11
|
+
# matches the argument using `==`, while `any?`, `none?` and `one?` use
|
|
12
|
+
# `===`).
|
|
13
|
+
#
|
|
14
|
+
# NOTE: This cop doesn't check `length` and `size` methods because they
|
|
15
|
+
# would yield false positives. For example, `String` implements `length`
|
|
16
|
+
# and `size`, but it doesn't include `Enumerable`.
|
|
17
|
+
#
|
|
18
|
+
# @safety
|
|
19
|
+
# The cop is unsafe because receiver might not include `Enumerable`, or
|
|
20
|
+
# it has nonstandard implementation of `count` or any replacement
|
|
21
|
+
# methods.
|
|
22
|
+
#
|
|
23
|
+
# It's also unsafe because for collections with falsey values, expressions
|
|
24
|
+
# with `count` without a block return a different result than methods `any?`,
|
|
25
|
+
# `none?` and `one?`:
|
|
26
|
+
#
|
|
27
|
+
# [source,ruby]
|
|
28
|
+
# ----
|
|
29
|
+
# [nil, false].count.positive?
|
|
30
|
+
# [nil].count == 1
|
|
31
|
+
# # => true
|
|
32
|
+
#
|
|
33
|
+
# [nil, false].any?
|
|
34
|
+
# [nil].one?
|
|
35
|
+
# # => false
|
|
36
|
+
#
|
|
37
|
+
# [nil].count == 0
|
|
38
|
+
# # => false
|
|
39
|
+
#
|
|
40
|
+
# [nil].none?
|
|
41
|
+
# # => true
|
|
42
|
+
# ----
|
|
43
|
+
#
|
|
44
|
+
# Autocorrection is unsafe when replacement methods don't iterate over
|
|
45
|
+
# every element in collection and the given block runs side effects:
|
|
46
|
+
#
|
|
47
|
+
# [source,ruby]
|
|
48
|
+
# ----
|
|
49
|
+
# x.count(&:method_with_side_effects).positive?
|
|
50
|
+
# # calls `method_with_side_effects` on every element
|
|
51
|
+
#
|
|
52
|
+
# x.any?(&:method_with_side_effects)
|
|
53
|
+
# # calls `method_with_side_effects` until first element returns a truthy value
|
|
54
|
+
# ----
|
|
55
|
+
#
|
|
56
|
+
# @example
|
|
57
|
+
#
|
|
58
|
+
# # bad
|
|
59
|
+
# x.count.positive?
|
|
60
|
+
# x.count > 0
|
|
61
|
+
# x.count != 0
|
|
62
|
+
#
|
|
63
|
+
# x.count(&:foo?).positive?
|
|
64
|
+
# x.count { |item| item.foo? }.positive?
|
|
65
|
+
#
|
|
66
|
+
# # good
|
|
67
|
+
# x.any?
|
|
68
|
+
#
|
|
69
|
+
# x.any?(&:foo?)
|
|
70
|
+
# x.any? { |item| item.foo? }
|
|
71
|
+
#
|
|
72
|
+
# # bad
|
|
73
|
+
# x.count.zero?
|
|
74
|
+
# x.count == 0
|
|
75
|
+
#
|
|
76
|
+
# # good
|
|
77
|
+
# x.none?
|
|
78
|
+
#
|
|
79
|
+
# # bad
|
|
80
|
+
# x.count == 1
|
|
81
|
+
# x.one?
|
|
82
|
+
#
|
|
83
|
+
# @example AllCops:ActiveSupportExtensionsEnabled: false (default)
|
|
84
|
+
#
|
|
85
|
+
# # good
|
|
86
|
+
# x.count > 1
|
|
87
|
+
#
|
|
88
|
+
# @example AllCops:ActiveSupportExtensionsEnabled: true
|
|
89
|
+
#
|
|
90
|
+
# # bad
|
|
91
|
+
# x.count > 1
|
|
92
|
+
#
|
|
93
|
+
# # good
|
|
94
|
+
# x.many?
|
|
95
|
+
#
|
|
96
|
+
class CollectionQuerying < Base
|
|
97
|
+
include RangeHelp
|
|
98
|
+
extend AutoCorrector
|
|
99
|
+
|
|
100
|
+
MSG = 'Use `%<prefer>s` instead.'
|
|
101
|
+
|
|
102
|
+
RESTRICT_ON_SEND = %i[positive? > != zero? ==].freeze
|
|
103
|
+
|
|
104
|
+
REPLACEMENTS = {
|
|
105
|
+
[:positive?, nil] => :any?,
|
|
106
|
+
[:>, 0] => :any?,
|
|
107
|
+
[:!=, 0] => :any?,
|
|
108
|
+
[:zero?, nil] => :none?,
|
|
109
|
+
[:==, 0] => :none?,
|
|
110
|
+
[:==, 1] => :one?,
|
|
111
|
+
[:>, 1] => :many?
|
|
112
|
+
}.freeze
|
|
113
|
+
|
|
114
|
+
# @!method count_predicate(node)
|
|
115
|
+
def_node_matcher :count_predicate, <<~PATTERN
|
|
116
|
+
(send
|
|
117
|
+
{
|
|
118
|
+
(any_block $(call !nil? :count) _ _)
|
|
119
|
+
$(call !nil? :count (block-pass _)?)
|
|
120
|
+
}
|
|
121
|
+
{
|
|
122
|
+
:positive? |
|
|
123
|
+
:> (int 0) |
|
|
124
|
+
:!= (int 0) |
|
|
125
|
+
:zero? |
|
|
126
|
+
:== (int 0) |
|
|
127
|
+
:== (int 1) |
|
|
128
|
+
:> (int 1)
|
|
129
|
+
})
|
|
130
|
+
PATTERN
|
|
131
|
+
|
|
132
|
+
def on_send(node)
|
|
133
|
+
return unless (count_node = count_predicate(node))
|
|
134
|
+
|
|
135
|
+
replacement_method = replacement_method(node)
|
|
136
|
+
|
|
137
|
+
return unless replacement_supported?(replacement_method)
|
|
138
|
+
|
|
139
|
+
offense_range = count_node.loc.selector.join(node.source_range.end)
|
|
140
|
+
add_offense(offense_range,
|
|
141
|
+
message: format(MSG, prefer: replacement_method)) do |corrector|
|
|
142
|
+
corrector.replace(count_node.loc.selector, replacement_method)
|
|
143
|
+
corrector.remove(removal_range(node))
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
private
|
|
148
|
+
|
|
149
|
+
def replacement_method(node)
|
|
150
|
+
REPLACEMENTS.fetch([node.method_name, node.first_argument&.value])
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def replacement_supported?(method_name)
|
|
154
|
+
return true if active_support_extensions_enabled?
|
|
155
|
+
|
|
156
|
+
method_name != :many?
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def removal_range(node)
|
|
160
|
+
range = (node.loc.dot || node.loc.selector).join(node.source_range.end)
|
|
161
|
+
|
|
162
|
+
range_with_surrounding_space(range, side: :left)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -4,7 +4,9 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for methods invoked via the `::` operator instead
|
|
7
|
-
# of the `.` operator (like `FileUtils::rmdir` instead of
|
|
7
|
+
# of the `.` operator (like `FileUtils::rmdir` instead of
|
|
8
|
+
# `FileUtils.rmdir`). The `::` operator is conventionally used to
|
|
9
|
+
# reference constants, so using it for method calls can be misleading.
|
|
8
10
|
#
|
|
9
11
|
# @example
|
|
10
12
|
# # bad
|
|
@@ -22,10 +24,9 @@ module RuboCop
|
|
|
22
24
|
|
|
23
25
|
MSG = 'Do not use `::` for method calls.'
|
|
24
26
|
|
|
25
|
-
# @!method
|
|
26
|
-
def_node_matcher :
|
|
27
|
-
(
|
|
28
|
-
(const nil? :Java) _)
|
|
27
|
+
# @!method java_root?(node)
|
|
28
|
+
def_node_matcher :java_root?, <<~PATTERN
|
|
29
|
+
(const nil? :Java)
|
|
29
30
|
PATTERN
|
|
30
31
|
|
|
31
32
|
def self.autocorrect_incompatible_with
|
|
@@ -35,11 +36,19 @@ module RuboCop
|
|
|
35
36
|
def on_send(node)
|
|
36
37
|
return unless node.receiver && node.double_colon?
|
|
37
38
|
return if node.camel_case_method?
|
|
38
|
-
# ignore Java interop code like Java::int
|
|
39
|
-
return if
|
|
39
|
+
# ignore Java interop code like `Java::int` or `Java::com::method`
|
|
40
|
+
return if java_interop?(node)
|
|
40
41
|
|
|
41
42
|
add_offense(node.loc.dot) { |corrector| corrector.replace(node.loc.dot, '.') }
|
|
42
43
|
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def java_interop?(node)
|
|
48
|
+
receiver = node.receiver
|
|
49
|
+
receiver = receiver.receiver while receiver.respond_to?(:receiver) && receiver.receiver
|
|
50
|
+
java_root?(receiver)
|
|
51
|
+
end
|
|
43
52
|
end
|
|
44
53
|
end
|
|
45
54
|
end
|
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
|
64
64
|
|
|
65
65
|
MSG = 'Combine this loop with the previous loop.'
|
|
66
66
|
|
|
67
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
67
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
68
68
|
def on_block(node)
|
|
69
69
|
return unless node.parent&.begin_type?
|
|
70
70
|
return unless collection_looping_method?(node)
|
|
@@ -77,15 +77,20 @@ module RuboCop
|
|
|
77
77
|
combine_with_left_sibling(corrector, node)
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
81
80
|
|
|
82
81
|
alias on_numblock on_block
|
|
82
|
+
alias on_itblock on_block
|
|
83
83
|
|
|
84
84
|
def on_for(node)
|
|
85
85
|
return unless node.parent&.begin_type?
|
|
86
86
|
return unless same_collection_looping_for?(node, node.left_sibling)
|
|
87
|
+
return unless node.body && node.left_sibling.body
|
|
87
88
|
|
|
88
89
|
add_offense(node) do |corrector|
|
|
90
|
+
# Combining loops with different iteration variables would leave the second
|
|
91
|
+
# body referencing an undefined variable, so only autocorrect when they match.
|
|
92
|
+
next unless node.variable == node.left_sibling.variable
|
|
93
|
+
|
|
89
94
|
combine_with_left_sibling(corrector, node)
|
|
90
95
|
end
|
|
91
96
|
end
|
|
@@ -9,8 +9,8 @@ module RuboCop
|
|
|
9
9
|
# These keywords are: `class`, `module`, `def`, `begin`, `end`.
|
|
10
10
|
#
|
|
11
11
|
# Note that some comments
|
|
12
|
-
# (`:nodoc:`, `:yields:`, `rubocop:disable` and `rubocop:todo`)
|
|
13
|
-
#
|
|
12
|
+
# (`:nodoc:`, `:yields:`, `rubocop:disable` and `rubocop:todo`),
|
|
13
|
+
# RBS::Inline annotation, and Steep annotation (`steep:ignore`) are allowed.
|
|
14
14
|
#
|
|
15
15
|
# Autocorrection removes comments from `end` keyword and keeps comments
|
|
16
16
|
# for `class`, `module`, `def` and `begin` above the keyword.
|
|
@@ -57,8 +57,10 @@ module RuboCop
|
|
|
57
57
|
|
|
58
58
|
REGEXP = /(?<keyword>\S+).*#/.freeze
|
|
59
59
|
|
|
60
|
-
SUBCLASS_DEFINITION = /\A\s*class\s
|
|
61
|
-
|
|
60
|
+
SUBCLASS_DEFINITION = /\A\s*class\s+(\w|::)+\s*<\s*(\w|::)+/.freeze
|
|
61
|
+
METHOD_OR_END_DEFINITIONS = /\A\s*(def\s|end)/.freeze
|
|
62
|
+
|
|
63
|
+
STEEP_REGEXP = /#\ssteep:ignore(\s|\z)/.freeze
|
|
62
64
|
|
|
63
65
|
def on_new_investigation
|
|
64
66
|
processed_source.comments.each do |comment|
|
|
@@ -86,6 +88,7 @@ module RuboCop
|
|
|
86
88
|
def offensive?(comment)
|
|
87
89
|
line = source_line(comment)
|
|
88
90
|
return false if rbs_inline_annotation?(line, comment)
|
|
91
|
+
return false if steep_annotation?(comment)
|
|
89
92
|
|
|
90
93
|
KEYWORD_REGEXES.any? { |r| r.match?(line) } &&
|
|
91
94
|
ALLOWED_COMMENT_REGEXES.none? { |r| r.match?(line) }
|
|
@@ -99,12 +102,16 @@ module RuboCop
|
|
|
99
102
|
case line
|
|
100
103
|
when SUBCLASS_DEFINITION
|
|
101
104
|
comment.text.start_with?(/#\[.+\]/)
|
|
102
|
-
when
|
|
105
|
+
when METHOD_OR_END_DEFINITIONS
|
|
103
106
|
comment.text.start_with?('#:')
|
|
104
107
|
else
|
|
105
108
|
false
|
|
106
109
|
end
|
|
107
110
|
end
|
|
111
|
+
|
|
112
|
+
def steep_annotation?(comment)
|
|
113
|
+
comment.text.match?(STEEP_REGEXP)
|
|
114
|
+
end
|
|
108
115
|
end
|
|
109
116
|
end
|
|
110
117
|
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Checks for logical comparison which can be replaced with `Comparable#between?`.
|
|
7
|
+
#
|
|
8
|
+
# NOTE: `Comparable#between?` is on average slightly slower than logical comparison,
|
|
9
|
+
# although the difference generally isn't observable. If you require maximum
|
|
10
|
+
# performance, consider using logical comparison.
|
|
11
|
+
#
|
|
12
|
+
# @safety
|
|
13
|
+
# This cop is unsafe because the receiver may not respond to `between?`.
|
|
14
|
+
#
|
|
15
|
+
# @example
|
|
16
|
+
#
|
|
17
|
+
# # bad
|
|
18
|
+
# x >= min && x <= max
|
|
19
|
+
#
|
|
20
|
+
# # bad
|
|
21
|
+
# x <= max && x >= min
|
|
22
|
+
#
|
|
23
|
+
# # good
|
|
24
|
+
# x.between?(min, max)
|
|
25
|
+
#
|
|
26
|
+
class ComparableBetween < Base
|
|
27
|
+
extend AutoCorrector
|
|
28
|
+
|
|
29
|
+
MSG = 'Prefer `%<prefer>s` over logical comparison.'
|
|
30
|
+
|
|
31
|
+
# @!method logical_comparison_between_by_min_first?(node)
|
|
32
|
+
def_node_matcher :logical_comparison_between_by_min_first?, <<~PATTERN
|
|
33
|
+
(and
|
|
34
|
+
(send
|
|
35
|
+
{$_value :>= $_min | $_min :<= $_value})
|
|
36
|
+
(send
|
|
37
|
+
{$_value :<= $_max | $_max :>= $_value}))
|
|
38
|
+
PATTERN
|
|
39
|
+
|
|
40
|
+
# @!method logical_comparison_between_by_max_first?(node)
|
|
41
|
+
def_node_matcher :logical_comparison_between_by_max_first?, <<~PATTERN
|
|
42
|
+
(and
|
|
43
|
+
(send
|
|
44
|
+
{$_value :<= $_max | $_max :>= $_value})
|
|
45
|
+
(send
|
|
46
|
+
{$_value :>= $_min | $_min :<= $_value}))
|
|
47
|
+
PATTERN
|
|
48
|
+
|
|
49
|
+
def on_and(node)
|
|
50
|
+
logical_comparison_between_by_min_first?(node) do |*args|
|
|
51
|
+
min_and_value, max_and_value = args.each_slice(2).to_a
|
|
52
|
+
|
|
53
|
+
register_offense(node, min_and_value, max_and_value)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
logical_comparison_between_by_max_first?(node) do |*args|
|
|
57
|
+
max_and_value, min_and_value = args.each_slice(2).to_a
|
|
58
|
+
|
|
59
|
+
register_offense(node, min_and_value, max_and_value)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def register_offense(node, min_and_value, max_and_value)
|
|
66
|
+
value = (min_and_value & max_and_value).first
|
|
67
|
+
min = min_and_value.find { _1 != value } || value
|
|
68
|
+
max = max_and_value.find { _1 != value } || value
|
|
69
|
+
|
|
70
|
+
prefer = "#{value.source}.between?(#{min.source}, #{max.source})"
|
|
71
|
+
add_offense(node, message: format(MSG, prefer: prefer)) do |corrector|
|
|
72
|
+
corrector.replace(node, prefer)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -90,7 +90,7 @@ module RuboCop
|
|
|
90
90
|
max = if_body.source
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
prefer = "#{
|
|
93
|
+
prefer = "#{parenthesize_if_needed(else_body)}.clamp(#{min}, #{max})"
|
|
94
94
|
|
|
95
95
|
add_offense(node, message: format(MSG, prefer: prefer)) do |corrector|
|
|
96
96
|
autocorrect(corrector, node, prefer)
|
|
@@ -119,6 +119,17 @@ module RuboCop
|
|
|
119
119
|
|
|
120
120
|
(lhs.source == else_body && op == :<) || (rhs.source == else_body && op == :>)
|
|
121
121
|
end
|
|
122
|
+
|
|
123
|
+
# `a + b` must become `(a + b).clamp(low, high)`, not `a + b.clamp(low, high)`
|
|
124
|
+
# (which parses as `a + (b.clamp(low, high))`).
|
|
125
|
+
def parenthesize_if_needed(node)
|
|
126
|
+
if node.type?(:and, :or, :if, :range) || node.assignment? ||
|
|
127
|
+
(node.send_type? && (node.operator_method? || node.unary_operation?))
|
|
128
|
+
"(#{node.source})"
|
|
129
|
+
else
|
|
130
|
+
node.source
|
|
131
|
+
end
|
|
132
|
+
end
|
|
122
133
|
end
|
|
123
134
|
end
|
|
124
135
|
end
|
|
@@ -30,7 +30,7 @@ module RuboCop
|
|
|
30
30
|
'Use `push` with elements as arguments without array brackets instead of `%<current>s`.'
|
|
31
31
|
RESTRICT_ON_SEND = %i[concat].freeze
|
|
32
32
|
|
|
33
|
-
# rubocop:disable Metrics
|
|
33
|
+
# rubocop:disable-next Metrics
|
|
34
34
|
def on_send(node)
|
|
35
35
|
return if node.arguments.empty?
|
|
36
36
|
return unless node.arguments.all?(&:array_type?)
|
|
@@ -52,7 +52,13 @@ module RuboCop
|
|
|
52
52
|
|
|
53
53
|
add_offense(offense, message: message) do |corrector|
|
|
54
54
|
if use_percent_literal
|
|
55
|
+
next unless prefer
|
|
56
|
+
|
|
55
57
|
corrector.replace(offense, prefer)
|
|
58
|
+
elsif node.arguments.any? { |argument| argument.children.empty? }
|
|
59
|
+
# In-place bracket removal would leave dangling commas (e.g.
|
|
60
|
+
# `concat([], [b])` -> `push(, b)`), so rebuild the call instead.
|
|
61
|
+
corrector.replace(offense, preferred_method(node))
|
|
56
62
|
else
|
|
57
63
|
corrector.replace(node.loc.selector, 'push')
|
|
58
64
|
node.arguments.each do |argument|
|
|
@@ -62,7 +68,6 @@ module RuboCop
|
|
|
62
68
|
end
|
|
63
69
|
end
|
|
64
70
|
end
|
|
65
|
-
# rubocop:enable Metrics
|
|
66
71
|
alias on_csend on_send
|
|
67
72
|
|
|
68
73
|
private
|
|
@@ -73,7 +78,7 @@ module RuboCop
|
|
|
73
78
|
|
|
74
79
|
def preferred_method(node)
|
|
75
80
|
new_arguments =
|
|
76
|
-
node.arguments.
|
|
81
|
+
node.arguments.flat_map do |arg|
|
|
77
82
|
if arg.percent_literal?
|
|
78
83
|
arg.children.map { |child| child.value.inspect }
|
|
79
84
|
else
|
|
@@ -99,10 +99,6 @@ module RuboCop
|
|
|
99
99
|
end
|
|
100
100
|
end
|
|
101
101
|
|
|
102
|
-
def setter_method?(method_name)
|
|
103
|
-
method_name.to_s.end_with?(EQUAL) && !%i[!= == === >= <=].include?(method_name)
|
|
104
|
-
end
|
|
105
|
-
|
|
106
102
|
def assignment_rhs_exist?(node)
|
|
107
103
|
parent = node.parent
|
|
108
104
|
return true unless parent
|
|
@@ -111,7 +107,7 @@ module RuboCop
|
|
|
111
107
|
end
|
|
112
108
|
end
|
|
113
109
|
|
|
114
|
-
#
|
|
110
|
+
# Checks for `if` and `case` statements where each branch is used for
|
|
115
111
|
# both the assignment and comparison of the same variable
|
|
116
112
|
# when using the return of the condition can be used instead.
|
|
117
113
|
#
|
|
@@ -207,15 +203,14 @@ module RuboCop
|
|
|
207
203
|
class ConditionalAssignment < Base
|
|
208
204
|
include ConditionalAssignmentHelper
|
|
209
205
|
include ConfigurableEnforcedStyle
|
|
206
|
+
include ReparsedEquivalence
|
|
210
207
|
extend AutoCorrector
|
|
211
208
|
|
|
212
209
|
MSG = 'Use the return of the conditional for variable assignment and comparison.'
|
|
213
210
|
ASSIGN_TO_CONDITION_MSG = 'Assign variables inside of conditionals.'
|
|
214
211
|
VARIABLE_ASSIGNMENT_TYPES = %i[casgn cvasgn gvasgn ivasgn lvasgn].freeze
|
|
215
212
|
ASSIGNMENT_TYPES = VARIABLE_ASSIGNMENT_TYPES + %i[and_asgn or_asgn op_asgn masgn].freeze
|
|
216
|
-
LINE_LENGTH = 'Layout/LineLength'
|
|
217
213
|
ENABLED = 'Enabled'
|
|
218
|
-
MAX = 'Max'
|
|
219
214
|
SINGLE_LINE_CONDITIONS_ONLY = 'SingleLineConditionsOnly'
|
|
220
215
|
|
|
221
216
|
# The shovel operator `<<` does not have its own type. It is a `send`
|
|
@@ -289,8 +284,12 @@ module RuboCop
|
|
|
289
284
|
|
|
290
285
|
_condition, *branches, else_branch = *assignment
|
|
291
286
|
|
|
292
|
-
|
|
287
|
+
# Use the node accessor rather than the raw destructured branch: for
|
|
288
|
+
# `x = unless cond; body; end` (no `else`) the parser puts `body` in the
|
|
289
|
+
# else slot, but `else_branch` correctly reports there is no `else` clause.
|
|
290
|
+
return unless assignment.else_branch
|
|
293
291
|
return if allowed_single_line?([*branches, else_branch])
|
|
292
|
+
return unless safe_to_correct?(node)
|
|
294
293
|
|
|
295
294
|
add_offense(node, message: ASSIGN_TO_CONDITION_MSG) do |corrector|
|
|
296
295
|
autocorrect(corrector, node)
|
|
@@ -314,6 +313,7 @@ module RuboCop
|
|
|
314
313
|
|
|
315
314
|
def assignment_node(node)
|
|
316
315
|
assignment = node.send_type? ? node.last_argument : node.expression
|
|
316
|
+
return unless assignment
|
|
317
317
|
|
|
318
318
|
# ignore pseudo-assignments without rhs in for nodes
|
|
319
319
|
return if node.parent&.for_type?
|
|
@@ -369,6 +369,7 @@ module RuboCop
|
|
|
369
369
|
return unless allowed_statements?(branches)
|
|
370
370
|
return if allowed_single_line?(branches)
|
|
371
371
|
return if correction_exceeds_line_limit?(node, branches)
|
|
372
|
+
return unless safe_to_correct?(node)
|
|
372
373
|
|
|
373
374
|
add_offense(node) { |corrector| autocorrect(corrector, node) }
|
|
374
375
|
end
|
|
@@ -381,6 +382,25 @@ module RuboCop
|
|
|
381
382
|
end
|
|
382
383
|
end
|
|
383
384
|
|
|
385
|
+
# The correction rewrites the conditional structurally, so full AST
|
|
386
|
+
# equivalence cannot be asserted, but the result must at least reparse
|
|
387
|
+
# to valid Ruby. Applying the correction to a throwaway buffer here
|
|
388
|
+
# also exercises the branch-shape handling before an offense is even
|
|
389
|
+
# reported, so unusual branches that the corrector cannot handle are
|
|
390
|
+
# left alone instead of crashing or emitting invalid code - the bug
|
|
391
|
+
# class behind most of this cop's history.
|
|
392
|
+
def safe_to_correct?(node)
|
|
393
|
+
correction_parses?(node)
|
|
394
|
+
rescue StandardError
|
|
395
|
+
false
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
# `ReparsedEquivalence#correction_parses?` contract: apply the exact
|
|
399
|
+
# correction this cop would perform.
|
|
400
|
+
def apply_reparse_correction(corrector, node)
|
|
401
|
+
autocorrect(corrector, node)
|
|
402
|
+
end
|
|
403
|
+
|
|
384
404
|
def allowed_statements?(branches)
|
|
385
405
|
return false unless branches.all?
|
|
386
406
|
|
|
@@ -398,7 +418,7 @@ module RuboCop
|
|
|
398
418
|
# of the longest line + the length of the corrected assignment is
|
|
399
419
|
# greater than the max configured line length
|
|
400
420
|
def correction_exceeds_line_limit?(node, branches)
|
|
401
|
-
return false unless
|
|
421
|
+
return false unless config.cop_enabled?('Layout/LineLength')
|
|
402
422
|
|
|
403
423
|
assignment = lhs(tail(branches[0]))
|
|
404
424
|
|
|
@@ -416,14 +436,6 @@ module RuboCop
|
|
|
416
436
|
assignment + longest_line
|
|
417
437
|
end
|
|
418
438
|
|
|
419
|
-
def line_length_cop_enabled?
|
|
420
|
-
config.for_cop(LINE_LENGTH)[ENABLED]
|
|
421
|
-
end
|
|
422
|
-
|
|
423
|
-
def max_line_length
|
|
424
|
-
config.for_cop(LINE_LENGTH)[MAX]
|
|
425
|
-
end
|
|
426
|
-
|
|
427
439
|
def single_line_conditions_only?
|
|
428
440
|
cop_config[SINGLE_LINE_CONDITIONS_ONLY]
|
|
429
441
|
end
|
|
@@ -436,26 +448,40 @@ module RuboCop
|
|
|
436
448
|
# Helper module to provide common methods to ConditionalAssignment
|
|
437
449
|
# correctors
|
|
438
450
|
module ConditionalCorrectorHelper
|
|
451
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
439
452
|
def remove_whitespace_in_branches(corrector, branch, condition, column)
|
|
440
453
|
branch.each_node do |child|
|
|
441
454
|
next if child.source_range.nil?
|
|
455
|
+
next if child.parent.dstr_type?
|
|
442
456
|
|
|
443
457
|
white_space = white_space_range(child, column)
|
|
444
|
-
corrector.remove(white_space) if white_space
|
|
458
|
+
corrector.remove(white_space) if white_space
|
|
445
459
|
end
|
|
446
460
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
corrector.remove_preceding(loc, loc.column - column)
|
|
461
|
+
if condition.loc.else && !same_line?(condition.else_branch, condition)
|
|
462
|
+
corrector.remove_preceding(condition.loc.else, condition.loc.else.column - column)
|
|
451
463
|
end
|
|
464
|
+
|
|
465
|
+
return unless condition.loc.end && !same_line?(
|
|
466
|
+
condition.branches.last.parent.else_branch, condition.loc.end
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
corrector.remove_preceding(condition.loc.end, condition.loc.end.column - column)
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
def same_line?(node1, node2)
|
|
473
|
+
RuboCop::Cop::Util.same_line?(node1, node2)
|
|
452
474
|
end
|
|
453
475
|
|
|
454
476
|
def white_space_range(node, column)
|
|
455
477
|
expression = node.source_range
|
|
456
|
-
|
|
478
|
+
end_pos = expression.begin_pos
|
|
479
|
+
begin_pos = end_pos - (expression.column - column - 2)
|
|
480
|
+
|
|
481
|
+
return nil if begin_pos > end_pos
|
|
457
482
|
|
|
458
|
-
Parser::Source::Range.new(expression.source_buffer, begin_pos,
|
|
483
|
+
white_space = Parser::Source::Range.new(expression.source_buffer, begin_pos, end_pos)
|
|
484
|
+
white_space if white_space.source.strip.empty?
|
|
459
485
|
end
|
|
460
486
|
|
|
461
487
|
def assignment(node)
|
|
@@ -595,6 +621,8 @@ module RuboCop
|
|
|
595
621
|
|
|
596
622
|
return unless (branch_else = branch.parent.loc.else)
|
|
597
623
|
|
|
624
|
+
return if same_line?(branch_else, condition)
|
|
625
|
+
|
|
598
626
|
corrector.remove_preceding(branch_else, branch_else.column - column)
|
|
599
627
|
end
|
|
600
628
|
end
|
|
@@ -653,6 +681,8 @@ module RuboCop
|
|
|
653
681
|
remove_whitespace_in_branches(corrector, branch, condition, column)
|
|
654
682
|
|
|
655
683
|
parent_keyword = branch.parent.loc.keyword
|
|
684
|
+
return if same_line?(parent_keyword, condition)
|
|
685
|
+
|
|
656
686
|
corrector.remove_preceding(parent_keyword, parent_keyword.column - column)
|
|
657
687
|
end
|
|
658
688
|
end
|