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
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# rubocop:disable Lint/RedundantCopDisableDirective
|
|
3
|
+
# rubocop:disable-next Lint/RedundantCopDisableDirective -- the examples below read as real directives
|
|
4
4
|
module RuboCop
|
|
5
5
|
module Cop
|
|
6
6
|
module Lint
|
|
7
7
|
# Checks that there is an `# rubocop:enable ...` statement
|
|
8
8
|
# after a `# rubocop:disable ...` statement. This will prevent leaving
|
|
9
|
-
# cop disables on wide ranges of code, that
|
|
9
|
+
# cop disables on wide ranges of code, that later contributors to
|
|
10
10
|
# a file wouldn't be aware of.
|
|
11
11
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
12
|
+
# You can set `MaxRangeSize` to define the maximum number of
|
|
13
|
+
# consecutive lines a cop can be disabled for.
|
|
14
|
+
#
|
|
15
|
+
# - `.inf` any size (default)
|
|
16
|
+
# - `0` allows only single-line disables
|
|
17
|
+
# - `1` means the maximum allowed is as follows:
|
|
18
|
+
#
|
|
19
|
+
# [source,ruby]
|
|
20
|
+
# ----
|
|
21
|
+
# # rubocop:disable SomeCop
|
|
22
|
+
# a = 1
|
|
23
|
+
# # rubocop:enable SomeCop
|
|
24
|
+
# ----
|
|
25
|
+
#
|
|
26
|
+
# @example MaxRangeSize: .inf (default)
|
|
15
27
|
#
|
|
16
28
|
# # good
|
|
17
29
|
# # rubocop:disable Layout/SpaceAroundOperators
|
|
@@ -25,9 +37,7 @@ module RuboCop
|
|
|
25
37
|
# x= 0
|
|
26
38
|
# # EOF
|
|
27
39
|
#
|
|
28
|
-
# @example
|
|
29
|
-
# # Lint/MissingCopEnableDirective:
|
|
30
|
-
# # MaximumRangeSize: 2
|
|
40
|
+
# @example MaxRangeSize: 2
|
|
31
41
|
#
|
|
32
42
|
# # good
|
|
33
43
|
# # rubocop:disable Layout/SpaceAroundOperators
|
|
@@ -45,17 +55,16 @@ module RuboCop
|
|
|
45
55
|
class MissingCopEnableDirective < Base
|
|
46
56
|
include RangeHelp
|
|
47
57
|
|
|
48
|
-
MSG = 'Re-enable %<cop>s %<type>s with
|
|
58
|
+
MSG = 'Re-enable %<cop>s %<type>s with `%<directive>s` after disabling it.'
|
|
49
59
|
MSG_BOUND = 'Re-enable %<cop>s %<type>s within %<max_range>s lines after disabling it.'
|
|
50
60
|
|
|
51
61
|
def on_new_investigation
|
|
52
62
|
each_missing_enable do |cop, line_range|
|
|
53
63
|
next if acceptable_range?(cop, line_range)
|
|
54
64
|
|
|
55
|
-
range = source_range(processed_source.buffer, line_range.min, (0..0))
|
|
56
65
|
comment = processed_source.comment_at_line(line_range.begin)
|
|
57
66
|
|
|
58
|
-
add_offense(
|
|
67
|
+
add_offense(comment, message: message(cop, comment))
|
|
59
68
|
end
|
|
60
69
|
end
|
|
61
70
|
|
|
@@ -63,7 +72,12 @@ module RuboCop
|
|
|
63
72
|
|
|
64
73
|
def each_missing_enable
|
|
65
74
|
processed_source.disabled_line_ranges.each do |cop, line_ranges|
|
|
66
|
-
line_ranges.each
|
|
75
|
+
line_ranges.each do |line_range|
|
|
76
|
+
# A `disable-next` scope closes itself with its statement.
|
|
77
|
+
next if line_range.respond_to?(:directive) && line_range.directive.disable_next?
|
|
78
|
+
|
|
79
|
+
yield cop, line_range
|
|
80
|
+
end
|
|
67
81
|
end
|
|
68
82
|
end
|
|
69
83
|
|
|
@@ -71,31 +85,40 @@ module RuboCop
|
|
|
71
85
|
# This has to remain a strict inequality to handle
|
|
72
86
|
# the case when max_range is Float::INFINITY
|
|
73
87
|
return true if line_range.max - line_range.min < max_range + 2
|
|
88
|
+
# A name that is not registered as written (e.g. a wrongly-namespaced
|
|
89
|
+
# cop) suppresses nothing; `Lint/RedundantCopDisableDirective` reports
|
|
90
|
+
# it, so demanding its re-enablement would only add noise.
|
|
91
|
+
return true unless Registry.global.names.include?(cop)
|
|
92
|
+
|
|
93
|
+
expected_open_range?(cop, line_range)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def expected_open_range?(cop, line_range)
|
|
74
97
|
# This cop is disabled in the config, it is not expected to be re-enabled
|
|
75
98
|
return true if line_range.min == CommentConfig::CONFIG_DISABLED_LINE_RANGE_MIN
|
|
76
99
|
|
|
77
|
-
cop_class = RuboCop::Cop::Registry.global.find_by_cop_name
|
|
78
|
-
|
|
100
|
+
cop_class = RuboCop::Cop::Registry.global.find_by_cop_name(cop)
|
|
101
|
+
!!(cop_class &&
|
|
79
102
|
!processed_source.registry.enabled?(cop_class, config) &&
|
|
80
|
-
line_range.max == Float::INFINITY
|
|
81
|
-
return true
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
false
|
|
103
|
+
line_range.max == Float::INFINITY)
|
|
85
104
|
end
|
|
86
105
|
|
|
87
106
|
def max_range
|
|
88
|
-
@max_range ||= cop_config['
|
|
107
|
+
@max_range ||= cop_config['MaxRangeSize']
|
|
89
108
|
end
|
|
90
109
|
|
|
91
110
|
def message(cop, comment, type = 'cop')
|
|
111
|
+
directive = DirectiveComment.new(comment)
|
|
92
112
|
if department_enabled?(cop, comment)
|
|
93
113
|
type = 'department'
|
|
94
114
|
cop = cop.split('/').first
|
|
95
115
|
end
|
|
96
116
|
|
|
97
117
|
if max_range == Float::INFINITY
|
|
98
|
-
|
|
118
|
+
# A range opened by `rubocop:push` is closed by `rubocop:pop`,
|
|
119
|
+
# not by `rubocop:enable`.
|
|
120
|
+
enabling_directive = directive.push? ? '# rubocop:pop' : '# rubocop:enable'
|
|
121
|
+
format(MSG, cop: cop, type: type, directive: enabling_directive)
|
|
99
122
|
else
|
|
100
123
|
format(MSG_BOUND, cop: cop, type: type, max_range: max_range)
|
|
101
124
|
end
|
|
@@ -108,4 +131,3 @@ module RuboCop
|
|
|
108
131
|
end
|
|
109
132
|
end
|
|
110
133
|
end
|
|
111
|
-
# rubocop:enable Lint/RedundantCopDisableDirective
|
|
@@ -21,6 +21,13 @@ module RuboCop
|
|
|
21
21
|
# `AllowedParentClasses` option to specify which classes should be allowed
|
|
22
22
|
# *in addition to* `Object` and `BasicObject`.
|
|
23
23
|
#
|
|
24
|
+
# When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is installed,
|
|
25
|
+
# the constructor check additionally consults the project-wide index: if the
|
|
26
|
+
# class' entire ancestry is resolvable and no ancestor defines `initialize`,
|
|
27
|
+
# no offense is registered, since `super` would only reach the no-op
|
|
28
|
+
# `Object#initialize`. Classes whose ancestry contains an unresolvable
|
|
29
|
+
# superclass or mixin (e.g. one defined in a gem) are still reported.
|
|
30
|
+
#
|
|
24
31
|
# @example
|
|
25
32
|
# # bad
|
|
26
33
|
# class Employee < Person
|
|
@@ -83,6 +90,8 @@ module RuboCop
|
|
|
83
90
|
# end
|
|
84
91
|
#
|
|
85
92
|
class MissingSuper < Base
|
|
93
|
+
include ProjectIndexHelp
|
|
94
|
+
|
|
86
95
|
CONSTRUCTOR_MSG = 'Call `super` to initialize state of the parent class.'
|
|
87
96
|
CALLBACK_MSG = 'Call `super` to invoke callback defined in the parent class.'
|
|
88
97
|
|
|
@@ -140,7 +149,8 @@ module RuboCop
|
|
|
140
149
|
|
|
141
150
|
!allowed_class?(super_class)
|
|
142
151
|
elsif (class_node = node.each_ancestor(:class).first)
|
|
143
|
-
class_node.parent_class && !allowed_class?(class_node.parent_class)
|
|
152
|
+
class_node.parent_class && !allowed_class?(class_node.parent_class) &&
|
|
153
|
+
!index_verified_stateless_ancestry?(class_node)
|
|
144
154
|
else
|
|
145
155
|
false
|
|
146
156
|
end
|
|
@@ -153,6 +163,26 @@ module RuboCop
|
|
|
153
163
|
def allowed_classes
|
|
154
164
|
@allowed_classes ||= STATELESS_CLASSES + cop_config.fetch('AllowedParentClasses', [])
|
|
155
165
|
end
|
|
166
|
+
|
|
167
|
+
# With the project index, the offense is skipped when the class' whole ancestry
|
|
168
|
+
# is resolvable and none of the inherited ancestors defines `initialize` —
|
|
169
|
+
# `super` would only reach the no-op `Object#initialize`. An unresolvable
|
|
170
|
+
# superclass or mixin anywhere in the chain (e.g. a class from a gem) means
|
|
171
|
+
# the ancestry cannot be verified and the offense is kept.
|
|
172
|
+
def index_verified_stateless_ancestry?(class_node)
|
|
173
|
+
return false unless project_index
|
|
174
|
+
|
|
175
|
+
declaration = resolve_constant_in_index(class_node.identifier)
|
|
176
|
+
return false unless declaration.is_a?(Rubydex::Class)
|
|
177
|
+
|
|
178
|
+
ancestors = declaration.ancestors.to_a
|
|
179
|
+
inherited = ancestors.reject { |ancestor| ancestor.name == declaration.name }
|
|
180
|
+
return false if inherited.any? { |ancestor| ancestor.member('initialize()') }
|
|
181
|
+
|
|
182
|
+
# `extend` affects the singleton class and cannot introduce an
|
|
183
|
+
# inherited `initialize`, so unresolved extends are tolerated.
|
|
184
|
+
fully_resolved_index_ancestry?(declaration, ignore_extend: true)
|
|
185
|
+
end
|
|
156
186
|
end
|
|
157
187
|
end
|
|
158
188
|
end
|
|
@@ -79,7 +79,7 @@ module RuboCop
|
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
def range_pairs(expr)
|
|
82
|
-
|
|
82
|
+
expr.expressions.filter_map { |e| [e.expressions[0], e.expressions[1]] if e.type == :set }
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def unsafe_range?(range_start, range_end)
|
|
@@ -94,7 +94,7 @@ module RuboCop
|
|
|
94
94
|
|
|
95
95
|
def skip_range?(range_start, range_end)
|
|
96
96
|
[range_start, range_end].any? do |bound|
|
|
97
|
-
bound
|
|
97
|
+
bound&.type != :literal
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
100
|
|
|
@@ -4,8 +4,8 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Lint
|
|
6
6
|
# In math and Python, we can use `x < y < z` style comparison to compare
|
|
7
|
-
# multiple
|
|
8
|
-
# the comparison is not syntax error. This cop checks the bad usage of
|
|
7
|
+
# multiple values. However, we can't use the comparison in Ruby. However,
|
|
8
|
+
# the comparison is not a syntax error. This cop checks the bad usage of
|
|
9
9
|
# comparison operators.
|
|
10
10
|
#
|
|
11
11
|
# @example
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'did_you_mean'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
nil
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module RuboCop
|
|
10
|
+
module Cop
|
|
11
|
+
module Lint
|
|
12
|
+
# Checks for probable typos in constant and method names: a name that
|
|
13
|
+
# does not resolve anywhere in the project, used in a namespace the
|
|
14
|
+
# project does define, with a close-named sibling to suggest instead.
|
|
15
|
+
#
|
|
16
|
+
# The check is powered by the project-wide index, so it only runs when
|
|
17
|
+
# `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is installed.
|
|
18
|
+
# Without the index the cop does nothing.
|
|
19
|
+
#
|
|
20
|
+
# Constants are checked only in qualified references (`Foo::Bar`) whose
|
|
21
|
+
# namespace resolves in the index; bare names cannot be distinguished
|
|
22
|
+
# from constants provided by gems or the standard library. Methods are
|
|
23
|
+
# checked only in calls on constant receivers (`Foo.bar`) whose entire
|
|
24
|
+
# indexed ancestry is resolved, so methods gained through gem classes or
|
|
25
|
+
# dynamic definitions never produce offenses. In both cases an offense
|
|
26
|
+
# requires a similarly named alternative to exist — an unknown name
|
|
27
|
+
# alone is not reported, since the index does not see gems or the
|
|
28
|
+
# standard library.
|
|
29
|
+
#
|
|
30
|
+
# For the same reason, a namespace whose root segment names a gem in the
|
|
31
|
+
# bundle (`Flipper` for the `flipper` gem) is left alone: a project that
|
|
32
|
+
# reopens it (`module Flipper; module Adapters; ...`) makes it resolve in
|
|
33
|
+
# the index, while the members the gem itself defines stay invisible and
|
|
34
|
+
# would look like typos. Enabling `AllCops/ProjectIndexIncludesGems`
|
|
35
|
+
# indexes those sources and restores the check.
|
|
36
|
+
#
|
|
37
|
+
# Names that appear as symbols or inside string literals in the same
|
|
38
|
+
# file are never reported, since they usually belong to runtime
|
|
39
|
+
# definitions the index cannot see (`stub_const`, `const_set`,
|
|
40
|
+
# `define_method`, and the like).
|
|
41
|
+
#
|
|
42
|
+
# @example
|
|
43
|
+
# # bad - Services::UserCraetor is not defined, Services::UserCreator is
|
|
44
|
+
# Services::UserCraetor.new
|
|
45
|
+
#
|
|
46
|
+
# # good
|
|
47
|
+
# Services::UserCreator.new
|
|
48
|
+
#
|
|
49
|
+
# # bad - Report.generate_sumary is not defined, Report.generate_summary is
|
|
50
|
+
# Report.generate_sumary
|
|
51
|
+
#
|
|
52
|
+
# # good
|
|
53
|
+
# Report.generate_summary
|
|
54
|
+
#
|
|
55
|
+
# @example CheckConstants: false
|
|
56
|
+
# # good - constant references are not checked
|
|
57
|
+
# Services::UserCraetor.new
|
|
58
|
+
#
|
|
59
|
+
# @example CheckMethods: false
|
|
60
|
+
# # good - method calls are not checked
|
|
61
|
+
# Report.generate_sumary
|
|
62
|
+
#
|
|
63
|
+
# @example AllowedNames: ['generate_sumary']
|
|
64
|
+
# # good - the name is explicitly allowed
|
|
65
|
+
# Report.generate_sumary
|
|
66
|
+
#
|
|
67
|
+
class NameTypo < Base
|
|
68
|
+
include ProjectIndexHelp
|
|
69
|
+
|
|
70
|
+
CONSTANT_MSG = 'Possible typo: `%<name>s` is not defined in `%<namespace>s`. ' \
|
|
71
|
+
'Did you mean `%<suggestion>s`?'
|
|
72
|
+
METHOD_MSG = 'Possible typo: `%<receiver>s` does not respond to `%<name>s`. ' \
|
|
73
|
+
'Did you mean `%<suggestion>s`?'
|
|
74
|
+
|
|
75
|
+
METHOD_MEMBER_REGEXP = /#([a-zA-Z_]\w*[?!]?)\(\)\z/.freeze
|
|
76
|
+
LITERAL_IDENTIFIER_PATTERN = /[a-zA-Z_]\w*[?!]?/.freeze
|
|
77
|
+
|
|
78
|
+
def on_const(node)
|
|
79
|
+
return unless check?('CheckConstants') && checkable_constant?(node)
|
|
80
|
+
|
|
81
|
+
suggestion = constant_typo_suggestion(node)
|
|
82
|
+
return unless suggestion
|
|
83
|
+
|
|
84
|
+
message = format(CONSTANT_MSG, name: node.short_name,
|
|
85
|
+
namespace: node.namespace.const_name,
|
|
86
|
+
suggestion: suggestion)
|
|
87
|
+
add_offense(node.loc.name, message: message)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def on_send(node)
|
|
91
|
+
return unless check?('CheckMethods')
|
|
92
|
+
return unless node.receiver&.const_type?
|
|
93
|
+
return if allowed_name?(node.method_name) || defined_check?(node)
|
|
94
|
+
|
|
95
|
+
suggestion = method_typo_suggestion(node)
|
|
96
|
+
return unless suggestion
|
|
97
|
+
|
|
98
|
+
message = format(METHOD_MSG, receiver: node.receiver.const_name,
|
|
99
|
+
name: node.method_name,
|
|
100
|
+
suggestion: suggestion)
|
|
101
|
+
add_offense(node.loc.selector, message: message)
|
|
102
|
+
end
|
|
103
|
+
alias on_csend on_send
|
|
104
|
+
|
|
105
|
+
def on_new_investigation
|
|
106
|
+
@literal_names = nil
|
|
107
|
+
super
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
private
|
|
111
|
+
|
|
112
|
+
def check?(key)
|
|
113
|
+
project_index && defined?(DidYouMean::SpellChecker) && cop_config.fetch(key, true)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def checkable_constant?(node)
|
|
117
|
+
node.namespace&.const_type? &&
|
|
118
|
+
!allowed_name?(node.short_name) &&
|
|
119
|
+
!definition_identifier?(node) && !defined_check?(node)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def allowed_name?(name)
|
|
123
|
+
cop_config.fetch('AllowedNames', []).include?(name.to_s)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# The last segment of a class, module or constant definition is being
|
|
127
|
+
# defined, not referenced.
|
|
128
|
+
def definition_identifier?(node)
|
|
129
|
+
node.parent&.defined_module
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# `defined?(Foo::Bar)` probes whether a name exists; unknown names
|
|
133
|
+
# there are deliberate.
|
|
134
|
+
def defined_check?(node)
|
|
135
|
+
node.each_ancestor(:defined?).any?
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def constant_typo_suggestion(node)
|
|
139
|
+
namespace = resolve_constant_in_index(node.namespace)
|
|
140
|
+
return nil unless namespace.is_a?(Rubydex::Namespace)
|
|
141
|
+
return nil if namespace.find_member(node.short_name.to_s)
|
|
142
|
+
return nil unless complete_index_members?(namespace)
|
|
143
|
+
return nil if literal_names.include?(node.short_name.to_s)
|
|
144
|
+
|
|
145
|
+
spell_check(node.short_name, constant_member_names(namespace))
|
|
146
|
+
rescue StandardError
|
|
147
|
+
nil
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Whether the index can be trusted to list everything the namespace
|
|
151
|
+
# defines. A name missing from an incomplete member list is not
|
|
152
|
+
# evidence of a typo, so both gaps have to be ruled out first:
|
|
153
|
+
# an ancestor that does not resolve may contribute the name, and so
|
|
154
|
+
# may a gem that reopens the namespace.
|
|
155
|
+
def complete_index_members?(declaration)
|
|
156
|
+
fully_resolved_index_ancestry?(declaration) && !gem_owned_namespace?(declaration)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Whether the namespace's root segment names a gem in the bundle,
|
|
160
|
+
# which is then free to define members the index never sees: gem
|
|
161
|
+
# sources are only indexed when `AllCops/ProjectIndexIncludesGems`
|
|
162
|
+
# is enabled. A project that reopens such a namespace to add its own
|
|
163
|
+
# members (`module Flipper; module Adapters; ...`) makes it resolve
|
|
164
|
+
# in the index while most of what it holds stays invisible.
|
|
165
|
+
def gem_owned_namespace?(declaration)
|
|
166
|
+
return false if config.for_all_cops['ProjectIndexIncludesGems']
|
|
167
|
+
|
|
168
|
+
root = declaration.name.to_s.split('::').first.to_s
|
|
169
|
+
bundled_gem_namespaces.include?(root.downcase)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Gem names normalized towards the constant they conventionally
|
|
173
|
+
# provide: `flipper` for `Flipper`, `activerecord` for `ActiveRecord`.
|
|
174
|
+
def bundled_gem_namespaces
|
|
175
|
+
@bundled_gem_namespaces ||= bundled_gem_names.to_set { |name| name.delete('-_').downcase }
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# The bundle's gems except those sourced from a local path, whose code
|
|
179
|
+
# lives in the project and is indexed like the rest of it — among them
|
|
180
|
+
# the project's own gem, which its lockfile lists in the `PATH` section.
|
|
181
|
+
def bundled_gem_names
|
|
182
|
+
(config.gem_versions_in_target || {}).keys - (config.path_sourced_gems_in_target || [])
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Writers are indexed under the reader's name, so setter calls are
|
|
186
|
+
# verified and spell-checked through the base name.
|
|
187
|
+
def method_typo_suggestion(node)
|
|
188
|
+
setter = setter_call?(node)
|
|
189
|
+
base = setter ? node.method_name.to_s.delete_suffix('=') : node.method_name.to_s
|
|
190
|
+
|
|
191
|
+
declaration = unknown_method_owner(node, base)
|
|
192
|
+
return nil unless declaration
|
|
193
|
+
return nil if literal_names.include?(base)
|
|
194
|
+
|
|
195
|
+
suggestion = spell_check(base, method_member_names(declaration))
|
|
196
|
+
suggestion && setter ? "#{suggestion}=" : suggestion
|
|
197
|
+
rescue StandardError
|
|
198
|
+
nil
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# The receiver's declaration when it resolves in the index, everything
|
|
202
|
+
# it can inherit or be reopened with is visible there, and the method
|
|
203
|
+
# is not found — nil otherwise.
|
|
204
|
+
def unknown_method_owner(node, base)
|
|
205
|
+
declaration = resolve_constant_in_index(node.receiver)
|
|
206
|
+
return nil unless declaration.is_a?(Rubydex::Namespace)
|
|
207
|
+
return nil if responds_in_index?(declaration, node.method_name.to_s, base)
|
|
208
|
+
return nil unless fully_resolved_index_ancestry?(declaration)
|
|
209
|
+
return nil if gem_owned_namespace?(declaration)
|
|
210
|
+
|
|
211
|
+
declaration
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def setter_call?(node)
|
|
215
|
+
node.assignment_method? && !node.operator_method?
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def responds_in_index?(declaration, name, base)
|
|
219
|
+
# Instance methods of a module are also callable on the module
|
|
220
|
+
# itself when exposed with `module_function`.
|
|
221
|
+
[name, base].uniq.any? do |candidate|
|
|
222
|
+
member_name = "#{candidate}()"
|
|
223
|
+
indexed_singleton_member(declaration, member_name) ||
|
|
224
|
+
declaration.find_member(member_name)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Names mentioned as symbols or inside string literals in the current
|
|
229
|
+
# file belong to runtime definitions (`stub_const`, `const_set`,
|
|
230
|
+
# `define_method`) that the index cannot see.
|
|
231
|
+
def literal_names
|
|
232
|
+
@literal_names ||=
|
|
233
|
+
processed_source.ast.each_descendant(:sym, :str)
|
|
234
|
+
.with_object(Set.new) do |literal, names|
|
|
235
|
+
if literal.sym_type?
|
|
236
|
+
names << literal.value.to_s
|
|
237
|
+
else
|
|
238
|
+
# `scan` raises on binary string literals with invalid byte sequences.
|
|
239
|
+
value = literal.value
|
|
240
|
+
value = value.scrub unless value.valid_encoding?
|
|
241
|
+
value.scan(LITERAL_IDENTIFIER_PATTERN) { |token| names << token }
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def constant_member_names(namespace)
|
|
247
|
+
namespace.members.filter_map do |member|
|
|
248
|
+
name = member.name
|
|
249
|
+
name.split('::').last unless name.include?('#') || name.include?('<')
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def method_member_names(declaration)
|
|
254
|
+
scopes = declaration.ancestors.filter_map { |ancestor| indexed_singleton_of(ancestor) }
|
|
255
|
+
scopes << declaration
|
|
256
|
+
|
|
257
|
+
scopes.flat_map do |scope|
|
|
258
|
+
scope.members.filter_map { |member| member.name[METHOD_MEMBER_REGEXP, 1] }
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def spell_check(name, dictionary)
|
|
263
|
+
return nil if dictionary.empty?
|
|
264
|
+
|
|
265
|
+
DidYouMean::SpellChecker.new(dictionary: dictionary.uniq).correct(name.to_s).first
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
@@ -95,10 +95,10 @@ module RuboCop
|
|
|
95
95
|
MSG = 'Method definitions must not be nested. Use `lambda` instead.'
|
|
96
96
|
|
|
97
97
|
def on_def(node)
|
|
98
|
-
subject, = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
|
98
|
+
subject, = *node # rubocop:disable InternalAffairs/NodeDestructuring -- the first child differs between `def` and `defs`
|
|
99
99
|
return if node.defs_type? && allowed_subject_type?(subject)
|
|
100
100
|
|
|
101
|
-
def_ancestor = node.each_ancestor(:
|
|
101
|
+
def_ancestor = node.each_ancestor(:any_def).first
|
|
102
102
|
return unless def_ancestor
|
|
103
103
|
|
|
104
104
|
within_scoping_def =
|
|
@@ -31,6 +31,7 @@ module RuboCop
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
alias on_numblock on_block
|
|
34
|
+
alias on_itblock on_block
|
|
34
35
|
|
|
35
36
|
private
|
|
36
37
|
|
|
@@ -39,6 +40,7 @@ module RuboCop
|
|
|
39
40
|
{
|
|
40
41
|
(block (call _recv {:reduce :inject} !sym) _blockargs $(begin ...))
|
|
41
42
|
(numblock (call _recv {:reduce :inject} !sym) _argscount $(begin ...))
|
|
43
|
+
(itblock (call _recv {:reduce :inject} !sym) _argscount $(begin ...))
|
|
42
44
|
}
|
|
43
45
|
PATTERN
|
|
44
46
|
|
|
@@ -41,12 +41,32 @@ module RuboCop
|
|
|
41
41
|
def on_lvasgn(node)
|
|
42
42
|
node.each_node(:kwbegin) do |kwbegin_node|
|
|
43
43
|
kwbegin_node.each_node(:return) do |return_node|
|
|
44
|
+
next if return_from_inner_scope?(return_node, kwbegin_node)
|
|
45
|
+
|
|
44
46
|
add_offense(return_node)
|
|
45
47
|
end
|
|
46
48
|
end
|
|
47
49
|
end
|
|
50
|
+
alias on_ivasgn on_lvasgn
|
|
51
|
+
alias on_cvasgn on_lvasgn
|
|
52
|
+
alias on_gvasgn on_lvasgn
|
|
53
|
+
alias on_casgn on_lvasgn
|
|
48
54
|
alias on_or_asgn on_lvasgn
|
|
49
55
|
alias on_op_asgn on_lvasgn
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
# A `return` inside a nested method definition or lambda within the
|
|
60
|
+
# `begin..end` returns from that inner scope rather than the assignment
|
|
61
|
+
# context, so it is not an offense. A `return` inside a plain block (or
|
|
62
|
+
# `proc`) does propagate out, so it remains an offense.
|
|
63
|
+
def return_from_inner_scope?(return_node, kwbegin_node)
|
|
64
|
+
return_node.each_ancestor do |ancestor|
|
|
65
|
+
break if ancestor == kwbegin_node
|
|
66
|
+
return true if ancestor.any_def_type? || (ancestor.any_block_type? && ancestor.lambda?)
|
|
67
|
+
end
|
|
68
|
+
false
|
|
69
|
+
end
|
|
50
70
|
end
|
|
51
71
|
end
|
|
52
72
|
end
|
|
@@ -12,7 +12,7 @@ module RuboCop
|
|
|
12
12
|
# always sort the list.
|
|
13
13
|
#
|
|
14
14
|
# `Dir.glob` and `Dir[]` sort globbed results by default in Ruby 3.0.
|
|
15
|
-
# So all bad cases are acceptable when Ruby 3.0 or higher
|
|
15
|
+
# So all bad cases are acceptable when Ruby 3.0 or higher is used.
|
|
16
16
|
#
|
|
17
17
|
# NOTE: This cop will be deprecated and removed when supporting only Ruby 3.0 and higher.
|
|
18
18
|
#
|
|
@@ -65,7 +65,9 @@ module RuboCop
|
|
|
65
65
|
|
|
66
66
|
maximum_target_ruby_version 2.7
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
# NOTE: itblock is not handled because this cop is limited to Ruby <= 2.7
|
|
69
|
+
# via `maximum_target_ruby_version`, so itblock nodes (Ruby 3.4+) are never encountered.
|
|
70
|
+
def on_block(node) # rubocop:disable InternalAffairs/ItblockHandler -- limited to Ruby <= 2.7, where `it` blocks do not exist
|
|
69
71
|
return unless node.body
|
|
70
72
|
return unless unsorted_dir_loop?(node.send_node)
|
|
71
73
|
|
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
|
46
46
|
def on_return(return_node)
|
|
47
47
|
return if return_value?(return_node)
|
|
48
48
|
|
|
49
|
-
return_node.each_ancestor(:
|
|
49
|
+
return_node.each_ancestor(:any_block, :any_def) do |node|
|
|
50
50
|
break if scoped_node?(node)
|
|
51
51
|
|
|
52
52
|
# if a proc is passed to `Module#define_method` or
|
|
@@ -54,7 +54,7 @@ module RuboCop
|
|
|
54
54
|
# non-local exit error
|
|
55
55
|
break if define_method?(node.send_node)
|
|
56
56
|
|
|
57
|
-
next
|
|
57
|
+
next if node.argument_list.empty?
|
|
58
58
|
|
|
59
59
|
if chained_send?(node.send_node)
|
|
60
60
|
add_offense(return_node.loc.keyword)
|
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
|
66
66
|
private
|
|
67
67
|
|
|
68
68
|
def scoped_node?(node)
|
|
69
|
-
node.
|
|
69
|
+
node.any_def_type? || node.lambda?
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
def return_value?(return_node)
|
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
# @!method chained_send?(node)
|
|
77
|
-
def_node_matcher :chained_send?, '(
|
|
77
|
+
def_node_matcher :chained_send?, '(call !nil? ...)'
|
|
78
78
|
|
|
79
79
|
# @!method define_method?(node)
|
|
80
80
|
def_node_matcher :define_method?, <<~PATTERN
|