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
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Lint
|
|
6
|
+
# Checks for private instance methods that are not referenced anywhere
|
|
7
|
+
# in the project.
|
|
8
|
+
#
|
|
9
|
+
# The check is powered by the project-wide index, so it only runs when
|
|
10
|
+
# `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is installed.
|
|
11
|
+
# Without the index the cop does nothing.
|
|
12
|
+
#
|
|
13
|
+
# A method counts as referenced when a call with its name appears anywhere
|
|
14
|
+
# in the indexed project (regardless of the receiver), when it is the source
|
|
15
|
+
# of an `alias`, or when its name appears in the same file as a symbol or
|
|
16
|
+
# inside a string literal (covering `send(:name)` and declarative DSLs like
|
|
17
|
+
# `before_action :name`). An interpolated symbol or string with a literal
|
|
18
|
+
# prefix (e.g. `send(:"format_#{type}")`) counts as a reference to every
|
|
19
|
+
# method whose name starts with that prefix; fully dynamic names cannot
|
|
20
|
+
# be detected. Methods defined in classes or modules with descendants are
|
|
21
|
+
# not checked, since they may be invoked through `super` or inherited
|
|
22
|
+
# dispatch.
|
|
23
|
+
#
|
|
24
|
+
# Methods whose names are composed by a framework (e.g. Rails
|
|
25
|
+
# `attribute_method_suffix` generating `attribute?` methods) can be
|
|
26
|
+
# excluded from the check with `AllowedNames` (exact names) or
|
|
27
|
+
# `AllowedPatterns` (regular expressions).
|
|
28
|
+
#
|
|
29
|
+
# The cop is disabled by default because symbol-based references from
|
|
30
|
+
# *other* files (e.g. a Rails callback declared in a concern) cannot be
|
|
31
|
+
# detected and would be reported as false positives. It is best suited
|
|
32
|
+
# for occasional dead-code sweeps rather than permanent enforcement.
|
|
33
|
+
#
|
|
34
|
+
# @example
|
|
35
|
+
# # bad - `helper` is never referenced anywhere in the project
|
|
36
|
+
# class Service
|
|
37
|
+
# def call
|
|
38
|
+
# do_something
|
|
39
|
+
# end
|
|
40
|
+
#
|
|
41
|
+
# private
|
|
42
|
+
#
|
|
43
|
+
# def helper
|
|
44
|
+
# end
|
|
45
|
+
# end
|
|
46
|
+
#
|
|
47
|
+
# # good
|
|
48
|
+
# class Service
|
|
49
|
+
# def call
|
|
50
|
+
# do_something(helper)
|
|
51
|
+
# end
|
|
52
|
+
#
|
|
53
|
+
# private
|
|
54
|
+
#
|
|
55
|
+
# def helper
|
|
56
|
+
# end
|
|
57
|
+
# end
|
|
58
|
+
#
|
|
59
|
+
# @example AllowedNames: ['attribute?']
|
|
60
|
+
# # good - the name is explicitly allowed
|
|
61
|
+
# class Contact
|
|
62
|
+
# private
|
|
63
|
+
#
|
|
64
|
+
# def attribute?
|
|
65
|
+
# end
|
|
66
|
+
# end
|
|
67
|
+
#
|
|
68
|
+
# @example AllowedPatterns: ['_hook\z']
|
|
69
|
+
# # good - the name matches an allowed pattern
|
|
70
|
+
# class Service
|
|
71
|
+
# private
|
|
72
|
+
#
|
|
73
|
+
# def before_save_hook
|
|
74
|
+
# end
|
|
75
|
+
# end
|
|
76
|
+
#
|
|
77
|
+
class UnusedPrivateMethod < Base
|
|
78
|
+
include AllowedPattern
|
|
79
|
+
include ProjectIndexHelp
|
|
80
|
+
|
|
81
|
+
MSG = 'Private method `%<method>s` appears to be unused.'
|
|
82
|
+
|
|
83
|
+
IDENTIFIER_PATTERN = /[a-zA-Z_]\w*[?!=]?/.freeze
|
|
84
|
+
NAME_PREFIX_PATTERN = /[a-zA-Z_]\w*\z/.freeze
|
|
85
|
+
|
|
86
|
+
# Methods invoked implicitly by the Ruby runtime.
|
|
87
|
+
IMPLICITLY_INVOKED_METHODS = %i[
|
|
88
|
+
initialize initialize_copy initialize_clone initialize_dup
|
|
89
|
+
method_missing respond_to_missing? marshal_dump marshal_load
|
|
90
|
+
coerce instance_variables_to_inspect
|
|
91
|
+
inherited included extended prepended
|
|
92
|
+
append_features extend_object prepend_features
|
|
93
|
+
const_missing const_added
|
|
94
|
+
method_added method_removed method_undefined
|
|
95
|
+
singleton_method_added singleton_method_removed singleton_method_undefined
|
|
96
|
+
].to_set.freeze
|
|
97
|
+
|
|
98
|
+
class << self
|
|
99
|
+
# The reference-name set is a property of the index, not of the cop
|
|
100
|
+
# instance, so all per-file instances share one computation. A
|
|
101
|
+
# single-entry cache (instead of a hash keyed by index) avoids
|
|
102
|
+
# retaining stale graphs in long-lived processes.
|
|
103
|
+
attr_accessor :cached_reference_names
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def on_new_investigation
|
|
107
|
+
@literal_names = nil
|
|
108
|
+
@literal_name_prefixes = nil
|
|
109
|
+
super
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def on_def(node)
|
|
113
|
+
return unless project_index
|
|
114
|
+
|
|
115
|
+
declaration = checkable_declaration(node)
|
|
116
|
+
return unless declaration
|
|
117
|
+
return if referenced?(node.method_name)
|
|
118
|
+
return if owner_with_descendants?(declaration) || override?(declaration, node.method_name)
|
|
119
|
+
|
|
120
|
+
message = format(MSG, method: node.method_name)
|
|
121
|
+
add_offense(node.loc.keyword.join(node.loc.name), message: message)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
def checkable_declaration(node)
|
|
127
|
+
return nil if IMPLICITLY_INVOKED_METHODS.include?(node.method_name)
|
|
128
|
+
return nil if allowed_name?(node.method_name)
|
|
129
|
+
return nil if node.each_ancestor(:any_def, :any_block, :sclass).any?
|
|
130
|
+
return nil unless (namespace_node = node.each_ancestor(:class, :module).first)
|
|
131
|
+
|
|
132
|
+
declaration = method_declaration(node, namespace_node)
|
|
133
|
+
declaration if declaration&.private?
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def allowed_name?(method_name)
|
|
137
|
+
name = method_name.to_s
|
|
138
|
+
|
|
139
|
+
cop_config.fetch('AllowedNames', []).include?(name) || matches_allowed_pattern?(name)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def method_declaration(node, namespace_node)
|
|
143
|
+
namespace = resolve_constant_in_index(namespace_node.identifier)
|
|
144
|
+
return nil unless namespace.is_a?(Rubydex::Namespace)
|
|
145
|
+
|
|
146
|
+
namespace.member("#{node.method_name}()")
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def referenced?(method_name)
|
|
150
|
+
name = method_name.to_s
|
|
151
|
+
|
|
152
|
+
referenced_names.include?(name) || literal_names.include?(name) ||
|
|
153
|
+
literal_name_prefixes.any? { |prefix| name.start_with?(prefix) }
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def referenced_names
|
|
157
|
+
index, names = self.class.cached_reference_names
|
|
158
|
+
return names if index.equal?(project_index)
|
|
159
|
+
|
|
160
|
+
compute_referenced_names.tap do |computed|
|
|
161
|
+
self.class.cached_reference_names = [project_index, computed]
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def compute_referenced_names
|
|
166
|
+
project_index.method_references
|
|
167
|
+
.to_set { |reference| reference.name.delete_suffix('()') }
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Symbol literals and identifier-like tokens inside string literals in the
|
|
171
|
+
# current file, covering `send(:name)`, declarative DSLs like
|
|
172
|
+
# `before_action :name` and names embedded in strings (e.g. node-pattern
|
|
173
|
+
# `#helper` references).
|
|
174
|
+
def literal_names
|
|
175
|
+
@literal_names ||=
|
|
176
|
+
processed_source.ast.each_descendant(:sym, :str)
|
|
177
|
+
.with_object(Set.new) do |literal, names|
|
|
178
|
+
if literal.sym_type?
|
|
179
|
+
names << literal.value.to_s
|
|
180
|
+
else
|
|
181
|
+
# `scan` raises on binary string literals with invalid byte sequences.
|
|
182
|
+
value = literal.value
|
|
183
|
+
value = value.scrub unless value.valid_encoding?
|
|
184
|
+
value.scan(IDENTIFIER_PATTERN) { |token| names << token }
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# The leading literal fragment of an interpolated symbol or string acts
|
|
190
|
+
# as a method-name prefix: `send(:"format_#{type}")` may invoke any
|
|
191
|
+
# method whose name starts with `format_`. Only the leading fragment
|
|
192
|
+
# qualifies (a mid-string fragment is not a name prefix), and a fully
|
|
193
|
+
# dynamic name contributes nothing.
|
|
194
|
+
def literal_name_prefixes
|
|
195
|
+
@literal_name_prefixes ||=
|
|
196
|
+
processed_source.ast.each_descendant(:dsym, :dstr)
|
|
197
|
+
.with_object(Set.new) do |literal, prefixes|
|
|
198
|
+
prefix = interpolation_prefix(literal)
|
|
199
|
+
prefixes << prefix if prefix
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def interpolation_prefix(node)
|
|
204
|
+
return nil if node.children.all?(&:str_type?)
|
|
205
|
+
|
|
206
|
+
leading_fragment = node.children.first
|
|
207
|
+
return nil unless leading_fragment&.str_type?
|
|
208
|
+
|
|
209
|
+
leading_fragment.value[NAME_PREFIX_PATTERN]
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# A method defined in a class or module with descendants may be invoked
|
|
213
|
+
# through `super` or inherited dispatch, which the index does not track.
|
|
214
|
+
def owner_with_descendants?(declaration)
|
|
215
|
+
owner = declaration.owner
|
|
216
|
+
return false unless owner.is_a?(Rubydex::Namespace)
|
|
217
|
+
|
|
218
|
+
owner.descendants.any? { |descendant| descendant.name != owner.name }
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# An override of an inherited method may be invoked polymorphically
|
|
222
|
+
# (e.g. a framework hook), even when no direct reference exists.
|
|
223
|
+
def override?(declaration, method_name)
|
|
224
|
+
owner = declaration.owner
|
|
225
|
+
return false unless owner.is_a?(Rubydex::Namespace)
|
|
226
|
+
|
|
227
|
+
owner.ancestors.any? do |ancestor|
|
|
228
|
+
ancestor.name != owner.name && ancestor.member("#{method_name}()")
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
@@ -17,6 +17,7 @@ module RuboCop
|
|
|
17
17
|
#
|
|
18
18
|
# # good
|
|
19
19
|
# CGI.escape('http://example.com')
|
|
20
|
+
# URI.encode_uri_component(uri) # Since Ruby 3.1
|
|
20
21
|
# URI.encode_www_form([['example', 'param'], ['lang', 'en']])
|
|
21
22
|
# URI.encode_www_form(page: 10, locale: 'en')
|
|
22
23
|
# URI.encode_www_form_component('http://example.com')
|
|
@@ -27,6 +28,7 @@ module RuboCop
|
|
|
27
28
|
#
|
|
28
29
|
# # good
|
|
29
30
|
# CGI.unescape(enc_uri)
|
|
31
|
+
# URI.decode_uri_component(uri) # Since Ruby 3.1
|
|
30
32
|
# URI.decode_www_form(enc_uri)
|
|
31
33
|
# URI.decode_www_form_component(enc_uri)
|
|
32
34
|
class UriEscapeUnescape < Base
|
|
@@ -4,10 +4,10 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Lint
|
|
6
6
|
# Checks for redundant access modifiers, including those with no
|
|
7
|
-
# code, those which are repeated,
|
|
8
|
-
# class or module body.
|
|
9
|
-
#
|
|
10
|
-
# are not redundant.
|
|
7
|
+
# code, those which are repeated, those which are on top-level, and
|
|
8
|
+
# leading `public` modifiers in a class or module body.
|
|
9
|
+
# Conditionally-defined methods are considered as always being defined,
|
|
10
|
+
# and thus access modifiers guarding such methods are not redundant.
|
|
11
11
|
#
|
|
12
12
|
# This cop has `ContextCreatingMethods` option. The default setting value
|
|
13
13
|
# is an empty array that means no method is specified.
|
|
@@ -58,6 +58,12 @@ module RuboCop
|
|
|
58
58
|
# private # this is redundant (no following methods are defined)
|
|
59
59
|
# end
|
|
60
60
|
#
|
|
61
|
+
# # bad
|
|
62
|
+
# private # this is useless (access modifiers have no effect on top-level)
|
|
63
|
+
#
|
|
64
|
+
# def method
|
|
65
|
+
# end
|
|
66
|
+
#
|
|
61
67
|
# # good
|
|
62
68
|
# class Foo
|
|
63
69
|
# private # this is not redundant (a method is defined)
|
|
@@ -143,6 +149,18 @@ module RuboCop
|
|
|
143
149
|
end
|
|
144
150
|
|
|
145
151
|
alias on_numblock on_block
|
|
152
|
+
alias on_itblock on_block
|
|
153
|
+
|
|
154
|
+
def on_begin(node)
|
|
155
|
+
return if node.parent
|
|
156
|
+
|
|
157
|
+
node.child_nodes.each do |child|
|
|
158
|
+
next unless child.send_type? && access_modifier?(child)
|
|
159
|
+
|
|
160
|
+
# This call always registers an offense for access modifier `child.method_name`
|
|
161
|
+
check_send_node(child, child.method_name, true)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
146
164
|
|
|
147
165
|
private
|
|
148
166
|
|
|
@@ -192,7 +210,7 @@ module RuboCop
|
|
|
192
210
|
end
|
|
193
211
|
end
|
|
194
212
|
|
|
195
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
213
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
196
214
|
def check_child_nodes(node, unused, cur_vis)
|
|
197
215
|
node.child_nodes.each do |child|
|
|
198
216
|
if child.send_type? && access_modifier?(child)
|
|
@@ -210,7 +228,6 @@ module RuboCop
|
|
|
210
228
|
|
|
211
229
|
[cur_vis, unused]
|
|
212
230
|
end
|
|
213
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
214
231
|
|
|
215
232
|
def check_send_node(node, cur_vis, unused)
|
|
216
233
|
if node.bare_access_modifier?
|
|
@@ -256,6 +273,10 @@ module RuboCop
|
|
|
256
273
|
|
|
257
274
|
def any_method_definition?(child)
|
|
258
275
|
cop_config.fetch('MethodCreatingMethods', []).any? do |m|
|
|
276
|
+
# Some users still have `"included"` in their `MethodCreatingMethods` configurations,
|
|
277
|
+
# so to prevent Ruby method redefinition warnings let's just skip this value.
|
|
278
|
+
next if m == 'included'
|
|
279
|
+
|
|
259
280
|
matcher_name = :"#{m}_method?"
|
|
260
281
|
unless respond_to?(matcher_name)
|
|
261
282
|
self.class.def_node_matcher matcher_name, <<~PATTERN
|
|
@@ -278,7 +299,11 @@ module RuboCop
|
|
|
278
299
|
end
|
|
279
300
|
|
|
280
301
|
def any_context_creating_methods?(child)
|
|
302
|
+
# Some users still have `"included"` in their `ContextCreatingMethods` configurations,
|
|
303
|
+
# so to prevent Ruby method redefinition warnings let's just skip this value.
|
|
281
304
|
cop_config.fetch('ContextCreatingMethods', []).any? do |m|
|
|
305
|
+
next if m == 'included'
|
|
306
|
+
|
|
282
307
|
matcher_name = :"#{m}_block?"
|
|
283
308
|
unless respond_to?(matcher_name)
|
|
284
309
|
self.class.def_node_matcher matcher_name, <<~PATTERN
|
|
@@ -40,8 +40,6 @@ module RuboCop
|
|
|
40
40
|
class UselessAssignment < Base
|
|
41
41
|
extend AutoCorrector
|
|
42
42
|
|
|
43
|
-
include RangeHelp
|
|
44
|
-
|
|
45
43
|
MSG = 'Useless assignment to variable - `%<variable>s`.'
|
|
46
44
|
|
|
47
45
|
def self.joining_forces
|
|
@@ -52,32 +50,44 @@ module RuboCop
|
|
|
52
50
|
scope.variables.each_value { |variable| check_for_unused_assignments(variable) }
|
|
53
51
|
end
|
|
54
52
|
|
|
55
|
-
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
56
53
|
def check_for_unused_assignments(variable)
|
|
57
54
|
return if variable.should_be_unused?
|
|
58
55
|
|
|
59
56
|
variable.assignments.reverse_each do |assignment|
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
check_for_unused_assignment(variable, assignment)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
62
60
|
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
def check_for_unused_assignment(variable, assignment)
|
|
62
|
+
assignment_node = assignment.node
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
# In cases like `x = 1, y = 2`, where removing a variable would cause a syntax error,
|
|
68
|
-
# and where changing `x ||= 1` to `x = 1` would cause `NameError`,
|
|
69
|
-
# the autocorrect will be skipped, even if the variable is unused.
|
|
70
|
-
if sequential_assignment?(assignment_node) || assignment_node.parent&.or_asgn_type?
|
|
71
|
-
next
|
|
72
|
-
end
|
|
64
|
+
return if ignored_assignment?(variable, assignment_node, assignment)
|
|
73
65
|
|
|
74
|
-
|
|
75
|
-
|
|
66
|
+
message = message_for_useless_assignment(assignment)
|
|
67
|
+
range = offense_range(assignment)
|
|
76
68
|
|
|
77
|
-
|
|
69
|
+
add_offense(range, message: message) do |corrector|
|
|
70
|
+
next if uncorrectable_assignment?(assignment_node)
|
|
71
|
+
|
|
72
|
+
autocorrect(corrector, assignment)
|
|
78
73
|
end
|
|
74
|
+
|
|
75
|
+
ignore_node(assignment_node) if chained_assignment?(assignment_node)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Autocorrect is skipped when removing a variable would cause a syntax error
|
|
79
|
+
# (`x = 1, y = 2`), or where rewriting `x ||= 1`/`x &&= 1` to `x = 1` would raise
|
|
80
|
+
# `NameError` because the variable is not declared before the operator assignment.
|
|
81
|
+
def uncorrectable_assignment?(assignment_node)
|
|
82
|
+
sequential_assignment?(assignment_node) ||
|
|
83
|
+
assignment_node.parent&.or_asgn_type? ||
|
|
84
|
+
assignment_node.parent&.and_asgn_type?
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def ignored_assignment?(variable, assignment_node, assignment)
|
|
88
|
+
assignment.used? || part_of_ignored_node?(assignment_node) ||
|
|
89
|
+
variable_in_loop_condition?(assignment_node, variable)
|
|
79
90
|
end
|
|
80
|
-
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
81
91
|
|
|
82
92
|
def message_for_useless_assignment(assignment)
|
|
83
93
|
variable = assignment.variable
|
|
@@ -104,6 +114,8 @@ module RuboCop
|
|
|
104
114
|
end
|
|
105
115
|
|
|
106
116
|
def chained_assignment?(node)
|
|
117
|
+
return true if node.lvasgn_type? && node.expression&.send_type?
|
|
118
|
+
|
|
107
119
|
node.respond_to?(:expression) && node.expression&.lvasgn_type?
|
|
108
120
|
end
|
|
109
121
|
|
|
@@ -161,7 +173,7 @@ module RuboCop
|
|
|
161
173
|
node.receiver.nil? && !node.arguments?
|
|
162
174
|
end
|
|
163
175
|
|
|
164
|
-
# rubocop:disable Metrics/AbcSize
|
|
176
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
165
177
|
def autocorrect(corrector, assignment)
|
|
166
178
|
if assignment.exception_assignment?
|
|
167
179
|
remove_exception_assignment_part(corrector, assignment.node)
|
|
@@ -177,15 +189,11 @@ module RuboCop
|
|
|
177
189
|
remove_local_variable_assignment_part(corrector, assignment.node)
|
|
178
190
|
end
|
|
179
191
|
end
|
|
180
|
-
# rubocop:enable Metrics/AbcSize
|
|
181
192
|
|
|
182
193
|
def remove_exception_assignment_part(corrector, node)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
node.source_range.end_pos
|
|
187
|
-
)
|
|
188
|
-
)
|
|
194
|
+
range = node.parent.children.first&.source_range || node.parent.location.keyword
|
|
195
|
+
|
|
196
|
+
corrector.remove(range.end.join(node.source_range.end))
|
|
189
197
|
end
|
|
190
198
|
|
|
191
199
|
def rename_variable_with_underscore(corrector, node)
|
|
@@ -204,7 +212,28 @@ module RuboCop
|
|
|
204
212
|
end
|
|
205
213
|
|
|
206
214
|
def remove_local_variable_assignment_part(corrector, node)
|
|
207
|
-
corrector.
|
|
215
|
+
corrector.remove(node.loc.name.begin.join(node.expression.source_range.begin))
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def variable_in_loop_condition?(assignment_node, variable)
|
|
219
|
+
return false if assignment_node.each_ancestor(:any_def).any?
|
|
220
|
+
|
|
221
|
+
loop_node = assignment_node.each_ancestor.find do |ancestor|
|
|
222
|
+
ancestor.type?(*VariableForce::LOOP_TYPES)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
return false unless loop_node.respond_to?(:condition)
|
|
226
|
+
|
|
227
|
+
condition_node = loop_node.condition
|
|
228
|
+
variable_name = variable.name
|
|
229
|
+
|
|
230
|
+
return true if condition_node.lvar_type? && condition_node.children.first == variable_name
|
|
231
|
+
|
|
232
|
+
condition_node.each_descendant(:lvar) do |lvar_node|
|
|
233
|
+
return true if lvar_node.children.first == variable_name
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
false
|
|
208
237
|
end
|
|
209
238
|
end
|
|
210
239
|
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Lint
|
|
6
|
+
# Checks for useless constant scoping. Private constants must be defined using
|
|
7
|
+
# `private_constant`. Even if `private` access modifier is used, it is public scope despite
|
|
8
|
+
# its appearance.
|
|
9
|
+
#
|
|
10
|
+
# It does not support autocorrection due to behavior change and multiple ways to fix it.
|
|
11
|
+
# Or a public constant may be intended.
|
|
12
|
+
#
|
|
13
|
+
# Constant assignments that define classes or modules via `Class.new`, `Module.new`,
|
|
14
|
+
# `Struct.new`, or `Data.define` are allowed. Those forms are class and module definitions
|
|
15
|
+
# written with assignment syntax, and match the common practice of placing nested
|
|
16
|
+
# `class` / `module` bodies after `private` without intending private constant visibility.
|
|
17
|
+
#
|
|
18
|
+
# @example
|
|
19
|
+
#
|
|
20
|
+
# # bad
|
|
21
|
+
# class Foo
|
|
22
|
+
# private
|
|
23
|
+
# PRIVATE_CONST = 42
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# # good
|
|
27
|
+
# class Foo
|
|
28
|
+
# PRIVATE_CONST = 42
|
|
29
|
+
# private_constant :PRIVATE_CONST
|
|
30
|
+
# end
|
|
31
|
+
#
|
|
32
|
+
# # good
|
|
33
|
+
# class Foo
|
|
34
|
+
# PUBLIC_CONST = 42 # If private scope is not intended.
|
|
35
|
+
# end
|
|
36
|
+
#
|
|
37
|
+
# # good - class/module definitions via assignment, same as nested `class`/`module`
|
|
38
|
+
# class Foo
|
|
39
|
+
# private
|
|
40
|
+
#
|
|
41
|
+
# def some_private_method
|
|
42
|
+
# end
|
|
43
|
+
#
|
|
44
|
+
# MyClass = Class.new
|
|
45
|
+
# MyModule = Module.new
|
|
46
|
+
# MyStruct = Struct.new(:name)
|
|
47
|
+
# MyData = Data.define(:name)
|
|
48
|
+
# end
|
|
49
|
+
#
|
|
50
|
+
class UselessConstantScoping < Base
|
|
51
|
+
MSG = 'Useless `private` access modifier for constant scope.'
|
|
52
|
+
|
|
53
|
+
# @!method private_constants(node)
|
|
54
|
+
def_node_matcher :private_constants, <<~PATTERN
|
|
55
|
+
(send nil? :private_constant $...)
|
|
56
|
+
PATTERN
|
|
57
|
+
|
|
58
|
+
# Matches class/module-like constant assignments. Nested `class` / `module`
|
|
59
|
+
# keyword definitions are not visited by this cop; these assignment forms are
|
|
60
|
+
# the equivalent syntax and should be treated the same way.
|
|
61
|
+
# @!method class_or_module_definition_assignment?(node)
|
|
62
|
+
def_node_matcher :class_or_module_definition_assignment?, <<~PATTERN
|
|
63
|
+
{
|
|
64
|
+
(send (const {nil? cbase} {:Class :Module :Struct}) :new ...)
|
|
65
|
+
(send (const {nil? cbase} :Data) :define ...)
|
|
66
|
+
(any_block
|
|
67
|
+
{
|
|
68
|
+
(send (const {nil? cbase} {:Class :Module :Struct}) :new ...)
|
|
69
|
+
(send (const {nil? cbase} :Data) :define ...)
|
|
70
|
+
}
|
|
71
|
+
...)
|
|
72
|
+
}
|
|
73
|
+
PATTERN
|
|
74
|
+
|
|
75
|
+
def on_casgn(node)
|
|
76
|
+
return unless after_private_modifier?(node.left_siblings)
|
|
77
|
+
return if private_constantize?(node.right_siblings, node.name)
|
|
78
|
+
return if class_or_module_definition_assignment?(node.expression)
|
|
79
|
+
|
|
80
|
+
add_offense(node)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
def after_private_modifier?(left_siblings)
|
|
86
|
+
access_modifier_candidates = left_siblings.compact.select do |left_sibling|
|
|
87
|
+
left_sibling.respond_to?(:bare_access_modifier?) && left_sibling.bare_access_modifier?
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
return false if access_modifier_candidates.empty?
|
|
91
|
+
|
|
92
|
+
access_modifier_candidates.last.command?(:private)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def private_constantize?(right_siblings, const_value)
|
|
96
|
+
private_constant_arguments = right_siblings.map { |node| private_constants(node) }
|
|
97
|
+
|
|
98
|
+
private_constant_values = private_constant_arguments.flatten.filter_map do |constant|
|
|
99
|
+
constant.value.to_sym if constant.respond_to?(:value)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
private_constant_values.include?(const_value)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Lint
|
|
6
|
+
# Checks for usage of method `fetch` or `Array.new` with default value argument
|
|
7
|
+
# and block. In such cases, block will always be used as default value.
|
|
8
|
+
#
|
|
9
|
+
# This cop emulates Ruby warning "block supersedes default value argument" which
|
|
10
|
+
# applies to `Array.new`, `Array#fetch`, `Hash#fetch`, `ENV.fetch` and
|
|
11
|
+
# `Thread#fetch`.
|
|
12
|
+
#
|
|
13
|
+
# A `fetch` call without a receiver is considered a custom method and does not register
|
|
14
|
+
# an offense.
|
|
15
|
+
#
|
|
16
|
+
# @safety
|
|
17
|
+
# This cop is unsafe because the receiver could have nonstandard implementation
|
|
18
|
+
# of `fetch`, or be a class other than the one listed above.
|
|
19
|
+
#
|
|
20
|
+
# It is also unsafe because default value argument could have side effects:
|
|
21
|
+
#
|
|
22
|
+
# [source,ruby]
|
|
23
|
+
# ----
|
|
24
|
+
# def x(a) = puts "side effect"
|
|
25
|
+
# Array.new(5, x(1)) { 2 }
|
|
26
|
+
# ----
|
|
27
|
+
#
|
|
28
|
+
# so removing it would change behavior.
|
|
29
|
+
#
|
|
30
|
+
# @example
|
|
31
|
+
# # bad
|
|
32
|
+
# x.fetch(key, default_value) { block_value }
|
|
33
|
+
# Array.new(size, default_value) { block_value }
|
|
34
|
+
#
|
|
35
|
+
# # good
|
|
36
|
+
# x.fetch(key) { block_value }
|
|
37
|
+
# Array.new(size) { block_value }
|
|
38
|
+
#
|
|
39
|
+
# # also good - in case default value argument is desired instead
|
|
40
|
+
# x.fetch(key, default_value)
|
|
41
|
+
# Array.new(size, default_value)
|
|
42
|
+
#
|
|
43
|
+
# # good - keyword arguments aren't registered as offenses
|
|
44
|
+
# x.fetch(key, keyword: :arg) { block_value }
|
|
45
|
+
#
|
|
46
|
+
# @example AllowedReceivers: ['Rails.cache']
|
|
47
|
+
# # good
|
|
48
|
+
# Rails.cache.fetch(name, options) { block }
|
|
49
|
+
#
|
|
50
|
+
class UselessDefaultValueArgument < Base
|
|
51
|
+
include AllowedReceivers
|
|
52
|
+
extend AutoCorrector
|
|
53
|
+
|
|
54
|
+
MSG = 'Block supersedes default value argument.'
|
|
55
|
+
|
|
56
|
+
RESTRICT_ON_SEND = %i[fetch new].freeze
|
|
57
|
+
|
|
58
|
+
# @!method default_value_argument_and_block(node)
|
|
59
|
+
def_node_matcher :default_value_argument_and_block, <<~PATTERN
|
|
60
|
+
(any_block
|
|
61
|
+
{
|
|
62
|
+
(call !nil? :fetch $_key $_default_value)
|
|
63
|
+
(send (const _ :Array) :new $_size $_default_value)
|
|
64
|
+
}
|
|
65
|
+
_args
|
|
66
|
+
_block_body)
|
|
67
|
+
PATTERN
|
|
68
|
+
|
|
69
|
+
def on_send(node)
|
|
70
|
+
return unless node.receiver
|
|
71
|
+
|
|
72
|
+
unless (prev_arg_node, default_value_node = default_value_argument_and_block(node.parent))
|
|
73
|
+
return
|
|
74
|
+
end
|
|
75
|
+
return if allowed_receiver?(node.receiver)
|
|
76
|
+
return if hash_without_braces?(default_value_node)
|
|
77
|
+
|
|
78
|
+
add_offense(default_value_node) do |corrector|
|
|
79
|
+
corrector.remove(prev_arg_node.source_range.end.join(default_value_node.source_range))
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
alias on_csend on_send
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
def hash_without_braces?(node)
|
|
87
|
+
node.hash_type? && !node.braces?
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -59,7 +59,7 @@ module RuboCop
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def use_rest_or_optional_args?(node)
|
|
62
|
-
node.arguments.any? { |arg| arg.type?(:restarg, :optarg, :kwoptarg) }
|
|
62
|
+
node.arguments.any? { |arg| arg.type?(:restarg, :optarg, :kwoptarg, :kwrestarg) }
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
def delegating?(node, def_node)
|