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
|
@@ -31,35 +31,36 @@ module RuboCop
|
|
|
31
31
|
#
|
|
32
32
|
class UselessNumericOperation < Base
|
|
33
33
|
extend AutoCorrector
|
|
34
|
+
|
|
34
35
|
MSG = 'Do not apply inconsequential numeric operations to variables.'
|
|
35
36
|
RESTRICT_ON_SEND = %i[+ - * / **].freeze
|
|
36
37
|
|
|
37
38
|
# @!method useless_operation?(node)
|
|
38
|
-
def_node_matcher :useless_operation?,
|
|
39
|
+
def_node_matcher :useless_operation?, <<~PATTERN
|
|
40
|
+
(call ${lvar ivar cvar gvar const (send nil? _)} $_ (int $_))
|
|
41
|
+
PATTERN
|
|
39
42
|
|
|
40
43
|
# @!method useless_abbreviated_assignment?(node)
|
|
41
|
-
def_node_matcher :useless_abbreviated_assignment?,
|
|
44
|
+
def_node_matcher :useless_abbreviated_assignment?, <<~PATTERN
|
|
45
|
+
(op-asgn ${lvasgn ivasgn cvasgn gvasgn casgn} $_ (int $_))
|
|
46
|
+
PATTERN
|
|
42
47
|
|
|
43
48
|
def on_send(node)
|
|
44
|
-
return unless useless_operation?(node)
|
|
45
|
-
|
|
46
|
-
variable, operation, number = useless_operation?(node)
|
|
49
|
+
return unless (receiver, operation, number = useless_operation?(node))
|
|
47
50
|
return unless useless?(operation, number)
|
|
48
51
|
|
|
49
52
|
add_offense(node) do |corrector|
|
|
50
|
-
corrector.replace(node,
|
|
53
|
+
corrector.replace(node, receiver.source)
|
|
51
54
|
end
|
|
52
55
|
end
|
|
53
56
|
alias on_csend on_send
|
|
54
57
|
|
|
55
58
|
def on_op_asgn(node)
|
|
56
|
-
return unless useless_abbreviated_assignment?(node)
|
|
57
|
-
|
|
58
|
-
variable, operation, number = useless_abbreviated_assignment?(node)
|
|
59
|
+
return unless (variable, operation, number = useless_abbreviated_assignment?(node))
|
|
59
60
|
return unless useless?(operation, number)
|
|
60
61
|
|
|
61
62
|
add_offense(node) do |corrector|
|
|
62
|
-
corrector.replace(node, "#{variable} = #{variable}")
|
|
63
|
+
corrector.replace(node, "#{variable.source} = #{variable.source}")
|
|
63
64
|
end
|
|
64
65
|
end
|
|
65
66
|
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Lint
|
|
6
|
+
# Checks for useless OR (`||` and `or`) expressions.
|
|
7
|
+
#
|
|
8
|
+
# Some methods always return a truthy value, even when called
|
|
9
|
+
# on `nil` (e.g. `nil.to_i` evaluates to `0`). Therefore, OR expressions
|
|
10
|
+
# appended after these methods will never evaluate.
|
|
11
|
+
#
|
|
12
|
+
# @safety
|
|
13
|
+
# As shown in the examples below, there are generally two possible ways to correct the
|
|
14
|
+
# offense, but this cop's autocorrection always chooses the option that preserves the
|
|
15
|
+
# current behavior. While this does not change how the code behaves, that option is not
|
|
16
|
+
# necessarily the appropriate fix in every situation. For this reason, the autocorrection
|
|
17
|
+
# provided by this cop is considered unsafe.
|
|
18
|
+
#
|
|
19
|
+
# @example
|
|
20
|
+
#
|
|
21
|
+
# # bad
|
|
22
|
+
# x.to_a || fallback
|
|
23
|
+
# x.to_c || fallback
|
|
24
|
+
# x.to_d || fallback
|
|
25
|
+
# x.to_i || fallback
|
|
26
|
+
# x.to_f || fallback
|
|
27
|
+
# x.to_h || fallback
|
|
28
|
+
# x.to_r || fallback
|
|
29
|
+
# x.to_s || fallback
|
|
30
|
+
# x.to_sym || fallback
|
|
31
|
+
# x.intern || fallback
|
|
32
|
+
# x.inspect || fallback
|
|
33
|
+
# x.hash || fallback
|
|
34
|
+
# x.object_id || fallback
|
|
35
|
+
# x.__id__ || fallback
|
|
36
|
+
#
|
|
37
|
+
# x.to_s or fallback
|
|
38
|
+
#
|
|
39
|
+
# # good - if fallback is same as return value of method called on nil
|
|
40
|
+
# x.to_a # nil.to_a returns []
|
|
41
|
+
# x.to_c # nil.to_c returns (0+0i)
|
|
42
|
+
# x.to_d # nil.to_d returns 0.0
|
|
43
|
+
# x.to_i # nil.to_i returns 0
|
|
44
|
+
# x.to_f # nil.to_f returns 0.0
|
|
45
|
+
# x.to_h # nil.to_h returns {}
|
|
46
|
+
# x.to_r # nil.to_r returns (0/1)
|
|
47
|
+
# x.to_s # nil.to_s returns ''
|
|
48
|
+
# x.to_sym # nil.to_sym raises an error
|
|
49
|
+
# x.intern # nil.intern raises an error
|
|
50
|
+
# x.inspect # nil.inspect returns "nil"
|
|
51
|
+
# x.hash # nil.hash returns an Integer
|
|
52
|
+
# x.object_id # nil.object_id returns an Integer
|
|
53
|
+
# x.__id__ # nil.object_id returns an Integer
|
|
54
|
+
#
|
|
55
|
+
# # good - if the intention is not to call the method on nil
|
|
56
|
+
# x&.to_a || fallback
|
|
57
|
+
# x&.to_c || fallback
|
|
58
|
+
# x&.to_d || fallback
|
|
59
|
+
# x&.to_i || fallback
|
|
60
|
+
# x&.to_f || fallback
|
|
61
|
+
# x&.to_h || fallback
|
|
62
|
+
# x&.to_r || fallback
|
|
63
|
+
# x&.to_s || fallback
|
|
64
|
+
# x&.to_sym || fallback
|
|
65
|
+
# x&.intern || fallback
|
|
66
|
+
# x&.inspect || fallback
|
|
67
|
+
# x&.hash || fallback
|
|
68
|
+
# x&.object_id || fallback
|
|
69
|
+
# x&.__id__ || fallback
|
|
70
|
+
#
|
|
71
|
+
# x&.to_s or fallback
|
|
72
|
+
#
|
|
73
|
+
class UselessOr < Base
|
|
74
|
+
extend AutoCorrector
|
|
75
|
+
|
|
76
|
+
MSG = '`%<rhs>s` will never evaluate because `%<lhs>s` always returns a truthy value.'
|
|
77
|
+
|
|
78
|
+
TRUTHY_RETURN_VALUE_METHODS = Set[:to_a, :to_c, :to_d, :to_i, :to_f, :to_h, :to_r,
|
|
79
|
+
:to_s, :to_sym, :intern, :inspect, :hash, :object_id,
|
|
80
|
+
:__id__].freeze
|
|
81
|
+
|
|
82
|
+
# @!method truthy_return_value_method?(node)
|
|
83
|
+
def_node_matcher :truthy_return_value_method?, <<~PATTERN
|
|
84
|
+
(send _ %TRUTHY_RETURN_VALUE_METHODS)
|
|
85
|
+
PATTERN
|
|
86
|
+
|
|
87
|
+
def on_or(node)
|
|
88
|
+
if truthy_return_value_method?(node.lhs)
|
|
89
|
+
report_offense(node, node.lhs)
|
|
90
|
+
elsif truthy_return_value_method?(node.rhs)
|
|
91
|
+
parent = node.parent
|
|
92
|
+
parent = parent.parent if parent&.begin_type?
|
|
93
|
+
|
|
94
|
+
report_offense(parent, node.rhs) if parent&.or_type?
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def report_offense(or_node, truthy_node)
|
|
101
|
+
add_offense(
|
|
102
|
+
or_node.loc.operator.join(or_node.rhs.source_range),
|
|
103
|
+
message: format(MSG, lhs: truthy_node.source, rhs: or_node.rhs.source)
|
|
104
|
+
) do |corrector|
|
|
105
|
+
corrector.replace(or_node, or_node.lhs.source)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Lint
|
|
6
|
-
# Checks for useless
|
|
6
|
+
# Checks for useless ``rescue``s, which only reraise rescued exceptions.
|
|
7
7
|
#
|
|
8
8
|
# @example
|
|
9
9
|
# # bad
|
|
@@ -56,7 +56,7 @@ module RuboCop
|
|
|
56
56
|
|
|
57
57
|
private
|
|
58
58
|
|
|
59
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
59
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
60
60
|
def only_reraising?(resbody_node)
|
|
61
61
|
return false if use_exception_variable_in_ensure?(resbody_node)
|
|
62
62
|
|
|
@@ -70,7 +70,6 @@ module RuboCop
|
|
|
70
70
|
|
|
71
71
|
exception_objects(resbody_node).include?(exception_name)
|
|
72
72
|
end
|
|
73
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
74
73
|
|
|
75
74
|
def use_exception_variable_in_ensure?(resbody_node)
|
|
76
75
|
return false unless (exception_variable = resbody_node.exception_variable)
|
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
|
6
6
|
# Looks for `ruby2_keywords` calls for methods that do not need it.
|
|
7
7
|
#
|
|
8
8
|
# `ruby2_keywords` should only be called on methods that accept an argument splat
|
|
9
|
-
# (`\*args`) but do not explicit keyword arguments (`k:` or `k: true`) or
|
|
9
|
+
# (`\*args`) but do not have explicit keyword arguments (`k:` or `k: true`) or
|
|
10
10
|
# a keyword splat (`**kwargs`).
|
|
11
11
|
#
|
|
12
12
|
# @example
|
|
@@ -89,7 +89,7 @@ module RuboCop
|
|
|
89
89
|
private
|
|
90
90
|
|
|
91
91
|
def inspect_def(node, def_node)
|
|
92
|
-
return if allowed_arguments(def_node.arguments)
|
|
92
|
+
return if allowed_arguments?(def_node.arguments)
|
|
93
93
|
|
|
94
94
|
add_offense(node.loc.selector, message: format(MSG, method_name: def_node.method_name))
|
|
95
95
|
end
|
|
@@ -101,21 +101,27 @@ module RuboCop
|
|
|
101
101
|
definition = find_method_definition(node, method_name)
|
|
102
102
|
|
|
103
103
|
return unless definition
|
|
104
|
-
return if allowed_arguments(definition.arguments)
|
|
104
|
+
return if allowed_arguments?(definition.arguments)
|
|
105
105
|
|
|
106
106
|
add_offense(node, message: format(MSG, method_name: method_name))
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
def find_method_definition(node, method_name)
|
|
110
|
-
node.each_ancestor
|
|
111
|
-
ancestor.each_child_node(:def, :any_block).find do |child|
|
|
110
|
+
node.each_ancestor do |ancestor|
|
|
111
|
+
found = ancestor.each_child_node(:def, :any_block).find do |child|
|
|
112
112
|
method_definition(child, method_name)
|
|
113
113
|
end
|
|
114
|
-
|
|
114
|
+
return found if found
|
|
115
|
+
# A method defined in an outer lexical scope does not define this scope's method,
|
|
116
|
+
# so stop searching once a class/module boundary is crossed without a match.
|
|
117
|
+
return nil if ancestor.type?(:class, :module, :sclass)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
nil
|
|
115
121
|
end
|
|
116
122
|
|
|
117
123
|
# `ruby2_keywords` is only allowed if there's a `restarg` and no keyword arguments
|
|
118
|
-
def allowed_arguments(arguments)
|
|
124
|
+
def allowed_arguments?(arguments)
|
|
119
125
|
return false if arguments.empty?
|
|
120
126
|
|
|
121
127
|
arguments.each_child_node(:restarg).any? &&
|
|
@@ -107,7 +107,10 @@ module RuboCop
|
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
def process_multiple_assignment(masgn_node)
|
|
110
|
-
|
|
110
|
+
# Iterate the top-level destructuring slots so each maps to the right-hand side
|
|
111
|
+
# element at the same position. Using the flattened `assignments` would misalign
|
|
112
|
+
# the index when a slot is itself a nested destructuring (e.g. `(a, b), c = x, y`).
|
|
113
|
+
masgn_node.lhs.children.each_with_index do |lhs_node, index|
|
|
111
114
|
next unless ASSIGNMENT_TYPES.include?(lhs_node.type)
|
|
112
115
|
|
|
113
116
|
if masgn_node.rhs.array_type? && (rhs_node = masgn_node.rhs.children[index])
|
|
@@ -83,7 +83,7 @@ module RuboCop
|
|
|
83
83
|
|
|
84
84
|
def autocorrect_block(corrector, node)
|
|
85
85
|
block_arg = block_arg(node)
|
|
86
|
-
return
|
|
86
|
+
return unless reducible_to_body?(node, block_arg)
|
|
87
87
|
|
|
88
88
|
source = node.body.source
|
|
89
89
|
source.gsub!(/\b#{block_arg}\b/, '0') if block_arg
|
|
@@ -91,6 +91,27 @@ module RuboCop
|
|
|
91
91
|
corrector.replace(node, fix_indentation(source, node.loc.column...node.body.loc.column))
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
+
def reducible_to_body?(node, block_arg)
|
|
95
|
+
# A block with multiple arguments can't be reduced to its body (the extra arguments
|
|
96
|
+
# would become undefined references), and `next`/`break`/`redo` bound to the block
|
|
97
|
+
# become orphaned (a syntax error) once the block is removed.
|
|
98
|
+
return false if node.arguments.size > 1 || orphans_loop_control_keyword?(node)
|
|
99
|
+
|
|
100
|
+
# A lone non-simple argument (destructuring `|(a, b)|` or a splat `|*a|`) can't be
|
|
101
|
+
# substituted either, so reducing to the body would leave it referencing an
|
|
102
|
+
# undefined variable.
|
|
103
|
+
return false if node.arguments.one? && block_arg.nil?
|
|
104
|
+
|
|
105
|
+
!block_reassigns_arg?(node, block_arg)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def orphans_loop_control_keyword?(node)
|
|
109
|
+
node.body&.each_node(:next, :break, :redo)&.any? do |control|
|
|
110
|
+
inner = control.each_ancestor.take_while { |ancestor| !ancestor.equal?(node) }
|
|
111
|
+
inner.none? { |ancestor| ancestor.type?(:any_block, :while, :until, :for) }
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
94
115
|
def fix_indentation(source, range)
|
|
95
116
|
# Cleanup indentation in a multiline block
|
|
96
117
|
source_lines = source.split("\n")
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Lint
|
|
6
|
+
module Utils
|
|
7
|
+
# Utility class that checks if the receiver can't be nil.
|
|
8
|
+
class NilReceiverChecker
|
|
9
|
+
NIL_METHODS = (nil.methods + %i[!]).to_set.freeze
|
|
10
|
+
|
|
11
|
+
def initialize(receiver, additional_nil_methods)
|
|
12
|
+
@receiver = receiver
|
|
13
|
+
@additional_nil_methods = additional_nil_methods
|
|
14
|
+
@checked_nodes = {}.compare_by_identity
|
|
15
|
+
@receiver_binding_name = binding_name(receiver)
|
|
16
|
+
@receiver_binding_scope = binding_scope(receiver) if @receiver_binding_name
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def cant_be_nil?
|
|
20
|
+
sole_condition_of_parent_if?(@receiver) || _cant_be_nil?(@receiver.parent, @receiver)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
# rubocop:disable-next Metrics
|
|
26
|
+
def _cant_be_nil?(node, receiver)
|
|
27
|
+
return false unless node
|
|
28
|
+
|
|
29
|
+
# For some nodes, we check their parent and then some children for these parents.
|
|
30
|
+
# This is added to avoid infinite loops.
|
|
31
|
+
return false if @checked_nodes.key?(node)
|
|
32
|
+
|
|
33
|
+
@checked_nodes[node] = true
|
|
34
|
+
|
|
35
|
+
case node.type
|
|
36
|
+
when :def, :defs, :class, :module, :sclass
|
|
37
|
+
return false
|
|
38
|
+
when :send
|
|
39
|
+
if node.receiver == receiver && same_binding_as_receiver?(node.receiver)
|
|
40
|
+
return non_nil_method?(node.method_name)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
node.arguments.each do |argument|
|
|
44
|
+
return true if _cant_be_nil?(argument, receiver)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
return true if _cant_be_nil?(node.receiver, receiver)
|
|
48
|
+
when :begin
|
|
49
|
+
return true if _cant_be_nil?(node.children.first, receiver)
|
|
50
|
+
when :if, :case
|
|
51
|
+
return true if _cant_be_nil?(node.condition, receiver)
|
|
52
|
+
when :and, :or
|
|
53
|
+
return true if _cant_be_nil?(node.lhs, receiver)
|
|
54
|
+
when :pair
|
|
55
|
+
if _cant_be_nil?(node.key, receiver) ||
|
|
56
|
+
_cant_be_nil?(node.value, receiver)
|
|
57
|
+
return true
|
|
58
|
+
end
|
|
59
|
+
when :when
|
|
60
|
+
node.conditions.each do |condition|
|
|
61
|
+
return true if _cant_be_nil?(condition, receiver)
|
|
62
|
+
end
|
|
63
|
+
when :lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
|
|
64
|
+
return true if _cant_be_nil?(node.expression, receiver)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
if sequentially_reached?(node)
|
|
68
|
+
node.left_siblings.reverse_each do |sibling|
|
|
69
|
+
next unless sibling.is_a?(AST::Node)
|
|
70
|
+
|
|
71
|
+
return true if _cant_be_nil?(sibling, receiver)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
if node.parent
|
|
76
|
+
_cant_be_nil?(node.parent, receiver)
|
|
77
|
+
else
|
|
78
|
+
false
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def non_nil_method?(method_name)
|
|
83
|
+
!NIL_METHODS.include?(method_name) && !@additional_nil_methods.include?(method_name)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
87
|
+
def sole_condition_of_parent_if?(node)
|
|
88
|
+
child = node
|
|
89
|
+
parent = node.parent
|
|
90
|
+
|
|
91
|
+
while parent
|
|
92
|
+
if parent.if_type?
|
|
93
|
+
unless parent.unless?
|
|
94
|
+
condition = parent.condition
|
|
95
|
+
return true if !child.equal?(condition) && non_nil_condition?(condition, node)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
parent = find_top_if(parent) if parent.elsif?
|
|
99
|
+
elsif else_branch?(parent)
|
|
100
|
+
# Find the top `if` for `else`.
|
|
101
|
+
parent = parent.parent
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
child = parent
|
|
105
|
+
parent = parent&.parent
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
false
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def non_nil_condition?(condition, node)
|
|
112
|
+
return true if condition == node && same_binding_as_receiver?(condition)
|
|
113
|
+
return false unless condition.csend_type?
|
|
114
|
+
|
|
115
|
+
root_receiver = csend_root_receiver(condition)
|
|
116
|
+
|
|
117
|
+
root_receiver == node && same_binding_as_receiver?(root_receiver)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Structurally equal occurrences can be different variables: `it` binds to
|
|
121
|
+
# its innermost block, and a block parameter can shadow an outer variable of
|
|
122
|
+
# the same name. Evidence about such a receiver only holds when both occurrences
|
|
123
|
+
# resolve to the same binding.
|
|
124
|
+
def same_binding_as_receiver?(occurrence)
|
|
125
|
+
return true unless @receiver_binding_name
|
|
126
|
+
|
|
127
|
+
binding_scope(occurrence).equal?(@receiver_binding_scope)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# The name whose binding can differ between structurally equal occurrences:
|
|
131
|
+
# a local variable (block parameters included), or a bare `it` call, which is
|
|
132
|
+
# how `it` parses when the target Ruby version is below 3.4 even though the code
|
|
133
|
+
# may run on 3.4+ where `it` is the implicit block parameter.
|
|
134
|
+
def binding_name(node)
|
|
135
|
+
if node.lvar_type?
|
|
136
|
+
node.children.first
|
|
137
|
+
elsif node.send_type? && !node.receiver && node.method?(:it) && node.arguments.empty?
|
|
138
|
+
:it
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def binding_scope(occurrence)
|
|
143
|
+
node = occurrence
|
|
144
|
+
|
|
145
|
+
while (parent = node.parent)
|
|
146
|
+
case parent.type
|
|
147
|
+
when :block, :numblock, :itblock
|
|
148
|
+
# Only the body is inside the block's scope; the send node and the arguments of
|
|
149
|
+
# the block node evaluate in the outer scope.
|
|
150
|
+
return parent if parent.body.equal?(node) && block_binds_name?(parent)
|
|
151
|
+
when :def, :defs, :class, :module, :sclass
|
|
152
|
+
return parent
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
node = parent
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
nil
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def block_binds_name?(block_node)
|
|
162
|
+
name = @receiver_binding_name
|
|
163
|
+
|
|
164
|
+
return true if block_node.argument_list.any? { |argument| argument.name == name }
|
|
165
|
+
|
|
166
|
+
name == :it && block_node.arguments.empty?
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Whether control reaches `node` by falling through its left siblings rather than by
|
|
170
|
+
# a non-sequential entry. A `resbody` is entered via an exception, the `ensure` branch
|
|
171
|
+
# runs even after a partway raise, and the `else` arm of an `if/elsif` chain is reached by
|
|
172
|
+
# branching (its `if/case` siblings are walked via parent recursion instead).
|
|
173
|
+
def sequentially_reached?(node)
|
|
174
|
+
return false if node.resbody_type?
|
|
175
|
+
return false if node.parent&.ensure_type? && node.parent.branch.equal?(node)
|
|
176
|
+
|
|
177
|
+
!else_branch?(node) || (node.if_type? && !node.elsif?)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def else_branch?(node)
|
|
181
|
+
node.parent&.if_type? && node.parent.else_branch == node
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def find_top_if(node)
|
|
185
|
+
node = node.parent while node.elsif?
|
|
186
|
+
|
|
187
|
+
node
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def csend_root_receiver(node)
|
|
191
|
+
return unless (receiver = node.receiver)
|
|
192
|
+
|
|
193
|
+
receiver = receiver.receiver while receiver.call_type? && receiver.receiver
|
|
194
|
+
|
|
195
|
+
receiver
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
@@ -16,6 +16,15 @@ module RuboCop
|
|
|
16
16
|
# enumerator.each { |item| item >= 2 } #=> [2, 3]
|
|
17
17
|
# ----
|
|
18
18
|
#
|
|
19
|
+
# NOTE: The last expression in an assignment method definition such as `def foo=(arg)`
|
|
20
|
+
# is not flagged. Ruby discards it (the method returns its argument), but the method can
|
|
21
|
+
# still be called directly and its return value relied upon, so flagging it would be a
|
|
22
|
+
# false positive for this lint.
|
|
23
|
+
#
|
|
24
|
+
# NOTE: A constant used in a void context is flagged but not autocorrected, since
|
|
25
|
+
# referencing a constant can trigger autoloading side effects (e.g. forcing a file to
|
|
26
|
+
# load before a monkey-patch), so removing it may change behavior.
|
|
27
|
+
#
|
|
19
28
|
# @example CheckForMethodsWithNoSideEffects: false (default)
|
|
20
29
|
# # bad
|
|
21
30
|
# def some_method
|
|
@@ -81,11 +90,13 @@ module RuboCop
|
|
|
81
90
|
def on_block(node)
|
|
82
91
|
return unless node.body && !node.body.begin_type?
|
|
83
92
|
return unless in_void_context?(node.body)
|
|
93
|
+
return if node.method?(:each)
|
|
84
94
|
|
|
85
|
-
check_void_op(node.body)
|
|
95
|
+
check_void_op(node.body)
|
|
86
96
|
check_expression(node.body)
|
|
87
97
|
end
|
|
88
98
|
alias on_numblock on_block
|
|
99
|
+
alias on_itblock on_block
|
|
89
100
|
|
|
90
101
|
def on_begin(node)
|
|
91
102
|
check_begin(node)
|
|
@@ -100,22 +111,23 @@ module RuboCop
|
|
|
100
111
|
|
|
101
112
|
def check_begin(node)
|
|
102
113
|
expressions = *node
|
|
103
|
-
|
|
114
|
+
inside_each_block = node.each_ancestor(:any_block).first&.method?(:each)
|
|
115
|
+
expressions.pop if !in_void_context?(node) || inside_each_block || setter_method?(node)
|
|
104
116
|
expressions.each do |expr|
|
|
105
|
-
check_void_op(expr)
|
|
106
|
-
block_node = node.each_ancestor(:block).first
|
|
107
|
-
|
|
108
|
-
block_node&.method?(:each)
|
|
109
|
-
end
|
|
110
|
-
|
|
117
|
+
check_void_op(expr) { inside_each_block }
|
|
111
118
|
check_expression(expr)
|
|
112
119
|
end
|
|
113
120
|
end
|
|
114
121
|
|
|
115
122
|
def check_expression(expr)
|
|
116
|
-
|
|
117
|
-
return
|
|
123
|
+
return check_if_expression(expr) if expr.if_type?
|
|
124
|
+
return check_case_expression(expr) if expr.case_type?
|
|
125
|
+
return check_case_match_expression(expr) if expr.case_match_type?
|
|
126
|
+
|
|
127
|
+
check_void_expression_nodes(expr)
|
|
128
|
+
end
|
|
118
129
|
|
|
130
|
+
def check_void_expression_nodes(expr)
|
|
119
131
|
check_literal(expr)
|
|
120
132
|
check_var(expr)
|
|
121
133
|
check_self(expr)
|
|
@@ -125,9 +137,30 @@ module RuboCop
|
|
|
125
137
|
check_nonmutating(expr)
|
|
126
138
|
end
|
|
127
139
|
|
|
140
|
+
def check_if_expression(if_node)
|
|
141
|
+
check_void_expression_nodes(if_node.body) if if_node.body
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def check_case_expression(case_node)
|
|
145
|
+
case_node.each_when { |when_node| check_expression(when_node.body) if when_node.body }
|
|
146
|
+
check_expression(case_node.else_branch) if case_node.else_branch
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def check_case_match_expression(case_node)
|
|
150
|
+
case_node.each_in_pattern do |in_pattern_node|
|
|
151
|
+
check_expression(in_pattern_node.body) if in_pattern_node.body
|
|
152
|
+
end
|
|
153
|
+
check_expression(case_node.else_branch) if case_node.else_branch
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
128
157
|
def check_void_op(node, &block)
|
|
129
|
-
node = node.children.first while node
|
|
130
|
-
return unless node
|
|
158
|
+
node = node.children.first while node&.begin_type?
|
|
159
|
+
return unless node&.call_type? && OPERATORS.include?(node.method_name)
|
|
160
|
+
if !UNARY_OPERATORS.include?(node.method_name) && node.loc.dot && node.arguments.none?
|
|
161
|
+
return
|
|
162
|
+
end
|
|
163
|
+
|
|
131
164
|
return if block && yield(node)
|
|
132
165
|
|
|
133
166
|
add_offense(node.loc.selector,
|
|
@@ -155,7 +188,9 @@ module RuboCop
|
|
|
155
188
|
end
|
|
156
189
|
|
|
157
190
|
def check_literal(node)
|
|
158
|
-
|
|
191
|
+
if !entirely_literal?(node) || node.xstr_type? || node.range_type? || node.nil_type?
|
|
192
|
+
return
|
|
193
|
+
end
|
|
159
194
|
|
|
160
195
|
add_offense(node, message: format(LIT_MSG, lit: node.source)) do |corrector|
|
|
161
196
|
autocorrect_void_expression(corrector, node)
|
|
@@ -179,7 +214,7 @@ module RuboCop
|
|
|
179
214
|
end
|
|
180
215
|
|
|
181
216
|
def check_nonmutating(node)
|
|
182
|
-
return unless node.type?(:
|
|
217
|
+
return unless node.type?(:call, :any_block)
|
|
183
218
|
|
|
184
219
|
method_name = node.method_name
|
|
185
220
|
return unless NONMUTATING_METHODS.include?(method_name)
|
|
@@ -201,11 +236,6 @@ module RuboCop
|
|
|
201
236
|
# NOTE: the `begin` node case is already handled via `on_begin`
|
|
202
237
|
return if body.begin_type?
|
|
203
238
|
|
|
204
|
-
check_void_op(body) do
|
|
205
|
-
block_node = node.each_ancestor(:block).first
|
|
206
|
-
block_node&.method?(:each)
|
|
207
|
-
end
|
|
208
|
-
|
|
209
239
|
check_expression(body)
|
|
210
240
|
end
|
|
211
241
|
|
|
@@ -216,6 +246,10 @@ module RuboCop
|
|
|
216
246
|
parent.respond_to?(:void_context?) && parent.void_context?
|
|
217
247
|
end
|
|
218
248
|
|
|
249
|
+
def setter_method?(node)
|
|
250
|
+
node.parent&.any_def_type? && node.parent.assignment_method?
|
|
251
|
+
end
|
|
252
|
+
|
|
219
253
|
def autocorrect_void_op(corrector, node)
|
|
220
254
|
if node.arguments.empty?
|
|
221
255
|
corrector.replace(node, node.receiver.source)
|
|
@@ -230,13 +264,18 @@ module RuboCop
|
|
|
230
264
|
end
|
|
231
265
|
|
|
232
266
|
def autocorrect_void_expression(corrector, node)
|
|
233
|
-
|
|
267
|
+
# Referencing a constant can trigger autoloading side effects (e.g. forcing a file
|
|
268
|
+
# to load before a monkey-patch), so removing it may change behavior. Flag but don't
|
|
269
|
+
# autocorrect, leaving it to the user.
|
|
270
|
+
return if node.const_type? && !node.special_keyword?
|
|
271
|
+
return if node.parent.type?(:if, :case, :when, :case_match, :in_pattern)
|
|
272
|
+
return if (def_node = node.each_ancestor(:any_def).first) && def_node.assignment_method?
|
|
234
273
|
|
|
235
274
|
corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
|
|
236
275
|
end
|
|
237
276
|
|
|
238
277
|
def autocorrect_nonmutating_send(corrector, node, suggestion)
|
|
239
|
-
send_node = if node.
|
|
278
|
+
send_node = if node.call_type?
|
|
240
279
|
node
|
|
241
280
|
else
|
|
242
281
|
node.send_node
|