rubocop 1.72.1 → 1.81.7
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/README.md +22 -18
- data/config/default.yml +240 -65
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +8 -3
- data/exe/rubocop +1 -8
- data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
- data/lib/rubocop/cli.rb +19 -4
- data/lib/rubocop/config.rb +35 -6
- data/lib/rubocop/config_loader.rb +8 -40
- data/lib/rubocop/config_loader_resolver.rb +9 -7
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -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 +5 -0
- data/lib/rubocop/config_validator.rb +7 -6
- data/lib/rubocop/cop/autocorrect_logic.rb +22 -14
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +7 -4
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +4 -4
- 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/redundant_described_class_as_subject.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +6 -1
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/block_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/class_structure.rb +36 -1
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +32 -14
- 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_block_body.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +4 -7
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
- data/lib/rubocop/cop/layout/leading_comment_space.rb +13 -1
- data/lib/rubocop/cop/layout/line_length.rb +43 -10
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
- 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/redundant_line_break.rb +9 -5
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +11 -5
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +10 -0
- data/lib/rubocop/cop/layout/space_around_keyword.rb +6 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +12 -1
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -38
- 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_range.rb +5 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -5
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +13 -7
- data/lib/rubocop/cop/lint/debugger.rb +2 -4
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +5 -2
- data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
- data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/float_comparison.rb +32 -10
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/literal_as_condition.rb +124 -10
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +17 -8
- data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +1 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
- data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +101 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +43 -13
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
- data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +4 -4
- data/lib/rubocop/cop/lint/self_assignment.rb +31 -5
- data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +12 -1
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
- 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 +2 -0
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +9 -12
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +1 -0
- data/lib/rubocop/cop/lint/useless_or.rb +98 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +3 -3
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
- data/lib/rubocop/cop/lint/void.rb +16 -2
- 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 +1 -0
- data/lib/rubocop/cop/metrics/method_length.rb +1 -0
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +3 -3
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
- 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 +16 -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_subset.rb +19 -4
- data/lib/rubocop/cop/mixin/line_length_help.rb +24 -8
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -0
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +12 -0
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +18 -2
- data/lib/rubocop/cop/naming/block_forwarding.rb +3 -3
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +187 -15
- data/lib/rubocop/cop/naming/predicate_method.rb +319 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +4 -4
- data/lib/rubocop/cop/naming/variable_name.rb +51 -6
- data/lib/rubocop/cop/registry.rb +9 -6
- data/lib/rubocop/cop/security/eval.rb +2 -1
- data/lib/rubocop/cop/security/json_load.rb +33 -11
- data/lib/rubocop/cop/security/open.rb +1 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +32 -10
- data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
- data/lib/rubocop/cop/style/arguments_forwarding.rb +21 -24
- data/lib/rubocop/cop/style/array_intersect.rb +113 -38
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
- data/lib/rubocop/cop/style/bitwise_predicate.rb +8 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +3 -2
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/class_and_module_children.rb +48 -10
- data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
- 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/combinable_loops.rb +1 -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/conditional_assignment.rb +26 -8
- data/lib/rubocop/cop/style/constant_visibility.rb +14 -9
- data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
- data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
- data/lib/rubocop/cop/style/dig_chain.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +3 -3
- data/lib/rubocop/cop/style/empty_literal.rb +4 -0
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
- data/lib/rubocop/cop/style/endless_method.rb +176 -18
- data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +3 -3
- data/lib/rubocop/cop/style/exponential_notation.rb +5 -4
- data/lib/rubocop/cop/style/fetch_env_var.rb +32 -6
- data/lib/rubocop/cop/style/float_division.rb +15 -1
- data/lib/rubocop/cop/style/for.rb +1 -0
- data/lib/rubocop/cop/style/format_string_token.rb +38 -11
- 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/guard_clause.rb +2 -1
- data/lib/rubocop/cop/style/hash_conversion.rb +16 -8
- 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_syntax.rb +4 -1
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +3 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
- data/lib/rubocop/cop/style/if_unless_modifier.rb +35 -8
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +10 -6
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
- data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
- 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_parameters_order.rb +13 -7
- data/lib/rubocop/cop/style/lambda.rb +1 -0
- data/lib/rubocop/cop/style/lambda_call.rb +7 -2
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/map_into_array.rb +4 -1
- 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.rb +16 -0
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
- data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
- 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_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
- data/lib/rubocop/cop/style/object_then.rb +1 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +17 -9
- data/lib/rubocop/cop/style/parallel_assignment.rb +32 -20
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +1 -0
- data/lib/rubocop/cop/style/raise_args.rb +8 -8
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +35 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +57 -0
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +14 -4
- data/lib/rubocop/cop/style/redundant_exception.rb +1 -1
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
- data/lib/rubocop/cop/style/redundant_format.rb +79 -18
- data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
- data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +1 -4
- data/lib/rubocop/cop/style/redundant_parentheses.rb +73 -18
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -0
- data/lib/rubocop/cop/style/redundant_self.rb +9 -5
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +61 -14
- data/lib/rubocop/cop/style/select_by_regexp.rb +4 -1
- data/lib/rubocop/cop/style/semicolon.rb +23 -7
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +3 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +10 -7
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +75 -101
- 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/struct_inheritance.rb +8 -1
- data/lib/rubocop/cop/style/super_arguments.rb +1 -2
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -0
- 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 +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/unless_else.rb +10 -9
- data/lib/rubocop/cop/team.rb +1 -1
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/utils/format_string.rb +15 -2
- data/lib/rubocop/cop/variable_force/assignment.rb +7 -3
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +3 -8
- data/lib/rubocop/cop/variable_force.rb +26 -9
- data/lib/rubocop/cops_documentation_generator.rb +23 -7
- data/lib/rubocop/directive_comment.rb +1 -1
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -5
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/html_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/lsp/diagnostic.rb +25 -24
- data/lib/rubocop/lsp/routes.rb +65 -9
- data/lib/rubocop/lsp/runtime.rb +5 -5
- data/lib/rubocop/lsp/server.rb +2 -2
- data/lib/rubocop/lsp/stdin_runner.rb +3 -17
- data/lib/rubocop/magic_comment.rb +8 -0
- data/lib/rubocop/pending_cops_reporter.rb +56 -0
- data/lib/rubocop/plugin/configuration_integrator.rb +2 -0
- data/lib/rubocop/plugin/load_error.rb +1 -1
- data/lib/rubocop/plugin.rb +9 -2
- data/lib/rubocop/result_cache.rb +14 -12
- data/lib/rubocop/rspec/cop_helper.rb +6 -1
- data/lib/rubocop/rspec/expect_offense.rb +9 -3
- data/lib/rubocop/rspec/shared_contexts.rb +34 -0
- data/lib/rubocop/rspec/support.rb +3 -0
- data/lib/rubocop/runner.rb +10 -4
- data/lib/rubocop/server/cache.rb +17 -12
- 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/target_finder.rb +13 -9
- data/lib/rubocop/target_ruby.rb +11 -2
- data/lib/rubocop/version.rb +14 -7
- data/lib/rubocop.rb +17 -2
- data/lib/ruby_lsp/rubocop/addon.rb +25 -10
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +57 -5
- metadata +24 -8
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
#
|
|
6
|
+
# Checks for redundant line continuation.
|
|
7
7
|
#
|
|
8
8
|
# This cop marks a line continuation as redundant if removing the backslash
|
|
9
9
|
# does not result in a syntax error.
|
|
@@ -181,9 +181,7 @@ module RuboCop
|
|
|
181
181
|
ARGUMENT_TYPES.include?(next_token.type)
|
|
182
182
|
end
|
|
183
183
|
|
|
184
|
-
# rubocop:disable Metrics/AbcSize
|
|
185
184
|
def argument_newline?(node)
|
|
186
|
-
node = node.to_a.last if node.assignment?
|
|
187
185
|
return false if node.parenthesized_call?
|
|
188
186
|
|
|
189
187
|
node = node.children.first if node.root? && node.begin_type?
|
|
@@ -196,7 +194,6 @@ module RuboCop
|
|
|
196
194
|
node.loc.selector.line != node.first_argument.loc.line
|
|
197
195
|
end
|
|
198
196
|
end
|
|
199
|
-
# rubocop:enable Metrics/AbcSize
|
|
200
197
|
|
|
201
198
|
def find_node_for_line(last_line)
|
|
202
199
|
processed_source.ast.each_node do |node|
|
|
@@ -13,21 +13,17 @@ module RuboCop
|
|
|
13
13
|
# # good
|
|
14
14
|
# x if y.z.nil?
|
|
15
15
|
#
|
|
16
|
-
# rubocop:disable Metrics/ClassLength
|
|
17
|
-
class RedundantParentheses < Base
|
|
16
|
+
class RedundantParentheses < Base # rubocop:disable Metrics/ClassLength
|
|
18
17
|
include Parentheses
|
|
19
18
|
extend AutoCorrector
|
|
20
19
|
|
|
21
|
-
ALLOWED_NODE_TYPES = %i[
|
|
20
|
+
ALLOWED_NODE_TYPES = %i[or send splat kwsplat].freeze
|
|
22
21
|
|
|
23
22
|
# @!method square_brackets?(node)
|
|
24
23
|
def_node_matcher :square_brackets?, <<~PATTERN
|
|
25
24
|
(send `{(send _recv _msg) str array hash const #variable?} :[] ...)
|
|
26
25
|
PATTERN
|
|
27
26
|
|
|
28
|
-
# @!method method_node_and_args(node)
|
|
29
|
-
def_node_matcher :method_node_and_args, '$(call _recv _msg $...)'
|
|
30
|
-
|
|
31
27
|
# @!method rescue?(node)
|
|
32
28
|
def_node_matcher :rescue?, '{^resbody ^^resbody}'
|
|
33
29
|
|
|
@@ -50,6 +46,7 @@ module RuboCop
|
|
|
50
46
|
empty_parentheses?(node) ||
|
|
51
47
|
first_arg_begins_with_hash_literal?(node) ||
|
|
52
48
|
rescue?(node) ||
|
|
49
|
+
in_pattern_matching_in_method_argument?(node) ||
|
|
53
50
|
allowed_pin_operator?(node) ||
|
|
54
51
|
allowed_expression?(node)
|
|
55
52
|
end
|
|
@@ -79,7 +76,7 @@ module RuboCop
|
|
|
79
76
|
ancestor = node.ancestors.first
|
|
80
77
|
return false unless ancestor
|
|
81
78
|
|
|
82
|
-
!ancestor.type?(:begin, :
|
|
79
|
+
!ancestor.type?(:begin, :any_def, :any_block)
|
|
83
80
|
end
|
|
84
81
|
|
|
85
82
|
def allowed_ternary?(node)
|
|
@@ -99,7 +96,7 @@ module RuboCop
|
|
|
99
96
|
return false unless node.type?(:send, :super, :yield)
|
|
100
97
|
|
|
101
98
|
node.arguments.one? && !node.parenthesized? &&
|
|
102
|
-
!node.
|
|
99
|
+
!node.operator_method? && node.first_argument.begin_type?
|
|
103
100
|
end
|
|
104
101
|
|
|
105
102
|
def multiline_control_flow_statements?(node)
|
|
@@ -123,6 +120,13 @@ module RuboCop
|
|
|
123
120
|
hash_literal && first_argument?(node) && !parentheses?(hash_literal) && !parenthesized
|
|
124
121
|
end
|
|
125
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
|
+
|
|
126
130
|
def method_chain_begins_with_hash_literal(node)
|
|
127
131
|
return if node.nil?
|
|
128
132
|
return node if node.hash_type?
|
|
@@ -135,12 +139,14 @@ module RuboCop
|
|
|
135
139
|
node = begin_node.children.first
|
|
136
140
|
|
|
137
141
|
if (message = find_offense_message(begin_node, node))
|
|
138
|
-
|
|
142
|
+
if node.range_type? && !argument_of_parenthesized_method_call?(begin_node, node)
|
|
143
|
+
begin_node = begin_node.parent
|
|
144
|
+
end
|
|
139
145
|
|
|
140
146
|
return offense(begin_node, message)
|
|
141
147
|
end
|
|
142
148
|
|
|
143
|
-
check_send(begin_node, node) if node
|
|
149
|
+
check_send(begin_node, node) if call_node?(node)
|
|
144
150
|
end
|
|
145
151
|
|
|
146
152
|
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
@@ -155,7 +161,12 @@ module RuboCop
|
|
|
155
161
|
if node.lambda_or_proc? && (node.braces? || node.send_node.lambda_literal?)
|
|
156
162
|
return 'an expression'
|
|
157
163
|
end
|
|
164
|
+
if disallowed_one_line_pattern_matching?(begin_node, node)
|
|
165
|
+
return 'a one-line pattern matching'
|
|
166
|
+
end
|
|
158
167
|
return 'an interpolated expression' if interpolation?(begin_node)
|
|
168
|
+
return 'a method argument' if argument_of_parenthesized_method_call?(begin_node, node)
|
|
169
|
+
return 'a one-line rescue' if oneline_rescue_parentheses_required?(begin_node, node)
|
|
159
170
|
|
|
160
171
|
return if begin_node.chained?
|
|
161
172
|
|
|
@@ -163,6 +174,7 @@ module RuboCop
|
|
|
163
174
|
return if node.semantic_operator? && begin_node.parent
|
|
164
175
|
return if node.multiline? && allow_in_multiline_conditions?
|
|
165
176
|
return if ALLOWED_NODE_TYPES.include?(begin_node.parent&.type)
|
|
177
|
+
return if !node.and_type? && begin_node.parent&.and_type?
|
|
166
178
|
return if begin_node.parent&.if_type? && begin_node.parent.ternary?
|
|
167
179
|
|
|
168
180
|
'a logical expression'
|
|
@@ -177,14 +189,44 @@ module RuboCop
|
|
|
177
189
|
# @!method interpolation?(node)
|
|
178
190
|
def_node_matcher :interpolation?, '[^begin ^^dstr]'
|
|
179
191
|
|
|
192
|
+
def argument_of_parenthesized_method_call?(begin_node, node)
|
|
193
|
+
if node.basic_conditional? || node.rescue_type? || method_call_parentheses_required?(node)
|
|
194
|
+
return false
|
|
195
|
+
end
|
|
196
|
+
return false unless (parent = begin_node.parent)
|
|
197
|
+
|
|
198
|
+
parent.call_type? && parent.parenthesized? && parent.receiver != begin_node
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def oneline_rescue_parentheses_required?(begin_node, node)
|
|
202
|
+
return false unless node.rescue_type?
|
|
203
|
+
return false unless (parent = begin_node.parent)
|
|
204
|
+
return false if parent.if_type? && parent.ternary?
|
|
205
|
+
return false if parent.conditional? && parent.condition == begin_node
|
|
206
|
+
|
|
207
|
+
!parent.type?(:call, :array, :pair)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def method_call_parentheses_required?(node)
|
|
211
|
+
return false unless node.call_type?
|
|
212
|
+
|
|
213
|
+
(node.receiver.nil? || node.loc.dot) && node.arguments.any?
|
|
214
|
+
end
|
|
215
|
+
|
|
180
216
|
def allow_in_multiline_conditions?
|
|
181
217
|
!!config.for_enabled_cop('Style/ParenthesesAroundCondition')['AllowInMultilineConditions']
|
|
182
218
|
end
|
|
183
219
|
|
|
220
|
+
def call_node?(node)
|
|
221
|
+
node.call_type? || (node.any_block_type? && node.braces? && !node.lambda_or_proc?)
|
|
222
|
+
end
|
|
223
|
+
|
|
184
224
|
def check_send(begin_node, node)
|
|
225
|
+
node = node.send_node if node.any_block_type?
|
|
226
|
+
|
|
185
227
|
return check_unary(begin_node, node) if node.unary_operation?
|
|
186
228
|
|
|
187
|
-
return unless method_call_with_redundant_parentheses?(node)
|
|
229
|
+
return unless method_call_with_redundant_parentheses?(begin_node, node)
|
|
188
230
|
return if call_chain_starts_with_int?(begin_node, node) ||
|
|
189
231
|
do_end_block_in_method_chain?(begin_node, node)
|
|
190
232
|
|
|
@@ -195,8 +237,7 @@ module RuboCop
|
|
|
195
237
|
return if begin_node.chained?
|
|
196
238
|
|
|
197
239
|
node = node.children.first while suspect_unary?(node)
|
|
198
|
-
|
|
199
|
-
return if node.send_type? && !method_call_with_redundant_parentheses?(node)
|
|
240
|
+
return unless method_call_with_redundant_parentheses?(begin_node, node)
|
|
200
241
|
|
|
201
242
|
offense(begin_node, 'a unary operation')
|
|
202
243
|
end
|
|
@@ -225,6 +266,15 @@ module RuboCop
|
|
|
225
266
|
end
|
|
226
267
|
end
|
|
227
268
|
|
|
269
|
+
def disallowed_one_line_pattern_matching?(begin_node, node)
|
|
270
|
+
if (parent = begin_node.parent)
|
|
271
|
+
return false if parent.any_def_type? && parent.endless?
|
|
272
|
+
return false if parent.assignment?
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
node.any_match_pattern_type? && node.each_ancestor.none?(&:operator_keyword?)
|
|
276
|
+
end
|
|
277
|
+
|
|
228
278
|
def raised_to_power_negative_numeric?(begin_node, node)
|
|
229
279
|
return false unless node.numeric_type?
|
|
230
280
|
|
|
@@ -249,13 +299,19 @@ module RuboCop
|
|
|
249
299
|
end
|
|
250
300
|
end
|
|
251
301
|
|
|
252
|
-
def method_call_with_redundant_parentheses?(node)
|
|
253
|
-
return false unless node.
|
|
302
|
+
def method_call_with_redundant_parentheses?(begin_node, node)
|
|
303
|
+
return false unless node.type?(:call, :super, :yield, :defined?)
|
|
254
304
|
return false if node.prefix_not?
|
|
305
|
+
return true if singular_parenthesized_parent?(begin_node)
|
|
306
|
+
|
|
307
|
+
node.arguments.empty? || parentheses?(node) || square_brackets?(node)
|
|
308
|
+
end
|
|
255
309
|
|
|
256
|
-
|
|
310
|
+
def singular_parenthesized_parent?(begin_node)
|
|
311
|
+
return true unless begin_node.parent
|
|
312
|
+
return false if begin_node.parent.type?(:splat, :kwsplat)
|
|
257
313
|
|
|
258
|
-
|
|
314
|
+
parentheses?(begin_node) && begin_node.parent.children.one?
|
|
259
315
|
end
|
|
260
316
|
|
|
261
317
|
def only_begin_arg?(args)
|
|
@@ -299,7 +355,6 @@ module RuboCop
|
|
|
299
355
|
block.keywords? && begin_node.each_ancestor(:call).any?
|
|
300
356
|
end
|
|
301
357
|
end
|
|
302
|
-
# rubocop:enable Metrics/ClassLength
|
|
303
358
|
end
|
|
304
359
|
end
|
|
305
360
|
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,8 @@ module RuboCop
|
|
|
73
74
|
new_argument.gsub!("'", "\\\\'")
|
|
74
75
|
new_argument.gsub!('\"', '"')
|
|
75
76
|
quote = "'"
|
|
77
|
+
elsif new_argument.include?("\\'")
|
|
78
|
+
quote = "'"
|
|
76
79
|
elsif new_argument.include?('\'')
|
|
77
80
|
new_argument.gsub!("'", "\\\\'")
|
|
78
81
|
quote = "'"
|
|
@@ -84,6 +87,7 @@ module RuboCop
|
|
|
84
87
|
|
|
85
88
|
"#{quote}#{new_argument}#{quote}"
|
|
86
89
|
end
|
|
90
|
+
# rubocop:enable Metrics/MethodLength
|
|
87
91
|
|
|
88
92
|
def replacement(regexp_node)
|
|
89
93
|
regexp_content = regexp_node.content
|
|
@@ -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.source[index], char)
|
|
67
69
|
|
|
68
70
|
if within_character_class
|
|
69
71
|
ALLOWED_WITHIN_CHAR_CLASS_METACHAR_ESCAPES.include?(char) &&
|
|
@@ -95,6 +97,12 @@ module RuboCop
|
|
|
95
97
|
delimiters.include?(char)
|
|
96
98
|
end
|
|
97
99
|
|
|
100
|
+
def requires_escape_to_avoid_interpolation?(char_before_escape, escaped_char)
|
|
101
|
+
# Preserve escapes after '#' that would otherwise trigger interpolation:
|
|
102
|
+
# '#@ivar', '#@@cvar', and '#$gvar'.
|
|
103
|
+
char_before_escape == '#' && INTERPOLATION_SIGILS.include?(escaped_char)
|
|
104
|
+
end
|
|
105
|
+
|
|
98
106
|
def each_escape(node)
|
|
99
107
|
node.parsed_tree&.traverse&.reduce(0) do |char_class_depth, (event, expr)|
|
|
100
108
|
yield(expr.text[1], expr.ts, !char_class_depth.zero?) if expr.type == :escape
|
|
@@ -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
|
|
|
@@ -118,15 +121,16 @@ module RuboCop
|
|
|
118
121
|
end
|
|
119
122
|
|
|
120
123
|
alias on_numblock on_block
|
|
124
|
+
alias on_itblock on_block
|
|
121
125
|
|
|
122
126
|
def on_if(node)
|
|
123
127
|
# Allow conditional nodes to use `self` in the condition if that variable
|
|
124
128
|
# 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,
|
|
129
|
+
node.each_descendant(:lvasgn, :masgn) do |descendant_node|
|
|
130
|
+
if descendant_node.lvasgn_type?
|
|
131
|
+
add_lhs_to_local_variables_scopes(node.condition, descendant_node.lhs)
|
|
132
|
+
else
|
|
133
|
+
add_masgn_lhs_variables(node.condition, descendant_node.lhs)
|
|
130
134
|
end
|
|
131
135
|
end
|
|
132
136
|
end
|
|
@@ -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]
|
|
@@ -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
|
|
@@ -155,7 +155,7 @@ module RuboCop
|
|
|
155
155
|
end
|
|
156
156
|
|
|
157
157
|
def preferred_delimiters
|
|
158
|
-
config.for_cop('Style/PercentLiteralDelimiters')
|
|
158
|
+
config.for_cop('Style/PercentLiteralDelimiters')['PreferredDelimiters']['%r'].chars
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
def allowed_omit_parentheses_with_percent_r_literal?(node)
|
|
@@ -67,11 +67,13 @@ module RuboCop
|
|
|
67
67
|
node.parent && parentheses?(node.parent)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
+
# rubocop:disable Metrics/AbcSize
|
|
70
71
|
def correct_rescue_block(corrector, node, parenthesized)
|
|
71
72
|
operation = node.body
|
|
72
73
|
|
|
73
74
|
node_indentation, node_offset = indentation_and_offset(node, parenthesized)
|
|
74
75
|
|
|
76
|
+
corrector.wrap(operation, '[', ']') if operation.array_type? && !operation.bracketed?
|
|
75
77
|
corrector.remove(range_between(operation.source_range.end_pos, node.source_range.end_pos))
|
|
76
78
|
corrector.insert_before(operation, "begin\n#{node_indentation}")
|
|
77
79
|
corrector.insert_after(heredoc_end(operation) || operation, <<~RESCUE_CLAUSE.chop)
|
|
@@ -81,6 +83,7 @@ module RuboCop
|
|
|
81
83
|
#{node_offset}end
|
|
82
84
|
RESCUE_CLAUSE
|
|
83
85
|
end
|
|
86
|
+
# rubocop:enable Metrics/AbcSize
|
|
84
87
|
|
|
85
88
|
def indentation_and_offset(node, parenthesized)
|
|
86
89
|
node_indentation = indentation(node)
|
|
@@ -47,7 +47,7 @@ module RuboCop
|
|
|
47
47
|
|
|
48
48
|
def on_return(node)
|
|
49
49
|
# Check Lint/NonLocalExitFromIterator first before this cop
|
|
50
|
-
node.each_ancestor(:block, :
|
|
50
|
+
node.each_ancestor(:block, :any_def) do |n|
|
|
51
51
|
break if scoped_node?(n)
|
|
52
52
|
|
|
53
53
|
send_node, args_node, _body_node = *n
|
|
@@ -83,7 +83,7 @@ module RuboCop
|
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def scoped_node?(node)
|
|
86
|
-
node.
|
|
86
|
+
node.any_def_type? || node.lambda?
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
# @!method chained_send?(node)
|
|
@@ -86,6 +86,10 @@ module RuboCop
|
|
|
86
86
|
# foo.baz = bar if foo
|
|
87
87
|
# foo.baz + bar if foo
|
|
88
88
|
# foo.bar > 2 if foo
|
|
89
|
+
#
|
|
90
|
+
# foo ? foo[index] : nil # Ignored `foo&.[](index)` due to unclear readability benefit.
|
|
91
|
+
# foo ? foo[idx] = v : nil # Ignored `foo&.[]=(idx, v)` due to unclear readability benefit.
|
|
92
|
+
# foo ? foo * 42 : nil # Ignored `foo&.*(42)` due to unclear readability benefit.
|
|
89
93
|
class SafeNavigation < Base # rubocop:disable Metrics/ClassLength
|
|
90
94
|
include NilMethods
|
|
91
95
|
include RangeHelp
|
|
@@ -138,6 +142,7 @@ module RuboCop
|
|
|
138
142
|
# @!method strip_begin(node)
|
|
139
143
|
def_node_matcher :strip_begin, '{ (begin $!begin) $!(begin) }'
|
|
140
144
|
|
|
145
|
+
# rubocop:disable Metrics/AbcSize
|
|
141
146
|
def on_if(node)
|
|
142
147
|
return if allowed_if_condition?(node)
|
|
143
148
|
|
|
@@ -146,13 +151,16 @@ module RuboCop
|
|
|
146
151
|
|
|
147
152
|
body = extract_if_body(node)
|
|
148
153
|
method_call = receiver.parent
|
|
154
|
+
return if dotless_operator_call?(method_call) || method_call.double_colon?
|
|
149
155
|
|
|
150
156
|
removal_ranges = [begin_range(node, body), end_range(node, body)]
|
|
151
157
|
|
|
152
158
|
report_offense(node, method_chain, method_call, *removal_ranges) do |corrector|
|
|
159
|
+
corrector.replace(receiver, checked_variable.source) if checked_variable.csend_type?
|
|
153
160
|
corrector.insert_before(method_call.loc.dot, '&') unless method_call.safe_navigation?
|
|
154
161
|
end
|
|
155
162
|
end
|
|
163
|
+
# rubocop:enable Metrics/AbcSize
|
|
156
164
|
|
|
157
165
|
def on_and(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
|
158
166
|
collect_and_clauses(node).each do |(lhs, lhs_operator_range), (rhs, _rhs_operator_range)|
|
|
@@ -174,12 +182,19 @@ module RuboCop
|
|
|
174
182
|
range_with_surrounding_space(range: lhs.source_range, side: :right),
|
|
175
183
|
range_with_surrounding_space(range: lhs_operator_range, side: :right),
|
|
176
184
|
offense_range: range_between(lhs.source_range.begin_pos, rhs.source_range.end_pos)
|
|
177
|
-
)
|
|
185
|
+
) do |corrector|
|
|
186
|
+
corrector.replace(rhs_receiver, lhs_receiver.source)
|
|
187
|
+
end
|
|
188
|
+
ignore_node(node)
|
|
178
189
|
end
|
|
179
190
|
end
|
|
180
191
|
|
|
192
|
+
private
|
|
193
|
+
|
|
181
194
|
def report_offense(node, rhs, rhs_receiver, *removal_ranges, offense_range: node)
|
|
182
195
|
add_offense(offense_range) do |corrector|
|
|
196
|
+
next if ignored_node?(node)
|
|
197
|
+
|
|
183
198
|
# If the RHS is an `or` we cannot safely autocorrect because in order to remove
|
|
184
199
|
# the non-nil check we need to add safe-navs to all clauses where the receiver is used
|
|
185
200
|
next if and_with_rhs_or?(node)
|
|
@@ -193,8 +208,6 @@ module RuboCop
|
|
|
193
208
|
end
|
|
194
209
|
end
|
|
195
210
|
|
|
196
|
-
private
|
|
197
|
-
|
|
198
211
|
def find_method_chain(node)
|
|
199
212
|
return node unless node&.parent&.call_type?
|
|
200
213
|
|
|
@@ -227,10 +240,10 @@ module RuboCop
|
|
|
227
240
|
end
|
|
228
241
|
|
|
229
242
|
def offending_node?(node, lhs_receiver, rhs, rhs_receiver) # rubocop:disable Metrics/CyclomaticComplexity
|
|
230
|
-
return false if lhs_receiver
|
|
243
|
+
return false if !matching_nodes?(lhs_receiver, rhs_receiver) || rhs_receiver.nil?
|
|
231
244
|
return false if use_var_only_in_unless_modifier?(node, lhs_receiver)
|
|
232
245
|
return false if chain_length(rhs, rhs_receiver) > max_chain_length
|
|
233
|
-
return false if unsafe_method_used?(rhs, rhs_receiver.parent)
|
|
246
|
+
return false if unsafe_method_used?(node, rhs, rhs_receiver.parent)
|
|
234
247
|
return false if rhs.send_type? && rhs.method?(:empty?)
|
|
235
248
|
|
|
236
249
|
true
|
|
@@ -248,6 +261,20 @@ module RuboCop
|
|
|
248
261
|
end
|
|
249
262
|
end
|
|
250
263
|
|
|
264
|
+
def dotless_operator_call?(method_call)
|
|
265
|
+
return true if dotless_operator_method?(method_call)
|
|
266
|
+
|
|
267
|
+
method_call = method_call.parent while method_call.parent.send_type?
|
|
268
|
+
|
|
269
|
+
dotless_operator_method?(method_call)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def dotless_operator_method?(method_call)
|
|
273
|
+
return false if method_call.loc.dot
|
|
274
|
+
|
|
275
|
+
method_call.method?(:[]) || method_call.method?(:[]=) || method_call.operator_method?
|
|
276
|
+
end
|
|
277
|
+
|
|
251
278
|
def handle_comments(corrector, node, method_call)
|
|
252
279
|
comments = comments(node)
|
|
253
280
|
return if comments.empty?
|
|
@@ -306,11 +333,29 @@ module RuboCop
|
|
|
306
333
|
|
|
307
334
|
receiver = method_chain.receiver
|
|
308
335
|
|
|
309
|
-
return receiver if receiver
|
|
336
|
+
return receiver if matching_nodes?(receiver, checked_variable)
|
|
310
337
|
|
|
311
338
|
find_matching_receiver_invocation(receiver, checked_variable)
|
|
312
339
|
end
|
|
313
340
|
|
|
341
|
+
def matching_nodes?(left, right)
|
|
342
|
+
left == right || matching_call_nodes?(left, right)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
def matching_call_nodes?(left, right)
|
|
346
|
+
return false unless left && right.respond_to?(:call_type?)
|
|
347
|
+
return false unless left.call_type? && right.call_type?
|
|
348
|
+
|
|
349
|
+
# Compare receiver and method name, but ignore the difference between
|
|
350
|
+
# safe navigation method call (`&.`) and dot method call (`.`).
|
|
351
|
+
left_receiver, left_method, *left_args = left.children
|
|
352
|
+
right_receiver, right_method, *right_args = right.children
|
|
353
|
+
|
|
354
|
+
left_method == right_method &&
|
|
355
|
+
matching_nodes?(left_receiver, right_receiver) &&
|
|
356
|
+
left_args == right_args
|
|
357
|
+
end
|
|
358
|
+
|
|
314
359
|
def chain_length(method_chain, method)
|
|
315
360
|
method.each_ancestor(:call).inject(0) do |total, ancestor|
|
|
316
361
|
break total + 1 if ancestor == method_chain
|
|
@@ -319,21 +364,24 @@ module RuboCop
|
|
|
319
364
|
end
|
|
320
365
|
end
|
|
321
366
|
|
|
322
|
-
def unsafe_method_used?(method_chain, method)
|
|
323
|
-
return true if unsafe_method?(method)
|
|
367
|
+
def unsafe_method_used?(node, method_chain, method)
|
|
368
|
+
return true if unsafe_method?(node, method)
|
|
324
369
|
|
|
325
370
|
method.each_ancestor(:send).any? do |ancestor|
|
|
326
371
|
break true unless config.cop_enabled?('Lint/SafeNavigationChain')
|
|
327
372
|
|
|
328
|
-
break true if unsafe_method?(ancestor)
|
|
373
|
+
break true if unsafe_method?(node, ancestor)
|
|
329
374
|
break true if nil_methods.include?(ancestor.method_name)
|
|
330
375
|
break false if ancestor == method_chain
|
|
331
376
|
end
|
|
332
377
|
end
|
|
333
378
|
|
|
334
|
-
def unsafe_method?(send_node)
|
|
335
|
-
negated?(send_node)
|
|
336
|
-
|
|
379
|
+
def unsafe_method?(node, send_node)
|
|
380
|
+
return true if negated?(send_node)
|
|
381
|
+
|
|
382
|
+
return false if node.respond_to?(:ternary?) && node.ternary?
|
|
383
|
+
|
|
384
|
+
send_node.assignment? ||
|
|
337
385
|
(!send_node.dot? && !send_node.safe_navigation?)
|
|
338
386
|
end
|
|
339
387
|
|
|
@@ -362,8 +410,7 @@ module RuboCop
|
|
|
362
410
|
method_chain)
|
|
363
411
|
start_method.each_ancestor do |ancestor|
|
|
364
412
|
break unless %i[send block].include?(ancestor.type)
|
|
365
|
-
next
|
|
366
|
-
next if ancestor.safe_navigation?
|
|
413
|
+
next if !ancestor.send_type? || ancestor.operator_method?
|
|
367
414
|
|
|
368
415
|
corrector.insert_before(ancestor.loc.dot, '&')
|
|
369
416
|
|
|
@@ -59,6 +59,7 @@ module RuboCop
|
|
|
59
59
|
{
|
|
60
60
|
(block call (args (arg $_)) ${(send _ %REGEXP_METHODS _) match-with-lvasgn})
|
|
61
61
|
(numblock call $1 ${(send _ %REGEXP_METHODS _) match-with-lvasgn})
|
|
62
|
+
(itblock call $_ ${(send _ %REGEXP_METHODS _) match-with-lvasgn})
|
|
62
63
|
}
|
|
63
64
|
PATTERN
|
|
64
65
|
|
|
@@ -137,6 +138,7 @@ module RuboCop
|
|
|
137
138
|
return unless (block_arg_name, regexp_method_send_node = regexp_match?(block_node))
|
|
138
139
|
|
|
139
140
|
block_arg_name = :"_#{block_arg_name}" if block_node.numblock_type?
|
|
141
|
+
|
|
140
142
|
return unless calls_lvar?(regexp_method_send_node, block_arg_name)
|
|
141
143
|
|
|
142
144
|
regexp_method_send_node
|
|
@@ -150,7 +152,8 @@ module RuboCop
|
|
|
150
152
|
return node.child_nodes.first if node.match_with_lvasgn_type?
|
|
151
153
|
|
|
152
154
|
if node.receiver.lvar_type? &&
|
|
153
|
-
(block.
|
|
155
|
+
(block.type?(:numblock, :itblock) ||
|
|
156
|
+
node.receiver.source == block.first_argument.source)
|
|
154
157
|
node.first_argument
|
|
155
158
|
elsif node.first_argument.lvar_type?
|
|
156
159
|
node.receiver
|