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
data/lib/rubocop/cli.rb
CHANGED
|
@@ -12,8 +12,8 @@ module RuboCop
|
|
|
12
12
|
STATUS_INTERRUPTED = Signal.list['INT'] + 128
|
|
13
13
|
DEFAULT_PARALLEL_OPTIONS = %i[
|
|
14
14
|
color config debug display_style_guide display_time display_only_fail_level_offenses
|
|
15
|
-
display_only_failed editor_mode except extra_details fail_level fix_layout format
|
|
16
|
-
ignore_disable_comments lint only only_guide_cops require safe
|
|
15
|
+
display_only_failed editor_mode except extra_details fail_level fix_layout format formatters
|
|
16
|
+
ignore_disable_comments lint only only_guide_cops out preview require safe
|
|
17
17
|
autocorrect safe_autocorrect autocorrect_all
|
|
18
18
|
].freeze
|
|
19
19
|
|
|
@@ -35,8 +35,10 @@ module RuboCop
|
|
|
35
35
|
# @param args [Array<String>] command line arguments
|
|
36
36
|
# @return [Integer] UNIX exit code
|
|
37
37
|
#
|
|
38
|
-
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
38
|
+
# rubocop:disable-next Metrics/MethodLength, Metrics/AbcSize
|
|
39
39
|
def run(args = ARGV)
|
|
40
|
+
time_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
41
|
+
|
|
40
42
|
@options, paths = Options.new.parse(args)
|
|
41
43
|
@env = Environment.new(@options, @config_store, paths)
|
|
42
44
|
|
|
@@ -48,11 +50,12 @@ module RuboCop
|
|
|
48
50
|
validate_options_vs_config
|
|
49
51
|
parallel_by_default!
|
|
50
52
|
apply_default_formatter
|
|
53
|
+
report_pending_cops
|
|
51
54
|
execute_runners
|
|
52
55
|
end
|
|
53
56
|
end
|
|
54
57
|
rescue ConfigNotFoundError, IncorrectCopNameError, OptionArgumentError => e
|
|
55
|
-
warn e.message
|
|
58
|
+
warn Rainbow(e.message).red
|
|
56
59
|
STATUS_ERROR
|
|
57
60
|
rescue RuboCop::Error => e
|
|
58
61
|
warn Rainbow("Error: #{e.message}").red
|
|
@@ -63,7 +66,7 @@ module RuboCop
|
|
|
63
66
|
STATUS_INTERRUPTED
|
|
64
67
|
rescue Finished
|
|
65
68
|
STATUS_SUCCESS
|
|
66
|
-
rescue OptionParser::
|
|
69
|
+
rescue OptionParser::ParseError => e
|
|
67
70
|
warn e.message
|
|
68
71
|
warn 'For usage information, use --help'
|
|
69
72
|
STATUS_ERROR
|
|
@@ -71,12 +74,16 @@ module RuboCop
|
|
|
71
74
|
warn e.message
|
|
72
75
|
warn e.backtrace
|
|
73
76
|
STATUS_ERROR
|
|
77
|
+
ensure
|
|
78
|
+
elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - time_start
|
|
79
|
+
if @options[:debug] || @options[:display_time]
|
|
80
|
+
puts "Finished in #{elapsed_time.round(5)} seconds"
|
|
81
|
+
end
|
|
74
82
|
end
|
|
75
|
-
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
76
83
|
|
|
77
84
|
private
|
|
78
85
|
|
|
79
|
-
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
86
|
+
# rubocop:disable-next Metrics/MethodLength, Metrics/AbcSize
|
|
80
87
|
def profile_if_needed
|
|
81
88
|
return yield unless @options[:profile]
|
|
82
89
|
|
|
@@ -108,7 +115,6 @@ module RuboCop
|
|
|
108
115
|
end
|
|
109
116
|
status
|
|
110
117
|
end
|
|
111
|
-
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
112
118
|
|
|
113
119
|
def require_gem(name)
|
|
114
120
|
require name
|
|
@@ -155,10 +161,14 @@ module RuboCop
|
|
|
155
161
|
|
|
156
162
|
def act_on_options
|
|
157
163
|
set_options_to_config_loader
|
|
164
|
+
set_options_to_pending_cops_reporter
|
|
158
165
|
handle_editor_mode
|
|
159
166
|
|
|
160
|
-
@config_store.
|
|
161
|
-
|
|
167
|
+
@config_store.apply_options!(@options)
|
|
168
|
+
# Set cache root after apply_options! to ensure force_default_config is applied first.
|
|
169
|
+
early_cache_root = ConfigLoader.cache_root(@options[:cache_root])
|
|
170
|
+
ConfigLoader.cache_root = ResultCache.cache_root(@config_store, @options[:cache_root])
|
|
171
|
+
warn_if_cache_root_changed(early_cache_root, ConfigLoader.cache_root)
|
|
162
172
|
|
|
163
173
|
handle_exiting_options
|
|
164
174
|
|
|
@@ -173,27 +183,38 @@ module RuboCop
|
|
|
173
183
|
|
|
174
184
|
def set_options_to_config_loader
|
|
175
185
|
ConfigLoader.debug = @options[:debug]
|
|
176
|
-
ConfigLoader.disable_pending_cops = @options[:disable_pending_cops]
|
|
177
|
-
ConfigLoader.enable_pending_cops = @options[:enable_pending_cops]
|
|
178
186
|
ConfigLoader.ignore_parent_exclusion = @options[:ignore_parent_exclusion]
|
|
179
187
|
ConfigLoader.ignore_unrecognized_cops = @options[:ignore_unrecognized_cops]
|
|
188
|
+
set_cop_selection_options_to_config_loader
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Options that decide which cops run, as opposed to how configuration is loaded.
|
|
192
|
+
def set_cop_selection_options_to_config_loader
|
|
193
|
+
ConfigLoader.disable_pending_cops = @options[:disable_pending_cops]
|
|
194
|
+
ConfigLoader.enable_pending_cops = @options[:enable_pending_cops]
|
|
195
|
+
ConfigLoader.enabled_by_default = @options[:enable_all_cops]
|
|
196
|
+
ConfigLoader.disabled_by_default = @options[:disable_all_cops]
|
|
197
|
+
ConfigLoader.preview = @options[:preview]
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def set_options_to_pending_cops_reporter
|
|
201
|
+
PendingCopsReporter.disable_pending_cops = @options[:disable_pending_cops]
|
|
202
|
+
PendingCopsReporter.enable_pending_cops = @options[:enable_pending_cops]
|
|
180
203
|
end
|
|
181
204
|
|
|
182
205
|
def handle_editor_mode
|
|
183
206
|
RuboCop::LSP.enable if @options[:editor_mode]
|
|
184
207
|
end
|
|
185
208
|
|
|
186
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
187
209
|
def handle_exiting_options
|
|
188
210
|
return unless Options::EXITING_OPTIONS.any? { |o| @options.key? o }
|
|
189
211
|
|
|
190
212
|
run_command(:version) if @options[:version] || @options[:verbose_version]
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
213
|
+
%i[show_cops list_enabled_cops_for show_docs_url lsp mcp].each do |name|
|
|
214
|
+
run_command(name) if @options[name]
|
|
215
|
+
end
|
|
194
216
|
raise Finished
|
|
195
217
|
end
|
|
196
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
197
218
|
|
|
198
219
|
def apply_default_formatter
|
|
199
220
|
# This must be done after the options have already been processed,
|
|
@@ -208,5 +229,25 @@ module RuboCop
|
|
|
208
229
|
[[formatter, @options[:output_path]]]
|
|
209
230
|
end
|
|
210
231
|
end
|
|
232
|
+
|
|
233
|
+
def report_pending_cops
|
|
234
|
+
PendingCopsReporter.warn_if_needed(@config_store.for_pwd)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def warn_if_cache_root_changed(early, desired)
|
|
238
|
+
return if early == desired
|
|
239
|
+
# Normalize paths to avoid false positives from symlink resolution differences
|
|
240
|
+
if File.exist?(early) && File.exist?(desired) &&
|
|
241
|
+
File.realpath(early) == File.realpath(desired)
|
|
242
|
+
return
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
warn Rainbow(
|
|
246
|
+
"Warning: Remote configuration cache files were stored in `#{early}` " \
|
|
247
|
+
"because a desired cache root (`#{desired}`) was not set at the top level. " \
|
|
248
|
+
'Consider setting `AllCops: CacheRootDirectory` in your toplevel configuration file, ' \
|
|
249
|
+
'using the `RUBOCOP_CACHE_ROOT` environment variable, or using CLI options.'
|
|
250
|
+
).yellow
|
|
251
|
+
end
|
|
211
252
|
end
|
|
212
253
|
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
class CommentConfig
|
|
5
|
+
# A disabled line range that remembers the directive comment that opened
|
|
6
|
+
# it. Value-equal to a plain `Range`, so consumers comparing or hashing
|
|
7
|
+
# ranges are unaffected.
|
|
8
|
+
# @api private
|
|
9
|
+
class DirectiveRange < Range
|
|
10
|
+
attr_reader :directive
|
|
11
|
+
|
|
12
|
+
def initialize(first_line, last_line, directive)
|
|
13
|
+
super(first_line, last_line)
|
|
14
|
+
@directive = directive
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# The per-cop state accumulated while analyzing directives: the disabled
|
|
19
|
+
# ranges so far, plus the line and directive of the currently open
|
|
20
|
+
# disable, if any.
|
|
21
|
+
# @api private
|
|
22
|
+
CopAnalysis = Struct.new(:line_ranges, :start_line_number, :start_directive) do
|
|
23
|
+
# The open range (if any) closed at the given line, appended to the
|
|
24
|
+
# accumulated ranges, each remembering the directive that opened it.
|
|
25
|
+
# Closing above the opening line (e.g. a `pop` directly below a
|
|
26
|
+
# statement whose disable a `next +Cop` suspended) yields no range.
|
|
27
|
+
def close(line)
|
|
28
|
+
return line_ranges if !start_line_number || line < start_line_number
|
|
29
|
+
|
|
30
|
+
line_ranges + [DirectiveRange.new(start_line_number, line, start_directive)]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
class CommentConfig
|
|
5
|
+
# Handling of next-statement directives (`disable-next`, `todo-next` and
|
|
6
|
+
# `next`): computing the statement scope they apply to and tracking
|
|
7
|
+
# directives that attached to nothing.
|
|
8
|
+
# The scope is the whole statement starting on the next line bearing
|
|
9
|
+
# code. Comment-only lines between the directive and the code chain (so
|
|
10
|
+
# several directives can stack), while a blank line breaks the attachment.
|
|
11
|
+
# @api private
|
|
12
|
+
module DisableNext
|
|
13
|
+
# Next-statement directives that affect nothing: nothing follows
|
|
14
|
+
# them, or they sit at the end of a code line.
|
|
15
|
+
def detached_next_directives
|
|
16
|
+
cop_disabled_line_ranges # ensure the analysis that collects them ran
|
|
17
|
+
@detached_next_directives
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# The line range of the statement a `disable-next` directive on the
|
|
21
|
+
# given line scopes to (or would scope to), or `nil` when no statement
|
|
22
|
+
# is attached. A directive is only honored on a comment-only line.
|
|
23
|
+
# Stacked directives share the target, so the computation is memoized.
|
|
24
|
+
# @api private
|
|
25
|
+
def statement_scope_after(line)
|
|
26
|
+
return nil unless comment_only_line?(line)
|
|
27
|
+
|
|
28
|
+
code_line = attached_code_line(line)
|
|
29
|
+
return nil unless code_line
|
|
30
|
+
|
|
31
|
+
(@statement_bounds ||= {})[code_line] ||= statement_bounds_at(code_line)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def apply_disable_next(analyses, directive)
|
|
37
|
+
bounds = statement_scope_after(directive.line_number)
|
|
38
|
+
return @detached_next_directives << directive unless bounds
|
|
39
|
+
|
|
40
|
+
range = DirectiveRange.new(bounds.begin, bounds.end, directive)
|
|
41
|
+
directive.cop_names.each do |cop_name|
|
|
42
|
+
add_next_range(analyses, qualified_cop_name(cop_name), range)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def add_next_range(analyses, cop_name, range)
|
|
47
|
+
analysis = analyses[cop_name]
|
|
48
|
+
analyses[cop_name] = CopAnalysis.new(analysis.line_ranges + [range],
|
|
49
|
+
analysis.start_line_number, analysis.start_directive)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Applies a `next` directive: `-` cops are disabled for the attached
|
|
53
|
+
# statement (exactly like `disable-next`), `+` cops have any open
|
|
54
|
+
# disable suspended for it. The `resolved_cops` come pre-expanded and
|
|
55
|
+
# qualified, mirroring `push`.
|
|
56
|
+
def apply_next_directive(analyses, resolved_cops, directive)
|
|
57
|
+
bounds = statement_scope_after(directive.line_number)
|
|
58
|
+
return @detached_next_directives << directive unless bounds
|
|
59
|
+
|
|
60
|
+
range = DirectiveRange.new(bounds.begin, bounds.end, directive)
|
|
61
|
+
resolved_cops.each do |op, cops|
|
|
62
|
+
cops.each do |cop|
|
|
63
|
+
if op == '-'
|
|
64
|
+
add_next_range(analyses, cop, range)
|
|
65
|
+
else
|
|
66
|
+
suspend_disable(analyses, cop, bounds)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Applies an `enable-next` directive: every listed cop (departments
|
|
73
|
+
# and `all` included) has any open disable suspended for the attached
|
|
74
|
+
# statement.
|
|
75
|
+
def apply_enable_next(analyses, directive)
|
|
76
|
+
bounds = statement_scope_after(directive.line_number)
|
|
77
|
+
return @detached_next_directives << directive unless bounds
|
|
78
|
+
|
|
79
|
+
directive.cop_names.each do |cop_name|
|
|
80
|
+
suspend_disable(analyses, qualified_cop_name(cop_name), bounds)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Punches a statement-sized hole into the currently open disable of the
|
|
85
|
+
# cop (whether opened by a directive or injected for a config-disabled
|
|
86
|
+
# cop): the open range closes just above the statement and reopens
|
|
87
|
+
# right below it, still attributed to its opening directive. Aligned
|
|
88
|
+
# with `push`, a `+` for a cop that is not disabled is a no-op.
|
|
89
|
+
def suspend_disable(analyses, cop, bounds)
|
|
90
|
+
analysis = analyses[cop]
|
|
91
|
+
return unless analysis.start_line_number
|
|
92
|
+
|
|
93
|
+
analyses[cop] = CopAnalysis.new(analysis.close(bounds.begin - 1),
|
|
94
|
+
bounds.end + 1, analysis.start_directive)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def attached_code_line(directive_line)
|
|
98
|
+
((directive_line + 1)..processed_source.lines.size).each do |line|
|
|
99
|
+
return line unless comment_only_line?(line)
|
|
100
|
+
return nil if processed_source[line - 1].blank?
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
nil
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def statement_bounds_at(line)
|
|
107
|
+
statement = statement_starting_at(line)
|
|
108
|
+
# A code line where no statement starts (e.g. a lone `end`) scopes
|
|
109
|
+
# the directive to that line alone.
|
|
110
|
+
return (line..line) unless statement
|
|
111
|
+
|
|
112
|
+
(line..statement_end_line(statement))
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def statement_start_line?(node, line)
|
|
116
|
+
# Synthetic nodes (e.g. parentheses-less argument lists) have no
|
|
117
|
+
# source range. `begin` nodes are sequences of statements, not
|
|
118
|
+
# statements themselves - taking one would scope the directive to
|
|
119
|
+
# everything up to the last statement of the sequence.
|
|
120
|
+
node.source_range && node.first_line == line && !node.begin_type?
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def statement_starting_at(line)
|
|
124
|
+
ast = processed_source.ast
|
|
125
|
+
return nil unless ast
|
|
126
|
+
|
|
127
|
+
ast.each_node.select { |node| statement_start_line?(node, line) }.max_by(&:last_line)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def statement_end_line(statement)
|
|
131
|
+
statement.each_node.filter_map do |node|
|
|
132
|
+
next unless node.source_range
|
|
133
|
+
|
|
134
|
+
heredoc?(node) ? node.loc.heredoc_end.line : node.last_line
|
|
135
|
+
end.max
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def heredoc?(node)
|
|
139
|
+
node.respond_to?(:heredoc?) && node.heredoc?
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
class CommentConfig
|
|
5
|
+
# Handling of `push`/`pop` directives and their signed cop arguments:
|
|
6
|
+
# saving and restoring the per-cop analysis state, and resolving the
|
|
7
|
+
# `+`/`-` argument lists (shared with the `next` directive).
|
|
8
|
+
# @api private
|
|
9
|
+
module PushPop
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def resolve_push_cops(directive)
|
|
13
|
+
directive.push_args.transform_values do |names|
|
|
14
|
+
names.flat_map { |name| expand_cop_name(name) }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def expand_cop_name(name)
|
|
19
|
+
registry = Cop::Registry.global
|
|
20
|
+
cops = registry.department?(name) ? registry.names_for_department(name) : [name]
|
|
21
|
+
cops.map { |c| qualified_cop_name(c) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def apply_push(analyses, resolved_cops, directive)
|
|
25
|
+
resolved_cops.each do |op, cops|
|
|
26
|
+
cops.each { |cop| apply_cop_op(analyses, op, cop, directive) }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def apply_cop_op(analyses, operation, cop, directive)
|
|
31
|
+
analysis = analyses[cop]
|
|
32
|
+
line = directive.line_number
|
|
33
|
+
if operation == '-' && !analysis.start_line_number
|
|
34
|
+
analyses[cop] = CopAnalysis.new(analysis.line_ranges, line, directive)
|
|
35
|
+
elsif operation == '+' && analysis.start_line_number
|
|
36
|
+
analyses[cop] = CopAnalysis.new(analysis.close(line), nil)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def pop_state(analyses, line)
|
|
41
|
+
restore_point = @stack.pop
|
|
42
|
+
(restore_point.keys | analyses.keys).each do |cop|
|
|
43
|
+
analyses[cop] = popped_analysis(analyses[cop], restore_point[cop], line)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def popped_analysis(current, restored, line)
|
|
48
|
+
ranges = current.close(line - 1)
|
|
49
|
+
return CopAnalysis.new(ranges, nil) unless restored&.start_line_number
|
|
50
|
+
|
|
51
|
+
CopAnalysis.new(ranges, line, restored.start_directive)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -5,6 +5,8 @@ module RuboCop
|
|
|
5
5
|
# and provides a way to check if each cop is enabled at arbitrary line.
|
|
6
6
|
class CommentConfig
|
|
7
7
|
extend SimpleForwardable
|
|
8
|
+
include DisableNext
|
|
9
|
+
include PushPop
|
|
8
10
|
|
|
9
11
|
CONFIG_DISABLED_LINE_RANGE_MIN = -Float::INFINITY
|
|
10
12
|
|
|
@@ -25,8 +27,6 @@ module RuboCop
|
|
|
25
27
|
end
|
|
26
28
|
end
|
|
27
29
|
|
|
28
|
-
CopAnalysis = Struct.new(:line_ranges, :start_line_number)
|
|
29
|
-
|
|
30
30
|
attr_reader :processed_source
|
|
31
31
|
|
|
32
32
|
def_delegators :@processed_source, :config, :registry
|
|
@@ -34,14 +34,26 @@ module RuboCop
|
|
|
34
34
|
def initialize(processed_source)
|
|
35
35
|
@processed_source = processed_source
|
|
36
36
|
@no_directives = !processed_source.raw_source.include?('rubocop')
|
|
37
|
+
@stack = []
|
|
38
|
+
@detached_next_directives = []
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
def cop_enabled_at_line?(cop, line_number)
|
|
42
|
+
cop_enabled_at_lines?(cop, line_number, line_number)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Whether the cop is enabled for all of the given line span. The cop
|
|
46
|
+
# counts as disabled for the span when any of its disabled ranges
|
|
47
|
+
# overlaps it, so that a directive on any line of a multi-line offense
|
|
48
|
+
# suppresses the offense.
|
|
49
|
+
def cop_enabled_at_lines?(cop, first_line, last_line)
|
|
40
50
|
cop = cop.cop_name if cop.respond_to?(:cop_name)
|
|
41
51
|
disabled_line_ranges = cop_disabled_line_ranges[cop]
|
|
42
52
|
return true unless disabled_line_ranges
|
|
43
53
|
|
|
44
|
-
disabled_line_ranges.none?
|
|
54
|
+
disabled_line_ranges.none? do |range|
|
|
55
|
+
range.end >= first_line && range.begin <= last_line
|
|
56
|
+
end
|
|
45
57
|
end
|
|
46
58
|
|
|
47
59
|
def cop_opted_in?(cop)
|
|
@@ -54,8 +66,8 @@ module RuboCop
|
|
|
54
66
|
|
|
55
67
|
def extra_enabled_comments
|
|
56
68
|
disable_count = Hash.new(0)
|
|
57
|
-
registry.
|
|
58
|
-
disable_count[
|
|
69
|
+
registry.disabled_names(config).each do |cop_name|
|
|
70
|
+
disable_count[cop_name] += 1
|
|
59
71
|
end
|
|
60
72
|
extra_enabled_comments_with_names(extras: Hash.new { |h, k| h[k] = [] }, names: disable_count)
|
|
61
73
|
end
|
|
@@ -64,11 +76,32 @@ module RuboCop
|
|
|
64
76
|
non_comment_token_line_numbers.none?(line_number)
|
|
65
77
|
end
|
|
66
78
|
|
|
79
|
+
# The names of the cops that are opted in by an `enable` comment directive
|
|
80
|
+
# or a `+` argument of a `push`/`next` directive, used to mobilize cops
|
|
81
|
+
# disabled in the config on demand.
|
|
82
|
+
#
|
|
83
|
+
# @api private
|
|
84
|
+
# @return [Set<String>]
|
|
85
|
+
def opt_in_cops
|
|
86
|
+
@opt_in_cops ||= begin
|
|
87
|
+
cops = Set.new
|
|
88
|
+
each_directive do |directive|
|
|
89
|
+
if directive.enabled?
|
|
90
|
+
cops.merge(directive.raw_cop_names) unless directive.all_cops?
|
|
91
|
+
elsif directive.push? || directive.next?
|
|
92
|
+
cops.merge(directive.signed_args.fetch('+', []))
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
cops
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
67
99
|
private
|
|
68
100
|
|
|
69
101
|
def extra_enabled_comments_with_names(extras:, names:)
|
|
70
102
|
each_directive do |directive|
|
|
71
103
|
next unless comment_only_line?(directive.line_number)
|
|
104
|
+
next if self_closing_directive?(directive)
|
|
72
105
|
|
|
73
106
|
if directive.enabled_all?
|
|
74
107
|
handle_enable_all(directive, names, extras)
|
|
@@ -80,43 +113,47 @@ module RuboCop
|
|
|
80
113
|
extras
|
|
81
114
|
end
|
|
82
115
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
cops = Set.new
|
|
86
|
-
each_directive do |directive|
|
|
87
|
-
next unless directive.enabled?
|
|
88
|
-
next if directive.all_cops?
|
|
89
|
-
|
|
90
|
-
cops.merge(directive.raw_cop_names)
|
|
91
|
-
end
|
|
92
|
-
cops
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def analyze # rubocop:todo Metrics/AbcSize
|
|
116
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
117
|
+
def analyze
|
|
97
118
|
return {} if @no_directives
|
|
98
119
|
|
|
99
120
|
analyses = Hash.new { |hash, key| hash[key] = CopAnalysis.new([], nil) }
|
|
100
121
|
inject_disabled_cops_directives(analyses)
|
|
101
122
|
|
|
102
123
|
each_directive do |directive|
|
|
103
|
-
directive.
|
|
104
|
-
|
|
105
|
-
|
|
124
|
+
if directive.push?
|
|
125
|
+
restore_point = analyses.transform_values(&:dup)
|
|
126
|
+
@stack.push(restore_point)
|
|
127
|
+
apply_push(analyses, resolve_push_cops(directive), directive)
|
|
128
|
+
elsif directive.pop?
|
|
129
|
+
pop_state(analyses, directive.line_number) if @stack.any?
|
|
130
|
+
elsif directive.disable_next?
|
|
131
|
+
apply_disable_next(analyses, directive)
|
|
132
|
+
elsif directive.next?
|
|
133
|
+
apply_next_directive(analyses, resolve_push_cops(directive), directive)
|
|
134
|
+
elsif directive.enable_next?
|
|
135
|
+
apply_enable_next(analyses, directive)
|
|
136
|
+
else
|
|
137
|
+
directive.cop_names.each do |cop_name|
|
|
138
|
+
cop_name = qualified_cop_name(cop_name)
|
|
139
|
+
analyses[cop_name] = analyze_cop(analyses[cop_name], directive)
|
|
140
|
+
end
|
|
106
141
|
end
|
|
107
142
|
end
|
|
108
143
|
|
|
109
144
|
analyses.each_with_object({}) do |element, hash|
|
|
110
145
|
cop_name, analysis = *element
|
|
146
|
+
next if prevent_directive_disabling?(cop_name)
|
|
147
|
+
|
|
111
148
|
hash[cop_name] = cop_line_ranges(analysis)
|
|
112
149
|
end
|
|
113
150
|
end
|
|
114
151
|
|
|
115
152
|
def inject_disabled_cops_directives(analyses)
|
|
116
|
-
registry.
|
|
117
|
-
analyses[
|
|
118
|
-
analyses[
|
|
119
|
-
DirectiveComment.new(ConfigDisabledCopDirectiveComment.new(
|
|
153
|
+
registry.disabled_names(config).each do |cop_name|
|
|
154
|
+
analyses[cop_name] = analyze_cop(
|
|
155
|
+
analyses[cop_name],
|
|
156
|
+
DirectiveComment.new(ConfigDisabledCopDirectiveComment.new(cop_name))
|
|
120
157
|
)
|
|
121
158
|
end
|
|
122
159
|
end
|
|
@@ -136,35 +173,21 @@ module RuboCop
|
|
|
136
173
|
return analysis unless directive.disabled?
|
|
137
174
|
|
|
138
175
|
line = directive.line_number
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
176
|
+
range = DirectiveRange.new(line, line, directive)
|
|
177
|
+
CopAnalysis.new(analysis.line_ranges + [range], analysis.start_line_number,
|
|
178
|
+
analysis.start_directive)
|
|
142
179
|
end
|
|
143
180
|
|
|
144
181
|
def analyze_disabled(analysis, directive)
|
|
145
|
-
|
|
146
|
-
start_line = analysis.start_line_number
|
|
147
|
-
|
|
148
|
-
# Cop already disabled on this line, so we end the current disabled
|
|
149
|
-
# range before we start a new range.
|
|
150
|
-
return CopAnalysis.new(analysis.line_ranges + [start_line..line], line) if start_line
|
|
151
|
-
|
|
152
|
-
CopAnalysis.new(analysis.line_ranges, line)
|
|
182
|
+
CopAnalysis.new(analysis.close(directive.line_number), directive.line_number, directive)
|
|
153
183
|
end
|
|
154
184
|
|
|
155
185
|
def analyze_rest(analysis, directive)
|
|
156
|
-
|
|
157
|
-
start_line = analysis.start_line_number
|
|
158
|
-
|
|
159
|
-
return CopAnalysis.new(analysis.line_ranges + [start_line..line], nil) if start_line
|
|
160
|
-
|
|
161
|
-
CopAnalysis.new(analysis.line_ranges, nil)
|
|
186
|
+
CopAnalysis.new(analysis.close(directive.line_number), nil)
|
|
162
187
|
end
|
|
163
188
|
|
|
164
189
|
def cop_line_ranges(analysis)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
analysis.line_ranges + [(analysis.start_line_number..Float::INFINITY)]
|
|
190
|
+
analysis.close(Float::INFINITY)
|
|
168
191
|
end
|
|
169
192
|
|
|
170
193
|
def each_directive
|
|
@@ -176,8 +199,29 @@ module RuboCop
|
|
|
176
199
|
end
|
|
177
200
|
end
|
|
178
201
|
|
|
202
|
+
# Push/pop and next-statement directives close themselves, so they
|
|
203
|
+
# play no part in the disable/enable pairing.
|
|
204
|
+
def self_closing_directive?(directive)
|
|
205
|
+
directive.push? || directive.pop? || directive.disable_next? ||
|
|
206
|
+
directive.next? || directive.enable_next?
|
|
207
|
+
end
|
|
208
|
+
|
|
179
209
|
def qualified_cop_name(cop_name)
|
|
180
|
-
|
|
210
|
+
# A directive naming a cop under the wrong department is not honored -
|
|
211
|
+
# the mistake is surfaced by `Lint/RedundantCopDisableDirective` (with a
|
|
212
|
+
# did-you-mean hint) instead of a stderr warning that is easy to miss
|
|
213
|
+
# and disappears entirely on cached runs.
|
|
214
|
+
Cop::Registry.qualified_cop_name(cop_name.strip, processed_source.file_path,
|
|
215
|
+
correct_namespace: false)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# `Style/DisableCopsWithinSourceCodeDirective` cannot be disabled via
|
|
219
|
+
# directive comments when it is explicitly enabled with `Enabled: true`.
|
|
220
|
+
# This prevents users from bypassing the cop by writing a disable
|
|
221
|
+
# directive that targets this cop itself.
|
|
222
|
+
def prevent_directive_disabling?(cop_name)
|
|
223
|
+
cop_name == DirectiveComment::STYLE_DISABLE_COPS_DIRECTIVE_COP &&
|
|
224
|
+
config.dig(cop_name, 'Enabled') == true
|
|
181
225
|
end
|
|
182
226
|
|
|
183
227
|
def non_comment_token_line_numbers
|
|
@@ -205,7 +249,7 @@ module RuboCop
|
|
|
205
249
|
directive.cop_names.each do |name|
|
|
206
250
|
if directive.disabled?
|
|
207
251
|
names[name] += 1
|
|
208
|
-
elsif
|
|
252
|
+
elsif names[name].positive?
|
|
209
253
|
names[name] -= 1
|
|
210
254
|
else
|
|
211
255
|
extras[directive.comment] << name
|