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
|
@@ -13,17 +13,16 @@ module RuboCop
|
|
|
13
13
|
# # good
|
|
14
14
|
# x if y.z.nil?
|
|
15
15
|
#
|
|
16
|
-
class RedundantParentheses < Base
|
|
16
|
+
class RedundantParentheses < Base # rubocop:disable Metrics/ClassLength
|
|
17
17
|
include Parentheses
|
|
18
18
|
extend AutoCorrector
|
|
19
19
|
|
|
20
|
-
ALLOWED_NODE_TYPES = %i[
|
|
20
|
+
ALLOWED_NODE_TYPES = %i[or send splat kwsplat].freeze
|
|
21
21
|
|
|
22
22
|
# @!method square_brackets?(node)
|
|
23
|
-
def_node_matcher :square_brackets?,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def_node_matcher :method_node_and_args, '$(call _recv _msg $...)'
|
|
23
|
+
def_node_matcher :square_brackets?, <<~PATTERN
|
|
24
|
+
(send `{(send _recv _msg) str array hash const #variable?} :[] ...)
|
|
25
|
+
PATTERN
|
|
27
26
|
|
|
28
27
|
# @!method rescue?(node)
|
|
29
28
|
def_node_matcher :rescue?, '{^resbody ^^resbody}'
|
|
@@ -39,10 +38,15 @@ module RuboCop
|
|
|
39
38
|
|
|
40
39
|
private
|
|
41
40
|
|
|
41
|
+
def variable?(node)
|
|
42
|
+
node.respond_to?(:variable?) && node.variable?
|
|
43
|
+
end
|
|
44
|
+
|
|
42
45
|
def parens_allowed?(node)
|
|
43
46
|
empty_parentheses?(node) ||
|
|
44
47
|
first_arg_begins_with_hash_literal?(node) ||
|
|
45
48
|
rescue?(node) ||
|
|
49
|
+
in_pattern_matching_in_method_argument?(node) ||
|
|
46
50
|
allowed_pin_operator?(node) ||
|
|
47
51
|
allowed_expression?(node)
|
|
48
52
|
end
|
|
@@ -72,7 +76,7 @@ module RuboCop
|
|
|
72
76
|
ancestor = node.ancestors.first
|
|
73
77
|
return false unless ancestor
|
|
74
78
|
|
|
75
|
-
!ancestor.type?(:begin, :
|
|
79
|
+
!ancestor.type?(:begin, :any_def, :any_block)
|
|
76
80
|
end
|
|
77
81
|
|
|
78
82
|
def allowed_ternary?(node)
|
|
@@ -92,7 +96,7 @@ module RuboCop
|
|
|
92
96
|
return false unless node.type?(:send, :super, :yield)
|
|
93
97
|
|
|
94
98
|
node.arguments.one? && !node.parenthesized? &&
|
|
95
|
-
!node.
|
|
99
|
+
!node.operator_method? && node.first_argument.begin_type?
|
|
96
100
|
end
|
|
97
101
|
|
|
98
102
|
def multiline_control_flow_statements?(node)
|
|
@@ -110,12 +114,19 @@ module RuboCop
|
|
|
110
114
|
def first_arg_begins_with_hash_literal?(node)
|
|
111
115
|
# Don't flag `method ({key: value})` or `method ({key: value}.method)`
|
|
112
116
|
hash_literal = method_chain_begins_with_hash_literal(node.children.first)
|
|
113
|
-
if (root_method = node.each_ancestor(:
|
|
117
|
+
if (root_method = node.each_ancestor(:call).to_a.last)
|
|
114
118
|
parenthesized = root_method.parenthesized_call?
|
|
115
119
|
end
|
|
116
120
|
hash_literal && first_argument?(node) && !parentheses?(hash_literal) && !parenthesized
|
|
117
121
|
end
|
|
118
122
|
|
|
123
|
+
def in_pattern_matching_in_method_argument?(begin_node)
|
|
124
|
+
return false unless begin_node.parent&.call_type?
|
|
125
|
+
return false unless (node = begin_node.children.first)
|
|
126
|
+
|
|
127
|
+
target_ruby_version <= 2.7 ? node.match_pattern_type? : node.match_pattern_p_type?
|
|
128
|
+
end
|
|
129
|
+
|
|
119
130
|
def method_chain_begins_with_hash_literal(node)
|
|
120
131
|
return if node.nil?
|
|
121
132
|
return node if node.hash_type?
|
|
@@ -128,25 +139,38 @@ module RuboCop
|
|
|
128
139
|
node = begin_node.children.first
|
|
129
140
|
|
|
130
141
|
if (message = find_offense_message(begin_node, node))
|
|
142
|
+
return offense(begin_node, message) if message == 'block body'
|
|
143
|
+
|
|
144
|
+
if node.range_type? && !argument_of_parenthesized_method_call?(begin_node, node)
|
|
145
|
+
begin_node = begin_node.parent
|
|
146
|
+
end
|
|
147
|
+
|
|
131
148
|
return offense(begin_node, message)
|
|
132
149
|
end
|
|
133
150
|
|
|
134
|
-
check_send(begin_node, node) if node
|
|
151
|
+
check_send(begin_node, node) if call_node?(node)
|
|
135
152
|
end
|
|
136
153
|
|
|
137
154
|
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
138
155
|
def find_offense_message(begin_node, node)
|
|
139
156
|
return 'a keyword' if keyword_with_redundant_parentheses?(node)
|
|
140
|
-
return 'a literal' if disallowed_literal?(begin_node, node)
|
|
157
|
+
return 'a literal' if node.literal? && disallowed_literal?(begin_node, node)
|
|
141
158
|
return 'a variable' if node.variable?
|
|
142
159
|
return 'a constant' if node.const_type?
|
|
160
|
+
return 'block body' if begin_node.parent&.any_block_type? || body_range?(begin_node, node)
|
|
161
|
+
|
|
143
162
|
if node.assignment? && (begin_node.parent.nil? || begin_node.parent.begin_type?)
|
|
144
163
|
return 'an assignment'
|
|
145
164
|
end
|
|
146
165
|
if node.lambda_or_proc? && (node.braces? || node.send_node.lambda_literal?)
|
|
147
166
|
return 'an expression'
|
|
148
167
|
end
|
|
168
|
+
if disallowed_one_line_pattern_matching?(begin_node, node)
|
|
169
|
+
return 'a one-line pattern matching'
|
|
170
|
+
end
|
|
149
171
|
return 'an interpolated expression' if interpolation?(begin_node)
|
|
172
|
+
return 'a method argument' if argument_of_parenthesized_method_call?(begin_node, node)
|
|
173
|
+
return 'a one-line rescue' if oneline_rescue_parentheses_required?(begin_node, node)
|
|
150
174
|
|
|
151
175
|
return if begin_node.chained?
|
|
152
176
|
|
|
@@ -154,6 +178,7 @@ module RuboCop
|
|
|
154
178
|
return if node.semantic_operator? && begin_node.parent
|
|
155
179
|
return if node.multiline? && allow_in_multiline_conditions?
|
|
156
180
|
return if ALLOWED_NODE_TYPES.include?(begin_node.parent&.type)
|
|
181
|
+
return if !node.and_type? && begin_node.parent&.and_type?
|
|
157
182
|
return if begin_node.parent&.if_type? && begin_node.parent.ternary?
|
|
158
183
|
|
|
159
184
|
'a logical expression'
|
|
@@ -168,14 +193,44 @@ module RuboCop
|
|
|
168
193
|
# @!method interpolation?(node)
|
|
169
194
|
def_node_matcher :interpolation?, '[^begin ^^dstr]'
|
|
170
195
|
|
|
196
|
+
def argument_of_parenthesized_method_call?(begin_node, node)
|
|
197
|
+
if node.basic_conditional? || node.rescue_type? || method_call_parentheses_required?(node)
|
|
198
|
+
return false
|
|
199
|
+
end
|
|
200
|
+
return false unless (parent = begin_node.parent)
|
|
201
|
+
|
|
202
|
+
parent.call_type? && parent.parenthesized? && parent.receiver != begin_node
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def oneline_rescue_parentheses_required?(begin_node, node)
|
|
206
|
+
return false unless node.rescue_type?
|
|
207
|
+
return false unless (parent = begin_node.parent)
|
|
208
|
+
return false if parent.if_type? && parent.ternary?
|
|
209
|
+
return false if parent.conditional? && parent.condition == begin_node
|
|
210
|
+
|
|
211
|
+
!parent.type?(:call, :array, :pair)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def method_call_parentheses_required?(node)
|
|
215
|
+
return false unless node.call_type?
|
|
216
|
+
|
|
217
|
+
(node.receiver.nil? || node.loc.dot) && node.arguments.any?
|
|
218
|
+
end
|
|
219
|
+
|
|
171
220
|
def allow_in_multiline_conditions?
|
|
172
221
|
!!config.for_enabled_cop('Style/ParenthesesAroundCondition')['AllowInMultilineConditions']
|
|
173
222
|
end
|
|
174
223
|
|
|
224
|
+
def call_node?(node)
|
|
225
|
+
node.call_type? || (node.any_block_type? && node.braces? && !node.lambda_or_proc?)
|
|
226
|
+
end
|
|
227
|
+
|
|
175
228
|
def check_send(begin_node, node)
|
|
229
|
+
node = node.send_node if node.any_block_type?
|
|
230
|
+
|
|
176
231
|
return check_unary(begin_node, node) if node.unary_operation?
|
|
177
232
|
|
|
178
|
-
return unless method_call_with_redundant_parentheses?(node)
|
|
233
|
+
return unless method_call_with_redundant_parentheses?(begin_node, node)
|
|
179
234
|
return if call_chain_starts_with_int?(begin_node, node) ||
|
|
180
235
|
do_end_block_in_method_chain?(begin_node, node)
|
|
181
236
|
|
|
@@ -186,8 +241,7 @@ module RuboCop
|
|
|
186
241
|
return if begin_node.chained?
|
|
187
242
|
|
|
188
243
|
node = node.children.first while suspect_unary?(node)
|
|
189
|
-
|
|
190
|
-
return if node.send_type? && !method_call_with_redundant_parentheses?(node)
|
|
244
|
+
return unless method_call_with_redundant_parentheses?(begin_node, node)
|
|
191
245
|
|
|
192
246
|
offense(begin_node, 'a unary operation')
|
|
193
247
|
end
|
|
@@ -207,7 +261,34 @@ module RuboCop
|
|
|
207
261
|
end
|
|
208
262
|
|
|
209
263
|
def disallowed_literal?(begin_node, node)
|
|
210
|
-
|
|
264
|
+
if node.range_type?
|
|
265
|
+
return false unless (parent = begin_node.parent)
|
|
266
|
+
|
|
267
|
+
parent.begin_type? && parent.children.one?
|
|
268
|
+
else
|
|
269
|
+
!raised_to_power_negative_numeric?(begin_node, node)
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
274
|
+
def body_range?(begin_node, node)
|
|
275
|
+
return false if begin_node.chained?
|
|
276
|
+
return false unless node.range_type?
|
|
277
|
+
return false unless (parent = begin_node.parent)
|
|
278
|
+
return false unless parent.begin_type?
|
|
279
|
+
|
|
280
|
+
(node.begin.nil? && begin_node == parent.children.first) ||
|
|
281
|
+
(node.end.nil? && begin_node == parent.children.last)
|
|
282
|
+
end
|
|
283
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
284
|
+
|
|
285
|
+
def disallowed_one_line_pattern_matching?(begin_node, node)
|
|
286
|
+
if (parent = begin_node.parent)
|
|
287
|
+
return false if parent.any_def_type? && parent.endless?
|
|
288
|
+
return false if parent.assignment?
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
node.any_match_pattern_type? && node.each_ancestor.none?(&:operator_keyword?)
|
|
211
292
|
end
|
|
212
293
|
|
|
213
294
|
def raised_to_power_negative_numeric?(begin_node, node)
|
|
@@ -234,13 +315,19 @@ module RuboCop
|
|
|
234
315
|
end
|
|
235
316
|
end
|
|
236
317
|
|
|
237
|
-
def method_call_with_redundant_parentheses?(node)
|
|
238
|
-
return false unless node.
|
|
318
|
+
def method_call_with_redundant_parentheses?(begin_node, node)
|
|
319
|
+
return false unless node.type?(:call, :super, :yield, :defined?)
|
|
239
320
|
return false if node.prefix_not?
|
|
321
|
+
return true if singular_parenthesized_parent?(begin_node)
|
|
322
|
+
|
|
323
|
+
node.arguments.empty? || parentheses?(node) || square_brackets?(node)
|
|
324
|
+
end
|
|
240
325
|
|
|
241
|
-
|
|
326
|
+
def singular_parenthesized_parent?(begin_node)
|
|
327
|
+
return true unless (parent = begin_node.parent)
|
|
328
|
+
return false if parent.type?(:splat, :kwsplat)
|
|
242
329
|
|
|
243
|
-
|
|
330
|
+
parent.children.one?
|
|
244
331
|
end
|
|
245
332
|
|
|
246
333
|
def only_begin_arg?(args)
|
|
@@ -248,28 +335,15 @@ module RuboCop
|
|
|
248
335
|
end
|
|
249
336
|
|
|
250
337
|
def first_argument?(node)
|
|
251
|
-
if
|
|
252
|
-
first_super_argument?(node) ||
|
|
253
|
-
first_yield_argument?(node)
|
|
254
|
-
return true
|
|
255
|
-
end
|
|
338
|
+
return true if first_call_argument?(node)
|
|
256
339
|
|
|
257
340
|
node.each_ancestor.any? { |ancestor| first_argument?(ancestor) }
|
|
258
341
|
end
|
|
259
342
|
|
|
260
|
-
# @!method
|
|
261
|
-
def_node_matcher :
|
|
262
|
-
^(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
# @!method first_super_argument?(node)
|
|
266
|
-
def_node_matcher :first_super_argument?, <<~PATTERN
|
|
267
|
-
^(super equal?(%0) ...)
|
|
268
|
-
PATTERN
|
|
269
|
-
|
|
270
|
-
# @!method first_yield_argument?(node)
|
|
271
|
-
def_node_matcher :first_yield_argument?, <<~PATTERN
|
|
272
|
-
^(yield equal?(%0) ...)
|
|
343
|
+
# @!method first_call_argument?(node)
|
|
344
|
+
def_node_matcher :first_call_argument?, <<~PATTERN
|
|
345
|
+
{^(call _ _ equal?(%0) ...)
|
|
346
|
+
^({super yield} equal?(%0) ...)}
|
|
273
347
|
PATTERN
|
|
274
348
|
|
|
275
349
|
def call_chain_starts_with_int?(begin_node, send_node)
|
|
@@ -80,8 +80,7 @@ module RuboCop
|
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
def string_literal?(node)
|
|
83
|
-
node.loc
|
|
84
|
-
node.loc.begin && node.loc.end
|
|
83
|
+
node.loc?(:begin) && node.loc?(:end)
|
|
85
84
|
end
|
|
86
85
|
|
|
87
86
|
def start_with_percent_q_variant?(string)
|
|
@@ -91,7 +90,10 @@ module RuboCop
|
|
|
91
90
|
def acceptable_q?(node)
|
|
92
91
|
src = node.source
|
|
93
92
|
|
|
94
|
-
|
|
93
|
+
# If the string contains interpolation-like syntax and would be
|
|
94
|
+
# converted to a double-quoted string (because it contains single
|
|
95
|
+
# quotes), the replacement would activate interpolation.
|
|
96
|
+
return true if STRING_INTERPOLATION_REGEXP.match?(src) && src.include?(SINGLE_QUOTE)
|
|
95
97
|
|
|
96
98
|
src.scan(/\\./).any?(ESCAPED_NON_BACKSLASH)
|
|
97
99
|
end
|
|
@@ -66,6 +66,7 @@ module RuboCop
|
|
|
66
66
|
DETERMINISTIC_REGEX.match?(regexp_node.source)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
+
# rubocop:disable Metrics/MethodLength
|
|
69
70
|
def preferred_argument(regexp_node)
|
|
70
71
|
new_argument = replacement(regexp_node)
|
|
71
72
|
|
|
@@ -73,6 +74,13 @@ module RuboCop
|
|
|
73
74
|
new_argument.gsub!("'", "\\\\'")
|
|
74
75
|
new_argument.gsub!('\"', '"')
|
|
75
76
|
quote = "'"
|
|
77
|
+
elsif new_argument.include?("\\'")
|
|
78
|
+
# Add a backslash before single quotes preceded by an even number of backslashes.
|
|
79
|
+
# An even number (including zero) of backslashes before a quote means the quote itself
|
|
80
|
+
# is not escaped.
|
|
81
|
+
# Otherwise an odd number means the quote is already escaped so this doesn't touch it.
|
|
82
|
+
new_argument.gsub!(/(?<!\\)((?:\\\\)*)'/) { "#{::Regexp.last_match(1)}\\'" }
|
|
83
|
+
quote = "'"
|
|
76
84
|
elsif new_argument.include?('\'')
|
|
77
85
|
new_argument.gsub!("'", "\\\\'")
|
|
78
86
|
quote = "'"
|
|
@@ -84,6 +92,7 @@ module RuboCop
|
|
|
84
92
|
|
|
85
93
|
"#{quote}#{new_argument}#{quote}"
|
|
86
94
|
end
|
|
95
|
+
# rubocop:enable Metrics/MethodLength
|
|
87
96
|
|
|
88
97
|
def replacement(regexp_node)
|
|
89
98
|
regexp_content = regexp_node.content
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for the instantiation of regexp using redundant `Regexp.new` or `Regexp.compile`.
|
|
7
|
-
# Autocorrect replaces
|
|
6
|
+
# Checks for the instantiation of a regexp using a redundant `Regexp.new` or `Regexp.compile`.
|
|
7
|
+
# Autocorrect replaces it with a regexp literal which is the simplest and fastest.
|
|
8
8
|
#
|
|
9
9
|
# @example
|
|
10
10
|
#
|
|
@@ -41,6 +41,7 @@ module RuboCop
|
|
|
41
41
|
ALLOWED_ALWAYS_ESCAPES = " \n[]^\\#".chars.freeze
|
|
42
42
|
ALLOWED_WITHIN_CHAR_CLASS_METACHAR_ESCAPES = '-'.chars.freeze
|
|
43
43
|
ALLOWED_OUTSIDE_CHAR_CLASS_METACHAR_ESCAPES = '.*+?{}()|$'.chars.freeze
|
|
44
|
+
INTERPOLATION_SIGILS = %w[@ $].freeze
|
|
44
45
|
|
|
45
46
|
def on_regexp(node)
|
|
46
47
|
each_escape(node) do |char, index, within_character_class|
|
|
@@ -64,6 +65,7 @@ module RuboCop
|
|
|
64
65
|
# different versions of Ruby so that e.g. /\i/ != /i/
|
|
65
66
|
return true if /[[:alnum:]]/.match?(char)
|
|
66
67
|
return true if ALLOWED_ALWAYS_ESCAPES.include?(char) || delimiter?(node, char)
|
|
68
|
+
return true if requires_escape_to_avoid_interpolation?(node, index, char)
|
|
67
69
|
|
|
68
70
|
if within_character_class
|
|
69
71
|
ALLOWED_WITHIN_CHAR_CLASS_METACHAR_ESCAPES.include?(char) &&
|
|
@@ -95,6 +97,16 @@ module RuboCop
|
|
|
95
97
|
delimiters.include?(char)
|
|
96
98
|
end
|
|
97
99
|
|
|
100
|
+
def requires_escape_to_avoid_interpolation?(node, index, escaped_char)
|
|
101
|
+
# Preserve escapes after '#' that would otherwise trigger interpolation:
|
|
102
|
+
# '#@ivar', '#@@cvar', and '#$gvar'. `index` is relative to the regexp
|
|
103
|
+
# contents, so index into those rather than `node.source` (which also
|
|
104
|
+
# includes the opening delimiter, e.g. `%r{`).
|
|
105
|
+
return false unless index.positive? && INTERPOLATION_SIGILS.include?(escaped_char)
|
|
106
|
+
|
|
107
|
+
contents_range(node).source[index - 1] == '#'
|
|
108
|
+
end
|
|
109
|
+
|
|
98
110
|
def each_escape(node)
|
|
99
111
|
node.parsed_tree&.traverse&.reduce(0) do |char_class_depth, (event, expr)|
|
|
100
112
|
yield(expr.text[1], expr.ts, !char_class_depth.zero?) if expr.type == :escape
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for redundant `return` expressions.
|
|
6
|
+
# Checks for redundant `return` expressions. Ruby methods
|
|
7
|
+
# implicitly return the value of the last evaluated expression,
|
|
8
|
+
# so an explicit `return` at the end of a method body is unnecessary.
|
|
7
9
|
#
|
|
8
10
|
# @example
|
|
9
11
|
# # These bad cases should be extended to handle methods whose body is
|
|
@@ -59,7 +59,7 @@ module RuboCop
|
|
|
59
59
|
|
|
60
60
|
def initialize(config = nil, options = nil)
|
|
61
61
|
super
|
|
62
|
-
@allowed_send_nodes =
|
|
62
|
+
@allowed_send_nodes = Set.new.compare_by_identity
|
|
63
63
|
@local_variables_scopes = Hash.new { |hash, key| hash[key] = [] }.compare_by_identity
|
|
64
64
|
end
|
|
65
65
|
|
|
@@ -67,6 +67,9 @@ module RuboCop
|
|
|
67
67
|
|
|
68
68
|
def on_or_asgn(node)
|
|
69
69
|
allow_self(node.lhs)
|
|
70
|
+
|
|
71
|
+
lhs_name = node.lhs.lvasgn_type? ? node.lhs.name : node.lhs
|
|
72
|
+
add_lhs_to_local_variables_scopes(node.rhs, lhs_name)
|
|
70
73
|
end
|
|
71
74
|
alias on_and_asgn on_or_asgn
|
|
72
75
|
|
|
@@ -97,6 +100,15 @@ module RuboCop
|
|
|
97
100
|
add_lhs_to_local_variables_scopes(node.rhs, node.lhs)
|
|
98
101
|
end
|
|
99
102
|
|
|
103
|
+
# Register the exception variable of `rescue => e` so that `self.e` in the
|
|
104
|
+
# body is not treated as redundant (it disambiguates the local variable).
|
|
105
|
+
def on_resbody(node)
|
|
106
|
+
exception_variable = node.exception_variable
|
|
107
|
+
return unless exception_variable&.lvasgn_type?
|
|
108
|
+
|
|
109
|
+
@local_variables_scopes[node] << exception_variable.name
|
|
110
|
+
end
|
|
111
|
+
|
|
100
112
|
def on_in_pattern(node)
|
|
101
113
|
add_match_var_scopes(node)
|
|
102
114
|
end
|
|
@@ -118,15 +130,16 @@ module RuboCop
|
|
|
118
130
|
end
|
|
119
131
|
|
|
120
132
|
alias on_numblock on_block
|
|
133
|
+
alias on_itblock on_block
|
|
121
134
|
|
|
122
135
|
def on_if(node)
|
|
123
136
|
# Allow conditional nodes to use `self` in the condition if that variable
|
|
124
137
|
# name is used in an `lvasgn` or `masgn` within the `if`.
|
|
125
|
-
node.
|
|
126
|
-
if
|
|
127
|
-
add_lhs_to_local_variables_scopes(node.condition,
|
|
128
|
-
|
|
129
|
-
add_masgn_lhs_variables(node.condition,
|
|
138
|
+
node.each_descendant(:lvasgn, :masgn) do |descendant_node|
|
|
139
|
+
if descendant_node.lvasgn_type?
|
|
140
|
+
add_lhs_to_local_variables_scopes(node.condition, descendant_node.lhs)
|
|
141
|
+
else
|
|
142
|
+
add_masgn_lhs_variables(node.condition, descendant_node.lhs)
|
|
130
143
|
end
|
|
131
144
|
end
|
|
132
145
|
end
|
|
@@ -183,7 +196,7 @@ module RuboCop
|
|
|
183
196
|
def allow_self(node)
|
|
184
197
|
return unless node.send_type? && node.self_receiver?
|
|
185
198
|
|
|
186
|
-
@allowed_send_nodes
|
|
199
|
+
@allowed_send_nodes.add(node)
|
|
187
200
|
end
|
|
188
201
|
|
|
189
202
|
def add_lhs_to_local_variables_scopes(rhs, lhs)
|
|
@@ -58,7 +58,7 @@ module RuboCop
|
|
|
58
58
|
# rubocop:disable Metrics/AbcSize
|
|
59
59
|
def on_lvasgn(node)
|
|
60
60
|
return unless (rhs = node.rhs)
|
|
61
|
-
return unless rhs.
|
|
61
|
+
return unless rhs.type?(:any_block, :call) && method_returning_self?(rhs.method_name)
|
|
62
62
|
return unless (receiver = rhs.receiver)
|
|
63
63
|
|
|
64
64
|
receiver_type = ASSIGNMENT_TYPE_TO_RECEIVER_TYPE[node.type]
|
|
@@ -26,17 +26,17 @@ module RuboCop
|
|
|
26
26
|
#
|
|
27
27
|
# [source,ruby]
|
|
28
28
|
# ----
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
29
|
+
# class MyString < String; end
|
|
30
|
+
# strings = [MyString.new('test'), 'test']
|
|
31
|
+
# strings.sort.last.class #=> String
|
|
32
|
+
# strings.max.class #=> MyString
|
|
33
33
|
# ----
|
|
34
34
|
#
|
|
35
35
|
# [source,ruby]
|
|
36
36
|
# ----
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
37
|
+
# words = %w(dog horse mouse)
|
|
38
|
+
# words.sort_by { |word| word.length }.last #=> 'mouse'
|
|
39
|
+
# words.max_by { |word| word.length } #=> 'horse'
|
|
40
40
|
# ----
|
|
41
41
|
#
|
|
42
42
|
# @example
|
|
@@ -21,6 +21,7 @@ module RuboCop
|
|
|
21
21
|
|
|
22
22
|
MSG_BLOCK = 'Use `sort` instead of `sort_by { |%<var>s| %<var>s }`.'
|
|
23
23
|
MSG_NUMBLOCK = 'Use `sort` instead of `sort_by { _1 }`.'
|
|
24
|
+
MSG_ITBLOCK = 'Use `sort` instead of `sort_by { it }`.'
|
|
24
25
|
|
|
25
26
|
def on_block(node)
|
|
26
27
|
redundant_sort_by_block(node) do |send, var_name|
|
|
@@ -36,7 +37,17 @@ module RuboCop
|
|
|
36
37
|
redundant_sort_by_numblock(node) do |send|
|
|
37
38
|
range = sort_by_range(send, node)
|
|
38
39
|
|
|
39
|
-
add_offense(range, message:
|
|
40
|
+
add_offense(range, message: MSG_NUMBLOCK) do |corrector|
|
|
41
|
+
corrector.replace(range, 'sort')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def on_itblock(node)
|
|
47
|
+
redundant_sort_by_itblock(node) do |send|
|
|
48
|
+
range = sort_by_range(send, node)
|
|
49
|
+
|
|
50
|
+
add_offense(range, message: MSG_ITBLOCK) do |corrector|
|
|
40
51
|
corrector.replace(range, 'sort')
|
|
41
52
|
end
|
|
42
53
|
end
|
|
@@ -54,6 +65,11 @@ module RuboCop
|
|
|
54
65
|
(numblock $(call _ :sort_by) 1 (lvar :_1))
|
|
55
66
|
PATTERN
|
|
56
67
|
|
|
68
|
+
# @!method redundant_sort_by_itblock(node)
|
|
69
|
+
def_node_matcher :redundant_sort_by_itblock, <<~PATTERN
|
|
70
|
+
(itblock $(call _ :sort_by) _ (lvar :it))
|
|
71
|
+
PATTERN
|
|
72
|
+
|
|
57
73
|
def sort_by_range(send, node)
|
|
58
74
|
range_between(send.loc.selector.begin_pos, node.loc.end.end_pos)
|
|
59
75
|
end
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Checks for redundant `keyword_init` option for `Struct.new`.
|
|
7
|
+
#
|
|
8
|
+
# Since Ruby 3.2, `keyword_init` in `Struct.new` defaults to `nil` behavior.
|
|
9
|
+
# Therefore, this cop detects and autocorrects redundant `keyword_init: nil`
|
|
10
|
+
# and `keyword_init: true` in `Struct.new`.
|
|
11
|
+
#
|
|
12
|
+
# This cop is disabled by default because `keyword_init: true` is not purely
|
|
13
|
+
# redundant. It changes behavior in the following ways:
|
|
14
|
+
#
|
|
15
|
+
# - `Struct#keyword_init?` returns `true` instead of `nil`.
|
|
16
|
+
# - A `Struct` with `keyword_init: true` accepts a `Hash` argument and
|
|
17
|
+
# expands it as keyword arguments, whereas without it the `Hash` is
|
|
18
|
+
# treated as a positional argument.
|
|
19
|
+
# - `keyword_init: true` raises an `ArgumentError` for positional arguments,
|
|
20
|
+
# enforcing keyword-only initialization.
|
|
21
|
+
#
|
|
22
|
+
# @safety
|
|
23
|
+
# This autocorrect is unsafe because when the value of `keyword_init` changes
|
|
24
|
+
# from `true` to `nil`, the return value of `Struct#keyword_init?` changes.
|
|
25
|
+
#
|
|
26
|
+
# @example
|
|
27
|
+
#
|
|
28
|
+
# # bad
|
|
29
|
+
# Struct.new(:foo, keyword_init: nil)
|
|
30
|
+
# Struct.new(:foo, keyword_init: true)
|
|
31
|
+
#
|
|
32
|
+
# # good
|
|
33
|
+
# Struct.new(:foo)
|
|
34
|
+
#
|
|
35
|
+
class RedundantStructKeywordInit < Base
|
|
36
|
+
extend AutoCorrector
|
|
37
|
+
extend TargetRubyVersion
|
|
38
|
+
|
|
39
|
+
MSG = 'Remove the redundant `keyword_init: %<value>s`.'
|
|
40
|
+
RESTRICT_ON_SEND = %i[new].freeze
|
|
41
|
+
|
|
42
|
+
minimum_target_ruby_version 3.2
|
|
43
|
+
|
|
44
|
+
# @!method struct_new?(node)
|
|
45
|
+
def_node_matcher :struct_new?, <<~PATTERN
|
|
46
|
+
(call (const {nil? cbase} :Struct) :new ...)
|
|
47
|
+
PATTERN
|
|
48
|
+
|
|
49
|
+
# @!method keyword_init?(node)
|
|
50
|
+
def_node_matcher :keyword_init?, <<~PATTERN
|
|
51
|
+
{#redundant_keyword_init? #keyword_init_false?}
|
|
52
|
+
PATTERN
|
|
53
|
+
|
|
54
|
+
# @!method redundant_keyword_init?(node)
|
|
55
|
+
def_node_matcher :redundant_keyword_init?, <<~PATTERN
|
|
56
|
+
(pair (sym :keyword_init) {(true) (nil)})
|
|
57
|
+
PATTERN
|
|
58
|
+
|
|
59
|
+
# @!method keyword_init_false?(node)
|
|
60
|
+
def_node_matcher :keyword_init_false?, <<~PATTERN
|
|
61
|
+
(pair (sym :keyword_init) (false))
|
|
62
|
+
PATTERN
|
|
63
|
+
|
|
64
|
+
def on_send(node)
|
|
65
|
+
return if !struct_new?(node) || node.arguments.none? || !node.last_argument.hash_type?
|
|
66
|
+
|
|
67
|
+
keyword_init_nodes = select_keyword_init_nodes(node)
|
|
68
|
+
return if keyword_init_nodes.any? { |node| keyword_init_false?(node) }
|
|
69
|
+
|
|
70
|
+
redundant_keyword_init_nodes = select_redundant_keyword_init_nodes(keyword_init_nodes)
|
|
71
|
+
|
|
72
|
+
redundant_keyword_init_nodes.each do |redundant_keyword_init|
|
|
73
|
+
register_offense(redundant_keyword_init)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
alias on_csend on_send
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def select_keyword_init_nodes(node)
|
|
81
|
+
node.last_argument.pairs.select do |pair|
|
|
82
|
+
keyword_init?(pair)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def select_redundant_keyword_init_nodes(keyword_init_nodes)
|
|
87
|
+
keyword_init_nodes.select do |keyword_init_node|
|
|
88
|
+
redundant_keyword_init?(keyword_init_node)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def register_offense(keyword_init)
|
|
93
|
+
message = format(MSG, value: keyword_init.value.source)
|
|
94
|
+
|
|
95
|
+
add_offense(keyword_init, message: message) do |corrector|
|
|
96
|
+
range = range(keyword_init)
|
|
97
|
+
|
|
98
|
+
corrector.remove(range)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def range(redundant_keyword_init)
|
|
103
|
+
if redundant_keyword_init.parent.pairs.all? { |pair| keyword_init?(pair) }
|
|
104
|
+
# The hash holds only `keyword_init` pairs, so it is emptied; anchor the
|
|
105
|
+
# removal before the hash to also drop the comma that precedes it.
|
|
106
|
+
range_emptying_hash(redundant_keyword_init)
|
|
107
|
+
else
|
|
108
|
+
# Other pairs remain, so just drop this pair and one adjacent comma.
|
|
109
|
+
range_within_hash(redundant_keyword_init)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def range_within_hash(pair)
|
|
114
|
+
if (left = pair.left_sibling)
|
|
115
|
+
left.source_range.end.join(pair.source_range.end)
|
|
116
|
+
elsif (right = pair.right_sibling)
|
|
117
|
+
pair.source_range.begin.join(right.source_range.begin)
|
|
118
|
+
else
|
|
119
|
+
pair.source_range
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def range_emptying_hash(pair)
|
|
124
|
+
if (preceding = pair.parent.left_sibling).is_a?(AST::Node)
|
|
125
|
+
preceding.source_range.end.join(pair.source_range.end)
|
|
126
|
+
else
|
|
127
|
+
pair.source_range
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|