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
|
@@ -36,31 +36,45 @@ module RuboCop
|
|
|
36
36
|
|
|
37
37
|
MSG = 'Prefer multiline `do`...`end` block.'
|
|
38
38
|
|
|
39
|
-
# rubocop:disable Metrics/AbcSize
|
|
39
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
40
40
|
def on_block(node)
|
|
41
|
-
return if
|
|
41
|
+
return if node.multiline? || node.braces?
|
|
42
42
|
return if single_line_blocks_preferred? && suitable_as_single_line?(node)
|
|
43
43
|
|
|
44
44
|
add_offense(node) do |corrector|
|
|
45
45
|
corrector.insert_after(do_line(node), "\n")
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
if (heredoc = trailing_heredoc(node.body))
|
|
48
|
+
# The heredoc body extends past the `end` on the source, so the
|
|
49
|
+
# `end` has to be moved after it rather than before, which would
|
|
50
|
+
# otherwise move it into the heredoc body and break the syntax.
|
|
50
51
|
corrector.remove(node.loc.end)
|
|
51
|
-
corrector.insert_after(
|
|
52
|
+
corrector.insert_after(heredoc.loc.heredoc_end, "\nend")
|
|
52
53
|
else
|
|
53
54
|
corrector.insert_before(node.loc.end, "\n")
|
|
54
55
|
end
|
|
55
56
|
end
|
|
56
57
|
end
|
|
57
|
-
# rubocop:enable Metrics/AbcSize
|
|
58
58
|
alias on_numblock on_block
|
|
59
|
+
alias on_itblock on_block
|
|
59
60
|
|
|
60
61
|
private
|
|
61
62
|
|
|
63
|
+
# Returns the heredoc opened on the block's line whose body extends the
|
|
64
|
+
# furthest down, whether it is the block body itself or nested within it.
|
|
65
|
+
def trailing_heredoc(node_body)
|
|
66
|
+
return unless node_body
|
|
67
|
+
|
|
68
|
+
heredocs = [node_body, *node_body.each_descendant].select do |node|
|
|
69
|
+
node.respond_to?(:heredoc?) && node.heredoc?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
heredocs.max_by { |heredoc| heredoc.loc.heredoc_end.line }
|
|
73
|
+
end
|
|
74
|
+
|
|
62
75
|
def do_line(node)
|
|
63
|
-
if node.
|
|
76
|
+
if node.type?(:numblock, :itblock) ||
|
|
77
|
+
node.arguments.children.empty? || node.send_node.lambda_literal?
|
|
64
78
|
node.loc.begin
|
|
65
79
|
else
|
|
66
80
|
node.arguments
|
|
@@ -4,13 +4,15 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for single-line method definitions that contain a body.
|
|
7
|
-
#
|
|
7
|
+
# Single-line methods with a body are harder to read and debug
|
|
8
|
+
# than their multi-line equivalents. It will accept single-line
|
|
9
|
+
# methods with no body.
|
|
8
10
|
#
|
|
9
11
|
# Endless methods added in Ruby 3.0 are also accepted by this cop.
|
|
10
12
|
#
|
|
11
|
-
# If `Style/EndlessMethod` is enabled with `EnforcedStyle: allow_single_line`
|
|
12
|
-
# `
|
|
13
|
-
# methods if there is only one statement in the body.
|
|
13
|
+
# If `Style/EndlessMethod` is enabled with `EnforcedStyle: allow_single_line`, `allow_always`,
|
|
14
|
+
# `require_single_line`, or `require_always`, single-line methods will be autocorrected
|
|
15
|
+
# to endless methods if there is only one statement in the body.
|
|
14
16
|
#
|
|
15
17
|
# @example
|
|
16
18
|
# # bad
|
|
@@ -65,7 +67,7 @@ module RuboCop
|
|
|
65
67
|
return false if target_ruby_version < 3.0
|
|
66
68
|
return false if disallow_endless_method_style?
|
|
67
69
|
return false unless body_node
|
|
68
|
-
return false if body_node.parent.assignment_method? ||
|
|
70
|
+
return false if body_node.basic_conditional? || body_node.parent.assignment_method? ||
|
|
69
71
|
NOT_SUPPORTED_ENDLESS_METHOD_BODY_TYPES.include?(body_node.type)
|
|
70
72
|
|
|
71
73
|
!body_node.type?(:begin, :kwbegin)
|
|
@@ -86,10 +88,10 @@ module RuboCop
|
|
|
86
88
|
end
|
|
87
89
|
|
|
88
90
|
def correct_to_endless(corrector, node)
|
|
89
|
-
|
|
91
|
+
receiver = "#{node.receiver.source}." if node.receiver
|
|
90
92
|
arguments = node.arguments.any? ? node.arguments.source : '()'
|
|
91
93
|
body_source = method_body_source(node.body)
|
|
92
|
-
replacement = "def #{
|
|
94
|
+
replacement = "def #{receiver}#{node.method_name}#{arguments} = #{body_source}"
|
|
93
95
|
|
|
94
96
|
corrector.replace(node, replacement)
|
|
95
97
|
end
|
|
@@ -130,7 +132,10 @@ module RuboCop
|
|
|
130
132
|
end
|
|
131
133
|
|
|
132
134
|
def require_parentheses?(method_body)
|
|
133
|
-
|
|
135
|
+
return false unless method_body.send_type?
|
|
136
|
+
return false if method_body.arithmetic_operation?
|
|
137
|
+
|
|
138
|
+
!method_body.arguments.empty? && !method_body.comparison_method?
|
|
134
139
|
end
|
|
135
140
|
|
|
136
141
|
def disallow_endless_method_style?
|
|
@@ -48,6 +48,7 @@ module RuboCop
|
|
|
48
48
|
# end if condition_a
|
|
49
49
|
class SoleNestedConditional < Base
|
|
50
50
|
include RangeHelp
|
|
51
|
+
include ReparsedEquivalence
|
|
51
52
|
extend AutoCorrector
|
|
52
53
|
|
|
53
54
|
MSG = 'Consider merging nested conditions into outer `%<conditional_type>s` conditions.'
|
|
@@ -57,20 +58,39 @@ module RuboCop
|
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
def on_if(node)
|
|
60
|
-
return
|
|
61
|
+
return unless offending_conditional?(node)
|
|
61
62
|
|
|
62
63
|
if_branch = node.if_branch
|
|
63
|
-
return
|
|
64
|
-
return unless offending_branch?(node, if_branch)
|
|
64
|
+
return unless correction_parses?(node)
|
|
65
65
|
|
|
66
66
|
message = format(MSG, conditional_type: node.keyword)
|
|
67
67
|
add_offense(if_branch.loc.keyword, message: message) do |corrector|
|
|
68
|
+
next if ignored_node?(node)
|
|
69
|
+
|
|
68
70
|
autocorrect(corrector, node, if_branch)
|
|
71
|
+
ignore_node(if_branch)
|
|
69
72
|
end
|
|
70
73
|
end
|
|
71
74
|
|
|
72
75
|
private
|
|
73
76
|
|
|
77
|
+
def offending_conditional?(node)
|
|
78
|
+
return false if node.ternary? || node.else? || node.elsif?
|
|
79
|
+
|
|
80
|
+
if_branch = node.if_branch
|
|
81
|
+
return false if use_variable_assignment_in_condition?(node.condition, if_branch)
|
|
82
|
+
|
|
83
|
+
offending_branch?(node, if_branch)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Merging the conditionals intentionally produces a different AST, so
|
|
87
|
+
# full equivalence cannot be checked, but the corrected source must at
|
|
88
|
+
# least remain parseable (see `ReparsedEquivalence#correction_parses?`),
|
|
89
|
+
# which suppresses the entire produces-invalid-code bug class.
|
|
90
|
+
def apply_reparse_correction(corrector, node)
|
|
91
|
+
autocorrect(corrector, node, node.if_branch)
|
|
92
|
+
end
|
|
93
|
+
|
|
74
94
|
def use_variable_assignment_in_condition?(condition, if_branch)
|
|
75
95
|
assigned_variables = assigned_variables(condition)
|
|
76
96
|
|
|
@@ -96,11 +116,7 @@ module RuboCop
|
|
|
96
116
|
end
|
|
97
117
|
|
|
98
118
|
def autocorrect(corrector, node, if_branch)
|
|
99
|
-
if node.
|
|
100
|
-
corrector.wrap(node.condition, '(', ')')
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
if outer_condition_modify_form?(node, if_branch)
|
|
119
|
+
if node.modifier_form?
|
|
104
120
|
autocorrect_outer_condition_modify_form(corrector, node, if_branch)
|
|
105
121
|
else
|
|
106
122
|
autocorrect_outer_condition_basic(corrector, node, if_branch)
|
|
@@ -108,74 +124,54 @@ module RuboCop
|
|
|
108
124
|
end
|
|
109
125
|
|
|
110
126
|
def autocorrect_outer_condition_basic(corrector, node, if_branch)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
outer_condition = node.condition
|
|
114
|
-
correct_outer_condition(corrector, outer_condition)
|
|
127
|
+
correct_node(corrector, node)
|
|
115
128
|
|
|
116
|
-
and_operator = if_branch.unless? ? ' && !' : ' && '
|
|
117
129
|
if if_branch.modifier_form?
|
|
118
|
-
correct_for_guard_condition_style(corrector,
|
|
130
|
+
correct_for_guard_condition_style(corrector, node, if_branch)
|
|
119
131
|
else
|
|
120
|
-
correct_for_basic_condition_style(corrector, node, if_branch
|
|
132
|
+
correct_for_basic_condition_style(corrector, node, if_branch)
|
|
121
133
|
correct_for_comment(corrector, node, if_branch)
|
|
122
134
|
end
|
|
123
135
|
end
|
|
124
136
|
|
|
125
|
-
def
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def correct_from_unless_to_if(corrector, node, is_modify_form: false)
|
|
131
|
-
corrector.replace(node.loc.keyword, 'if')
|
|
132
|
-
|
|
133
|
-
insert_bang(corrector, node, is_modify_form)
|
|
137
|
+
def correct_node(corrector, node)
|
|
138
|
+
corrector.replace(node.loc.keyword, 'if') if node.unless?
|
|
139
|
+
corrector.replace(node.condition, chainable_condition(node))
|
|
134
140
|
end
|
|
135
141
|
|
|
136
|
-
def correct_for_guard_condition_style(corrector,
|
|
137
|
-
condition
|
|
138
|
-
corrector.insert_after(outer_condition, "#{and_operator}#{replace_condition(condition)}")
|
|
142
|
+
def correct_for_guard_condition_style(corrector, node, if_branch)
|
|
143
|
+
corrector.insert_after(node.condition, " && #{chainable_condition(if_branch)}")
|
|
139
144
|
|
|
140
|
-
range = range_between(
|
|
145
|
+
range = range_between(
|
|
146
|
+
if_branch.loc.keyword.begin_pos, if_branch.condition.source_range.end_pos
|
|
147
|
+
)
|
|
141
148
|
corrector.remove(range_with_surrounding_space(range, newlines: false))
|
|
142
|
-
corrector.remove(if_branch.loc.keyword)
|
|
143
149
|
end
|
|
144
150
|
|
|
145
|
-
|
|
151
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
152
|
+
def correct_for_basic_condition_style(corrector, node, if_branch)
|
|
146
153
|
range = range_between(
|
|
147
154
|
node.condition.source_range.end_pos, if_branch.condition.source_range.begin_pos
|
|
148
155
|
)
|
|
149
|
-
corrector.replace(range,
|
|
150
|
-
corrector.remove(range_by_whole_lines(node.loc.end, include_final_newline: true))
|
|
151
|
-
|
|
152
|
-
wrap_condition(corrector, if_branch.condition)
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
def wrap_condition(corrector, condition)
|
|
156
|
-
# Handle `send` and `block` nodes that need to be wrapped in parens
|
|
157
|
-
# FIXME: autocorrection prevents syntax errors by wrapping the entire node in parens,
|
|
158
|
-
# but wrapping the argument list would be a more ergonomic correction.
|
|
159
|
-
node_to_check = condition&.any_block_type? ? condition.send_node : condition
|
|
160
|
-
return unless wrap_condition?(node_to_check)
|
|
156
|
+
corrector.replace(range, ' && ')
|
|
161
157
|
|
|
162
|
-
|
|
163
|
-
source = parenthesized_method_arguments(condition)
|
|
158
|
+
corrector.replace(if_branch.condition, chainable_condition(if_branch))
|
|
164
159
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
160
|
+
end_range = if same_line?(node.loc.end, node.if_branch.loc.end)
|
|
161
|
+
node.loc.end
|
|
162
|
+
else
|
|
163
|
+
range_by_whole_lines(node.loc.end, include_final_newline: true)
|
|
164
|
+
end
|
|
165
|
+
corrector.remove(end_range)
|
|
169
166
|
end
|
|
170
167
|
|
|
171
|
-
def
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
168
|
+
def autocorrect_outer_condition_modify_form(corrector, node, if_branch)
|
|
169
|
+
correct_node(corrector, if_branch)
|
|
170
|
+
|
|
171
|
+
corrector.insert_before(if_branch.condition, "#{chainable_condition(node)} && ")
|
|
175
172
|
|
|
176
|
-
|
|
177
|
-
corrector.remove(range_with_surrounding_space(
|
|
178
|
-
corrector.replace(if_branch.loc.keyword, 'if')
|
|
173
|
+
range = range_between(node.loc.keyword.begin_pos, node.condition.source_range.end_pos)
|
|
174
|
+
corrector.remove(range_with_surrounding_space(range, newlines: false))
|
|
179
175
|
end
|
|
180
176
|
|
|
181
177
|
def correct_for_comment(corrector, node, if_branch)
|
|
@@ -187,67 +183,47 @@ module RuboCop
|
|
|
187
183
|
corrector.insert_before(node.loc.keyword, comment_text) unless comments.empty?
|
|
188
184
|
end
|
|
189
185
|
|
|
190
|
-
def
|
|
191
|
-
|
|
186
|
+
def chainable_condition(node)
|
|
187
|
+
wrapped_condition = add_parentheses_if_needed(node.condition)
|
|
192
188
|
|
|
193
|
-
|
|
194
|
-
begin_pos = condition.first_argument.source_range.begin_pos
|
|
195
|
-
return if end_pos > begin_pos
|
|
189
|
+
return wrapped_condition if node.if?
|
|
196
190
|
|
|
197
|
-
|
|
198
|
-
corrector.remove(range)
|
|
199
|
-
corrector.insert_after(range, '(')
|
|
200
|
-
corrector.insert_after(condition.last_argument, ')')
|
|
191
|
+
node.condition.and_type? ? "!(#{wrapped_condition})" : "!#{wrapped_condition}"
|
|
201
192
|
end
|
|
202
193
|
|
|
203
|
-
def
|
|
204
|
-
|
|
194
|
+
def add_parentheses_if_needed(condition)
|
|
195
|
+
# Handle `send` and `block` nodes that need to be wrapped in parens
|
|
196
|
+
# FIXME: autocorrection prevents syntax errors by wrapping the entire node in parens,
|
|
197
|
+
# but wrapping the argument list would be a more ergonomic correction.
|
|
198
|
+
node_to_check = condition&.any_block_type? ? condition.send_node : condition
|
|
199
|
+
return condition.source unless add_parentheses?(node_to_check)
|
|
205
200
|
|
|
206
|
-
if (condition
|
|
207
|
-
|
|
208
|
-
corrector.wrap(node.condition, '!(', ')')
|
|
201
|
+
if parenthesize_method?(condition)
|
|
202
|
+
parenthesized_method_arguments(condition)
|
|
209
203
|
elsif condition.and_type?
|
|
210
|
-
|
|
211
|
-
else
|
|
212
|
-
corrector.insert_before(condition, '!')
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
def insert_bang_for_and(corrector, node)
|
|
217
|
-
lhs, rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
|
218
|
-
|
|
219
|
-
if lhs.and_type?
|
|
220
|
-
insert_bang_for_and(corrector, lhs)
|
|
221
|
-
corrector.insert_before(rhs, '!') if rhs
|
|
204
|
+
parenthesized_and(condition)
|
|
222
205
|
else
|
|
223
|
-
|
|
224
|
-
corrector.insert_before(rhs, '!')
|
|
206
|
+
"(#{condition.source})"
|
|
225
207
|
end
|
|
226
208
|
end
|
|
227
209
|
|
|
228
|
-
def
|
|
229
|
-
|
|
230
|
-
!
|
|
210
|
+
def parenthesize_method?(node)
|
|
211
|
+
node.call_type? && node.arguments.any? && !node.parenthesized? &&
|
|
212
|
+
!node.comparison_method? && !node.operator_method?
|
|
231
213
|
end
|
|
232
214
|
|
|
233
|
-
def
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
end
|
|
215
|
+
def add_parentheses?(node)
|
|
216
|
+
return true if node.assignment? || node.or_type?
|
|
217
|
+
return true if assignment_in_and?(node)
|
|
218
|
+
return false unless node.call_type?
|
|
238
219
|
|
|
239
|
-
|
|
240
|
-
node.operator_keyword? || (node.call_type? && node.arguments.any? && !node.parenthesized?)
|
|
220
|
+
(node.arguments.any? && !node.parenthesized?) || node.prefix_not?
|
|
241
221
|
end
|
|
242
222
|
|
|
243
|
-
def
|
|
244
|
-
return
|
|
223
|
+
def assignment_in_and?(node)
|
|
224
|
+
return false unless node.and_type?
|
|
245
225
|
|
|
246
|
-
|
|
247
|
-
parenthesized_method_arguments(condition)
|
|
248
|
-
else
|
|
249
|
-
"(#{condition.source})"
|
|
250
|
-
end
|
|
226
|
+
node.each_descendant.any?(&:assignment?)
|
|
251
227
|
end
|
|
252
228
|
|
|
253
229
|
def parenthesized_method_arguments(node)
|
|
@@ -257,12 +233,28 @@ module RuboCop
|
|
|
257
233
|
"#{method_call}(#{arguments})"
|
|
258
234
|
end
|
|
259
235
|
|
|
260
|
-
def
|
|
261
|
-
|
|
236
|
+
def parenthesized_and(node)
|
|
237
|
+
# We only need to add parentheses around the last clause if it's an assignment,
|
|
238
|
+
# because other clauses will be unchanged by merging conditionals.
|
|
239
|
+
lhs = node.lhs.source
|
|
240
|
+
rhs = parenthesized_and_clause(node.rhs)
|
|
241
|
+
operator = range_with_surrounding_space(node.loc.operator, whitespace: true).source
|
|
242
|
+
|
|
243
|
+
"#{lhs}#{operator}#{rhs}"
|
|
262
244
|
end
|
|
263
245
|
|
|
264
|
-
def
|
|
265
|
-
node.
|
|
246
|
+
def parenthesized_and_clause(node)
|
|
247
|
+
if node.and_type?
|
|
248
|
+
parenthesized_and(node)
|
|
249
|
+
elsif node.assignment?
|
|
250
|
+
"(#{node.source})"
|
|
251
|
+
else
|
|
252
|
+
node.source
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def allow_modifier?
|
|
257
|
+
cop_config['AllowModifier']
|
|
266
258
|
end
|
|
267
259
|
end
|
|
268
260
|
end
|
|
@@ -4,7 +4,12 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Looks for uses of Perl-style global variables.
|
|
7
|
-
#
|
|
7
|
+
# Perl-style global variables like `$;` or `$/` are cryptic
|
|
8
|
+
# and hard to understand without consulting documentation.
|
|
9
|
+
# The `English` library provides descriptive aliases like
|
|
10
|
+
# `$FIELD_SEPARATOR` and `$INPUT_RECORD_SEPARATOR`.
|
|
11
|
+
#
|
|
12
|
+
# Correcting to global variables in the `English` library
|
|
8
13
|
# will add a require statement to the top of the file if
|
|
9
14
|
# enabled by RequireEnglish config.
|
|
10
15
|
#
|
|
@@ -96,7 +101,7 @@ module RuboCop
|
|
|
96
101
|
'module (don\'t forget to require it) over `%<global>s`.'
|
|
97
102
|
MSG_REGULAR = 'Prefer `%<prefer>s` over `%<global>s`.'
|
|
98
103
|
|
|
99
|
-
ENGLISH_VARS = { # rubocop:disable Style/MutableConstant
|
|
104
|
+
ENGLISH_VARS = { # rubocop:disable Style/MutableConstant -- merged into below, then frozen
|
|
100
105
|
:$: => [:$LOAD_PATH],
|
|
101
106
|
:$" => [:$LOADED_FEATURES],
|
|
102
107
|
:$0 => [:$PROGRAM_NAME],
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
#
|
|
6
|
+
# Checks for parentheses around stabby lambda arguments.
|
|
7
7
|
# There are two different styles. Defaults to `require_parentheses`.
|
|
8
8
|
#
|
|
9
9
|
# @example EnforcedStyle: require_parentheses (default)
|
|
@@ -25,6 +25,8 @@ module RuboCop
|
|
|
25
25
|
|
|
26
26
|
MSG_REQUIRE = 'Wrap stabby lambda arguments with parentheses.'
|
|
27
27
|
MSG_NO_REQUIRE = 'Do not wrap stabby lambda arguments with parentheses.'
|
|
28
|
+
RESTRICT_ON_SEND = %i[lambda].freeze
|
|
29
|
+
|
|
28
30
|
def on_send(node)
|
|
29
31
|
return unless stabby_lambda_with_args?(node)
|
|
30
32
|
return unless redundant_parentheses?(node) || missing_parentheses?(node)
|
|
@@ -12,6 +12,11 @@ module RuboCop
|
|
|
12
12
|
# for some other subclass, monkey-patched with instance methods or
|
|
13
13
|
# a dummy instance is instantiated from it somewhere.
|
|
14
14
|
#
|
|
15
|
+
# When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is
|
|
16
|
+
# installed, classes that are subclassed anywhere in the project are
|
|
17
|
+
# not reported, since converting them to modules would break their
|
|
18
|
+
# subclasses.
|
|
19
|
+
#
|
|
15
20
|
# @example
|
|
16
21
|
# # bad
|
|
17
22
|
# class SomeClass
|
|
@@ -44,6 +49,7 @@ module RuboCop
|
|
|
44
49
|
# end
|
|
45
50
|
#
|
|
46
51
|
class StaticClass < Base
|
|
52
|
+
include ProjectIndexHelp
|
|
47
53
|
include RangeHelp
|
|
48
54
|
include VisibilityHelp
|
|
49
55
|
extend AutoCorrector
|
|
@@ -53,6 +59,7 @@ module RuboCop
|
|
|
53
59
|
def on_class(class_node)
|
|
54
60
|
return if class_node.parent_class
|
|
55
61
|
return unless class_convertible_to_module?(class_node)
|
|
62
|
+
return if subclassed_in_project?(class_node)
|
|
56
63
|
|
|
57
64
|
add_offense(class_node) do |corrector|
|
|
58
65
|
autocorrect(corrector, class_node)
|
|
@@ -61,6 +68,20 @@ module RuboCop
|
|
|
61
68
|
|
|
62
69
|
private
|
|
63
70
|
|
|
71
|
+
# When `AllCops/UseProjectIndex` is enabled, a class with descendants
|
|
72
|
+
# anywhere in the project is not reported: converting it to a module
|
|
73
|
+
# would break its subclasses.
|
|
74
|
+
def subclassed_in_project?(class_node)
|
|
75
|
+
return false unless project_index
|
|
76
|
+
|
|
77
|
+
declaration = resolve_constant_in_index(class_node.identifier)
|
|
78
|
+
return false unless declaration.is_a?(Rubydex::Class)
|
|
79
|
+
|
|
80
|
+
declaration.descendants.any? { |descendant| descendant.name != declaration.name }
|
|
81
|
+
rescue StandardError
|
|
82
|
+
false
|
|
83
|
+
end
|
|
84
|
+
|
|
64
85
|
def autocorrect(corrector, class_node)
|
|
65
86
|
corrector.replace(class_node.loc.keyword, 'module')
|
|
66
87
|
corrector.insert_after(class_node.loc.name, "\nmodule_function\n")
|
|
@@ -51,7 +51,6 @@ module RuboCop
|
|
|
51
51
|
# Pathname.new('/') + 'test'
|
|
52
52
|
#
|
|
53
53
|
class StringConcatenation < Base
|
|
54
|
-
include RangeHelp
|
|
55
54
|
extend AutoCorrector
|
|
56
55
|
|
|
57
56
|
MSG = 'Prefer string interpolation to string concatenation.'
|
|
@@ -101,7 +100,7 @@ module RuboCop
|
|
|
101
100
|
node.receiver.str_type? &&
|
|
102
101
|
node.first_argument.str_type? &&
|
|
103
102
|
node.multiline? &&
|
|
104
|
-
node.source
|
|
103
|
+
node.source.match?(/\+\s*\n/)
|
|
105
104
|
end
|
|
106
105
|
|
|
107
106
|
def find_topmost_plus_node(node)
|
|
@@ -128,7 +127,7 @@ module RuboCop
|
|
|
128
127
|
end
|
|
129
128
|
|
|
130
129
|
def uncorrectable?(part)
|
|
131
|
-
part.multiline? || heredoc?(part) || part.each_descendant(:
|
|
130
|
+
part.multiline? || heredoc?(part) || part.each_descendant(:any_block).any?
|
|
132
131
|
end
|
|
133
132
|
|
|
134
133
|
def heredoc?(node)
|
|
@@ -142,22 +141,35 @@ module RuboCop
|
|
|
142
141
|
end
|
|
143
142
|
|
|
144
143
|
def replacement(parts)
|
|
145
|
-
interpolated_parts = parts.map
|
|
146
|
-
case part.type
|
|
147
|
-
when :str
|
|
148
|
-
adjust_str(part)
|
|
149
|
-
when :dstr
|
|
150
|
-
part.children.all?(&:str_type?) ? adjust_str(part) : contents_range(part).source
|
|
151
|
-
else
|
|
152
|
-
"\#{#{part.source}}"
|
|
153
|
-
end
|
|
154
|
-
end
|
|
144
|
+
interpolated_parts = parts.map { |part| adjust_str(part) }
|
|
155
145
|
|
|
156
146
|
"\"#{handle_quotes(interpolated_parts).join}\""
|
|
157
147
|
end
|
|
158
148
|
|
|
159
|
-
def adjust_str(
|
|
160
|
-
|
|
149
|
+
def adjust_str(part)
|
|
150
|
+
case part.type
|
|
151
|
+
when :str
|
|
152
|
+
adjust_str_literal(part)
|
|
153
|
+
when :dstr, :begin
|
|
154
|
+
part.children.map do |child|
|
|
155
|
+
adjust_str(child)
|
|
156
|
+
end.join
|
|
157
|
+
else
|
|
158
|
+
"\#{#{part.source}}"
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def adjust_str_literal(part)
|
|
163
|
+
if single_quoted?(part)
|
|
164
|
+
part.value.gsub(/(\\|"|#\{|#@|#\$)/, '\\\\\&')
|
|
165
|
+
elsif double_quoted?(part)
|
|
166
|
+
# Reuse the source as written - rebuilding it from the value via
|
|
167
|
+
# `inspect` would rewrite the author's escape notation
|
|
168
|
+
# (e.g. `\x0a` into `\n`).
|
|
169
|
+
part.source[1..-2]
|
|
170
|
+
else
|
|
171
|
+
part.value.inspect[1..-2]
|
|
172
|
+
end
|
|
161
173
|
end
|
|
162
174
|
|
|
163
175
|
def handle_quotes(parts)
|
|
@@ -170,6 +182,10 @@ module RuboCop
|
|
|
170
182
|
str_node.source.start_with?("'")
|
|
171
183
|
end
|
|
172
184
|
|
|
185
|
+
def double_quoted?(str_node)
|
|
186
|
+
str_node.source.start_with?('"')
|
|
187
|
+
end
|
|
188
|
+
|
|
173
189
|
def mode
|
|
174
190
|
cop_config['Mode'].to_sym
|
|
175
191
|
end
|
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for inheritance from Struct.new.
|
|
6
|
+
# Checks for inheritance from `Struct.new`. Inheriting from `Struct.new`
|
|
7
|
+
# adds a superfluous level in inheritance tree.
|
|
7
8
|
#
|
|
8
9
|
# @safety
|
|
9
10
|
# Autocorrection is unsafe because it will change the inheritance
|
|
10
11
|
# tree (e.g. return value of `Module#ancestors`) of the constant.
|
|
11
12
|
#
|
|
13
|
+
# It is also unsafe because constants that the class body resolves through its
|
|
14
|
+
# ancestors (e.g. one provided by an included module) fall out of scope inside
|
|
15
|
+
# the block.
|
|
16
|
+
#
|
|
12
17
|
# @example
|
|
13
18
|
# # bad
|
|
14
19
|
# class Person < Struct.new(:first_name, :last_name)
|
|
@@ -17,12 +22,18 @@ module RuboCop
|
|
|
17
22
|
# end
|
|
18
23
|
# end
|
|
19
24
|
#
|
|
25
|
+
# Person.ancestors
|
|
26
|
+
# # => [Person, #<Class:0x000000010b4e14a0>, Struct, (...)]
|
|
27
|
+
#
|
|
20
28
|
# # good
|
|
21
29
|
# Person = Struct.new(:first_name, :last_name) do
|
|
22
30
|
# def age
|
|
23
31
|
# 42
|
|
24
32
|
# end
|
|
25
33
|
# end
|
|
34
|
+
#
|
|
35
|
+
# Person.ancestors
|
|
36
|
+
# # => [Person, Struct, (...)]
|
|
26
37
|
class StructInheritance < Base
|
|
27
38
|
include RangeHelp
|
|
28
39
|
extend AutoCorrector
|
|
@@ -32,9 +43,12 @@ module RuboCop
|
|
|
32
43
|
|
|
33
44
|
def on_class(node)
|
|
34
45
|
return unless struct_constructor?(node.parent_class)
|
|
46
|
+
return if defines_constants?(node.body)
|
|
35
47
|
|
|
36
48
|
add_offense(node.parent_class) do |corrector|
|
|
37
|
-
corrector.remove(
|
|
49
|
+
corrector.remove(
|
|
50
|
+
range_with_surrounding_space(node.loc.keyword, side: :right, newlines: false)
|
|
51
|
+
)
|
|
38
52
|
corrector.replace(node.loc.operator, '=')
|
|
39
53
|
|
|
40
54
|
correct_parent(node.parent_class, corrector)
|
|
@@ -49,11 +63,22 @@ module RuboCop
|
|
|
49
63
|
|
|
50
64
|
private
|
|
51
65
|
|
|
66
|
+
# Constants, including nested classes and modules, are scoped to the class when they
|
|
67
|
+
# are defined in a class body, but leak into the enclosing namespace once moved into a
|
|
68
|
+
# `Struct.new` block, so such a class cannot be rewritten as an assignment.
|
|
69
|
+
def defines_constants?(class_body)
|
|
70
|
+
return false unless class_body
|
|
71
|
+
|
|
72
|
+
class_body.each_node(:casgn, :class, :module).any?
|
|
73
|
+
end
|
|
74
|
+
|
|
52
75
|
def correct_parent(parent, corrector)
|
|
53
76
|
if parent.block_type?
|
|
54
77
|
corrector.remove(range_with_surrounding_space(parent.loc.end, newlines: false))
|
|
55
78
|
elsif (class_node = parent.parent).body.nil?
|
|
56
79
|
corrector.remove(range_for_empty_class_body(class_node, parent))
|
|
80
|
+
elsif unparenthesized_struct_new?(parent)
|
|
81
|
+
wrap_unparenthesized_call_with_do(corrector, parent)
|
|
57
82
|
else
|
|
58
83
|
corrector.insert_after(parent, ' do')
|
|
59
84
|
end
|
|
@@ -66,6 +91,17 @@ module RuboCop
|
|
|
66
91
|
range_by_whole_lines(class_node.loc.end, include_final_newline: true)
|
|
67
92
|
end
|
|
68
93
|
end
|
|
94
|
+
|
|
95
|
+
def unparenthesized_struct_new?(parent)
|
|
96
|
+
parent.send_type? && parent.arguments.any? && !parent.parenthesized?
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def wrap_unparenthesized_call_with_do(corrector, parent)
|
|
100
|
+
args_source = parent.arguments.map(&:source).join(', ')
|
|
101
|
+
range = parent.loc.selector.end.join(parent.source_range.end)
|
|
102
|
+
|
|
103
|
+
corrector.replace(range, "(#{args_source}) do")
|
|
104
|
+
end
|
|
69
105
|
end
|
|
70
106
|
end
|
|
71
107
|
end
|