rubocop 1.67.0 → 1.81.6
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 +384 -72
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +8 -3
- data/exe/rubocop +1 -8
- data/lib/rubocop/cached_data.rb +12 -4
- data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
- data/lib/rubocop/cli/command/execute_runner.rb +4 -4
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/cli/command/version.rb +2 -2
- data/lib/rubocop/cli.rb +19 -4
- data/lib/rubocop/comment_config.rb +2 -2
- data/lib/rubocop/config.rb +52 -10
- data/lib/rubocop/config_loader.rb +56 -48
- data/lib/rubocop/config_loader_resolver.rb +36 -10
- 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 +25 -14
- data/lib/rubocop/cop/autocorrect_logic.rb +53 -28
- data/lib/rubocop/cop/base.rb +7 -1
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +8 -16
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +8 -3
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
- 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/gemspec/required_ruby_version.rb +0 -2
- data/lib/rubocop/cop/generator.rb +6 -0
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +233 -0
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
- data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
- data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
- 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_source_range.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +7 -16
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/class_structure.rb +45 -10
- 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 +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +34 -20
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- 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/empty_lines_around_exception_handling_keywords.rb +4 -5
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +8 -11
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
- data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/line_length.rb +158 -10
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +11 -8
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +14 -7
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +8 -2
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +31 -21
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +7 -40
- data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +18 -3
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -4
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
- data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +90 -0
- data/lib/rubocop/cop/lint/debugger.rb +3 -3
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +7 -3
- data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +6 -43
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
- data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_file.rb +0 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/float_comparison.rb +51 -18
- data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
- data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +125 -10
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -2
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
- data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +94 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
- data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +113 -9
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
- 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/refinement_import_methods.rb +1 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +2 -5
- data/lib/rubocop/cop/lint/rescue_type.rb +4 -8
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +39 -15
- 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 +13 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +4 -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/unescaped_bracket_in_regexp.rb +88 -0
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
- data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
- data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
- data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +3 -1
- data/lib/rubocop/cop/lint/useless_or.rb +98 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
- data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
- data/lib/rubocop/cop/lint/void.rb +23 -12
- 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/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +9 -9
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
- data/lib/rubocop/cop/metrics/method_length.rb +9 -1
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/mixin/alignment.rb +3 -3
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
- data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
- data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
- 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 +4 -3
- 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 +203 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
- data/lib/rubocop/cop/mixin/line_length_help.rb +27 -10
- data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
- data/lib/rubocop/cop/mixin/range_help.rb +15 -4
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
- data/lib/rubocop/cop/mixin/string_help.rb +2 -2
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
- data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
- data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
- data/lib/rubocop/cop/naming/constant_name.rb +6 -7
- data/lib/rubocop/cop/naming/file_name.rb +2 -4
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
- data/lib/rubocop/cop/naming/method_name.rb +185 -15
- data/lib/rubocop/cop/naming/predicate_method.rb +319 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
- data/lib/rubocop/cop/naming/variable_name.rb +50 -6
- data/lib/rubocop/cop/naming/variable_number.rb +2 -3
- data/lib/rubocop/cop/offense.rb +2 -3
- data/lib/rubocop/cop/registry.rb +9 -6
- data/lib/rubocop/cop/security/compound_hash.rb +2 -0
- 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/security/yaml_load.rb +3 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
- data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +57 -44
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/array_intersect.rb +115 -39
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
- data/lib/rubocop/cop/style/bitwise_predicate.rb +107 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +44 -26
- data/lib/rubocop/cop/style/case_like_if.rb +9 -12
- data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
- data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
- data/lib/rubocop/cop/style/collection_methods.rb +2 -1
- data/lib/rubocop/cop/style/collection_querying.rb +167 -0
- data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
- data/lib/rubocop/cop/style/comparable_between.rb +78 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +49 -31
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
- 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 +89 -0
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +5 -5
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -3
- data/lib/rubocop/cop/style/empty_else.rb +4 -2
- data/lib/rubocop/cop/style/empty_literal.rb +5 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
- data/lib/rubocop/cop/style/endless_method.rb +163 -18
- data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +17 -4
- data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
- data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
- data/lib/rubocop/cop/style/file_null.rb +89 -0
- data/lib/rubocop/cop/style/file_touch.rb +75 -0
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/for.rb +1 -1
- 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/global_vars.rb +1 -3
- data/lib/rubocop/cop/style/guard_clause.rb +17 -3
- data/lib/rubocop/cop/style/hash_conversion.rb +16 -9
- data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
- data/lib/rubocop/cop/style/hash_except.rb +35 -147
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
- 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 +25 -6
- data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
- data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
- 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 +3 -4
- data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +16 -13
- 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 +93 -0
- data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
- data/lib/rubocop/cop/style/lambda.rb +1 -0
- data/lib/rubocop/cop/style/lambda_call.rb +10 -4
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/map_into_array.rb +11 -3
- data/lib/rubocop/cop/style/map_to_hash.rb +13 -4
- data/lib/rubocop/cop/style/map_to_set.rb +4 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +28 -20
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +18 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
- data/lib/rubocop/cop/style/missing_else.rb +2 -0
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
- data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
- data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +15 -15
- data/lib/rubocop/cop/style/one_line_conditional.rb +42 -13
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
- data/lib/rubocop/cop/style/or_assignment.rb +3 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +41 -38
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +2 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +15 -13
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +36 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
- data/lib/rubocop/cop/style/redundant_each.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
- data/lib/rubocop/cop/style/redundant_format.rb +283 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +55 -19
- data/lib/rubocop/cop/style/redundant_parentheses.rb +105 -36
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +8 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +9 -1
- data/lib/rubocop/cop/style/redundant_return.rb +2 -2
- data/lib/rubocop/cop/style/redundant_self.rb +15 -18
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +75 -16
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
- data/lib/rubocop/cop/style/self_assignment.rb +11 -17
- data/lib/rubocop/cop/style/semicolon.rb +21 -6
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
- data/lib/rubocop/cop/style/signal_exception.rb +2 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
- data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
- data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +68 -102
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +21 -17
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
- data/lib/rubocop/cop/style/super_arguments.rb +66 -19
- data/lib/rubocop/cop/style/swap_values.rb +4 -15
- 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/ternary_parentheses.rb +25 -4
- data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +56 -2
- 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/trailing_underscore_variable.rb +4 -4
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/unless_else.rb +10 -9
- data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
- data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
- data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
- data/lib/rubocop/cop/team.rb +1 -1
- data/lib/rubocop/cop/util.rb +12 -5
- data/lib/rubocop/cop/utils/format_string.rb +20 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +14 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
- data/lib/rubocop/cop/variable_force.rb +30 -19
- data/lib/rubocop/cops_documentation_generator.rb +54 -28
- data/lib/rubocop/directive_comment.rb +45 -11
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +20 -6
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- 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 +190 -0
- data/lib/rubocop/lsp/logger.rb +2 -2
- data/lib/rubocop/lsp/routes.rb +66 -26
- data/lib/rubocop/lsp/runtime.rb +18 -50
- data/lib/rubocop/lsp/server.rb +2 -4
- data/lib/rubocop/lsp/stdin_runner.rb +69 -0
- data/lib/rubocop/magic_comment.rb +11 -3
- data/lib/rubocop/options.rb +28 -12
- data/lib/rubocop/path_util.rb +15 -8
- 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/rake_task.rb +4 -1
- data/lib/rubocop/result_cache.rb +27 -25
- data/lib/rubocop/rspec/cop_helper.rb +13 -1
- data/lib/rubocop/rspec/expect_offense.rb +15 -5
- data/lib/rubocop/rspec/shared_contexts.rb +38 -1
- data/lib/rubocop/rspec/support.rb +4 -2
- data/lib/rubocop/runner.rb +31 -18
- data/lib/rubocop/server/cache.rb +51 -13
- 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/target_finder.rb +14 -9
- data/lib/rubocop/target_ruby.rb +27 -3
- data/lib/rubocop/version.rb +53 -12
- data/lib/rubocop.rb +44 -2
- data/lib/ruby_lsp/rubocop/addon.rb +90 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
- metadata +91 -21
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
|
6
6
|
# Checks for redundant safe navigation calls.
|
|
7
7
|
# Use cases where a constant, named in camel case for classes and modules is `nil` are rare,
|
|
8
8
|
# and an offense is not detected when the receiver is a constant. The detection also applies
|
|
9
|
-
# to literal receivers, except for `nil`.
|
|
9
|
+
# to `self`, and to literal receivers, except for `nil`.
|
|
10
10
|
#
|
|
11
11
|
# For all receivers, the `instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`,
|
|
12
12
|
# and `equal?` methods are checked by default.
|
|
@@ -20,6 +20,15 @@ module RuboCop
|
|
|
20
20
|
# In the example below, the safe navigation operator (`&.`) is unnecessary
|
|
21
21
|
# because `NilClass` has methods like `respond_to?` and `is_a?`.
|
|
22
22
|
#
|
|
23
|
+
# The `InferNonNilReceiver` option specifies whether to look into previous code
|
|
24
|
+
# paths to infer if the receiver can't be nil. This check is unsafe because the receiver
|
|
25
|
+
# can be redefined between the safe navigation call and previous regular method call.
|
|
26
|
+
# It does the inference only in the current scope, e.g. within the same method definition etc.
|
|
27
|
+
#
|
|
28
|
+
# The `AdditionalNilMethods` option specifies additional custom methods which are
|
|
29
|
+
# defined on `NilClass`. When `InferNonNilReceiver` is set, they are used to determine
|
|
30
|
+
# whether the receiver can be nil.
|
|
31
|
+
#
|
|
23
32
|
# @safety
|
|
24
33
|
# This cop is unsafe, because autocorrection can change the return type of
|
|
25
34
|
# the expression. An offending expression that previously could return `nil`
|
|
@@ -29,6 +38,23 @@ module RuboCop
|
|
|
29
38
|
# # bad
|
|
30
39
|
# CamelCaseConst&.do_something
|
|
31
40
|
#
|
|
41
|
+
# # good
|
|
42
|
+
# CamelCaseConst.do_something
|
|
43
|
+
#
|
|
44
|
+
# # bad
|
|
45
|
+
# foo.to_s&.strip
|
|
46
|
+
# foo.to_i&.zero?
|
|
47
|
+
# foo.to_f&.zero?
|
|
48
|
+
# foo.to_a&.size
|
|
49
|
+
# foo.to_h&.size
|
|
50
|
+
#
|
|
51
|
+
# # good
|
|
52
|
+
# foo.to_s.strip
|
|
53
|
+
# foo.to_i.zero?
|
|
54
|
+
# foo.to_f.zero?
|
|
55
|
+
# foo.to_a.size
|
|
56
|
+
# foo.to_h.size
|
|
57
|
+
#
|
|
32
58
|
# # bad
|
|
33
59
|
# do_something if attrs&.respond_to?(:[])
|
|
34
60
|
#
|
|
@@ -41,9 +67,6 @@ module RuboCop
|
|
|
41
67
|
# end
|
|
42
68
|
#
|
|
43
69
|
# # good
|
|
44
|
-
# CamelCaseConst.do_something
|
|
45
|
-
#
|
|
46
|
-
# # good
|
|
47
70
|
# while node.is_a?(BeginNode)
|
|
48
71
|
# node = node.parent
|
|
49
72
|
# end
|
|
@@ -67,6 +90,12 @@ module RuboCop
|
|
|
67
90
|
# foo.to_f
|
|
68
91
|
# foo.to_s
|
|
69
92
|
#
|
|
93
|
+
# # bad
|
|
94
|
+
# self&.foo
|
|
95
|
+
#
|
|
96
|
+
# # good
|
|
97
|
+
# self.foo
|
|
98
|
+
#
|
|
70
99
|
# @example AllowedMethods: [nil_safe_method]
|
|
71
100
|
# # bad
|
|
72
101
|
# do_something if attrs&.nil_safe_method(:[])
|
|
@@ -75,17 +104,59 @@ module RuboCop
|
|
|
75
104
|
# do_something if attrs.nil_safe_method(:[])
|
|
76
105
|
# do_something if attrs&.not_nil_safe_method(:[])
|
|
77
106
|
#
|
|
107
|
+
# @example InferNonNilReceiver: false (default)
|
|
108
|
+
# # good
|
|
109
|
+
# foo.bar
|
|
110
|
+
# foo&.baz
|
|
111
|
+
#
|
|
112
|
+
# @example InferNonNilReceiver: true
|
|
113
|
+
# # bad
|
|
114
|
+
# foo.bar
|
|
115
|
+
# foo&.baz # would raise on previous line if `foo` is nil
|
|
116
|
+
#
|
|
117
|
+
# # good
|
|
118
|
+
# foo.bar
|
|
119
|
+
# foo.baz
|
|
120
|
+
#
|
|
121
|
+
# # bad
|
|
122
|
+
# if foo.condition?
|
|
123
|
+
# foo&.bar
|
|
124
|
+
# end
|
|
125
|
+
#
|
|
126
|
+
# # good
|
|
127
|
+
# if foo.condition?
|
|
128
|
+
# foo.bar
|
|
129
|
+
# end
|
|
130
|
+
#
|
|
131
|
+
# # good (different scopes)
|
|
132
|
+
# def method1
|
|
133
|
+
# foo.bar
|
|
134
|
+
# end
|
|
135
|
+
#
|
|
136
|
+
# def method2
|
|
137
|
+
# foo&.bar
|
|
138
|
+
# end
|
|
139
|
+
#
|
|
140
|
+
# @example AdditionalNilMethods: [present?]
|
|
141
|
+
# # good
|
|
142
|
+
# foo.present?
|
|
143
|
+
# foo&.bar
|
|
144
|
+
#
|
|
78
145
|
class RedundantSafeNavigation < Base
|
|
79
146
|
include AllowedMethods
|
|
80
147
|
extend AutoCorrector
|
|
81
148
|
|
|
82
149
|
MSG = 'Redundant safe navigation detected, use `.` instead.'
|
|
83
150
|
MSG_LITERAL = 'Redundant safe navigation with default literal detected.'
|
|
151
|
+
MSG_NON_NIL = 'Redundant safe navigation on non-nil receiver (detected by analyzing ' \
|
|
152
|
+
'previous code/method invocations).'
|
|
84
153
|
|
|
85
154
|
NIL_SPECIFIC_METHODS = (nil.methods - Object.new.methods).to_set.freeze
|
|
86
155
|
|
|
87
156
|
SNAKE_CASE = /\A[[:digit:][:upper:]_]+\z/.freeze
|
|
88
157
|
|
|
158
|
+
GUARANTEED_INSTANCE_METHODS = %i[to_s to_i to_f to_a to_h].freeze
|
|
159
|
+
|
|
89
160
|
# @!method respond_to_nil_specific_method?(node)
|
|
90
161
|
def_node_matcher :respond_to_nil_specific_method?, <<~PATTERN
|
|
91
162
|
(csend _ :respond_to? (sym %NIL_SPECIFIC_METHODS))
|
|
@@ -105,15 +176,27 @@ module RuboCop
|
|
|
105
176
|
|
|
106
177
|
# rubocop:disable Metrics/AbcSize
|
|
107
178
|
def on_csend(node)
|
|
179
|
+
range = node.loc.dot
|
|
180
|
+
|
|
181
|
+
if infer_non_nil_receiver?
|
|
182
|
+
checker = Lint::Utils::NilReceiverChecker.new(node.receiver, additional_nil_methods)
|
|
183
|
+
|
|
184
|
+
if checker.cant_be_nil?
|
|
185
|
+
add_offense(range, message: MSG_NON_NIL) { |corrector| corrector.replace(range, '.') }
|
|
186
|
+
return
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
108
190
|
unless assume_receiver_instance_exists?(node.receiver)
|
|
109
|
-
return
|
|
191
|
+
return if !guaranteed_instance?(node.receiver) && !check?(node)
|
|
110
192
|
return if respond_to_nil_specific_method?(node)
|
|
111
193
|
end
|
|
112
194
|
|
|
113
|
-
range = node.loc.dot
|
|
114
195
|
add_offense(range) { |corrector| corrector.replace(range, '.') }
|
|
115
196
|
end
|
|
197
|
+
# rubocop:enable Metrics/AbcSize
|
|
116
198
|
|
|
199
|
+
# rubocop:disable Metrics/AbcSize
|
|
117
200
|
def on_or(node)
|
|
118
201
|
conversion_with_default?(node) do |send_node|
|
|
119
202
|
range = send_node.loc.dot.begin.join(node.source_range.end)
|
|
@@ -133,22 +216,43 @@ module RuboCop
|
|
|
133
216
|
def assume_receiver_instance_exists?(receiver)
|
|
134
217
|
return true if receiver.const_type? && !receiver.short_name.match?(SNAKE_CASE)
|
|
135
218
|
|
|
136
|
-
receiver.literal? && !receiver.nil_type?
|
|
219
|
+
receiver.self_type? || (receiver.literal? && !receiver.nil_type?)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def guaranteed_instance?(node)
|
|
223
|
+
receiver = if node.any_block_type?
|
|
224
|
+
node.send_node
|
|
225
|
+
else
|
|
226
|
+
node
|
|
227
|
+
end
|
|
228
|
+
return false unless receiver.send_type?
|
|
229
|
+
|
|
230
|
+
GUARANTEED_INSTANCE_METHODS.include?(receiver.method_name)
|
|
137
231
|
end
|
|
138
232
|
|
|
139
233
|
def check?(node)
|
|
234
|
+
return false unless allowed_method?(node.method_name)
|
|
235
|
+
|
|
140
236
|
parent = node.parent
|
|
141
237
|
return false unless parent
|
|
142
238
|
|
|
143
239
|
condition?(parent, node) ||
|
|
144
|
-
parent.
|
|
145
|
-
parent.or_type? ||
|
|
240
|
+
parent.operator_keyword? ||
|
|
146
241
|
(parent.send_type? && parent.negation_method?)
|
|
147
242
|
end
|
|
148
243
|
|
|
149
244
|
def condition?(parent, node)
|
|
150
245
|
(parent.conditional? || parent.post_condition_loop?) && parent.condition == node
|
|
151
246
|
end
|
|
247
|
+
|
|
248
|
+
def infer_non_nil_receiver?
|
|
249
|
+
cop_config['InferNonNilReceiver']
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def additional_nil_methods
|
|
253
|
+
@additional_nil_methods ||=
|
|
254
|
+
Array(cop_config.fetch('AdditionalNilMethods', []).map(&:to_sym))
|
|
255
|
+
end
|
|
152
256
|
end
|
|
153
257
|
end
|
|
154
258
|
end
|
|
@@ -135,10 +135,10 @@ module RuboCop
|
|
|
135
135
|
grandparent.array_type? && grandparent.children.size > 1
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
+
# rubocop:disable Metrics/AbcSize
|
|
138
139
|
def replacement_range_and_content(node)
|
|
139
|
-
variable
|
|
140
|
-
|
|
141
|
-
expression = loc.expression
|
|
140
|
+
variable = node.children.first
|
|
141
|
+
expression = node.source_range
|
|
142
142
|
|
|
143
143
|
if array_new?(variable)
|
|
144
144
|
expression = node.parent.source_range if node.parent.array_type?
|
|
@@ -148,16 +148,17 @@ module RuboCop
|
|
|
148
148
|
elsif redundant_brackets?(node)
|
|
149
149
|
[expression, remove_brackets(variable)]
|
|
150
150
|
else
|
|
151
|
-
[loc.operator, '']
|
|
151
|
+
[node.loc.operator, '']
|
|
152
152
|
end
|
|
153
153
|
end
|
|
154
|
+
# rubocop:enable Metrics/AbcSize
|
|
154
155
|
|
|
155
156
|
def array_splat?(node)
|
|
156
157
|
node.children.first.array_type?
|
|
157
158
|
end
|
|
158
159
|
|
|
159
160
|
def method_argument?(node)
|
|
160
|
-
node.parent.
|
|
161
|
+
node.parent.call_type?
|
|
161
162
|
end
|
|
162
163
|
|
|
163
164
|
def part_of_an_array?(node)
|
|
@@ -171,7 +172,7 @@ module RuboCop
|
|
|
171
172
|
parent = node.parent
|
|
172
173
|
grandparent = node.parent.parent
|
|
173
174
|
|
|
174
|
-
parent.when_type? ||
|
|
175
|
+
parent.when_type? || method_argument?(node) || part_of_an_array?(node) ||
|
|
175
176
|
grandparent&.resbody_type?
|
|
176
177
|
end
|
|
177
178
|
|
|
@@ -196,7 +197,7 @@ module RuboCop
|
|
|
196
197
|
def use_percent_literal_array_argument?(node)
|
|
197
198
|
argument = node.children.first
|
|
198
199
|
|
|
199
|
-
node
|
|
200
|
+
method_argument?(node) &&
|
|
200
201
|
(argument.percent_literal?(:string) || argument.percent_literal?(:symbol))
|
|
201
202
|
end
|
|
202
203
|
|
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
|
29
29
|
RESTRICT_ON_SEND = %i[print puts warn].freeze
|
|
30
30
|
|
|
31
31
|
# @!method to_s_without_args?(node)
|
|
32
|
-
def_node_matcher :to_s_without_args?, '(
|
|
32
|
+
def_node_matcher :to_s_without_args?, '(call _ :to_s)'
|
|
33
33
|
|
|
34
34
|
def on_interpolation(begin_node)
|
|
35
35
|
final_node = begin_node.children.last
|
|
@@ -42,7 +42,7 @@ module RuboCop
|
|
|
42
42
|
def on_send(node)
|
|
43
43
|
return if node.receiver
|
|
44
44
|
|
|
45
|
-
node.each_child_node(:
|
|
45
|
+
node.each_child_node(:call) do |child|
|
|
46
46
|
next if !child.method?(:to_s) || child.arguments.any?
|
|
47
47
|
|
|
48
48
|
register_offense(child, "`#{node.method_name}`")
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Lint
|
|
6
|
+
# Checks for redundant uses of `to_s`, `to_sym`, `to_i`, `to_f`, `to_d`, `to_r`, `to_c`,
|
|
7
|
+
# `to_a`, `to_h`, and `to_set`.
|
|
8
|
+
#
|
|
9
|
+
# When one of these methods is called on an object of the same type, that object
|
|
10
|
+
# is returned, making the call unnecessary. The cop detects conversion methods called
|
|
11
|
+
# on object literals, class constructors, class `[]` methods, and the `Kernel` methods
|
|
12
|
+
# `String()`, `Integer()`, `Float()`, BigDecimal(), `Rational()`, `Complex()`, and `Array()`.
|
|
13
|
+
#
|
|
14
|
+
# Specifically, these cases are detected for each conversion method:
|
|
15
|
+
#
|
|
16
|
+
# * `to_s` when called on a string literal, interpolated string, heredoc,
|
|
17
|
+
# or with `String.new` or `String()`.
|
|
18
|
+
# * `to_sym` when called on a symbol literal or interpolated symbol.
|
|
19
|
+
# * `to_i` when called on an integer literal or with `Integer()`.
|
|
20
|
+
# * `to_f` when called on a float literal of with `Float()`.
|
|
21
|
+
# * `to_r` when called on a rational literal or with `Rational()`.
|
|
22
|
+
# * `to_c` when called on a complex literal of with `Complex()`.
|
|
23
|
+
# * `to_a` when called on an array literal, or with `Array.new`, `Array()` or `Array[]`.
|
|
24
|
+
# * `to_h` when called on a hash literal, or with `Hash.new`, `Hash()` or `Hash[]`.
|
|
25
|
+
# * `to_set` when called on `Set.new` or `Set[]`.
|
|
26
|
+
#
|
|
27
|
+
# In all cases, chaining one same `to_*` conversion methods listed above is redundant.
|
|
28
|
+
#
|
|
29
|
+
# The cop can also register an offense for chaining conversion methods on methods that are
|
|
30
|
+
# expected to return a specific type regardless of receiver (eg. `foo.inspect.to_s` and
|
|
31
|
+
# `foo.to_json.to_s`).
|
|
32
|
+
#
|
|
33
|
+
# @example
|
|
34
|
+
# # bad
|
|
35
|
+
# "text".to_s
|
|
36
|
+
# :sym.to_sym
|
|
37
|
+
# 42.to_i
|
|
38
|
+
# 8.5.to_f
|
|
39
|
+
# 12r.to_r
|
|
40
|
+
# 1i.to_c
|
|
41
|
+
# [].to_a
|
|
42
|
+
# {}.to_h
|
|
43
|
+
# Set.new.to_set
|
|
44
|
+
#
|
|
45
|
+
# # good
|
|
46
|
+
# "text"
|
|
47
|
+
# :sym
|
|
48
|
+
# 42
|
|
49
|
+
# 8.5
|
|
50
|
+
# 12r
|
|
51
|
+
# 1i
|
|
52
|
+
# []
|
|
53
|
+
# {}
|
|
54
|
+
# Set.new
|
|
55
|
+
#
|
|
56
|
+
# # bad
|
|
57
|
+
# Integer(var).to_i
|
|
58
|
+
#
|
|
59
|
+
# # good
|
|
60
|
+
# Integer(var)
|
|
61
|
+
#
|
|
62
|
+
# # good - chaining to a type constructor with exceptions suppressed
|
|
63
|
+
# # in this case, `Integer()` could return `nil`
|
|
64
|
+
# Integer(var, exception: false).to_i
|
|
65
|
+
#
|
|
66
|
+
# # bad - chaining the same conversion
|
|
67
|
+
# foo.to_s.to_s
|
|
68
|
+
#
|
|
69
|
+
# # good
|
|
70
|
+
# foo.to_s
|
|
71
|
+
#
|
|
72
|
+
# # bad - chaining a conversion to a method that is expected to return the same type
|
|
73
|
+
# foo.inspect.to_s
|
|
74
|
+
# foo.to_json.to_s
|
|
75
|
+
#
|
|
76
|
+
# # good
|
|
77
|
+
# foo.inspect
|
|
78
|
+
# foo.to_json
|
|
79
|
+
#
|
|
80
|
+
class RedundantTypeConversion < Base
|
|
81
|
+
extend AutoCorrector
|
|
82
|
+
|
|
83
|
+
MSG = 'Redundant `%<method>s` detected.'
|
|
84
|
+
|
|
85
|
+
# Maps conversion methods to the node types for the literals of that type
|
|
86
|
+
LITERAL_NODE_TYPES = {
|
|
87
|
+
to_s: %i[str dstr],
|
|
88
|
+
to_sym: %i[sym dsym],
|
|
89
|
+
to_i: %i[int],
|
|
90
|
+
to_f: %i[float],
|
|
91
|
+
to_r: %i[rational],
|
|
92
|
+
to_c: %i[complex],
|
|
93
|
+
to_a: %i[array],
|
|
94
|
+
to_h: %i[hash],
|
|
95
|
+
to_set: [] # sets don't have a literal or node type
|
|
96
|
+
}.freeze
|
|
97
|
+
|
|
98
|
+
# Maps each conversion method to the pattern matcher for that type's constructors
|
|
99
|
+
# Not every type has a constructor, for instance Symbol.
|
|
100
|
+
CONSTRUCTOR_MAPPING = {
|
|
101
|
+
to_s: 'string_constructor?',
|
|
102
|
+
to_i: 'integer_constructor?',
|
|
103
|
+
to_f: 'float_constructor?',
|
|
104
|
+
to_d: 'bigdecimal_constructor?',
|
|
105
|
+
to_r: 'rational_constructor?',
|
|
106
|
+
to_c: 'complex_constructor?',
|
|
107
|
+
to_a: 'array_constructor?',
|
|
108
|
+
to_h: 'hash_constructor?',
|
|
109
|
+
to_set: 'set_constructor?'
|
|
110
|
+
}.freeze
|
|
111
|
+
|
|
112
|
+
# Methods that already are expected to return a given type, which makes a further
|
|
113
|
+
# conversion redundant.
|
|
114
|
+
TYPED_METHODS = { to_s: %i[inspect to_json] }.freeze
|
|
115
|
+
|
|
116
|
+
CONVERSION_METHODS = Set[*LITERAL_NODE_TYPES.keys].freeze
|
|
117
|
+
RESTRICT_ON_SEND = CONVERSION_METHODS + [:to_d]
|
|
118
|
+
|
|
119
|
+
private_constant :LITERAL_NODE_TYPES, :CONSTRUCTOR_MAPPING
|
|
120
|
+
|
|
121
|
+
# @!method type_constructor?(node, type_symbol)
|
|
122
|
+
def_node_matcher :type_constructor?, <<~PATTERN
|
|
123
|
+
(send {nil? (const {cbase nil?} :Kernel)} %1 ...)
|
|
124
|
+
PATTERN
|
|
125
|
+
|
|
126
|
+
# @!method string_constructor?(node)
|
|
127
|
+
def_node_matcher :string_constructor?, <<~PATTERN
|
|
128
|
+
{
|
|
129
|
+
(send (const {cbase nil?} :String) :new ...)
|
|
130
|
+
#type_constructor?(:String)
|
|
131
|
+
}
|
|
132
|
+
PATTERN
|
|
133
|
+
|
|
134
|
+
# @!method integer_constructor?(node)
|
|
135
|
+
def_node_matcher :integer_constructor?, <<~PATTERN
|
|
136
|
+
#type_constructor?(:Integer)
|
|
137
|
+
PATTERN
|
|
138
|
+
|
|
139
|
+
# @!method float_constructor?(node)
|
|
140
|
+
def_node_matcher :float_constructor?, <<~PATTERN
|
|
141
|
+
#type_constructor?(:Float)
|
|
142
|
+
PATTERN
|
|
143
|
+
|
|
144
|
+
# @!method bigdecimal_constructor?(node)
|
|
145
|
+
def_node_matcher :bigdecimal_constructor?, <<~PATTERN
|
|
146
|
+
#type_constructor?(:BigDecimal)
|
|
147
|
+
PATTERN
|
|
148
|
+
|
|
149
|
+
# @!method rational_constructor?(node)
|
|
150
|
+
def_node_matcher :rational_constructor?, <<~PATTERN
|
|
151
|
+
#type_constructor?(:Rational)
|
|
152
|
+
PATTERN
|
|
153
|
+
|
|
154
|
+
# @!method complex_constructor?(node)
|
|
155
|
+
def_node_matcher :complex_constructor?, <<~PATTERN
|
|
156
|
+
#type_constructor?(:Complex)
|
|
157
|
+
PATTERN
|
|
158
|
+
|
|
159
|
+
# @!method array_constructor?(node)
|
|
160
|
+
def_node_matcher :array_constructor?, <<~PATTERN
|
|
161
|
+
{
|
|
162
|
+
(send (const {cbase nil?} :Array) {:new :[]} ...)
|
|
163
|
+
#type_constructor?(:Array)
|
|
164
|
+
}
|
|
165
|
+
PATTERN
|
|
166
|
+
|
|
167
|
+
# @!method hash_constructor?(node)
|
|
168
|
+
def_node_matcher :hash_constructor?, <<~PATTERN
|
|
169
|
+
{
|
|
170
|
+
(block (send (const {cbase nil?} :Hash) :new) ...)
|
|
171
|
+
(send (const {cbase nil?} :Hash) {:new :[]} ...)
|
|
172
|
+
(send {nil? (const {cbase nil?} :Kernel)} :Hash ...)
|
|
173
|
+
}
|
|
174
|
+
PATTERN
|
|
175
|
+
|
|
176
|
+
# @!method set_constructor?(node)
|
|
177
|
+
def_node_matcher :set_constructor?, <<~PATTERN
|
|
178
|
+
{
|
|
179
|
+
(send (const {cbase nil?} :Set) {:new :[]} ...)
|
|
180
|
+
}
|
|
181
|
+
PATTERN
|
|
182
|
+
|
|
183
|
+
# @!method exception_false_keyword_argument?(node)
|
|
184
|
+
def_node_matcher :exception_false_keyword_argument?, <<~PATTERN
|
|
185
|
+
(hash (pair (sym :exception) false))
|
|
186
|
+
PATTERN
|
|
187
|
+
|
|
188
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
189
|
+
def on_send(node)
|
|
190
|
+
return if node.arguments.any? || hash_or_set_with_block?(node)
|
|
191
|
+
|
|
192
|
+
receiver = find_receiver(node)
|
|
193
|
+
return unless literal_receiver?(node, receiver) ||
|
|
194
|
+
constructor?(node, receiver) ||
|
|
195
|
+
chained_conversion?(node, receiver) ||
|
|
196
|
+
chained_to_typed_method?(node, receiver)
|
|
197
|
+
|
|
198
|
+
message = format(MSG, method: node.method_name)
|
|
199
|
+
|
|
200
|
+
add_offense(node.loc.selector, message: message) do |corrector|
|
|
201
|
+
corrector.remove(node.loc.dot.join(node.loc.end || node.loc.selector))
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
205
|
+
alias on_csend on_send
|
|
206
|
+
|
|
207
|
+
private
|
|
208
|
+
|
|
209
|
+
def hash_or_set_with_block?(node)
|
|
210
|
+
return false if !node.method?(:to_h) && !node.method?(:to_set)
|
|
211
|
+
|
|
212
|
+
node.parent&.any_block_type? || node.last_argument&.block_pass_type?
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def find_receiver(node)
|
|
216
|
+
receiver = node.receiver
|
|
217
|
+
return unless receiver
|
|
218
|
+
|
|
219
|
+
while receiver.begin_type?
|
|
220
|
+
break unless receiver.children.one?
|
|
221
|
+
|
|
222
|
+
receiver = receiver.children.first
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
receiver
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def literal_receiver?(node, receiver)
|
|
229
|
+
return false unless receiver
|
|
230
|
+
|
|
231
|
+
receiver.type?(*LITERAL_NODE_TYPES[node.method_name])
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def constructor?(node, receiver)
|
|
235
|
+
matcher = CONSTRUCTOR_MAPPING[node.method_name]
|
|
236
|
+
return false unless matcher
|
|
237
|
+
|
|
238
|
+
public_send(matcher, receiver) && !constructor_suppresses_exceptions?(receiver)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def constructor_suppresses_exceptions?(receiver)
|
|
242
|
+
# If the constructor suppresses exceptions with `exception: false`, it is possible
|
|
243
|
+
# it could return `nil`, and therefore a chained conversion is not redundant.
|
|
244
|
+
receiver.arguments.any? { |arg| exception_false_keyword_argument?(arg) }
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def chained_conversion?(node, receiver)
|
|
248
|
+
return false unless receiver&.call_type?
|
|
249
|
+
|
|
250
|
+
receiver.method?(node.method_name)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def chained_to_typed_method?(node, receiver)
|
|
254
|
+
return false unless receiver&.call_type?
|
|
255
|
+
|
|
256
|
+
TYPED_METHODS.fetch(node.method_name, []).include?(receiver.method_name)
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
end
|
|
@@ -53,6 +53,7 @@ module RuboCop
|
|
|
53
53
|
# rubocop:enable Metrics/AbcSize
|
|
54
54
|
|
|
55
55
|
alias on_numblock on_block
|
|
56
|
+
alias on_itblock on_block
|
|
56
57
|
|
|
57
58
|
private
|
|
58
59
|
|
|
@@ -64,6 +65,8 @@ module RuboCop
|
|
|
64
65
|
(args (arg _)) ...)
|
|
65
66
|
(numblock
|
|
66
67
|
$(call _ {:each_with_index :with_index} ...) 1 ...)
|
|
68
|
+
(itblock
|
|
69
|
+
$(call _ {:each_with_index :with_index} ...) _ ...)
|
|
67
70
|
}
|
|
68
71
|
PATTERN
|
|
69
72
|
|
|
@@ -49,6 +49,7 @@ module RuboCop
|
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
alias on_numblock on_block
|
|
52
|
+
alias on_itblock on_block
|
|
52
53
|
|
|
53
54
|
private
|
|
54
55
|
|
|
@@ -59,6 +60,8 @@ module RuboCop
|
|
|
59
60
|
$(call _ {:each_with_object :with_object} _) (args (arg _)) ...)
|
|
60
61
|
(numblock
|
|
61
62
|
$(call _ {:each_with_object :with_object} _) 1 ...)
|
|
63
|
+
(itblock
|
|
64
|
+
$(call _ {:each_with_object :with_object} _) _ ...)
|
|
62
65
|
}
|
|
63
66
|
PATTERN
|
|
64
67
|
|
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
|
6
6
|
# Checks if `include` or `prepend` is called in `refine` block.
|
|
7
7
|
# These methods are deprecated and should be replaced with `Refinement#import_methods`.
|
|
8
8
|
#
|
|
9
|
-
# It emulates deprecation warnings in Ruby 3.1.
|
|
9
|
+
# It emulates deprecation warnings in Ruby 3.1. Functionality has been removed in Ruby 3.2.
|
|
10
10
|
#
|
|
11
11
|
# @safety
|
|
12
12
|
# This cop's autocorrection is unsafe because `include M` will affect the included class
|
|
@@ -43,7 +43,7 @@ module RuboCop
|
|
|
43
43
|
def on_irange(node)
|
|
44
44
|
return if node.parent&.begin_type?
|
|
45
45
|
return unless node.begin && node.end
|
|
46
|
-
return if same_line?(node.
|
|
46
|
+
return if same_line?(node.loc.operator, node.end)
|
|
47
47
|
|
|
48
48
|
message = format(MSG, range: "#{node.begin.source}#{node.loc.operator.source}")
|
|
49
49
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Lint
|
|
6
|
-
# Checks for `rescue` blocks targeting the Exception class.
|
|
6
|
+
# Checks for `rescue` blocks targeting the `Exception` class.
|
|
7
7
|
#
|
|
8
8
|
# @example
|
|
9
9
|
#
|
|
@@ -24,10 +24,7 @@ module RuboCop
|
|
|
24
24
|
MSG = 'Avoid rescuing the `Exception` class. Perhaps you meant to rescue `StandardError`?'
|
|
25
25
|
|
|
26
26
|
def on_resbody(node)
|
|
27
|
-
return unless node.
|
|
28
|
-
|
|
29
|
-
rescue_args = node.children.first.children
|
|
30
|
-
return unless rescue_args.any? { |a| targets_exception?(a) }
|
|
27
|
+
return unless node.exceptions.any? { |exception| targets_exception?(exception) }
|
|
31
28
|
|
|
32
29
|
add_offense(node)
|
|
33
30
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Lint
|
|
6
|
-
#
|
|
6
|
+
# Checks for arguments to `rescue` that will result in a `TypeError`
|
|
7
7
|
# if an exception is raised.
|
|
8
8
|
#
|
|
9
9
|
# @example
|
|
@@ -42,15 +42,11 @@ module RuboCop
|
|
|
42
42
|
INVALID_TYPES = %i[array dstr float hash nil int str sym].freeze
|
|
43
43
|
|
|
44
44
|
def on_resbody(node)
|
|
45
|
-
|
|
46
|
-
return if rescued.nil?
|
|
47
|
-
|
|
48
|
-
exceptions = *rescued
|
|
49
|
-
invalid_exceptions = invalid_exceptions(exceptions)
|
|
45
|
+
invalid_exceptions = invalid_exceptions(node.exceptions)
|
|
50
46
|
return if invalid_exceptions.empty?
|
|
51
47
|
|
|
52
48
|
add_offense(
|
|
53
|
-
node.loc.keyword.join(
|
|
49
|
+
node.loc.keyword.join(node.children.first.source_range),
|
|
54
50
|
message: format(MSG, invalid_exceptions: invalid_exceptions.map(&:source).join(', '))
|
|
55
51
|
) do |corrector|
|
|
56
52
|
autocorrect(corrector, node)
|
|
@@ -58,7 +54,7 @@ module RuboCop
|
|
|
58
54
|
end
|
|
59
55
|
|
|
60
56
|
def autocorrect(corrector, node)
|
|
61
|
-
rescued
|
|
57
|
+
rescued = node.children.first
|
|
62
58
|
range = node.loc.keyword.end.join(rescued.source_range.end)
|
|
63
59
|
|
|
64
60
|
corrector.replace(range, correction(*rescued))
|
|
@@ -32,25 +32,23 @@ module RuboCop
|
|
|
32
32
|
class ReturnInVoidContext < Base
|
|
33
33
|
MSG = 'Do not return a value in `%<method>s`.'
|
|
34
34
|
|
|
35
|
+
# Returning out of these methods only exits the block itself.
|
|
36
|
+
SCOPE_CHANGING_METHODS = %i[lambda define_method define_singleton_method].freeze
|
|
37
|
+
|
|
35
38
|
def on_return(return_node)
|
|
36
39
|
return unless return_node.descendants.any?
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return
|
|
41
|
-
|
|
41
|
+
def_node = return_node.each_ancestor(:any_def).first
|
|
42
|
+
return unless def_node&.void_context?
|
|
43
|
+
return if return_node.each_ancestor(:any_block).any? do |block_node|
|
|
44
|
+
SCOPE_CHANGING_METHODS.include?(block_node.method_name)
|
|
45
|
+
end
|
|
42
46
|
|
|
43
47
|
add_offense(
|
|
44
48
|
return_node.loc.keyword,
|
|
45
|
-
message: format(message, method:
|
|
49
|
+
message: format(message, method: def_node.method_name)
|
|
46
50
|
)
|
|
47
51
|
end
|
|
48
|
-
|
|
49
|
-
private
|
|
50
|
-
|
|
51
|
-
def non_void_context(return_node)
|
|
52
|
-
return_node.each_ancestor(:block, :def, :defs).first
|
|
53
|
-
end
|
|
54
52
|
end
|
|
55
53
|
end
|
|
56
54
|
end
|