rubocop 1.71.1 → 1.92.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 +885 -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 +50 -5
- data/lib/rubocop/changed_files.rb +134 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +36 -4
- data/lib/rubocop/cli/command/cop_names.rb +57 -0
- data/lib/rubocop/cli/command/execute_runner.rb +54 -3
- data/lib/rubocop/cli/command/explain.rb +34 -0
- 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 +8 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +8 -10
- data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
- data/lib/rubocop/cli.rb +59 -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 +98 -45
- data/lib/rubocop/config.rb +137 -19
- data/lib/rubocop/config_finder.rb +1 -1
- data/lib/rubocop/config_loader.rb +75 -49
- data/lib/rubocop/config_loader_resolver.rb +124 -33
- 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 +9 -1
- 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 +75 -12
- data/lib/rubocop/cop/autocorrect_logic.rb +43 -17
- data/lib/rubocop/cop/badge.rb +9 -1
- data/lib/rubocop/cop/base.rb +128 -35
- data/lib/rubocop/cop/bundler/gem_comment.rb +5 -4
- data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
- data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -11
- data/lib/rubocop/cop/bundler.rb +19 -0
- data/lib/rubocop/cop/commissioner.rb +13 -11
- data/lib/rubocop/cop/cop_documentation.rb +81 -0
- data/lib/rubocop/cop/cop_explanation.rb +140 -0
- data/lib/rubocop/cop/corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +92 -11
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +22 -7
- data/lib/rubocop/cop/correctors/empty_line_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 +29 -2
- 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 +73 -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 +3 -4
- data/lib/rubocop/cop/exclude_limit.rb +31 -5
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
- 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 -9
- 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 +16 -20
- 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 +85 -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_context_config_parameter.rb +1 -7
- 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/style_detected_api_use.rb +1 -7
- 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 +86 -4
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +28 -10
- data/lib/rubocop/cop/layout/class_structure.rb +172 -36
- 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 +5 -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_after_multiline_condition.rb +14 -5
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +46 -21
- data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
- 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 +2 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +14 -3
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +17 -3
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
- 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 +20 -8
- data/lib/rubocop/cop/layout/extra_spacing.rb +109 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +57 -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 +25 -18
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +20 -18
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +5 -3
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +48 -3
- data/lib/rubocop/cop/layout/indentation_style.rb +5 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +159 -12
- data/lib/rubocop/cop/layout/leading_comment_space.rb +40 -1
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +10 -4
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
- data/lib/rubocop/cop/layout/line_length.rb +201 -30
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +69 -57
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +11 -1
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +63 -56
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +7 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +259 -40
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
- 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 +111 -7
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +29 -9
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
- data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +10 -4
- data/lib/rubocop/cop/layout/space_around_keyword.rb +20 -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 +5 -1
- 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 +55 -36
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +32 -8
- 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.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +3 -11
- 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 +22 -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 +152 -11
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +75 -37
- data/lib/rubocop/cop/lint/loop.rb +24 -2
- data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +245 -0
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +60 -23
- 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 +20 -11
- 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 +160 -39
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +53 -19
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +28 -6
- 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 +54 -11
- 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 +63 -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 +68 -22
- 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/class_length.rb +4 -2
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
- data/lib/rubocop/cop/metrics/method_length.rb +3 -2
- data/lib/rubocop/cop/metrics/module_length.rb +4 -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 +7 -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 +44 -23
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +10 -8
- data/lib/rubocop/cop/mixin/code_length.rb +10 -2
- 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 +13 -2
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/endless_method_body_help.rb +69 -0
- 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 +59 -17
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +52 -25
- 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/min_branches_count.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +10 -1
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +2 -2
- data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +79 -8
- data/lib/rubocop/cop/mixin/project_index_help.rb +203 -0
- data/lib/rubocop/cop/mixin/range_help.rb +16 -5
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +181 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +66 -10
- 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 +93 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +8 -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/heredoc_delimiter_case.rb +9 -2
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
- 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} +65 -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 +108 -9
- data/lib/rubocop/cop/registry.rb +234 -65
- 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 +45 -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 +54 -13
- data/lib/rubocop/cop/style/accessor_grouping.rb +47 -10
- data/lib/rubocop/cop/style/alias.rb +33 -8
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
- data/lib/rubocop/cop/style/and_or.rb +6 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +52 -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 +8 -6
- 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 +13 -5
- data/lib/rubocop/cop/style/block_delimiters.rb +71 -40
- data/lib/rubocop/cop/style/case_equality.rb +29 -15
- data/lib/rubocop/cop/style/case_like_if.rb +12 -11
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +179 -27
- data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -14
- data/lib/rubocop/cop/style/class_methods_definitions.rb +19 -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 +88 -9
- 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 +53 -9
- data/lib/rubocop/cop/style/conditional_assignment.rb +58 -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 +184 -20
- 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 +14 -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 +12 -3
- data/lib/rubocop/cop/style/empty_method.rb +15 -9
- 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 +252 -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 +52 -8
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +62 -9
- 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 +43 -15
- data/lib/rubocop/cop/style/for.rb +48 -1
- data/lib/rubocop/cop/style/format_string.rb +44 -9
- data/lib/rubocop/cop/style/format_string_token.rb +86 -16
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +5 -3
- 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 +41 -24
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
- data/lib/rubocop/cop/style/hash_conversion.rb +52 -16
- 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 +128 -0
- data/lib/rubocop/cop/style/hash_slice.rb +16 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +23 -6
- 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 +39 -11
- data/lib/rubocop/cop/style/if_inside_else.rb +46 -21
- data/lib/rubocop/cop/style/if_unless_modifier.rb +90 -66
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +19 -19
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +61 -8
- 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 +34 -8
- 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 +150 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +23 -11
- data/lib/rubocop/cop/style/lambda.rb +30 -1
- data/lib/rubocop/cop/style/lambda_call.rb +31 -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 +6 -4
- 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 +75 -24
- 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 +58 -6
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +36 -8
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
- data/lib/rubocop/cop/style/method_def_parentheses.rb +36 -8
- data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
- data/lib/rubocop/cop/style/missing_else.rb +7 -1
- 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 +47 -5
- data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
- data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +15 -22
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
- data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
- data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +139 -13
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +3 -3
- data/lib/rubocop/cop/style/negative_array_index.rb +228 -0
- data/lib/rubocop/cop/style/nested_modifier.rb +36 -12
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
- data/lib/rubocop/cop/style/next.rb +68 -10
- data/lib/rubocop/cop/style/nil_comparison.rb +53 -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 +12 -3
- 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 +22 -6
- 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 +35 -15
- 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 +18 -3
- 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 +216 -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 +58 -6
- data/lib/rubocop/cop/style/redundant_condition.rb +93 -18
- 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 +17 -3
- data/lib/rubocop/cop/style/redundant_each.rb +4 -5
- data/lib/rubocop/cop/style/redundant_exception.rb +22 -4
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +11 -11
- 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 +12 -3
- 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 +176 -83
- data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +15 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +27 -7
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +16 -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 +107 -29
- data/lib/rubocop/cop/style/require_order.rb +9 -0
- data/lib/rubocop/cop/style/rescue_modifier.rb +10 -12
- data/lib/rubocop/cop/style/return_nil.rb +19 -4
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
- 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 +19 -13
- 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 +13 -16
- data/lib/rubocop/cop/style/semicolon.rb +56 -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 +28 -11
- 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 +32 -6
- data/lib/rubocop/cop/style/static_class.rb +21 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +38 -16
- 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 +7 -6
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +34 -14
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +34 -1
- 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 +35 -32
- 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 +26 -12
- data/lib/rubocop/cop/style/yoda_expression.rb +11 -2
- 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 +172 -49
- 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 +8 -4
- 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 +42 -11
- 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/base_formatter.rb +22 -0
- 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 +7 -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 +82 -7
- 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 +5 -4
- data/lib/rubocop/formatter/pacman_formatter.rb +5 -2
- data/lib/rubocop/formatter/sarif_formatter.rb +186 -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 +5 -4
- 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 +66 -15
- data/lib/rubocop/lsp/server.rb +4 -2
- data/lib/rubocop/lsp/stdin_runner.rb +38 -19
- data/lib/rubocop/lsp.rb +5 -2
- data/lib/rubocop/magic_comment.rb +55 -0
- data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
- data/lib/rubocop/mcp/explain_tool.rb +68 -0
- data/lib/rubocop/mcp/scope.rb +65 -0
- data/lib/rubocop/mcp/server.rb +307 -0
- data/lib/rubocop/mcp/source_files.rb +35 -0
- data/lib/rubocop/offense_limit.rb +30 -0
- data/lib/rubocop/options.rb +166 -23
- data/lib/rubocop/path_util.rb +20 -5
- data/lib/rubocop/pending_cops_reporter.rb +51 -0
- data/lib/rubocop/plugin/configuration_integrator.rb +153 -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 +18 -13
- data/lib/rubocop/result_cache.rb +110 -65
- 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 +368 -106
- 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/util.rb +69 -0
- data/lib/rubocop/version.rb +48 -10
- data/lib/rubocop.rb +35 -682
- data/lib/ruby_lsp/rubocop/addon.rb +28 -17
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
- metadata +129 -21
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +0 -50
|
@@ -0,0 +1,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
|
|
@@ -1,17 +1,45 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# rubocop:disable Lint/RedundantCopDisableDirective
|
|
3
|
+
# rubocop:disable Lint/RedundantCopDisableDirective -- the examples below read as real directives
|
|
4
4
|
|
|
5
5
|
module RuboCop
|
|
6
6
|
module Cop
|
|
7
7
|
module Style
|
|
8
8
|
# Detects comments to enable/disable RuboCop.
|
|
9
|
-
# This is useful if want to make sure that every RuboCop error gets fixed
|
|
9
|
+
# This is useful if you want to make sure that every RuboCop error gets fixed
|
|
10
10
|
# and not quickly disabled with a comment.
|
|
11
11
|
#
|
|
12
12
|
# Specific cops can be allowed with the `AllowedCops` configuration. Note that
|
|
13
13
|
# if this configuration is set, `rubocop:disable all` is still disallowed.
|
|
14
14
|
#
|
|
15
|
+
# `AllowedCops` and `DisallowedCops` accept cop names and department names
|
|
16
|
+
# alike. Listing a cop does not cover its whole department: a directive
|
|
17
|
+
# disabling `Metrics` is broader than one disabling `Metrics/AbcSize`.
|
|
18
|
+
#
|
|
19
|
+
# Alternatively, specific cops can be disallowed with the `DisallowedCops`
|
|
20
|
+
# configuration. When `DisallowedCops` is set, only directives for the listed
|
|
21
|
+
# cops (and `all`) will be flagged. This is useful when you want
|
|
22
|
+
# to protect a small set of critical cops from being disabled rather than
|
|
23
|
+
# allowlisting all other cops. `AllowedCops` and `DisallowedCops` should not
|
|
24
|
+
# both be set at the same time; if `DisallowedCops` is set, it takes precedence.
|
|
25
|
+
#
|
|
26
|
+
# `AllowedDirectives` names directive forms - `disable`, `todo`,
|
|
27
|
+
# `disable-next`, `todo-next`, `push`, `next` - and exempts them from the
|
|
28
|
+
# cop entirely. `rubocop:todo` is the usual candidate, since
|
|
29
|
+
# `--disable-uncorrectable` generates those and they record debt rather
|
|
30
|
+
# than a decision someone should be asked to justify.
|
|
31
|
+
#
|
|
32
|
+
# With `AllowWithReason` set to `true`, a disable directive carrying
|
|
33
|
+
# a `--` trailing justification comment is allowed, so a team can require
|
|
34
|
+
# every disable to be documented instead of banning them outright. Enable
|
|
35
|
+
# directives are not checked in this mode, since they end a suppression
|
|
36
|
+
# rather than start one. Offenses in this mode are not autocorrected,
|
|
37
|
+
# since only a human can supply the missing justification.
|
|
38
|
+
#
|
|
39
|
+
# This cop cannot be disabled via directive comments when it is explicitly
|
|
40
|
+
# enabled with `Enabled: true`. This prevents users from bypassing the cop
|
|
41
|
+
# with `# rubocop:disable Style/DisableCopsWithinSourceCodeDirective`.
|
|
42
|
+
#
|
|
15
43
|
# @example
|
|
16
44
|
# # bad
|
|
17
45
|
# # rubocop:disable Metrics/AbcSize
|
|
@@ -30,57 +58,193 @@ module RuboCop
|
|
|
30
58
|
# end
|
|
31
59
|
# # rubocop:enable Metrics/AbcSize
|
|
32
60
|
#
|
|
61
|
+
# @example DisallowedCops: [Lint/Void]
|
|
62
|
+
# # bad
|
|
63
|
+
# # rubocop:disable Lint/Void
|
|
64
|
+
# foo
|
|
65
|
+
# # rubocop:enable Lint/Void
|
|
66
|
+
#
|
|
67
|
+
# # good
|
|
68
|
+
# # rubocop:disable Metrics/AbcSize
|
|
69
|
+
# foo
|
|
70
|
+
# # rubocop:enable Metrics/AbcSize
|
|
71
|
+
#
|
|
72
|
+
# @example AllowedDirectives: [todo]
|
|
73
|
+
# # good - the cop does not look at `todo` directives at all
|
|
74
|
+
# x = 0 # rubocop:todo Layout/SpaceAroundOperators
|
|
75
|
+
#
|
|
76
|
+
# # bad
|
|
77
|
+
# x = 0 # rubocop:disable Layout/SpaceAroundOperators
|
|
78
|
+
#
|
|
79
|
+
# @example AllowedCops: [Metrics]
|
|
80
|
+
# # good - every cop the directive disables is in an exempt department
|
|
81
|
+
# # rubocop:disable Metrics/AbcSize
|
|
82
|
+
# def foo
|
|
83
|
+
# end
|
|
84
|
+
# # rubocop:enable Metrics/AbcSize
|
|
85
|
+
#
|
|
86
|
+
# @example AllowWithReason: true
|
|
87
|
+
# # bad
|
|
88
|
+
# x = 0 # rubocop:disable Layout/SpaceAroundOperators
|
|
89
|
+
#
|
|
90
|
+
# # good
|
|
91
|
+
# x = 0 # rubocop:disable Layout/SpaceAroundOperators -- would misalign the table
|
|
92
|
+
#
|
|
33
93
|
class DisableCopsWithinSourceCodeDirective < Base
|
|
34
94
|
extend AutoCorrector
|
|
35
95
|
|
|
36
96
|
# rubocop:enable Lint/RedundantCopDisableDirective
|
|
37
97
|
MSG = 'RuboCop disable/enable directives are not permitted.'
|
|
38
98
|
MSG_FOR_COPS = 'RuboCop disable/enable directives for %<cops>s are not permitted.'
|
|
99
|
+
MSG_MISSING_REASON = 'RuboCop disable directives without a `--` justification ' \
|
|
100
|
+
'comment are not permitted.'
|
|
39
101
|
|
|
40
102
|
def on_new_investigation
|
|
103
|
+
@matching_pops = nil
|
|
104
|
+
|
|
41
105
|
processed_source.comments.each do |comment|
|
|
42
|
-
|
|
43
|
-
|
|
106
|
+
directive = DirectiveComment.new(comment)
|
|
107
|
+
next if ignored?(directive)
|
|
108
|
+
|
|
109
|
+
directive_cops = directive_cops(directive)
|
|
110
|
+
disallowed_cops = compute_disallowed_cops(directive_cops)
|
|
44
111
|
|
|
45
112
|
next unless disallowed_cops.any?
|
|
46
113
|
|
|
47
|
-
register_offense(
|
|
114
|
+
register_offense(directive, directive_cops, disallowed_cops)
|
|
48
115
|
end
|
|
49
116
|
end
|
|
50
117
|
|
|
51
118
|
private
|
|
52
119
|
|
|
53
|
-
def
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
120
|
+
def compute_disallowed_cops(directive_cops)
|
|
121
|
+
if disallowed_cops_config.any?
|
|
122
|
+
if directive_cops.include?('all')
|
|
123
|
+
directive_cops
|
|
124
|
+
else
|
|
125
|
+
directive_cops.uniq.select { |cop| listed?(disallowed_cops_config, cop) }
|
|
126
|
+
end
|
|
127
|
+
else
|
|
128
|
+
directive_cops.reject { |cop| cop != 'all' && listed?(allowed_cops, cop) }
|
|
129
|
+
end
|
|
130
|
+
end
|
|
59
131
|
|
|
60
|
-
|
|
61
|
-
|
|
132
|
+
def register_offense(directive, directive_cops, disallowed_cops)
|
|
133
|
+
comment = directive.comment
|
|
62
134
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
135
|
+
add_offense(comment, message: offense_message(disallowed_cops)) do |corrector|
|
|
136
|
+
# The remedy in `AllowWithReason` mode is to write the missing `--` justification,
|
|
137
|
+
# which cannot be autocorrected. Removing the directive would also unsuppress
|
|
138
|
+
# the disabled cops and let their autocorrections rewrite the annotated code.
|
|
139
|
+
next if allow_with_reason?
|
|
140
|
+
|
|
141
|
+
if directive_cops.length == disallowed_cops.length
|
|
142
|
+
remove_directive(corrector, directive)
|
|
143
|
+
elsif signed_args?(directive)
|
|
144
|
+
remove_signed_args(corrector, directive, disallowed_cops)
|
|
145
|
+
else
|
|
146
|
+
remove_cops(corrector, comment, disallowed_cops)
|
|
66
147
|
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
67
150
|
|
|
68
|
-
|
|
151
|
+
# A `push` without its `pop` leaves an orphan `pop` behind, so the pair goes together.
|
|
152
|
+
def remove_directive(corrector, directive)
|
|
153
|
+
corrector.replace(directive.comment, '')
|
|
154
|
+
return unless directive.push? && (pop = matching_pop(directive.comment))
|
|
155
|
+
|
|
156
|
+
corrector.replace(pop, '')
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def matching_pop(push_comment)
|
|
160
|
+
@matching_pops ||= pair_pushes_with_pops
|
|
161
|
+
@matching_pops[push_comment]
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def pair_pushes_with_pops
|
|
165
|
+
pushes = []
|
|
166
|
+
processed_source.comments.each_with_object({}) do |comment, pairs|
|
|
167
|
+
directive = DirectiveComment.new(comment)
|
|
168
|
+
if directive.push?
|
|
169
|
+
pushes.push(comment)
|
|
170
|
+
elsif directive.pop? && (push = pushes.pop)
|
|
171
|
+
pairs[push] = comment
|
|
172
|
+
end
|
|
69
173
|
end
|
|
70
174
|
end
|
|
71
175
|
|
|
72
|
-
def
|
|
73
|
-
|
|
176
|
+
def remove_signed_args(corrector, directive, disallowed_cops)
|
|
177
|
+
range = directive.range
|
|
178
|
+
names = Regexp.union(disallowed_cops)
|
|
179
|
+
corrector.replace(range, range.source.gsub(/\s+[+-]#{names}(?!\S)/, ''))
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def remove_cops(corrector, comment, disallowed_cops)
|
|
183
|
+
corrector.replace(comment, comment.text.sub(/#{Regexp.union(disallowed_cops)},?\s*/, '')
|
|
184
|
+
.sub(/,\s*$/, ''))
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def offense_message(disallowed_cops)
|
|
188
|
+
if allow_with_reason?
|
|
189
|
+
MSG_MISSING_REASON
|
|
190
|
+
elsif any_cops_allowed? || disallowed_cops_config.any?
|
|
191
|
+
format(MSG_FOR_COPS, cops: "`#{disallowed_cops.join('`, `')}`")
|
|
192
|
+
else
|
|
193
|
+
MSG
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def directive_cops(directive)
|
|
198
|
+
return directive.signed_args.values.flatten if signed_args?(directive)
|
|
199
|
+
|
|
200
|
+
match_captures = directive.match_captures
|
|
74
201
|
match_captures && match_captures[1] ? match_captures[1].split(',').map(&:strip) : []
|
|
75
202
|
end
|
|
76
203
|
|
|
204
|
+
def signed_args?(directive)
|
|
205
|
+
directive.push? || directive.next?
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def ignored?(directive)
|
|
209
|
+
return true if exempt_mode?(directive)
|
|
210
|
+
|
|
211
|
+
allow_with_reason? && (directive.reason || directive.enabled?)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def exempt_mode?(directive)
|
|
215
|
+
allowed_directives.include?(directive.mode)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def allowed_directives
|
|
219
|
+
@allowed_directives ||= Array(cop_config['AllowedDirectives'])
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def allow_with_reason?
|
|
223
|
+
# TODO: The obsolete `AllowTrailingComment` is honored for backward compatibility
|
|
224
|
+
# and will be removed in RuboCop 2.0.
|
|
225
|
+
allow_trailing_comment = cop_config['AllowTrailingComment'] # rubocop:disable InternalAffairs/UndefinedConfig -- obsolete key, gone from default.yml on purpose
|
|
226
|
+
return allow_trailing_comment unless allow_trailing_comment.nil?
|
|
227
|
+
|
|
228
|
+
cop_config['AllowWithReason']
|
|
229
|
+
end
|
|
230
|
+
|
|
77
231
|
def allowed_cops
|
|
78
|
-
Array(cop_config['AllowedCops'])
|
|
232
|
+
@allowed_cops ||= Array(cop_config['AllowedCops']).to_set
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# A name matches either outright or through its department, so
|
|
236
|
+
# `Metrics` covers `Metrics/AbcSize` but not the other way round.
|
|
237
|
+
def listed?(names, cop)
|
|
238
|
+
names.include?(cop) || names.include?(cop.split('/').first)
|
|
79
239
|
end
|
|
80
240
|
|
|
81
241
|
def any_cops_allowed?
|
|
82
242
|
allowed_cops.any?
|
|
83
243
|
end
|
|
244
|
+
|
|
245
|
+
def disallowed_cops_config
|
|
246
|
+
@disallowed_cops_config ||= Array(cop_config['DisallowedCops']).to_set
|
|
247
|
+
end
|
|
84
248
|
end
|
|
85
249
|
end
|
|
86
250
|
end
|
|
@@ -161,7 +161,12 @@ module RuboCop
|
|
|
161
161
|
source = source.gsub(COMMENT_REGEXP, '')
|
|
162
162
|
return if source.blank?
|
|
163
163
|
|
|
164
|
-
|
|
164
|
+
# Treat `\#` (an escaped interpolation marker in the heredoc) as matching
|
|
165
|
+
# either `\#` or `#` in the comment, since the comment may show either
|
|
166
|
+
# the literal source form or the runtime appearance.
|
|
167
|
+
segments = source.strip.split('\\#', -1).map { |segment| Regexp.escape(segment) }
|
|
168
|
+
|
|
169
|
+
/\s*#{segments.join('\\\\?#')}/
|
|
165
170
|
end
|
|
166
171
|
end
|
|
167
172
|
end
|
|
@@ -13,6 +13,11 @@ module RuboCop
|
|
|
13
13
|
# a `#:nodoc:` comment next to it. Likewise, `#:nodoc: all` does the
|
|
14
14
|
# same for all its children.
|
|
15
15
|
#
|
|
16
|
+
# When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is
|
|
17
|
+
# installed, a reopened class or module is not reported when any of its
|
|
18
|
+
# other definition sites (in the same or another file) carries a
|
|
19
|
+
# documentation comment.
|
|
20
|
+
#
|
|
16
21
|
# @example
|
|
17
22
|
# # bad
|
|
18
23
|
# class Person
|
|
@@ -62,19 +67,24 @@ module RuboCop
|
|
|
62
67
|
#
|
|
63
68
|
# @example AllowedConstants: ['ClassMethods']
|
|
64
69
|
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
#
|
|
70
|
-
#
|
|
70
|
+
# # good
|
|
71
|
+
# module A
|
|
72
|
+
# module ClassMethods
|
|
73
|
+
# # ...
|
|
74
|
+
# end
|
|
75
|
+
# end
|
|
71
76
|
#
|
|
72
77
|
class Documentation < Base
|
|
73
78
|
include DocumentationComment
|
|
79
|
+
include ProjectIndexHelp
|
|
74
80
|
include RangeHelp
|
|
75
81
|
|
|
76
82
|
MSG = 'Missing top-level documentation comment for `%<type>s %<identifier>s`.'
|
|
77
83
|
|
|
84
|
+
# Comments that configure tooling rather than document the code.
|
|
85
|
+
DIRECTIVE_COMMENT_REGEXP = /\A\#\s*(rubocop:|frozen_string_literal:|encoding:|
|
|
86
|
+
shareable_constant_value:|typed:|-\*-)/x.freeze
|
|
87
|
+
|
|
78
88
|
# @!method constant_definition?(node)
|
|
79
89
|
def_node_matcher :constant_definition?, '{class module casgn}'
|
|
80
90
|
|
|
@@ -109,12 +119,49 @@ module RuboCop
|
|
|
109
119
|
return if constant_allowed?(node)
|
|
110
120
|
return if nodoc_self_or_outer_module?(node)
|
|
111
121
|
return if include_statement_only?(body)
|
|
122
|
+
return if documented_elsewhere?(node)
|
|
123
|
+
|
|
124
|
+
add_documentation_offense(node)
|
|
125
|
+
end
|
|
112
126
|
|
|
127
|
+
def add_documentation_offense(node)
|
|
113
128
|
range = range_between(node.source_range.begin_pos, node.loc.name.end_pos)
|
|
114
129
|
message = format(MSG, type: node.type, identifier: identifier(node))
|
|
115
130
|
add_offense(range, message: message)
|
|
116
131
|
end
|
|
117
132
|
|
|
133
|
+
# A reopened class or module is typically documented at a single
|
|
134
|
+
# definition site. When `AllCops/UseProjectIndex` is enabled, the
|
|
135
|
+
# documentation requirement is satisfied by a comment on any other
|
|
136
|
+
# definition of the same class or module.
|
|
137
|
+
def documented_elsewhere?(node)
|
|
138
|
+
return false unless project_index
|
|
139
|
+
|
|
140
|
+
declaration = resolve_constant_in_index(node.identifier)
|
|
141
|
+
return false unless declaration.is_a?(Rubydex::Namespace)
|
|
142
|
+
|
|
143
|
+
declaration.definitions.any? do |definition|
|
|
144
|
+
other_definition?(definition, node) && documenting_comments?(definition)
|
|
145
|
+
end
|
|
146
|
+
rescue StandardError
|
|
147
|
+
false
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def other_definition?(definition, node)
|
|
151
|
+
location = definition.location
|
|
152
|
+
return false unless location.uri.start_with?(FILE_URI_PREFIX)
|
|
153
|
+
|
|
154
|
+
!same_file?(location.to_file_path, processed_source.file_path) ||
|
|
155
|
+
location.to_display.start_line != node.first_line
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def documenting_comments?(definition)
|
|
159
|
+
definition.comments.to_a.any? do |comment|
|
|
160
|
+
text = comment.string.strip
|
|
161
|
+
!text.empty? && !DIRECTIVE_COMMENT_REGEXP.match?(text)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
118
165
|
def nodoc_self_or_outer_module?(node)
|
|
119
166
|
nodoc_comment?(node) ||
|
|
120
167
|
(compact_namespace?(node) && nodoc_comment?(outer_module(node).first))
|