rubocop 1.71.1 → 1.88.2
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 +513 -149
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +38 -4
- data/exe/rubocop +1 -8
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +36 -4
- 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 +48 -11
- data/lib/rubocop/comment_config.rb +60 -18
- data/lib/rubocop/config.rb +53 -16
- data/lib/rubocop/config_finder.rb +1 -1
- data/lib/rubocop/config_loader.rb +65 -49
- data/lib/rubocop/config_loader_resolver.rb +44 -19
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +46 -2
- data/lib/rubocop/config_store.rb +7 -2
- data/lib/rubocop/config_validator.rb +7 -6
- data/lib/rubocop/cop/autocorrect_logic.rb +27 -14
- data/lib/rubocop/cop/base.rb +38 -12
- 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/commissioner.rb +13 -11
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +26 -7
- 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/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 +13 -13
- 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 -1
- 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 +1 -1
- 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 +2 -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 +60 -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 +56 -10
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
- data/lib/rubocop/cop/layout/comment_indentation.rb +9 -2
- 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 +2 -15
- data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +28 -9
- 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 +10 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +35 -2
- 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/hash_alignment.rb +5 -8
- 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 +152 -7
- data/lib/rubocop/cop/layout/leading_comment_space.rb +13 -1
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +62 -15
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -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 +236 -41
- 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 +12 -6
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +15 -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 +1 -1
- 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 +18 -3
- 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 +12 -3
- 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/lint/ambiguous_assignment.rb +1 -11
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1 -10
- data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +13 -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 +93 -11
- data/lib/rubocop/cop/lint/constant_resolution.rb +6 -6
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +90 -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/duplicate_match_pattern.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +219 -32
- 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/incompatible_io_select_with_fiber_scheduler.rb +5 -1
- data/lib/rubocop/cop/lint/interpolation_check.rb +25 -5
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +129 -11
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +9 -12
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +19 -10
- 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/nested_method_definition.rb +1 -1
- 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/parentheses_as_grouped_expression.rb +3 -13
- 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 +27 -10
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6 -12
- 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 +4 -23
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +134 -11
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +12 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +268 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +4 -1
- 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 +22 -4
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +7 -1
- 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/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +123 -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 +36 -3
- 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 +17 -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/uri_escape_unescape.rb +2 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +30 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +55 -25
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +92 -0
- 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 +1 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +11 -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 +147 -0
- data/lib/rubocop/cop/lint/void.rb +50 -21
- 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 +38 -7
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- 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/migration/department_name.rb +12 -1
- 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/check_line_breakable.rb +4 -4
- 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 +1 -1
- 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/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 +15 -14
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
- data/lib/rubocop/cop/mixin/hash_subset.rb +27 -4
- 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/line_length_help.rb +45 -10
- 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/project_index_help.rb +48 -0
- data/lib/rubocop/cop/mixin/range_help.rb +15 -3
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -7
- 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 +25 -6
- data/lib/rubocop/cop/mixin.rb +86 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +3 -3
- 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 +11 -2
- data/lib/rubocop/cop/naming/method_name.rb +187 -15
- data/lib/rubocop/cop/naming/predicate_method.rb +330 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -4
- data/lib/rubocop/cop/naming/variable_name.rb +51 -6
- data/lib/rubocop/cop/offense.rb +17 -1
- data/lib/rubocop/cop/registry.rb +66 -39
- 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/style/access_modifier_declarations.rb +45 -12
- data/lib/rubocop/cop/style/accessor_grouping.rb +46 -8
- 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 +46 -31
- data/lib/rubocop/cop/style/array_first_last.rb +12 -1
- data/lib/rubocop/cop/style/array_intersect.rb +117 -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 +8 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +42 -34
- data/lib/rubocop/cop/style/case_equality.rb +29 -15
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +67 -12
- 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 +6 -0
- 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 +7 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +33 -24
- data/lib/rubocop/cop/style/constant_visibility.rb +20 -12
- data/lib/rubocop/cop/style/copyright.rb +22 -11
- data/lib/rubocop/cop/style/data_inheritance.rb +11 -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/disable_cops_within_source_code_directive.rb +1 -1
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
- data/lib/rubocop/cop/style/documentation.rb +6 -6
- data/lib/rubocop/cop/style/documentation_method.rb +12 -8
- 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 +12 -2
- 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 +0 -6
- 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 +181 -18
- 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 +4 -2
- 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 +15 -1
- data/lib/rubocop/cop/style/for.rb +4 -0
- data/lib/rubocop/cop/style/format_string.rb +17 -4
- data/lib/rubocop/cop/style/format_string_token.rb +85 -14
- 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 +29 -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 +3 -2
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_lookup_method.rb +102 -0
- data/lib/rubocop/cop/style/hash_slice.rb +16 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +6 -1
- 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 -7
- data/lib/rubocop/cop/style/if_inside_else.rb +26 -20
- data/lib/rubocop/cop/style/if_unless_modifier.rb +83 -16
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +16 -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 +8 -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 +3 -3
- 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 +12 -3
- data/lib/rubocop/cop/style/map_to_set.rb +1 -3
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +9 -8
- 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 +33 -4
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -5
- 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 +10 -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 +4 -4
- data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +13 -16
- data/lib/rubocop/cop/style/mutable_constant.rb +106 -12
- data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +11 -10
- data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
- data/lib/rubocop/cop/style/not.rb +2 -0
- 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 +21 -12
- data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +11 -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 +57 -25
- 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_begin.rb +38 -3
- data/lib/rubocop/cop/style/redundant_condition.rb +61 -1
- data/lib/rubocop/cop/style/redundant_constant_base.rb +5 -5
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +26 -4
- data/lib/rubocop/cop/style/redundant_each.rb +3 -3
- 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_filter_chain.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +312 -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 +28 -7
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +111 -37
- data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +9 -0
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +12 -0
- data/lib/rubocop/cop/style/redundant_return.rb +3 -1
- data/lib/rubocop/cop/style/redundant_self.rb +20 -7
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -1
- 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_struct_keyword_init.rb +133 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +32 -3
- data/lib/rubocop/cop/style/rescue_modifier.rb +6 -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 +67 -20
- 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 +53 -20
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +45 -12
- data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +21 -6
- data/lib/rubocop/cop/style/single_line_methods.rb +13 -8
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +77 -101
- data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +18 -15
- data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +24 -2
- data/lib/rubocop/cop/style/super_arguments.rb +3 -4
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +10 -7
- 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/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 +1 -1
- 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/team.rb +105 -40
- data/lib/rubocop/cop/util.rb +4 -5
- 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 +10 -3
- data/lib/rubocop/cop/variable_force.rb +26 -9
- data/lib/rubocop/cops_documentation_generator.rb +23 -7
- data/lib/rubocop/directive_comment.rb +80 -3
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- 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 +38 -13
- data/lib/rubocop/formatter/formatter_set.rb +2 -2
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +1 -1
- data/lib/rubocop/formatter/junit_formatter.rb +1 -1
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +0 -2
- data/lib/rubocop/formatter/tap_formatter.rb +5 -2
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
- data/lib/rubocop/formatter.rb +22 -21
- data/lib/rubocop/lsp/diagnostic.rb +22 -37
- data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
- data/lib/rubocop/lsp/routes.rb +47 -11
- data/lib/rubocop/lsp/runtime.rb +19 -8
- data/lib/rubocop/lsp/server.rb +0 -2
- data/lib/rubocop/lsp/stdin_runner.rb +11 -18
- data/lib/rubocop/magic_comment.rb +28 -0
- data/lib/rubocop/mcp/server.rb +200 -0
- data/lib/rubocop/options.rb +60 -14
- data/lib/rubocop/path_util.rb +18 -2
- data/lib/rubocop/pending_cops_reporter.rb +56 -0
- data/lib/rubocop/plugin/configuration_integrator.rb +143 -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 +66 -0
- data/lib/rubocop/rake_task.rb +5 -2
- data/lib/rubocop/remote_config.rb +10 -8
- data/lib/rubocop/result_cache.rb +72 -47
- data/lib/rubocop/rspec/cop_helper.rb +21 -1
- data/lib/rubocop/rspec/expect_offense.rb +9 -3
- data/lib/rubocop/rspec/shared_contexts.rb +71 -3
- data/lib/rubocop/rspec/support.rb +4 -0
- data/lib/rubocop/runner.rb +188 -65
- data/lib/rubocop/server/cache.rb +56 -41
- data/lib/rubocop/server/cli.rb +2 -2
- 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/target_finder.rb +21 -10
- data/lib/rubocop/target_ruby.rb +31 -14
- data/lib/rubocop/version.rb +50 -10
- data/lib/rubocop.rb +47 -96
- data/lib/ruby_lsp/rubocop/addon.rb +29 -17
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
- metadata +86 -16
- 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,220 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Identifies usages of `arr[arr.length - n]`, `arr[arr.size - n]`, or
|
|
7
|
+
# `arr[arr.count - n]` and suggests to change them to use `arr[-n]` instead.
|
|
8
|
+
# Also handles range patterns like `arr[0..(arr.length - n)]`.
|
|
9
|
+
#
|
|
10
|
+
# The cop recognizes preserving methods (`sort`, `reverse`, `shuffle`, `rotate`)
|
|
11
|
+
# and their combinations, allowing safe replacement when the receiver matches.
|
|
12
|
+
# It works with variables, instance variables, class variables, and constants.
|
|
13
|
+
#
|
|
14
|
+
# @example
|
|
15
|
+
# # bad
|
|
16
|
+
# arr[arr.count - 2]
|
|
17
|
+
# arr[0..(arr.length - 2)]
|
|
18
|
+
# arr[0...(arr.length - 4)]
|
|
19
|
+
# arr.sort[arr.reverse.length - 2]
|
|
20
|
+
# arr.sort.reverse[arr.sort.size - 2]
|
|
21
|
+
#
|
|
22
|
+
# # good
|
|
23
|
+
# arr[-2]
|
|
24
|
+
# arr[0..-2]
|
|
25
|
+
# arr[0...-4]
|
|
26
|
+
# arr.sort[-2]
|
|
27
|
+
# arr.sort.reverse[-2]
|
|
28
|
+
#
|
|
29
|
+
class NegativeArrayIndex < Base
|
|
30
|
+
extend AutoCorrector
|
|
31
|
+
include RangeHelp
|
|
32
|
+
|
|
33
|
+
MSG = 'Use `%<receiver>s[-%<index>s]` instead of `%<current>s`.'
|
|
34
|
+
MSG_RANGE = 'Use `%<receiver>s[%<start>s%<range_op>s-%<index>s]` instead of `%<current>s`.'
|
|
35
|
+
RESTRICT_ON_SEND = %i[[]].freeze
|
|
36
|
+
|
|
37
|
+
LENGTH_METHODS = %i[length size count].freeze
|
|
38
|
+
|
|
39
|
+
PRESERVING_METHODS = %i[sort reverse shuffle rotate].freeze
|
|
40
|
+
|
|
41
|
+
# @!method length_subtraction?(node)
|
|
42
|
+
def_node_matcher :length_subtraction?, <<~PATTERN
|
|
43
|
+
(send
|
|
44
|
+
(send $_ {:length :size :count}) :-
|
|
45
|
+
(int $_))
|
|
46
|
+
PATTERN
|
|
47
|
+
|
|
48
|
+
def on_send(node)
|
|
49
|
+
return if node.arguments.empty?
|
|
50
|
+
|
|
51
|
+
index_arg = node.first_argument
|
|
52
|
+
range_node = extract_range_from_begin(index_arg)
|
|
53
|
+
if range_with_length_subtraction?(range_node, node.receiver)
|
|
54
|
+
receiver = node.receiver.source
|
|
55
|
+
return handle_range_pattern(receiver, range_node, index_arg)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
handle_simple_index_pattern(node, index_arg)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
alias on_csend on_send
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def handle_simple_index_pattern(node, index_arg)
|
|
66
|
+
length_receiver, negative_index = length_subtraction?(index_arg)
|
|
67
|
+
|
|
68
|
+
return unless negative_index&.positive?
|
|
69
|
+
return unless receivers_match?(length_receiver, node.receiver)
|
|
70
|
+
|
|
71
|
+
add_offense_for_subtraction(node, index_arg, negative_index)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def extract_range_from_begin(node)
|
|
75
|
+
node.begin_type? ? node.children.first : node
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def extract_inner_end(node)
|
|
79
|
+
node.children.size == 1 ? node.children.first : node
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def add_offense_for_subtraction(node, index_arg, negative_index)
|
|
83
|
+
receiver = node.receiver.source
|
|
84
|
+
offense_range = index_arg.source_range
|
|
85
|
+
current = "#{receiver}[#{index_arg.source}]"
|
|
86
|
+
|
|
87
|
+
message = format(MSG, receiver: receiver, index: negative_index, current: current)
|
|
88
|
+
|
|
89
|
+
add_offense(offense_range, message: message) do |corrector|
|
|
90
|
+
corrector.replace(offense_range, "-#{negative_index}")
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def range_with_length_subtraction?(range_node, array_receiver)
|
|
95
|
+
return false unless range_node.range_type?
|
|
96
|
+
|
|
97
|
+
range_end = range_node.end
|
|
98
|
+
range_start = range_node.begin
|
|
99
|
+
return false unless range_end && range_start
|
|
100
|
+
|
|
101
|
+
return false unless preserving_method?(range_start)
|
|
102
|
+
|
|
103
|
+
inner_end = extract_inner_end(range_end)
|
|
104
|
+
length_receiver, negative_index = length_subtraction?(inner_end)
|
|
105
|
+
|
|
106
|
+
return false unless negative_index&.positive?
|
|
107
|
+
|
|
108
|
+
receivers_match_strict?(length_receiver, array_receiver)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def handle_range_pattern(receiver, range_node, index_arg)
|
|
112
|
+
range_end = range_node.end
|
|
113
|
+
inner_end = extract_inner_end(range_end)
|
|
114
|
+
_length_receiver, negative_index = length_subtraction?(inner_end)
|
|
115
|
+
|
|
116
|
+
message, replacement = build_range_offense_data(
|
|
117
|
+
receiver, range_node, range_end, inner_end, negative_index, index_arg
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
add_offense(range_end, message: message) do |corrector|
|
|
121
|
+
corrector.replace(index_arg, replacement)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# rubocop:disable Metrics/ParameterLists
|
|
126
|
+
def build_range_offense_data(receiver, range_node, range_end, inner_end, negative_index,
|
|
127
|
+
index_arg)
|
|
128
|
+
range_op = range_node.erange_type? ? '...' : '..'
|
|
129
|
+
range_start = range_node.begin.source
|
|
130
|
+
|
|
131
|
+
range_without_parens =
|
|
132
|
+
build_range_without_parens(range_start, range_op, range_end, inner_end)
|
|
133
|
+
current_source = build_current_source(receiver, range_without_parens, index_arg)
|
|
134
|
+
start, index = format_range_message_parts(range_start, negative_index, index_arg)
|
|
135
|
+
|
|
136
|
+
message = build_message_for_range(receiver, start, range_op, index, current_source)
|
|
137
|
+
replacement = build_replacement_string(range_start, range_op, negative_index, index_arg)
|
|
138
|
+
|
|
139
|
+
[message, replacement]
|
|
140
|
+
end
|
|
141
|
+
# rubocop:enable Metrics/ParameterLists
|
|
142
|
+
|
|
143
|
+
def format_range_message_parts(range_start, negative_index, index_arg)
|
|
144
|
+
has_parentheses = index_arg.begin_type?
|
|
145
|
+
start = has_parentheses ? "(#{range_start}" : range_start
|
|
146
|
+
index = has_parentheses ? "#{negative_index})" : negative_index
|
|
147
|
+
|
|
148
|
+
[start, index]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def build_message_for_range(receiver, start, range_op, index, current)
|
|
152
|
+
format(
|
|
153
|
+
MSG_RANGE,
|
|
154
|
+
receiver: receiver, start: start, range_op: range_op, index: index, current: current
|
|
155
|
+
)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def build_replacement_string(range_start, range_op, negative_index, index_arg)
|
|
159
|
+
has_parentheses = index_arg.begin_type?
|
|
160
|
+
|
|
161
|
+
if has_parentheses
|
|
162
|
+
"(#{range_start}#{range_op}-#{negative_index})"
|
|
163
|
+
else
|
|
164
|
+
"#{range_start}#{range_op}-#{negative_index}"
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def build_current_source(receiver, range_without_parens, index_arg)
|
|
169
|
+
has_parentheses = index_arg.begin_type?
|
|
170
|
+
|
|
171
|
+
if has_parentheses
|
|
172
|
+
"#{receiver}[(#{range_without_parens})]"
|
|
173
|
+
else
|
|
174
|
+
"#{receiver}[#{range_without_parens}]"
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def build_range_without_parens(range_start, range_op, range_end, inner_end)
|
|
179
|
+
end_expression = range_end.begin_type? ? range_end.source : inner_end.source
|
|
180
|
+
|
|
181
|
+
"#{range_start}#{range_op}#{end_expression}"
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def receivers_match?(length_receiver, array_receiver)
|
|
185
|
+
return array_receiver.self_type? unless length_receiver
|
|
186
|
+
|
|
187
|
+
unless preserving_method?(array_receiver) && preserving_method?(length_receiver)
|
|
188
|
+
return false
|
|
189
|
+
end
|
|
190
|
+
return true if length_receiver.source == array_receiver.source
|
|
191
|
+
|
|
192
|
+
!extract_base_receiver(array_receiver).nil?
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def receivers_match_strict?(length_receiver, array_receiver)
|
|
196
|
+
preserving_method?(array_receiver) &&
|
|
197
|
+
length_receiver.source == array_receiver.source
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def extract_base_receiver(node)
|
|
201
|
+
receiver = node.receiver
|
|
202
|
+
|
|
203
|
+
return nil unless receiver
|
|
204
|
+
return receiver unless receiver.receiver
|
|
205
|
+
|
|
206
|
+
extract_base_receiver(receiver)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def preserving_method?(node)
|
|
210
|
+
return true if node.receiver.nil?
|
|
211
|
+
|
|
212
|
+
method_name = node.method_name
|
|
213
|
+
return false unless PRESERVING_METHODS.include?(method_name)
|
|
214
|
+
|
|
215
|
+
preserving_method?(node.receiver)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
@@ -46,6 +46,38 @@ module RuboCop
|
|
|
46
46
|
# next unless a == 1
|
|
47
47
|
# puts a
|
|
48
48
|
# end
|
|
49
|
+
#
|
|
50
|
+
# @example AllowConsecutiveConditionals: false (default)
|
|
51
|
+
# # bad
|
|
52
|
+
# [1, 2].each do |a|
|
|
53
|
+
# if a == 1
|
|
54
|
+
# puts a
|
|
55
|
+
# end
|
|
56
|
+
# if a == 2
|
|
57
|
+
# puts a
|
|
58
|
+
# end
|
|
59
|
+
# end
|
|
60
|
+
#
|
|
61
|
+
# # good
|
|
62
|
+
# [1, 2].each do |a|
|
|
63
|
+
# if a == 1
|
|
64
|
+
# puts a
|
|
65
|
+
# end
|
|
66
|
+
# next unless a == 2
|
|
67
|
+
# puts a
|
|
68
|
+
# end
|
|
69
|
+
#
|
|
70
|
+
# @example AllowConsecutiveConditionals: true
|
|
71
|
+
# # good
|
|
72
|
+
# [1, 2].each do |a|
|
|
73
|
+
# if a == 1
|
|
74
|
+
# puts a
|
|
75
|
+
# end
|
|
76
|
+
# if a == 2
|
|
77
|
+
# puts a
|
|
78
|
+
# end
|
|
79
|
+
# end
|
|
80
|
+
#
|
|
49
81
|
class Next < Base
|
|
50
82
|
include ConfigurableEnforcedStyle
|
|
51
83
|
include MinBodyLength
|
|
@@ -72,6 +104,7 @@ module RuboCop
|
|
|
72
104
|
end
|
|
73
105
|
|
|
74
106
|
alias on_numblock on_block
|
|
107
|
+
alias on_itblock on_block
|
|
75
108
|
|
|
76
109
|
def on_while(node)
|
|
77
110
|
check(node)
|
|
@@ -86,6 +119,9 @@ module RuboCop
|
|
|
86
119
|
|
|
87
120
|
offending_node = offense_node(node.body)
|
|
88
121
|
|
|
122
|
+
return if allowed_consecutive_conditionals? &&
|
|
123
|
+
consecutive_conditionals?(offending_node)
|
|
124
|
+
|
|
89
125
|
add_offense(offense_location(offending_node)) do |corrector|
|
|
90
126
|
if offending_node.modifier_form?
|
|
91
127
|
autocorrect_modifier(corrector, offending_node)
|
|
@@ -227,6 +263,14 @@ module RuboCop
|
|
|
227
263
|
|
|
228
264
|
corrector.remove_leading(buffer.line_range(lineno), adjustment) if adjustment.positive?
|
|
229
265
|
end
|
|
266
|
+
|
|
267
|
+
def consecutive_conditionals?(if_node)
|
|
268
|
+
if_node.parent&.begin_type? && if_node.left_sibling&.if_type?
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def allowed_consecutive_conditionals?
|
|
272
|
+
cop_config.fetch('AllowConsecutiveConditionals', false)
|
|
273
|
+
end
|
|
230
274
|
end
|
|
231
275
|
end
|
|
232
276
|
end
|
|
@@ -4,9 +4,8 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for comparison of something with nil using `==` and
|
|
7
|
-
# `nil?`.
|
|
8
|
-
#
|
|
9
|
-
# Supported styles are: predicate, comparison.
|
|
7
|
+
# `nil?`. Enforcing a consistent style (either the `nil?`
|
|
8
|
+
# predicate or `==` comparison) improves readability.
|
|
10
9
|
#
|
|
11
10
|
# @example EnforcedStyle: predicate (default)
|
|
12
11
|
#
|
|
@@ -43,24 +42,26 @@ module RuboCop
|
|
|
43
42
|
# @!method nil_check?(node)
|
|
44
43
|
def_node_matcher :nil_check?, '(send _ :nil?)'
|
|
45
44
|
|
|
45
|
+
# rubocop:disable Metrics/AbcSize
|
|
46
46
|
def on_send(node)
|
|
47
47
|
return unless node.receiver
|
|
48
48
|
|
|
49
49
|
style_check?(node) do
|
|
50
50
|
add_offense(node.loc.selector) do |corrector|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
if prefer_comparison?
|
|
52
|
+
range = node.loc.dot.join(node.loc.selector.end)
|
|
53
|
+
corrector.replace(range, ' == nil')
|
|
54
|
+
else
|
|
55
|
+
range = node.receiver.source_range.end.join(node.source_range.end)
|
|
56
|
+
corrector.replace(range, '.nil?')
|
|
57
|
+
end
|
|
58
58
|
|
|
59
59
|
parent = node.parent
|
|
60
60
|
corrector.wrap(node, '(', ')') if parent.respond_to?(:method?) && parent.method?(:!)
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
|
+
# rubocop:enable Metrics/AbcSize
|
|
64
65
|
|
|
65
66
|
private
|
|
66
67
|
|
|
@@ -6,6 +6,11 @@ module RuboCop
|
|
|
6
6
|
# Checks for lambdas and procs that always return nil,
|
|
7
7
|
# which can be replaced with an empty lambda or proc instead.
|
|
8
8
|
#
|
|
9
|
+
# NOTE: A `proc` that returns nil via an explicit `return` is allowed,
|
|
10
|
+
# because in a `proc` `return` exits the enclosing method, so removing it
|
|
11
|
+
# would change behavior. A lambda is still reported, since there `return`
|
|
12
|
+
# only exits the lambda itself.
|
|
13
|
+
#
|
|
9
14
|
# @example
|
|
10
15
|
# # bad
|
|
11
16
|
# -> { nil }
|
|
@@ -43,9 +48,12 @@ module RuboCop
|
|
|
43
48
|
{ ({return next break} nil) (nil) }
|
|
44
49
|
PATTERN
|
|
45
50
|
|
|
46
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
51
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
47
52
|
return unless node.lambda_or_proc?
|
|
48
53
|
return unless nil_return?(node.body)
|
|
54
|
+
# `return` inside a non-lambda proc returns from the enclosing method,
|
|
55
|
+
# so dropping it changes behavior; only a lambda can omit it safely.
|
|
56
|
+
return if node.body.return_type? && !node.lambda?
|
|
49
57
|
|
|
50
58
|
message = format(MSG, type: node.lambda? ? 'lambda' : 'proc')
|
|
51
59
|
add_offense(node, message: message) do |corrector|
|
|
@@ -121,17 +121,11 @@ module RuboCop
|
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
def autocorrect_comparison(corrector, node)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
expr.sub(/^(\S*)\s*!=\s*nil/, '!\1.nil?')
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
return if expr == new_code
|
|
133
|
-
|
|
134
|
-
corrector.replace(node, new_code)
|
|
124
|
+
if include_semantic_changes?
|
|
125
|
+
corrector.replace(node, node.receiver.source)
|
|
126
|
+
else
|
|
127
|
+
corrector.replace(node, "!#{node.receiver.source}.nil?")
|
|
128
|
+
end
|
|
135
129
|
end
|
|
136
130
|
|
|
137
131
|
def autocorrect_non_nil(corrector, node, inner_node)
|
|
@@ -4,7 +4,8 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for big numeric literals without `_` between groups
|
|
7
|
-
# of digits in them.
|
|
7
|
+
# of digits in them. Underscores make large numbers easier to
|
|
8
|
+
# read by visually separating groups of digits.
|
|
8
9
|
#
|
|
9
10
|
# Additional allowed patterns can be added by adding regexps to
|
|
10
11
|
# the `AllowedPatterns` configuration. All regexps are treated
|
|
@@ -116,7 +117,7 @@ module RuboCop
|
|
|
116
117
|
end
|
|
117
118
|
|
|
118
119
|
def allowed_numbers
|
|
119
|
-
cop_config.fetch('AllowedNumbers', []).map(&:to_s)
|
|
120
|
+
@allowed_numbers ||= cop_config.fetch('AllowedNumbers', []).map(&:to_s).freeze
|
|
120
121
|
end
|
|
121
122
|
|
|
122
123
|
def allowed_patterns
|
|
@@ -92,7 +92,7 @@ module RuboCop
|
|
|
92
92
|
return unless numeric
|
|
93
93
|
|
|
94
94
|
return if allowed_method_name?(node.method_name) ||
|
|
95
|
-
node.each_ancestor(:send, :
|
|
95
|
+
node.each_ancestor(:send, :any_block).any? do |ancestor|
|
|
96
96
|
allowed_method_name?(ancestor.method_name)
|
|
97
97
|
end
|
|
98
98
|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Checks that each source file defines at most one top-level class or module.
|
|
7
|
+
#
|
|
8
|
+
# Keeping one class or module per file makes it easier to find and navigate
|
|
9
|
+
# code, and follows the convention used by most Ruby projects.
|
|
10
|
+
#
|
|
11
|
+
# Classes and modules listed in `AllowedClasses` are not counted toward the
|
|
12
|
+
# limit. This is useful for small ancillary classes like custom exception
|
|
13
|
+
# classes that logically belong with the main class.
|
|
14
|
+
#
|
|
15
|
+
# @example
|
|
16
|
+
# # bad - Multiple top-level classes
|
|
17
|
+
# class Foo
|
|
18
|
+
# end
|
|
19
|
+
#
|
|
20
|
+
# class Bar
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# # bad - Multiple top-level modules
|
|
24
|
+
# module Foo
|
|
25
|
+
# end
|
|
26
|
+
#
|
|
27
|
+
# module Bar
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
# # bad - A top-level class and a top-level module
|
|
31
|
+
# class Foo
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
# module Bar
|
|
35
|
+
# end
|
|
36
|
+
#
|
|
37
|
+
# # good - A single top-level class
|
|
38
|
+
# class Foo
|
|
39
|
+
# end
|
|
40
|
+
#
|
|
41
|
+
# # good - A single top-level module
|
|
42
|
+
# module Foo
|
|
43
|
+
# end
|
|
44
|
+
#
|
|
45
|
+
# # good - Nested classes within a single top-level class
|
|
46
|
+
# class Foo
|
|
47
|
+
# class Bar
|
|
48
|
+
# end
|
|
49
|
+
# end
|
|
50
|
+
#
|
|
51
|
+
# # good - Multiple classes within a single top-level module
|
|
52
|
+
# module Foo
|
|
53
|
+
# class Bar
|
|
54
|
+
# end
|
|
55
|
+
#
|
|
56
|
+
# class Baz
|
|
57
|
+
# end
|
|
58
|
+
# end
|
|
59
|
+
#
|
|
60
|
+
# @example AllowedClasses: ['AllowedClass']
|
|
61
|
+
# # good
|
|
62
|
+
# class Foo
|
|
63
|
+
# end
|
|
64
|
+
#
|
|
65
|
+
# class AllowedClass
|
|
66
|
+
# end
|
|
67
|
+
#
|
|
68
|
+
class OneClassPerFile < Base
|
|
69
|
+
include RangeHelp
|
|
70
|
+
|
|
71
|
+
MSG = 'Do not define multiple classes/modules at the top level in a single file.'
|
|
72
|
+
|
|
73
|
+
def on_new_investigation
|
|
74
|
+
@top_level_definitions = []
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def on_class(node)
|
|
78
|
+
check_top_level(node)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def on_module(node)
|
|
82
|
+
check_top_level(node)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def check_top_level(node)
|
|
88
|
+
return unless top_level_definition?(node)
|
|
89
|
+
return if allowed_class?(node)
|
|
90
|
+
|
|
91
|
+
@top_level_definitions << node
|
|
92
|
+
return unless @top_level_definitions.length > 1
|
|
93
|
+
|
|
94
|
+
add_offense(range_between(node.source_range.begin_pos, node.loc.name.end_pos))
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def top_level_definition?(node)
|
|
98
|
+
if node.parent&.begin_type?
|
|
99
|
+
node.parent.root?
|
|
100
|
+
else
|
|
101
|
+
node.root?
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def allowed_class?(node)
|
|
106
|
+
allowed_classes.include?(node.identifier.short_name)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def allowed_classes
|
|
110
|
+
@allowed_classes ||= cop_config.fetch('AllowedClasses', []).map(&:intern)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for uses of if/then/else/end constructs on a single line.
|
|
7
|
-
#
|
|
8
|
-
#
|
|
6
|
+
# Checks for uses of `if/then/else/end` constructs on a single line.
|
|
7
|
+
# A ternary operator (`?:`) or multi-line `if` is more readable.
|
|
8
|
+
# `AlwaysCorrectToMultiline` config option can be set to `true` to autocorrect all offenses to
|
|
9
|
+
# multi-line constructs. When `AlwaysCorrectToMultiline` is `false` (default case) the
|
|
9
10
|
# autocorrect will first try converting them to ternary operators.
|
|
10
11
|
#
|
|
11
12
|
# @example
|
|
@@ -55,19 +56,21 @@ module RuboCop
|
|
|
55
56
|
include OnNormalIfUnless
|
|
56
57
|
extend AutoCorrector
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
MSG_SUFFIX = 'over single-line `%<keyword>s/then/else/end` constructs.'
|
|
60
|
+
MSG_TERNARY = "Favor the ternary operator (`?:`) #{MSG_SUFFIX}"
|
|
61
|
+
MSG_MULTILINE = "Favor multi-line `%<keyword>s` #{MSG_SUFFIX}"
|
|
60
62
|
|
|
61
63
|
def on_normal_if_unless(node)
|
|
62
64
|
return unless node.single_line?
|
|
63
65
|
return unless node.else_branch
|
|
64
66
|
return if node.elsif? || node.if_branch&.begin_type?
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
multiline = multiline?(node)
|
|
69
|
+
|
|
70
|
+
add_offense(node, message: message(node, multiline)) do |corrector|
|
|
68
71
|
next if part_of_ignored_node?(node)
|
|
69
72
|
|
|
70
|
-
autocorrect(corrector, node)
|
|
73
|
+
autocorrect(corrector, node, multiline)
|
|
71
74
|
|
|
72
75
|
ignore_node(node)
|
|
73
76
|
end
|
|
@@ -75,12 +78,18 @@ module RuboCop
|
|
|
75
78
|
|
|
76
79
|
private
|
|
77
80
|
|
|
78
|
-
def
|
|
79
|
-
|
|
81
|
+
def multiline?(node)
|
|
82
|
+
always_multiline? || cannot_replace_to_ternary?(node)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def message(node, multiline)
|
|
86
|
+
template = multiline ? MSG_MULTILINE : MSG_TERNARY
|
|
87
|
+
|
|
88
|
+
format(template, keyword: node.keyword)
|
|
80
89
|
end
|
|
81
90
|
|
|
82
|
-
def autocorrect(corrector, node)
|
|
83
|
-
if
|
|
91
|
+
def autocorrect(corrector, node, multiline)
|
|
92
|
+
if multiline
|
|
84
93
|
IfThenCorrector.new(node, indentation: configured_indentation_width).call(corrector)
|
|
85
94
|
else
|
|
86
95
|
corrector.replace(node, ternary_correction(node))
|
|
@@ -26,9 +26,10 @@ module RuboCop
|
|
|
26
26
|
splat kwsplat forwarded_args forwarded_restarg forwarded_kwrestarg block_pass
|
|
27
27
|
].freeze
|
|
28
28
|
|
|
29
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
29
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
30
30
|
def on_send(node)
|
|
31
31
|
return unless (dot = node.loc.dot)
|
|
32
|
+
return if unary_method_no_operator?(node)
|
|
32
33
|
return if node.receiver.const_type? || !node.arguments.one?
|
|
33
34
|
|
|
34
35
|
return unless (rhs = node.first_argument)
|
|
@@ -43,10 +44,18 @@ module RuboCop
|
|
|
43
44
|
corrector.insert_after(selector, ' ') if insert_space_after?(node)
|
|
44
45
|
end
|
|
45
46
|
end
|
|
46
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
47
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
47
48
|
|
|
48
49
|
private
|
|
49
50
|
|
|
51
|
+
# `foo.~@` and `foo.!@` call the method `~` and `!` respectively. While those
|
|
52
|
+
# are operator methods, we don't want to actually consider them as such.
|
|
53
|
+
def unary_method_no_operator?(node)
|
|
54
|
+
return false unless node.nonmutating_unary_operator_method?
|
|
55
|
+
|
|
56
|
+
node.method_name.to_s != node.selector.source
|
|
57
|
+
end
|
|
58
|
+
|
|
50
59
|
# Checks for an acceptable case of `foo.+(bar).baz`.
|
|
51
60
|
def method_call_with_parenthesized_arg?(argument)
|
|
52
61
|
return false unless argument.parent.parent&.send_type?
|