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
|
@@ -13,17 +13,17 @@ module RuboCop
|
|
|
13
13
|
# # good
|
|
14
14
|
# x if y.z.nil?
|
|
15
15
|
#
|
|
16
|
-
class RedundantParentheses < Base
|
|
16
|
+
class RedundantParentheses < Base # rubocop:disable Metrics/ClassLength
|
|
17
17
|
include Parentheses
|
|
18
|
+
include ReparsedEquivalence
|
|
18
19
|
extend AutoCorrector
|
|
19
20
|
|
|
20
|
-
ALLOWED_NODE_TYPES = %i[
|
|
21
|
+
ALLOWED_NODE_TYPES = %i[or send splat kwsplat].freeze
|
|
21
22
|
|
|
22
23
|
# @!method square_brackets?(node)
|
|
23
|
-
def_node_matcher :square_brackets?,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def_node_matcher :method_node_and_args, '$(call _recv _msg $...)'
|
|
24
|
+
def_node_matcher :square_brackets?, <<~PATTERN
|
|
25
|
+
(send `{(send _recv _msg) str array hash const #variable?} :[] ...)
|
|
26
|
+
PATTERN
|
|
27
27
|
|
|
28
28
|
# @!method rescue?(node)
|
|
29
29
|
def_node_matcher :rescue?, '{^resbody ^^resbody}'
|
|
@@ -31,18 +31,40 @@ module RuboCop
|
|
|
31
31
|
# @!method allowed_pin_operator?(node)
|
|
32
32
|
def_node_matcher :allowed_pin_operator?, '^(pin (begin !{lvar ivar cvar gvar}))'
|
|
33
33
|
|
|
34
|
+
def on_new_investigation
|
|
35
|
+
@pending_offenses = {}.compare_by_identity
|
|
36
|
+
super
|
|
37
|
+
end
|
|
38
|
+
|
|
34
39
|
def on_begin(node)
|
|
35
40
|
return if !parentheses?(node) || parens_allowed?(node) || ignore_syntax?(node)
|
|
36
41
|
|
|
37
42
|
check(node)
|
|
38
43
|
end
|
|
39
44
|
|
|
45
|
+
def on_investigation_end
|
|
46
|
+
# Each candidate's exact correction is verified by reparsing before
|
|
47
|
+
# the offense is registered, so redundancy never depends on
|
|
48
|
+
# hand-maintained knowledge of Ruby's grammar.
|
|
49
|
+
verified_by_reparse(@pending_offenses.keys).each do |node|
|
|
50
|
+
add_offense(node, message: @pending_offenses[node]) do |corrector|
|
|
51
|
+
ParenthesesCorrector.correct(corrector, node)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
super
|
|
56
|
+
end
|
|
57
|
+
|
|
40
58
|
private
|
|
41
59
|
|
|
60
|
+
def variable?(node)
|
|
61
|
+
node.respond_to?(:variable?) && node.variable?
|
|
62
|
+
end
|
|
63
|
+
|
|
42
64
|
def parens_allowed?(node)
|
|
43
65
|
empty_parentheses?(node) ||
|
|
44
|
-
first_arg_begins_with_hash_literal?(node) ||
|
|
45
66
|
rescue?(node) ||
|
|
67
|
+
in_pattern_matching_in_method_argument?(node) ||
|
|
46
68
|
allowed_pin_operator?(node) ||
|
|
47
69
|
allowed_expression?(node)
|
|
48
70
|
end
|
|
@@ -72,7 +94,7 @@ module RuboCop
|
|
|
72
94
|
ancestor = node.ancestors.first
|
|
73
95
|
return false unless ancestor
|
|
74
96
|
|
|
75
|
-
!ancestor.type?(:begin, :
|
|
97
|
+
!ancestor.type?(:begin, :any_def, :any_block)
|
|
76
98
|
end
|
|
77
99
|
|
|
78
100
|
def allowed_ternary?(node)
|
|
@@ -92,7 +114,7 @@ module RuboCop
|
|
|
92
114
|
return false unless node.type?(:send, :super, :yield)
|
|
93
115
|
|
|
94
116
|
node.arguments.one? && !node.parenthesized? &&
|
|
95
|
-
!node.
|
|
117
|
+
!node.operator_method? && node.first_argument.begin_type?
|
|
96
118
|
end
|
|
97
119
|
|
|
98
120
|
def multiline_control_flow_statements?(node)
|
|
@@ -107,46 +129,52 @@ module RuboCop
|
|
|
107
129
|
node.children.empty?
|
|
108
130
|
end
|
|
109
131
|
|
|
110
|
-
def
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (root_method = node.each_ancestor(:send).to_a.last)
|
|
114
|
-
parenthesized = root_method.parenthesized_call?
|
|
115
|
-
end
|
|
116
|
-
hash_literal && first_argument?(node) && !parentheses?(hash_literal) && !parenthesized
|
|
117
|
-
end
|
|
132
|
+
def in_pattern_matching_in_method_argument?(begin_node)
|
|
133
|
+
return false unless begin_node.parent&.call_type?
|
|
134
|
+
return false unless (node = begin_node.children.first)
|
|
118
135
|
|
|
119
|
-
|
|
120
|
-
return if node.nil?
|
|
121
|
-
return node if node.hash_type?
|
|
122
|
-
return unless node.send_type?
|
|
123
|
-
|
|
124
|
-
method_chain_begins_with_hash_literal(node.children.first)
|
|
136
|
+
target_ruby_version <= 2.7 ? node.match_pattern_type? : node.match_pattern_p_type?
|
|
125
137
|
end
|
|
126
138
|
|
|
127
139
|
def check(begin_node)
|
|
128
140
|
node = begin_node.children.first
|
|
129
141
|
|
|
130
142
|
if (message = find_offense_message(begin_node, node))
|
|
143
|
+
return offense(begin_node, message) if message == 'block body'
|
|
144
|
+
|
|
145
|
+
if node.range_type? && !argument_of_parenthesized_method_call?(begin_node, node)
|
|
146
|
+
begin_node = begin_node.parent
|
|
147
|
+
end
|
|
148
|
+
|
|
131
149
|
return offense(begin_node, message)
|
|
132
150
|
end
|
|
133
151
|
|
|
134
|
-
check_send(begin_node, node) if node
|
|
152
|
+
check_send(begin_node, node) if call_node?(node)
|
|
135
153
|
end
|
|
136
154
|
|
|
137
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
155
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
138
156
|
def find_offense_message(begin_node, node)
|
|
139
157
|
return 'a keyword' if keyword_with_redundant_parentheses?(node)
|
|
140
|
-
return 'a literal' if disallowed_literal?(begin_node, node)
|
|
158
|
+
return 'a literal' if node.literal? && disallowed_literal?(begin_node, node)
|
|
141
159
|
return 'a variable' if node.variable?
|
|
142
160
|
return 'a constant' if node.const_type?
|
|
161
|
+
return 'block body' if begin_node.parent&.any_block_type? || body_range?(begin_node, node)
|
|
162
|
+
|
|
143
163
|
if node.assignment? && (begin_node.parent.nil? || begin_node.parent.begin_type?)
|
|
144
164
|
return 'an assignment'
|
|
145
165
|
end
|
|
146
166
|
if node.lambda_or_proc? && (node.braces? || node.send_node.lambda_literal?)
|
|
147
167
|
return 'an expression'
|
|
148
168
|
end
|
|
169
|
+
if disallowed_one_line_pattern_matching?(begin_node, node)
|
|
170
|
+
return 'a one-line pattern matching'
|
|
171
|
+
end
|
|
149
172
|
return 'an interpolated expression' if interpolation?(begin_node)
|
|
173
|
+
if argument_of_parenthesized_method_call?(begin_node, node) &&
|
|
174
|
+
!keyword_logical_operator?(node)
|
|
175
|
+
return 'a method argument'
|
|
176
|
+
end
|
|
177
|
+
return 'a one-line rescue' if oneline_rescue_parentheses_required?(begin_node, node)
|
|
150
178
|
|
|
151
179
|
return if begin_node.chained?
|
|
152
180
|
|
|
@@ -154,6 +182,7 @@ module RuboCop
|
|
|
154
182
|
return if node.semantic_operator? && begin_node.parent
|
|
155
183
|
return if node.multiline? && allow_in_multiline_conditions?
|
|
156
184
|
return if ALLOWED_NODE_TYPES.include?(begin_node.parent&.type)
|
|
185
|
+
return if !node.and_type? && begin_node.parent&.and_type?
|
|
157
186
|
return if begin_node.parent&.if_type? && begin_node.parent.ternary?
|
|
158
187
|
|
|
159
188
|
'a logical expression'
|
|
@@ -163,21 +192,48 @@ module RuboCop
|
|
|
163
192
|
'a comparison expression'
|
|
164
193
|
end
|
|
165
194
|
end
|
|
166
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
167
195
|
|
|
168
196
|
# @!method interpolation?(node)
|
|
169
197
|
def_node_matcher :interpolation?, '[^begin ^^dstr]'
|
|
170
198
|
|
|
199
|
+
def argument_of_parenthesized_method_call?(begin_node, node)
|
|
200
|
+
if node.basic_conditional? || node.rescue_type? || method_call_parentheses_required?(node)
|
|
201
|
+
return false
|
|
202
|
+
end
|
|
203
|
+
return false unless (parent = begin_node.parent)
|
|
204
|
+
|
|
205
|
+
parent.call_type? && parent.parenthesized? && parent.receiver != begin_node
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def oneline_rescue_parentheses_required?(begin_node, node)
|
|
209
|
+
return false unless node.rescue_type?
|
|
210
|
+
return false unless (parent = begin_node.parent)
|
|
211
|
+
return false if parent.if_type? && parent.ternary?
|
|
212
|
+
return false if parent.conditional? && parent.condition == begin_node
|
|
213
|
+
|
|
214
|
+
!parent.type?(:call, :array, :pair)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def method_call_parentheses_required?(node)
|
|
218
|
+
return false unless node.call_type?
|
|
219
|
+
|
|
220
|
+
(node.receiver.nil? || node.loc.dot) && node.arguments.any?
|
|
221
|
+
end
|
|
222
|
+
|
|
171
223
|
def allow_in_multiline_conditions?
|
|
172
224
|
!!config.for_enabled_cop('Style/ParenthesesAroundCondition')['AllowInMultilineConditions']
|
|
173
225
|
end
|
|
174
226
|
|
|
227
|
+
def call_node?(node)
|
|
228
|
+
node.call_type? || (node.any_block_type? && node.braces? && !node.lambda_or_proc?)
|
|
229
|
+
end
|
|
230
|
+
|
|
175
231
|
def check_send(begin_node, node)
|
|
232
|
+
node = node.send_node if node.any_block_type?
|
|
233
|
+
|
|
176
234
|
return check_unary(begin_node, node) if node.unary_operation?
|
|
177
235
|
|
|
178
|
-
return unless method_call_with_redundant_parentheses?(node)
|
|
179
|
-
return if call_chain_starts_with_int?(begin_node, node) ||
|
|
180
|
-
do_end_block_in_method_chain?(begin_node, node)
|
|
236
|
+
return unless method_call_with_redundant_parentheses?(begin_node, node)
|
|
181
237
|
|
|
182
238
|
offense(begin_node, 'a method call')
|
|
183
239
|
end
|
|
@@ -186,18 +242,56 @@ module RuboCop
|
|
|
186
242
|
return if begin_node.chained?
|
|
187
243
|
|
|
188
244
|
node = node.children.first while suspect_unary?(node)
|
|
189
|
-
|
|
190
|
-
return if node.send_type? && !method_call_with_redundant_parentheses?(node)
|
|
245
|
+
return unless method_call_with_redundant_parentheses?(begin_node, node)
|
|
191
246
|
|
|
192
247
|
offense(begin_node, 'a unary operation')
|
|
193
248
|
end
|
|
194
249
|
|
|
195
250
|
def offense(node, msg)
|
|
196
|
-
|
|
197
|
-
|
|
251
|
+
@pending_offenses[node] = "Don't use parentheses around #{msg}."
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def apply_reparse_correction(corrector, node)
|
|
255
|
+
ParenthesesCorrector.correct(corrector, node)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# Grouping parentheses are transparent to the comparison: single-child
|
|
259
|
+
# `begin` nodes are collapsed, a parenthesized statement sequence
|
|
260
|
+
# inside another sequence is spliced in place, and chains of the same
|
|
261
|
+
# `&&`/`||` operator are normalized to left association (`x && (y &&
|
|
262
|
+
# z)` and `x && y && z` differ as trees but `&&` and `||` cannot be
|
|
263
|
+
# redefined, so same-operator regrouping is semantically transparent).
|
|
264
|
+
def normalize_reparsed_ast(node)
|
|
265
|
+
return node unless node.is_a?(::Parser::AST::Node)
|
|
266
|
+
|
|
267
|
+
children = node.children.map { |child| normalize_reparsed_ast(child) }
|
|
268
|
+
children = splice_nested_sequences(children) if %i[begin kwbegin].include?(node.type)
|
|
269
|
+
|
|
270
|
+
node = node.updated(nil, children)
|
|
271
|
+
if node.begin_type? && children.one? && children.first.is_a?(::Parser::AST::Node)
|
|
272
|
+
children.first
|
|
273
|
+
else
|
|
274
|
+
rotate_same_operator(node)
|
|
198
275
|
end
|
|
199
276
|
end
|
|
200
277
|
|
|
278
|
+
def splice_nested_sequences(children)
|
|
279
|
+
children.flat_map do |child|
|
|
280
|
+
child.is_a?(::Parser::AST::Node) && child.begin_type? ? child.children : [child]
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def rotate_same_operator(node)
|
|
285
|
+
return node unless node.type?(:and, :or)
|
|
286
|
+
|
|
287
|
+
right = node.rhs
|
|
288
|
+
return node unless right.is_a?(::Parser::AST::Node) && right.type == node.type
|
|
289
|
+
|
|
290
|
+
rotated_left = rotate_same_operator(node.updated(nil, [node.lhs, right.lhs]))
|
|
291
|
+
|
|
292
|
+
rotate_same_operator(node.updated(nil, [rotated_left, right.rhs]))
|
|
293
|
+
end
|
|
294
|
+
|
|
201
295
|
def suspect_unary?(node)
|
|
202
296
|
node.send_type? && node.unary_operation? && !node.prefix_not?
|
|
203
297
|
end
|
|
@@ -207,18 +301,37 @@ module RuboCop
|
|
|
207
301
|
end
|
|
208
302
|
|
|
209
303
|
def disallowed_literal?(begin_node, node)
|
|
210
|
-
|
|
304
|
+
return true unless node.range_type?
|
|
305
|
+
return false unless (parent = begin_node.parent)
|
|
306
|
+
|
|
307
|
+
parent.begin_type? && parent.children.one?
|
|
211
308
|
end
|
|
212
309
|
|
|
213
|
-
|
|
214
|
-
|
|
310
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
311
|
+
def body_range?(begin_node, node)
|
|
312
|
+
return false if begin_node.chained?
|
|
313
|
+
return false unless node.range_type?
|
|
314
|
+
return false unless (parent = begin_node.parent)
|
|
315
|
+
return false unless parent.begin_type?
|
|
316
|
+
|
|
317
|
+
(node.begin.nil? && begin_node == parent.children.first) ||
|
|
318
|
+
(node.end.nil? && begin_node == parent.children.last)
|
|
319
|
+
end
|
|
215
320
|
|
|
216
|
-
|
|
217
|
-
|
|
321
|
+
# `and`/`or` keyword operators bind looser than the method-argument
|
|
322
|
+
# boundary, so `foo((x and y))` cannot drop its parentheses without
|
|
323
|
+
# becoming a syntax error (unlike `&&`/`||`).
|
|
324
|
+
def keyword_logical_operator?(node)
|
|
325
|
+
node.operator_keyword? && node.semantic_operator?
|
|
326
|
+
end
|
|
218
327
|
|
|
219
|
-
|
|
328
|
+
def disallowed_one_line_pattern_matching?(begin_node, node)
|
|
329
|
+
if (parent = begin_node.parent)
|
|
330
|
+
return false if parent.any_def_type? && parent.endless?
|
|
331
|
+
return false if parent.assignment?
|
|
332
|
+
end
|
|
220
333
|
|
|
221
|
-
|
|
334
|
+
node.any_match_pattern_type? && node.each_ancestor.none?(&:operator_keyword?)
|
|
222
335
|
end
|
|
223
336
|
|
|
224
337
|
def keyword_with_redundant_parentheses?(node)
|
|
@@ -234,54 +347,23 @@ module RuboCop
|
|
|
234
347
|
end
|
|
235
348
|
end
|
|
236
349
|
|
|
237
|
-
def method_call_with_redundant_parentheses?(node)
|
|
238
|
-
return false unless node.
|
|
350
|
+
def method_call_with_redundant_parentheses?(begin_node, node)
|
|
351
|
+
return false unless node.type?(:call, :super, :yield, :defined?)
|
|
239
352
|
return false if node.prefix_not?
|
|
353
|
+
return true if singular_parenthesized_parent?(begin_node)
|
|
240
354
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
args.empty? || parentheses?(send_node) || square_brackets?(send_node)
|
|
355
|
+
node.arguments.empty? || parentheses?(node) || square_brackets?(node)
|
|
244
356
|
end
|
|
245
357
|
|
|
246
|
-
def
|
|
247
|
-
|
|
248
|
-
|
|
358
|
+
def singular_parenthesized_parent?(begin_node)
|
|
359
|
+
return true unless (parent = begin_node.parent)
|
|
360
|
+
return false if parent.type?(:splat, :kwsplat)
|
|
249
361
|
|
|
250
|
-
|
|
251
|
-
if first_send_argument?(node) ||
|
|
252
|
-
first_super_argument?(node) ||
|
|
253
|
-
first_yield_argument?(node)
|
|
254
|
-
return true
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
node.each_ancestor.any? { |ancestor| first_argument?(ancestor) }
|
|
362
|
+
parent.children.one?
|
|
258
363
|
end
|
|
259
364
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
^(send _ _ equal?(%0) ...)
|
|
263
|
-
PATTERN
|
|
264
|
-
|
|
265
|
-
# @!method first_super_argument?(node)
|
|
266
|
-
def_node_matcher :first_super_argument?, <<~PATTERN
|
|
267
|
-
^(super equal?(%0) ...)
|
|
268
|
-
PATTERN
|
|
269
|
-
|
|
270
|
-
# @!method first_yield_argument?(node)
|
|
271
|
-
def_node_matcher :first_yield_argument?, <<~PATTERN
|
|
272
|
-
^(yield equal?(%0) ...)
|
|
273
|
-
PATTERN
|
|
274
|
-
|
|
275
|
-
def call_chain_starts_with_int?(begin_node, send_node)
|
|
276
|
-
recv = first_part_of_call_chain(send_node)
|
|
277
|
-
recv&.int_type? && (parent = begin_node.parent) &&
|
|
278
|
-
parent.send_type? && (parent.method?(:-@) || parent.method?(:+@))
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
def do_end_block_in_method_chain?(begin_node, node)
|
|
282
|
-
return false unless (block = node.each_descendant(:any_block).first)
|
|
283
|
-
|
|
284
|
-
block.keywords? && begin_node.each_ancestor(:call).any?
|
|
365
|
+
def only_begin_arg?(args)
|
|
366
|
+
args.one? && args.first&.begin_type?
|
|
285
367
|
end
|
|
286
368
|
end
|
|
287
369
|
end
|
|
@@ -80,8 +80,7 @@ module RuboCop
|
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
def string_literal?(node)
|
|
83
|
-
node.loc
|
|
84
|
-
node.loc.begin && node.loc.end
|
|
83
|
+
node.loc?(:begin) && node.loc?(:end)
|
|
85
84
|
end
|
|
86
85
|
|
|
87
86
|
def start_with_percent_q_variant?(string)
|
|
@@ -91,7 +90,10 @@ module RuboCop
|
|
|
91
90
|
def acceptable_q?(node)
|
|
92
91
|
src = node.source
|
|
93
92
|
|
|
94
|
-
|
|
93
|
+
# If the string contains interpolation-like syntax and would be
|
|
94
|
+
# converted to a double-quoted string (because it contains single
|
|
95
|
+
# quotes), the replacement would activate interpolation.
|
|
96
|
+
return true if STRING_INTERPOLATION_REGEXP.match?(src) && src.include?(SINGLE_QUOTE)
|
|
95
97
|
|
|
96
98
|
src.scan(/\\./).any?(ESCAPED_NON_BACKSLASH)
|
|
97
99
|
end
|
|
@@ -66,6 +66,7 @@ module RuboCop
|
|
|
66
66
|
DETERMINISTIC_REGEX.match?(regexp_node.source)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
+
# rubocop:disable-next Metrics/MethodLength
|
|
69
70
|
def preferred_argument(regexp_node)
|
|
70
71
|
new_argument = replacement(regexp_node)
|
|
71
72
|
|
|
@@ -73,6 +74,13 @@ module RuboCop
|
|
|
73
74
|
new_argument.gsub!("'", "\\\\'")
|
|
74
75
|
new_argument.gsub!('\"', '"')
|
|
75
76
|
quote = "'"
|
|
77
|
+
elsif new_argument.include?("\\'")
|
|
78
|
+
# Add a backslash before single quotes preceded by an even number of backslashes.
|
|
79
|
+
# An even number (including zero) of backslashes before a quote means the quote itself
|
|
80
|
+
# is not escaped.
|
|
81
|
+
# Otherwise an odd number means the quote is already escaped so this doesn't touch it.
|
|
82
|
+
new_argument.gsub!(/(?<!\\)((?:\\\\)*)'/) { "#{::Regexp.last_match(1)}\\'" }
|
|
83
|
+
quote = "'"
|
|
76
84
|
elsif new_argument.include?('\'')
|
|
77
85
|
new_argument.gsub!("'", "\\\\'")
|
|
78
86
|
quote = "'"
|
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
|
74
74
|
|
|
75
75
|
non_redundant =
|
|
76
76
|
whitespace_in_free_space_mode?(node, class_elem) ||
|
|
77
|
-
backslash_b?(class_elem) ||
|
|
77
|
+
backslash_b?(class_elem) || backreference_requiring_char_class?(class_elem) ||
|
|
78
78
|
requires_escape_outside_char_class?(class_elem)
|
|
79
79
|
|
|
80
80
|
!non_redundant
|
|
@@ -104,10 +104,11 @@ module RuboCop
|
|
|
104
104
|
elem == '\b'
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
-
def
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
|
|
107
|
+
def backreference_requiring_char_class?(elem)
|
|
108
|
+
# `\1` to `\9` only match a literal digit inside a character class;
|
|
109
|
+
# outside it they are backreferences (and a syntax error when the
|
|
110
|
+
# referenced group does not exist), so the class is not redundant.
|
|
111
|
+
elem.match?(/\A\\[1-9]\z/)
|
|
111
112
|
end
|
|
112
113
|
|
|
113
114
|
def requires_escape_outside_char_class?(elem)
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for the instantiation of regexp using redundant `Regexp.new` or `Regexp.compile`.
|
|
7
|
-
# Autocorrect replaces
|
|
6
|
+
# Checks for the instantiation of a regexp using a redundant `Regexp.new` or `Regexp.compile`.
|
|
7
|
+
# Autocorrect replaces it with a regexp literal which is the simplest and fastest.
|
|
8
8
|
#
|
|
9
9
|
# @example
|
|
10
10
|
#
|
|
@@ -27,17 +27,17 @@ module RuboCop
|
|
|
27
27
|
def_node_matcher :redundant_regexp_constructor, <<~PATTERN
|
|
28
28
|
(send
|
|
29
29
|
(const {nil? cbase} :Regexp) {:new :compile}
|
|
30
|
-
(regexp
|
|
30
|
+
$(regexp _* (regopt _*)))
|
|
31
31
|
PATTERN
|
|
32
32
|
|
|
33
33
|
def on_send(node)
|
|
34
|
-
return unless (regexp
|
|
34
|
+
return unless (regexp = redundant_regexp_constructor(node))
|
|
35
35
|
|
|
36
36
|
add_offense(node, message: format(MSG, method: node.method_name)) do |corrector|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
corrector.replace(node,
|
|
37
|
+
# Reuse the inner literal's own source so its delimiters are preserved.
|
|
38
|
+
# Forcing `/.../` would break patterns like `%r{foo/bar}` that contain
|
|
39
|
+
# an unescaped slash.
|
|
40
|
+
corrector.replace(node, regexp.source)
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
end
|
|
@@ -41,6 +41,7 @@ module RuboCop
|
|
|
41
41
|
ALLOWED_ALWAYS_ESCAPES = " \n[]^\\#".chars.freeze
|
|
42
42
|
ALLOWED_WITHIN_CHAR_CLASS_METACHAR_ESCAPES = '-'.chars.freeze
|
|
43
43
|
ALLOWED_OUTSIDE_CHAR_CLASS_METACHAR_ESCAPES = '.*+?{}()|$'.chars.freeze
|
|
44
|
+
INTERPOLATION_SIGILS = %w[@ $].freeze
|
|
44
45
|
|
|
45
46
|
def on_regexp(node)
|
|
46
47
|
each_escape(node) do |char, index, within_character_class|
|
|
@@ -64,6 +65,7 @@ module RuboCop
|
|
|
64
65
|
# different versions of Ruby so that e.g. /\i/ != /i/
|
|
65
66
|
return true if /[[:alnum:]]/.match?(char)
|
|
66
67
|
return true if ALLOWED_ALWAYS_ESCAPES.include?(char) || delimiter?(node, char)
|
|
68
|
+
return true if requires_escape_to_avoid_interpolation?(node, index, char)
|
|
67
69
|
|
|
68
70
|
if within_character_class
|
|
69
71
|
ALLOWED_WITHIN_CHAR_CLASS_METACHAR_ESCAPES.include?(char) &&
|
|
@@ -95,6 +97,16 @@ module RuboCop
|
|
|
95
97
|
delimiters.include?(char)
|
|
96
98
|
end
|
|
97
99
|
|
|
100
|
+
def requires_escape_to_avoid_interpolation?(node, index, escaped_char)
|
|
101
|
+
# Preserve escapes after '#' that would otherwise trigger interpolation:
|
|
102
|
+
# '#@ivar', '#@@cvar', and '#$gvar'. `index` is relative to the regexp
|
|
103
|
+
# contents, so index into those rather than `node.source` (which also
|
|
104
|
+
# includes the opening delimiter, e.g. `%r{`).
|
|
105
|
+
return false unless index.positive? && INTERPOLATION_SIGILS.include?(escaped_char)
|
|
106
|
+
|
|
107
|
+
contents_range(node).source[index - 1] == '#'
|
|
108
|
+
end
|
|
109
|
+
|
|
98
110
|
def each_escape(node)
|
|
99
111
|
node.parsed_tree&.traverse&.reduce(0) do |char_class_depth, (event, expr)|
|
|
100
112
|
yield(expr.text[1], expr.ts, !char_class_depth.zero?) if expr.type == :escape
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for redundant `return` expressions.
|
|
6
|
+
# Checks for redundant `return` expressions. Ruby methods
|
|
7
|
+
# implicitly return the value of the last evaluated expression,
|
|
8
|
+
# so an explicit `return` at the end of a method body is unnecessary.
|
|
7
9
|
#
|
|
8
10
|
# @example
|
|
9
11
|
# # These bad cases should be extended to handle methods whose body is
|
|
@@ -106,7 +108,7 @@ module RuboCop
|
|
|
106
108
|
corrector.insert_after(node.children.last, '}')
|
|
107
109
|
end
|
|
108
110
|
|
|
109
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
111
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
110
112
|
def check_branch(node)
|
|
111
113
|
return unless node
|
|
112
114
|
|
|
@@ -122,7 +124,6 @@ module RuboCop
|
|
|
122
124
|
check_begin_node(node)
|
|
123
125
|
end
|
|
124
126
|
end
|
|
125
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
126
127
|
|
|
127
128
|
def check_return_node(node)
|
|
128
129
|
return if cop_config['AllowMultipleReturnValues'] && node.children.size > 1
|
|
@@ -59,7 +59,7 @@ module RuboCop
|
|
|
59
59
|
|
|
60
60
|
def initialize(config = nil, options = nil)
|
|
61
61
|
super
|
|
62
|
-
@allowed_send_nodes =
|
|
62
|
+
@allowed_send_nodes = Set.new.compare_by_identity
|
|
63
63
|
@local_variables_scopes = Hash.new { |hash, key| hash[key] = [] }.compare_by_identity
|
|
64
64
|
end
|
|
65
65
|
|
|
@@ -67,6 +67,9 @@ module RuboCop
|
|
|
67
67
|
|
|
68
68
|
def on_or_asgn(node)
|
|
69
69
|
allow_self(node.lhs)
|
|
70
|
+
|
|
71
|
+
lhs_name = node.lhs.lvasgn_type? ? node.lhs.name : node.lhs
|
|
72
|
+
add_lhs_to_local_variables_scopes(node.rhs, lhs_name)
|
|
70
73
|
end
|
|
71
74
|
alias on_and_asgn on_or_asgn
|
|
72
75
|
|
|
@@ -97,6 +100,15 @@ module RuboCop
|
|
|
97
100
|
add_lhs_to_local_variables_scopes(node.rhs, node.lhs)
|
|
98
101
|
end
|
|
99
102
|
|
|
103
|
+
# Register the exception variable of `rescue => e` so that `self.e` in the
|
|
104
|
+
# body is not treated as redundant (it disambiguates the local variable).
|
|
105
|
+
def on_resbody(node)
|
|
106
|
+
exception_variable = node.exception_variable
|
|
107
|
+
return unless exception_variable&.lvasgn_type?
|
|
108
|
+
|
|
109
|
+
@local_variables_scopes[node] << exception_variable.name
|
|
110
|
+
end
|
|
111
|
+
|
|
100
112
|
def on_in_pattern(node)
|
|
101
113
|
add_match_var_scopes(node)
|
|
102
114
|
end
|
|
@@ -118,15 +130,16 @@ module RuboCop
|
|
|
118
130
|
end
|
|
119
131
|
|
|
120
132
|
alias on_numblock on_block
|
|
133
|
+
alias on_itblock on_block
|
|
121
134
|
|
|
122
135
|
def on_if(node)
|
|
123
136
|
# Allow conditional nodes to use `self` in the condition if that variable
|
|
124
137
|
# name is used in an `lvasgn` or `masgn` within the `if`.
|
|
125
|
-
node.
|
|
126
|
-
if
|
|
127
|
-
add_lhs_to_local_variables_scopes(node.condition,
|
|
128
|
-
|
|
129
|
-
add_masgn_lhs_variables(node.condition,
|
|
138
|
+
node.each_descendant(:lvasgn, :masgn) do |descendant_node|
|
|
139
|
+
if descendant_node.lvasgn_type?
|
|
140
|
+
add_lhs_to_local_variables_scopes(node.condition, descendant_node.lhs)
|
|
141
|
+
else
|
|
142
|
+
add_masgn_lhs_variables(node.condition, descendant_node.lhs)
|
|
130
143
|
end
|
|
131
144
|
end
|
|
132
145
|
end
|
|
@@ -183,7 +196,7 @@ module RuboCop
|
|
|
183
196
|
def allow_self(node)
|
|
184
197
|
return unless node.send_type? && node.self_receiver?
|
|
185
198
|
|
|
186
|
-
@allowed_send_nodes
|
|
199
|
+
@allowed_send_nodes.add(node)
|
|
187
200
|
end
|
|
188
201
|
|
|
189
202
|
def add_lhs_to_local_variables_scopes(rhs, lhs)
|
|
@@ -55,10 +55,10 @@ module RuboCop
|
|
|
55
55
|
...))
|
|
56
56
|
PATTERN
|
|
57
57
|
|
|
58
|
-
# rubocop:disable Metrics/AbcSize
|
|
58
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
59
59
|
def on_lvasgn(node)
|
|
60
60
|
return unless (rhs = node.rhs)
|
|
61
|
-
return unless rhs.
|
|
61
|
+
return unless rhs.type?(:any_block, :call) && method_returning_self?(rhs.method_name)
|
|
62
62
|
return unless (receiver = rhs.receiver)
|
|
63
63
|
|
|
64
64
|
receiver_type = ASSIGNMENT_TYPE_TO_RECEIVER_TYPE[node.type]
|
|
@@ -69,7 +69,6 @@ module RuboCop
|
|
|
69
69
|
corrector.replace(node, rhs.source)
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
|
-
# rubocop:enable Metrics/AbcSize
|
|
73
72
|
alias on_ivasgn on_lvasgn
|
|
74
73
|
alias on_cvasgn on_lvasgn
|
|
75
74
|
alias on_gvasgn on_lvasgn
|