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
|
@@ -29,25 +29,30 @@ module RuboCop
|
|
|
29
29
|
# @example IgnoreModules: false (default)
|
|
30
30
|
# # bad
|
|
31
31
|
# class Foo
|
|
32
|
-
# MyClass = Struct.new
|
|
32
|
+
# MyClass = Struct.new
|
|
33
33
|
# end
|
|
34
34
|
#
|
|
35
35
|
# # good
|
|
36
36
|
# class Foo
|
|
37
|
-
# MyClass = Struct.new
|
|
37
|
+
# MyClass = Struct.new
|
|
38
38
|
# public_constant :MyClass
|
|
39
39
|
# end
|
|
40
40
|
#
|
|
41
41
|
# @example IgnoreModules: true
|
|
42
42
|
# # good
|
|
43
43
|
# class Foo
|
|
44
|
-
# MyClass = Struct.new
|
|
44
|
+
# MyClass = Struct.new
|
|
45
45
|
# end
|
|
46
46
|
#
|
|
47
47
|
class ConstantVisibility < Base
|
|
48
48
|
MSG = 'Explicitly make `%<constant_name>s` public or private using ' \
|
|
49
49
|
'either `#public_constant` or `#private_constant`.'
|
|
50
50
|
|
|
51
|
+
# @!method visibility_declaration_for(node)
|
|
52
|
+
def_node_matcher :visibility_declaration_for, <<~PATTERN
|
|
53
|
+
(send nil? {:public_constant :private_constant} $...)
|
|
54
|
+
PATTERN
|
|
55
|
+
|
|
51
56
|
def on_casgn(node)
|
|
52
57
|
return unless class_or_module_scope?(node)
|
|
53
58
|
return if visibility_declaration?(node)
|
|
@@ -77,19 +82,25 @@ module RuboCop
|
|
|
77
82
|
end
|
|
78
83
|
end
|
|
79
84
|
|
|
85
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
80
86
|
def visibility_declaration?(node)
|
|
81
87
|
node.parent.each_child_node(:send).any? do |child|
|
|
82
|
-
visibility_declaration_for
|
|
83
|
-
end
|
|
84
|
-
end
|
|
88
|
+
next false unless (arguments = visibility_declaration_for(child))
|
|
85
89
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
if (splat = arguments.first)&.splat_type?
|
|
91
|
+
next true unless splat.children.first.array_type?
|
|
92
|
+
|
|
93
|
+
arguments = splat.children.first.children
|
|
94
|
+
end
|
|
95
|
+
constant_values = arguments.map do |argument|
|
|
96
|
+
# `respond_to?(:value)` is too broad: `int`/`float` nodes respond to it
|
|
97
|
+
# but their value is a `Numeric`, which has no `to_sym` (e.g.
|
|
98
|
+
# `private_constant 42`). Only symbol/string arguments are real names.
|
|
99
|
+
argument.value.to_sym if argument.type?(:sym, :str)
|
|
100
|
+
end
|
|
90
101
|
|
|
91
|
-
|
|
92
|
-
|
|
102
|
+
constant_values.include?(node.name)
|
|
103
|
+
end
|
|
93
104
|
end
|
|
94
105
|
end
|
|
95
106
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
#
|
|
6
|
+
# Checks that a copyright notice was given in each source file.
|
|
7
7
|
#
|
|
8
8
|
# The default regexp for an acceptable copyright notice can be found in
|
|
9
9
|
# config/default.yml. The default can be changed as follows:
|
|
@@ -25,16 +25,20 @@ module RuboCop
|
|
|
25
25
|
MSG = 'Include a copyright notice matching /%<notice>s/ before any code.'
|
|
26
26
|
AUTOCORRECT_EMPTY_WARNING = 'An AutocorrectNotice must be defined in your RuboCop config'
|
|
27
27
|
|
|
28
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
28
29
|
def on_new_investigation
|
|
29
30
|
return if notice.empty? || notice_found?(processed_source)
|
|
30
31
|
|
|
31
|
-
verify_autocorrect_notice!
|
|
32
32
|
message = format(MSG, notice: notice)
|
|
33
33
|
if processed_source.blank?
|
|
34
34
|
add_global_offense(message)
|
|
35
35
|
else
|
|
36
36
|
offense_range = source_range(processed_source.buffer, 1, 0)
|
|
37
37
|
add_offense(offense_range, message: message) do |corrector|
|
|
38
|
+
next unless autocorrect?
|
|
39
|
+
|
|
40
|
+
verify_autocorrect_notice!
|
|
41
|
+
|
|
38
42
|
autocorrect(corrector)
|
|
39
43
|
end
|
|
40
44
|
end
|
|
@@ -46,15 +50,16 @@ module RuboCop
|
|
|
46
50
|
token = insert_notice_before(processed_source)
|
|
47
51
|
range = token.nil? ? range_between(0, 0) : token.pos
|
|
48
52
|
|
|
49
|
-
corrector.insert_before(range, "#{
|
|
53
|
+
corrector.insert_before(range, "#{normalized_autocorrect_notice}\n")
|
|
50
54
|
end
|
|
51
55
|
|
|
52
|
-
def
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
def normalized_autocorrect_notice
|
|
57
|
+
autocorrect_notice.lines.map do |line|
|
|
58
|
+
next line if line.start_with?('#')
|
|
59
|
+
next "#\n" if line.chomp.empty?
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
"# #{line}"
|
|
62
|
+
end.join
|
|
58
63
|
end
|
|
59
64
|
|
|
60
65
|
def verify_autocorrect_notice!
|
|
@@ -62,8 +67,7 @@ module RuboCop
|
|
|
62
67
|
raise Warning, "#{cop_name}: #{AUTOCORRECT_EMPTY_WARNING}"
|
|
63
68
|
end
|
|
64
69
|
|
|
65
|
-
|
|
66
|
-
return if autocorrect_notice.gsub(/^# */, '').match?(regex)
|
|
70
|
+
return if normalized_autocorrect_notice.gsub(/^# */, '').match?(notice_regexp)
|
|
67
71
|
|
|
68
72
|
message = "AutocorrectNotice '#{autocorrect_notice}' must match Notice /#{notice}/"
|
|
69
73
|
raise Warning, "#{cop_name}: #{message}"
|
|
@@ -91,18 +95,29 @@ module RuboCop
|
|
|
91
95
|
end
|
|
92
96
|
|
|
93
97
|
def notice_found?(processed_source)
|
|
94
|
-
notice_regexp = Regexp.new(notice.lines.map(&:strip).join)
|
|
95
98
|
multiline_notice = +''
|
|
96
99
|
processed_source.tokens.each do |token|
|
|
97
100
|
break unless token.comment?
|
|
98
101
|
|
|
99
|
-
multiline_notice << token.text.sub(/\A# */, '')
|
|
102
|
+
multiline_notice << token.text.sub(/\A# */, '') << "\n"
|
|
100
103
|
|
|
101
104
|
break if notice_regexp.match?(token.text)
|
|
102
105
|
end
|
|
103
106
|
|
|
104
107
|
multiline_notice.match?(notice_regexp)
|
|
105
108
|
end
|
|
109
|
+
|
|
110
|
+
def notice_regexp
|
|
111
|
+
@notice_regexp ||= Regexp.new(notice.sub(/\A(?:\\A|\^)?#(?:\\s[*+?]?|\s)*/, ''))
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def notice
|
|
115
|
+
cop_config['Notice']
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def autocorrect_notice
|
|
119
|
+
cop_config['AutocorrectNotice']
|
|
120
|
+
end
|
|
106
121
|
end
|
|
107
122
|
end
|
|
108
123
|
end
|
|
@@ -4,11 +4,16 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for inheritance from `Data.define` to avoid creating the anonymous parent class.
|
|
7
|
+
# Inheriting from `Data.define` adds a superfluous level in inheritance tree.
|
|
7
8
|
#
|
|
8
9
|
# @safety
|
|
9
10
|
# Autocorrection is unsafe because it will change the inheritance
|
|
10
11
|
# tree (e.g. return value of `Module#ancestors`) of the constant.
|
|
11
12
|
#
|
|
13
|
+
# It is also unsafe because constants that the class body resolves through its
|
|
14
|
+
# ancestors (e.g. one provided by an included module) fall out of scope inside
|
|
15
|
+
# the block.
|
|
16
|
+
#
|
|
12
17
|
# @example
|
|
13
18
|
# # bad
|
|
14
19
|
# class Person < Data.define(:first_name, :last_name)
|
|
@@ -17,12 +22,18 @@ module RuboCop
|
|
|
17
22
|
# end
|
|
18
23
|
# end
|
|
19
24
|
#
|
|
25
|
+
# Person.ancestors
|
|
26
|
+
# # => [Person, #<Class:0x000000010b4e14a0>, Data, (...)]
|
|
27
|
+
#
|
|
20
28
|
# # good
|
|
21
29
|
# Person = Data.define(:first_name, :last_name) do
|
|
22
30
|
# def age
|
|
23
31
|
# 42
|
|
24
32
|
# end
|
|
25
33
|
# end
|
|
34
|
+
#
|
|
35
|
+
# Person.ancestors
|
|
36
|
+
# # => [Person, Data, (...)]
|
|
26
37
|
class DataInheritance < Base
|
|
27
38
|
include RangeHelp
|
|
28
39
|
extend AutoCorrector
|
|
@@ -35,6 +46,7 @@ module RuboCop
|
|
|
35
46
|
|
|
36
47
|
def on_class(node)
|
|
37
48
|
return unless data_define?(node.parent_class)
|
|
49
|
+
return if defines_constants?(node.body)
|
|
38
50
|
|
|
39
51
|
add_offense(node.parent_class) do |corrector|
|
|
40
52
|
corrector.remove(range_with_surrounding_space(node.loc.keyword, newlines: false))
|
|
@@ -52,8 +64,21 @@ module RuboCop
|
|
|
52
64
|
|
|
53
65
|
private
|
|
54
66
|
|
|
67
|
+
# Constants, including nested classes and modules, are scoped to the class when they
|
|
68
|
+
# are defined in a class body, but leak into the enclosing namespace once moved into a
|
|
69
|
+
# `Data.define` block, so such a class cannot be rewritten as an assignment.
|
|
70
|
+
def defines_constants?(class_body)
|
|
71
|
+
return false unless class_body
|
|
72
|
+
|
|
73
|
+
class_body.each_node(:casgn, :class, :module).any?
|
|
74
|
+
end
|
|
75
|
+
|
|
55
76
|
def correct_parent(parent, corrector)
|
|
56
77
|
if parent.block_type?
|
|
78
|
+
# Convert a brace block to `do`, so the class's own `end` closes it
|
|
79
|
+
# once the closing delimiter is removed; otherwise a dangling `{` is
|
|
80
|
+
# left behind, producing invalid Ruby.
|
|
81
|
+
corrector.replace(parent.loc.begin, 'do') if parent.braces?
|
|
57
82
|
corrector.remove(range_with_surrounding_space(parent.loc.end, newlines: false))
|
|
58
83
|
elsif (class_node = parent.parent).body.nil?
|
|
59
84
|
corrector.remove(range_for_empty_class_body(class_node, parent))
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for consistent usage of the `
|
|
7
|
-
# `
|
|
6
|
+
# Checks for consistent usage of the `Time` class over the
|
|
7
|
+
# `DateTime` class. This cop is disabled by default since these classes,
|
|
8
8
|
# although highly overlapping, have particularities that make them not
|
|
9
9
|
# replaceable in certain situations when dealing with multiple timezones
|
|
10
10
|
# and/or DST.
|
|
@@ -59,12 +59,12 @@ module RuboCop
|
|
|
59
59
|
|
|
60
60
|
# @!method historic_date?(node)
|
|
61
61
|
def_node_matcher :historic_date?, <<~PATTERN
|
|
62
|
-
(
|
|
62
|
+
(call _ _ _ (const (const {nil? (cbase)} :Date) _))
|
|
63
63
|
PATTERN
|
|
64
64
|
|
|
65
65
|
# @!method to_datetime?(node)
|
|
66
66
|
def_node_matcher :to_datetime?, <<~PATTERN
|
|
67
|
-
(call
|
|
67
|
+
(call !nil? :to_datetime)
|
|
68
68
|
PATTERN
|
|
69
69
|
|
|
70
70
|
def on_send(node)
|
|
@@ -25,8 +25,9 @@ module RuboCop
|
|
|
25
25
|
# # good
|
|
26
26
|
# def foo = do_something
|
|
27
27
|
#
|
|
28
|
-
# # good
|
|
28
|
+
# # good - without parentheses it's a syntax error
|
|
29
29
|
# def foo() do_something end
|
|
30
|
+
# def foo()=do_something
|
|
30
31
|
#
|
|
31
32
|
# # bad
|
|
32
33
|
# def Baz.foo()
|
|
@@ -38,19 +39,35 @@ module RuboCop
|
|
|
38
39
|
# do_something
|
|
39
40
|
# end
|
|
40
41
|
class DefWithParentheses < Base
|
|
42
|
+
include RangeHelp
|
|
41
43
|
extend AutoCorrector
|
|
42
44
|
|
|
43
45
|
MSG = "Omit the parentheses in defs when the method doesn't accept any arguments."
|
|
44
46
|
|
|
45
47
|
def on_def(node)
|
|
46
|
-
return
|
|
47
|
-
return
|
|
48
|
+
return unless !node.arguments? && (arguments_range = node.arguments.source_range)
|
|
49
|
+
return if parentheses_required?(node, arguments_range)
|
|
48
50
|
|
|
49
|
-
add_offense(
|
|
50
|
-
corrector.remove(
|
|
51
|
+
add_offense(arguments_range) do |corrector|
|
|
52
|
+
corrector.remove(arguments_range)
|
|
51
53
|
end
|
|
52
54
|
end
|
|
53
55
|
alias on_defs on_def
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def parentheses_required?(node, arguments_range)
|
|
60
|
+
end_pos = arguments_range.end.end_pos
|
|
61
|
+
token_after_argument = range_between(end_pos, end_pos + 1).source
|
|
62
|
+
|
|
63
|
+
# A `;` after the parentheses (e.g. `def foo(); end`) already separates the
|
|
64
|
+
# signature from the body, so the parentheses can be removed (`def foo; end`).
|
|
65
|
+
return false if token_after_argument == ';'
|
|
66
|
+
|
|
67
|
+
return true if node.single_line? && !node.endless?
|
|
68
|
+
|
|
69
|
+
token_after_argument == '='
|
|
70
|
+
end
|
|
54
71
|
end
|
|
55
72
|
end
|
|
56
73
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
#
|
|
6
|
+
# Checks for chained `dig` calls that can be collapsed into a single `dig`.
|
|
7
7
|
#
|
|
8
8
|
# @safety
|
|
9
9
|
# This cop is unsafe because it cannot be guaranteed that the receiver
|
|
@@ -79,6 +79,11 @@ module RuboCop
|
|
|
79
79
|
corrector.replace(range, replacement)
|
|
80
80
|
|
|
81
81
|
comments_in_range(node).reverse_each do |comment|
|
|
82
|
+
# Only relocate comments that the replacement destroys. A trailing
|
|
83
|
+
# comment after the chain survives in place, so moving it would
|
|
84
|
+
# duplicate it (and splitting the line drops the indentation).
|
|
85
|
+
next if comment.source_range.begin_pos >= range.end_pos
|
|
86
|
+
|
|
82
87
|
corrector.insert_before(node, "#{comment.source}\n")
|
|
83
88
|
end
|
|
84
89
|
end
|
|
@@ -35,6 +35,10 @@ module RuboCop
|
|
|
35
35
|
PATTERN
|
|
36
36
|
|
|
37
37
|
def on_send(node)
|
|
38
|
+
# A trailing block (e.g. `Dir.each_child(path).none? { ... }`) changes
|
|
39
|
+
# the meaning and is not equivalent to `Dir.empty?`.
|
|
40
|
+
return if node.block_literal?
|
|
41
|
+
|
|
38
42
|
offensive?(node) do |const_node, arg_node|
|
|
39
43
|
replacement = "#{bang(node)}#{const_node.source}.empty?(#{arg_node.source})"
|
|
40
44
|
add_offense(node, message: format(MSG, replacement: replacement)) do |corrector|
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Checks for directive scopes that can be expressed with the tighter
|
|
7
|
+
# next-statement forms: a `disable`/`enable` pair, an
|
|
8
|
+
# `enable`/`disable` pair, or a `push`/`pop` with signed arguments
|
|
9
|
+
# wrapping exactly one statement. A statement-scoped directive cannot
|
|
10
|
+
# drift as the surrounding code changes and needs no closing boundary.
|
|
11
|
+
#
|
|
12
|
+
# @safety
|
|
13
|
+
# The autocorrection is unsafe because the suppression scope shrinks
|
|
14
|
+
# from the whole region to the statement: offenses of the suppressed
|
|
15
|
+
# cops located on the directive lines themselves resurface.
|
|
16
|
+
#
|
|
17
|
+
# @example
|
|
18
|
+
# # bad
|
|
19
|
+
# # rubocop:disable Metrics/AbcSize
|
|
20
|
+
# def foo
|
|
21
|
+
# end
|
|
22
|
+
# # rubocop:enable Metrics/AbcSize
|
|
23
|
+
#
|
|
24
|
+
# # good
|
|
25
|
+
# # rubocop:disable-next Metrics/AbcSize
|
|
26
|
+
# def foo
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
# # bad
|
|
30
|
+
# # rubocop:push -Metrics/AbcSize
|
|
31
|
+
# def foo
|
|
32
|
+
# end
|
|
33
|
+
# # rubocop:pop
|
|
34
|
+
#
|
|
35
|
+
# # good
|
|
36
|
+
# # rubocop:disable-next Metrics/AbcSize
|
|
37
|
+
# def foo
|
|
38
|
+
# end
|
|
39
|
+
#
|
|
40
|
+
# # bad
|
|
41
|
+
# # rubocop:disable Metrics/AbcSize
|
|
42
|
+
# # rubocop:push +Metrics/AbcSize
|
|
43
|
+
# def foo
|
|
44
|
+
# end
|
|
45
|
+
# # rubocop:pop
|
|
46
|
+
# # rubocop:enable Metrics/AbcSize
|
|
47
|
+
#
|
|
48
|
+
# # good
|
|
49
|
+
# # rubocop:disable Metrics/AbcSize
|
|
50
|
+
# # rubocop:enable-next Metrics/AbcSize
|
|
51
|
+
# def foo
|
|
52
|
+
# end
|
|
53
|
+
# # rubocop:enable Metrics/AbcSize
|
|
54
|
+
#
|
|
55
|
+
# # good - the region spans more than one statement
|
|
56
|
+
# # rubocop:disable Metrics/AbcSize
|
|
57
|
+
# def foo
|
|
58
|
+
# end
|
|
59
|
+
#
|
|
60
|
+
# def bar
|
|
61
|
+
# end
|
|
62
|
+
# # rubocop:enable Metrics/AbcSize
|
|
63
|
+
#
|
|
64
|
+
class DirectiveScope < Base
|
|
65
|
+
include RangeHelp
|
|
66
|
+
extend AutoCorrector
|
|
67
|
+
|
|
68
|
+
MSG_PAIR = 'Use `%<mode>s-next` instead of a `%<mode>s`/`enable` pair ' \
|
|
69
|
+
'around a single statement.'
|
|
70
|
+
MSG_ENABLE_PAIR = 'Use `enable-next` instead of an `enable`/`disable` pair ' \
|
|
71
|
+
'around a single statement.'
|
|
72
|
+
MSG_PUSH_POP = 'Use `%<replacement>s` instead of `push`/`pop` around a single statement.'
|
|
73
|
+
|
|
74
|
+
def on_new_investigation
|
|
75
|
+
processed_source.comments.each do |comment|
|
|
76
|
+
directive = DirectiveComment.new(comment)
|
|
77
|
+
next unless comment_config.comment_only_line?(directive.line_number)
|
|
78
|
+
|
|
79
|
+
if plain_disable?(directive)
|
|
80
|
+
check_pair(directive)
|
|
81
|
+
elsif signed_push?(directive)
|
|
82
|
+
check_push_pop(directive)
|
|
83
|
+
elsif plain_enable?(directive)
|
|
84
|
+
check_enable_pair(directive)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def comment_config
|
|
92
|
+
processed_source.comment_config
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def plain_disable?(directive)
|
|
96
|
+
directive.disabled? && !directive.disable_next?
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def plain_enable?(directive)
|
|
100
|
+
directive.enabled? && !directive.enable_next? && !directive.all_cops?
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def signed_push?(directive)
|
|
104
|
+
directive.push? && !directive.signed_args.empty?
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def check_pair(directive)
|
|
108
|
+
enable = single_statement_closing_directive(directive)
|
|
109
|
+
return unless enable&.enabled?
|
|
110
|
+
return unless enable.raw_cop_names.sort == directive.raw_cop_names.sort
|
|
111
|
+
|
|
112
|
+
message = format(MSG_PAIR, mode: directive.mode)
|
|
113
|
+
add_offense(directive.comment, message: message) do |corrector|
|
|
114
|
+
convert_pair(corrector, directive, enable)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def convert_pair(corrector, directive, enable)
|
|
119
|
+
replacement = directive.comment.text.sub(/\b#{directive.mode}\b/,
|
|
120
|
+
"#{directive.mode}-next")
|
|
121
|
+
corrector.replace(directive.comment, replacement)
|
|
122
|
+
remove_line(corrector, enable.comment)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def check_push_pop(directive)
|
|
126
|
+
pop_line = balancing_pop_line(directive)
|
|
127
|
+
return unless pop_line && comment_config.comment_only_line?(pop_line)
|
|
128
|
+
return unless wraps_single_statement?(directive, pop_line)
|
|
129
|
+
|
|
130
|
+
pop_comment = processed_source.comment_at_line(pop_line)
|
|
131
|
+
replacement = push_replacement(directive)
|
|
132
|
+
message = format(MSG_PUSH_POP, replacement: replacement_mode(directive))
|
|
133
|
+
add_offense(directive.comment, message: message) do |corrector|
|
|
134
|
+
corrector.replace(directive.comment, replacement)
|
|
135
|
+
remove_line(corrector, pop_comment)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# The line of the `pop` balancing this `push`, taking nesting into
|
|
140
|
+
# account, or `nil` when the push is never popped.
|
|
141
|
+
def balancing_pop_line(push_directive)
|
|
142
|
+
depth = 0
|
|
143
|
+
each_directive_after(push_directive) do |directive|
|
|
144
|
+
if directive.push?
|
|
145
|
+
depth += 1
|
|
146
|
+
elsif directive.pop?
|
|
147
|
+
return directive.line_number if depth.zero?
|
|
148
|
+
|
|
149
|
+
depth -= 1
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
nil
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def each_directive_after(reference)
|
|
156
|
+
processed_source.comments.each do |comment|
|
|
157
|
+
directive = DirectiveComment.new(comment)
|
|
158
|
+
next unless directive.cop_names || directive.push? || directive.pop?
|
|
159
|
+
|
|
160
|
+
yield directive if directive.line_number > reference.line_number
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def replacement_mode(directive)
|
|
165
|
+
ops = directive.signed_args.keys.sort
|
|
166
|
+
if ops == ['-']
|
|
167
|
+
'disable-next'
|
|
168
|
+
elsif ops == ['+']
|
|
169
|
+
'enable-next'
|
|
170
|
+
else
|
|
171
|
+
'next'
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def push_replacement(directive)
|
|
176
|
+
text = case replacement_mode(directive)
|
|
177
|
+
when 'disable-next'
|
|
178
|
+
"# rubocop:disable-next #{directive.signed_args['-'].join(', ')}"
|
|
179
|
+
when 'enable-next'
|
|
180
|
+
"# rubocop:enable-next #{directive.signed_args['+'].join(', ')}"
|
|
181
|
+
else
|
|
182
|
+
"# rubocop:next #{directive.cops}"
|
|
183
|
+
end
|
|
184
|
+
reason = directive.reason
|
|
185
|
+
reason ? "#{text} -- #{reason}" : text
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# An `enable`/`disable` pair around one statement inside a disabled
|
|
189
|
+
# region re-enables the cops for just that statement - `enable-next`
|
|
190
|
+
# says the same without the closing boundary. The pair only counts
|
|
191
|
+
# when the `enable` really closed open disables (otherwise the
|
|
192
|
+
# trailing `disable` opens a new region and the conversion would
|
|
193
|
+
# change what is covered).
|
|
194
|
+
def check_enable_pair(directive)
|
|
195
|
+
closing = enable_pair_closing(directive)
|
|
196
|
+
return unless closing
|
|
197
|
+
|
|
198
|
+
add_offense(directive.comment, message: MSG_ENABLE_PAIR) do |corrector|
|
|
199
|
+
corrector.replace(directive.comment,
|
|
200
|
+
directive.comment.text.sub(/\benable\b/, 'enable-next'))
|
|
201
|
+
remove_line(corrector, closing.comment)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def enable_pair_closing(directive)
|
|
206
|
+
scope = comment_config.statement_scope_after(directive.line_number)
|
|
207
|
+
return nil unless scope && scope.begin == directive.line_number + 1
|
|
208
|
+
|
|
209
|
+
closing = re_disable_below(directive, scope.end + 1)
|
|
210
|
+
closing if closing && closed_open_disables?(directive, closing)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def re_disable_below(directive, line)
|
|
214
|
+
return nil unless comment_config.comment_only_line?(line)
|
|
215
|
+
|
|
216
|
+
comment = processed_source.comment_at_line(line)
|
|
217
|
+
return nil unless comment
|
|
218
|
+
|
|
219
|
+
closing = DirectiveComment.new(comment)
|
|
220
|
+
return nil unless closing.disabled? && !closing.disable_next?
|
|
221
|
+
return nil unless closing.raw_cop_names.sort == directive.raw_cop_names.sort
|
|
222
|
+
|
|
223
|
+
closing
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Every cop of the pair must have a range the `enable` closed and a
|
|
227
|
+
# range the trailing `disable` reopened - otherwise the `enable` was
|
|
228
|
+
# not inside a disabled region and the conversion would change what
|
|
229
|
+
# is covered.
|
|
230
|
+
def closed_open_disables?(directive, closing)
|
|
231
|
+
directive.cop_names.all? do |cop|
|
|
232
|
+
ranges = comment_config.cop_disabled_line_ranges[qualified_name(cop)]
|
|
233
|
+
ranges && closed_at?(ranges, directive.line_number) && reopened_by?(ranges, closing)
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def closed_at?(ranges, line)
|
|
238
|
+
ranges.any? { |range| range.end == line }
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def reopened_by?(ranges, closing)
|
|
242
|
+
ranges.any? do |range|
|
|
243
|
+
range.respond_to?(:directive) && range.directive.comment.equal?(closing.comment)
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def qualified_name(cop_name)
|
|
248
|
+
Registry.qualified_cop_name(cop_name.strip, processed_source.file_path,
|
|
249
|
+
correct_namespace: false)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# The directive closing this one's scope, when that scope wraps
|
|
253
|
+
# exactly one statement - `nil` otherwise.
|
|
254
|
+
def single_statement_closing_directive(directive)
|
|
255
|
+
closing_line = single_closing_line(directive)
|
|
256
|
+
return nil unless closing_line
|
|
257
|
+
|
|
258
|
+
closing_comment = processed_source.comment_at_line(closing_line)
|
|
259
|
+
return nil unless closing_comment
|
|
260
|
+
return nil unless wraps_single_statement?(directive, closing_line)
|
|
261
|
+
|
|
262
|
+
DirectiveComment.new(closing_comment)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# The single line on which every disabled range opened by this
|
|
266
|
+
# directive ends, or `nil` when the ranges disagree or never close.
|
|
267
|
+
# For a `disable` that is the `enable` line; for a `push` it is the
|
|
268
|
+
# line before the `pop`.
|
|
269
|
+
def single_closing_line(directive)
|
|
270
|
+
ranges = ranges_opened_by(directive)
|
|
271
|
+
return nil if ranges.empty?
|
|
272
|
+
|
|
273
|
+
ends = ranges.map(&:end).uniq
|
|
274
|
+
return nil unless ends.size == 1 && ends.first.to_f.finite?
|
|
275
|
+
|
|
276
|
+
ends.first
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def ranges_opened_by(directive)
|
|
280
|
+
comment_config.cop_disabled_line_ranges.each_value.flat_map do |ranges|
|
|
281
|
+
ranges.select do |range|
|
|
282
|
+
range.respond_to?(:directive) && range.directive.comment.equal?(directive.comment)
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# The region wraps a single statement only when the directive sits
|
|
288
|
+
# immediately above it and the closing directive immediately below -
|
|
289
|
+
# any other line inside the region (a comment, a blank line) may
|
|
290
|
+
# carry offenses of the suppressed cops that the tighter scope
|
|
291
|
+
# would no longer cover.
|
|
292
|
+
def wraps_single_statement?(directive, closing_line)
|
|
293
|
+
scope = comment_config.statement_scope_after(directive.line_number)
|
|
294
|
+
|
|
295
|
+
!scope.nil? && scope.begin == directive.line_number + 1 && scope.end + 1 == closing_line
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def remove_line(corrector, comment)
|
|
299
|
+
corrector.remove(range_by_whole_lines(comment.source_range, include_final_newline: true))
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
end
|