rubocop 0.89.1 → 0.93.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/config/default.yml +160 -14
- data/lib/rubocop.rb +33 -5
- data/lib/rubocop/cached_data.rb +3 -1
- data/lib/rubocop/cli/command.rb +1 -0
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +1 -0
- data/lib/rubocop/cli/command/base.rb +1 -0
- data/lib/rubocop/cli/command/execute_runner.rb +9 -0
- data/lib/rubocop/cli/command/init_dotfile.rb +1 -0
- data/lib/rubocop/cli/command/show_cops.rb +1 -0
- data/lib/rubocop/cli/command/version.rb +1 -0
- data/lib/rubocop/cli/environment.rb +1 -0
- data/lib/rubocop/comment_config.rb +14 -5
- data/lib/rubocop/config_loader.rb +20 -9
- data/lib/rubocop/config_loader_resolver.rb +1 -0
- data/lib/rubocop/config_obsoletion.rb +1 -0
- data/lib/rubocop/config_regeneration.rb +33 -0
- data/lib/rubocop/config_store.rb +3 -3
- data/lib/rubocop/config_validator.rb +3 -0
- data/lib/rubocop/cop/base.rb +23 -0
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +5 -1
- data/lib/rubocop/cop/bundler/gem_comment.rb +8 -3
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -0
- data/lib/rubocop/cop/commissioner.rb +47 -7
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/condition_corrector.rb +3 -5
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +9 -10
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +8 -3
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -8
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +4 -9
- data/lib/rubocop/cop/correctors/punctuation_corrector.rb +8 -10
- data/lib/rubocop/cop/documentation.rb +22 -0
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +10 -10
- data/lib/rubocop/cop/generator.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -0
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -0
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +77 -0
- data/lib/rubocop/cop/layout/block_alignment.rb +23 -19
- data/lib/rubocop/cop/layout/case_indentation.rb +4 -7
- data/lib/rubocop/cop/layout/class_structure.rb +11 -10
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +4 -6
- data/lib/rubocop/cop/layout/condition_position.rb +13 -15
- data/lib/rubocop/cop/layout/def_end_alignment.rb +8 -5
- data/lib/rubocop/cop/layout/dot_position.rb +21 -20
- data/lib/rubocop/cop/layout/empty_comment.rb +30 -23
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +21 -18
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +13 -13
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +136 -0
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +21 -23
- data/lib/rubocop/cop/layout/empty_lines.rb +6 -7
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +17 -14
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +7 -8
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +5 -8
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +2 -5
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -5
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +2 -5
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +3 -7
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +2 -5
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +2 -5
- data/lib/rubocop/cop/layout/end_alignment.rb +11 -17
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +2 -5
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +2 -5
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +4 -8
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +2 -5
- data/lib/rubocop/cop/layout/hash_alignment.rb +17 -20
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +15 -14
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +14 -11
- data/lib/rubocop/cop/layout/initial_indentation.rb +6 -7
- data/lib/rubocop/cop/layout/leading_comment_space.rb +11 -9
- data/lib/rubocop/cop/layout/leading_empty_lines.rb +6 -11
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +2 -5
- data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +2 -5
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +10 -14
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +21 -19
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +2 -5
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +2 -5
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +5 -9
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -5
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +2 -5
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +41 -22
- data/lib/rubocop/cop/layout/space_after_colon.rb +11 -7
- data/lib/rubocop/cop/layout/space_after_comma.rb +2 -5
- data/lib/rubocop/cop/layout/space_after_method_name.rb +5 -6
- data/lib/rubocop/cop/layout/space_after_not.rb +9 -11
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +2 -5
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +17 -21
- data/lib/rubocop/cop/layout/space_around_keyword.rb +17 -18
- data/lib/rubocop/cop/layout/space_around_operators.rb +17 -16
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +23 -22
- data/lib/rubocop/cop/layout/space_before_comma.rb +3 -5
- data/lib/rubocop/cop/layout/space_before_comment.rb +10 -7
- data/lib/rubocop/cop/layout/space_before_first_arg.rb +7 -7
- data/lib/rubocop/cop/layout/space_before_semicolon.rb +2 -5
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -17
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +20 -23
- data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +3 -8
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +13 -16
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +19 -37
- data/lib/rubocop/cop/layout/space_inside_parens.rb +9 -14
- data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +5 -10
- data/lib/rubocop/cop/layout/space_inside_range_literal.rb +8 -17
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +16 -24
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +12 -13
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +10 -15
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +11 -11
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -0
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +2 -0
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +15 -1
- data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -2
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +1 -1
- data/lib/rubocop/cop/lint/boolean_symbol.rb +3 -0
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +74 -0
- data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +2 -3
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -3
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -4
- data/lib/rubocop/cop/lint/duplicate_require.rb +46 -0
- data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +2 -15
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -0
- data/lib/rubocop/cop/lint/empty_file.rb +50 -0
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +2 -0
- data/lib/rubocop/cop/lint/float_comparison.rb +2 -2
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +37 -0
- data/lib/rubocop/cop/lint/identity_comparison.rb +51 -0
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +2 -5
- data/lib/rubocop/cop/lint/inherit_exception.rb +2 -2
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +3 -35
- data/lib/rubocop/cop/lint/multiple_comparison.rb +3 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +1 -0
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +9 -20
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
- data/lib/rubocop/cop/lint/percent_string_array.rb +8 -12
- data/lib/rubocop/cop/lint/raise_exception.rb +1 -0
- data/lib/rubocop/cop/lint/rand_one.rb +2 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +22 -12
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +14 -4
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -0
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +45 -0
- data/lib/rubocop/cop/lint/rescue_type.rb +0 -1
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +3 -1
- data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -6
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +4 -4
- data/lib/rubocop/cop/lint/struct_new_override.rb +1 -0
- data/lib/rubocop/cop/lint/to_json.rb +16 -5
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +57 -0
- data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -6
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +3 -1
- data/lib/rubocop/cop/lint/uri_regexp.rb +2 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +3 -9
- data/lib/rubocop/cop/lint/useless_method_definition.rb +70 -0
- data/lib/rubocop/cop/lint/useless_times.rb +106 -0
- data/lib/rubocop/cop/metrics/block_length.rb +3 -1
- data/lib/rubocop/cop/metrics/class_length.rb +8 -6
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +27 -16
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -0
- data/lib/rubocop/cop/mixin/alignment.rb +3 -0
- data/lib/rubocop/cop/mixin/allowed_methods.rb +2 -0
- data/lib/rubocop/cop/mixin/annotation_comment.rb +5 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +16 -7
- data/lib/rubocop/cop/mixin/comments_help.rb +48 -0
- data/lib/rubocop/cop/mixin/configurable_naming.rb +2 -2
- data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +8 -7
- data/lib/rubocop/cop/mixin/empty_parameter.rb +3 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +12 -1
- data/lib/rubocop/cop/mixin/first_element_line_break.rb +3 -1
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +27 -2
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +12 -10
- data/lib/rubocop/cop/mixin/negative_conditional.rb +2 -2
- data/lib/rubocop/cop/mixin/percent_array.rb +14 -3
- data/lib/rubocop/cop/mixin/rescue_node.rb +11 -1
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +4 -3
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +4 -3
- data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -3
- data/lib/rubocop/cop/mixin/surrounding_space.rb +8 -4
- data/lib/rubocop/cop/mixin/trailing_comma.rb +7 -7
- data/lib/rubocop/cop/mixin/visibility_help.rb +4 -16
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +1 -1
- data/lib/rubocop/cop/offense.rb +16 -2
- data/lib/rubocop/cop/security/eval.rb +1 -0
- data/lib/rubocop/cop/security/json_load.rb +1 -0
- data/lib/rubocop/cop/security/marshal_load.rb +1 -0
- data/lib/rubocop/cop/security/open.rb +1 -0
- data/lib/rubocop/cop/security/yaml_load.rb +1 -0
- data/lib/rubocop/cop/severity.rb +0 -8
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +7 -11
- data/lib/rubocop/cop/style/accessor_grouping.rb +3 -0
- data/lib/rubocop/cop/style/alias.rb +2 -0
- data/lib/rubocop/cop/style/array_coercion.rb +4 -0
- data/lib/rubocop/cop/style/array_join.rb +1 -0
- data/lib/rubocop/cop/style/attr.rb +1 -0
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +2 -0
- data/lib/rubocop/cop/style/case_equality.rb +11 -3
- data/lib/rubocop/cop/style/case_like_if.rb +40 -8
- data/lib/rubocop/cop/style/class_and_module_children.rb +2 -0
- data/lib/rubocop/cop/style/class_check.rb +6 -9
- data/lib/rubocop/cop/style/class_equality_comparison.rb +49 -0
- data/lib/rubocop/cop/style/class_methods_definitions.rb +157 -0
- data/lib/rubocop/cop/style/class_vars.rb +1 -2
- data/lib/rubocop/cop/style/combinable_loops.rb +91 -0
- data/lib/rubocop/cop/style/comment_annotation.rb +6 -0
- data/lib/rubocop/cop/style/commented_keyword.rb +7 -8
- data/lib/rubocop/cop/style/conditional_assignment.rb +49 -60
- data/lib/rubocop/cop/style/date_time.rb +12 -1
- data/lib/rubocop/cop/style/dir.rb +1 -0
- data/lib/rubocop/cop/style/double_negation.rb +1 -0
- data/lib/rubocop/cop/style/empty_block_parameter.rb +9 -10
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +9 -10
- data/lib/rubocop/cop/style/empty_literal.rb +3 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -3
- data/lib/rubocop/cop/style/even_odd.rb +1 -0
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -2
- data/lib/rubocop/cop/style/explicit_block_argument.rb +7 -3
- data/lib/rubocop/cop/style/float_division.rb +2 -0
- data/lib/rubocop/cop/style/for.rb +0 -4
- data/lib/rubocop/cop/style/format_string.rb +1 -4
- data/lib/rubocop/cop/style/format_string_token.rb +1 -1
- data/lib/rubocop/cop/style/guard_clause.rb +1 -0
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +24 -5
- data/lib/rubocop/cop/style/hash_syntax.rb +6 -5
- data/lib/rubocop/cop/style/hash_transform_keys.rb +16 -9
- data/lib/rubocop/cop/style/hash_transform_values.rb +16 -9
- data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -6
- data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +53 -0
- data/lib/rubocop/cop/style/lambda_call.rb +3 -1
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +10 -1
- data/lib/rubocop/cop/style/method_def_parentheses.rb +0 -4
- data/lib/rubocop/cop/style/mixin_usage.rb +8 -27
- data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -2
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +14 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +3 -2
- data/lib/rubocop/cop/style/negated_if.rb +6 -6
- data/lib/rubocop/cop/style/negated_unless.rb +6 -6
- data/lib/rubocop/cop/style/negated_while.rb +7 -15
- data/lib/rubocop/cop/style/nested_modifier.rb +10 -13
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +11 -11
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +16 -16
- data/lib/rubocop/cop/style/next.rb +10 -14
- data/lib/rubocop/cop/style/nil_comparison.rb +13 -11
- data/lib/rubocop/cop/style/non_nil_check.rb +34 -26
- data/lib/rubocop/cop/style/not.rb +20 -26
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +4 -9
- data/lib/rubocop/cop/style/numeric_predicate.rb +5 -14
- data/lib/rubocop/cop/style/one_line_conditional.rb +73 -23
- data/lib/rubocop/cop/style/option_hash.rb +1 -1
- data/lib/rubocop/cop/style/optional_arguments.rb +1 -1
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +12 -1
- data/lib/rubocop/cop/style/or_assignment.rb +13 -10
- data/lib/rubocop/cop/style/parallel_assignment.rb +14 -14
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -6
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +13 -19
- data/lib/rubocop/cop/style/percent_q_literals.rb +8 -10
- data/lib/rubocop/cop/style/perl_backrefs.rb +8 -10
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +11 -14
- data/lib/rubocop/cop/style/proc.rb +6 -6
- data/lib/rubocop/cop/style/raise_args.rb +12 -24
- data/lib/rubocop/cop/style/random_with_offset.rb +19 -19
- data/lib/rubocop/cop/style/redundant_assignment.rb +8 -18
- data/lib/rubocop/cop/style/redundant_begin.rb +28 -12
- data/lib/rubocop/cop/style/redundant_capital_w.rb +6 -9
- data/lib/rubocop/cop/style/redundant_condition.rb +10 -7
- data/lib/rubocop/cop/style/redundant_conditional.rb +4 -5
- data/lib/rubocop/cop/style/redundant_exception.rb +1 -3
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -12
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -8
- data/lib/rubocop/cop/style/redundant_freeze.rb +5 -7
- data/lib/rubocop/cop/style/redundant_interpolation.rb +31 -25
- data/lib/rubocop/cop/style/redundant_parentheses.rb +21 -15
- data/lib/rubocop/cop/style/redundant_percent_q.rb +9 -11
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +44 -36
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +13 -29
- data/lib/rubocop/cop/style/redundant_return.rb +17 -17
- data/lib/rubocop/cop/style/redundant_self.rb +9 -11
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +116 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +12 -29
- data/lib/rubocop/cop/style/redundant_sort_by.rb +5 -9
- data/lib/rubocop/cop/style/regexp_literal.rb +10 -21
- data/lib/rubocop/cop/style/rescue_modifier.rb +29 -9
- data/lib/rubocop/cop/style/rescue_standard_error.rb +20 -16
- data/lib/rubocop/cop/style/return_nil.rb +5 -5
- data/lib/rubocop/cop/style/safe_navigation.rb +18 -12
- data/lib/rubocop/cop/style/sample.rb +12 -14
- data/lib/rubocop/cop/style/self_assignment.rb +26 -22
- data/lib/rubocop/cop/style/semicolon.rb +6 -9
- data/lib/rubocop/cop/style/send.rb +4 -5
- data/lib/rubocop/cop/style/signal_exception.rb +23 -19
- data/lib/rubocop/cop/style/single_argument_dig.rb +1 -0
- data/lib/rubocop/cop/style/single_line_block_params.rb +4 -2
- data/lib/rubocop/cop/style/single_line_methods.rb +17 -16
- data/lib/rubocop/cop/style/slicing_with_range.rb +6 -8
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +66 -0
- data/lib/rubocop/cop/style/special_global_vars.rb +10 -15
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +17 -21
- data/lib/rubocop/cop/style/stderr_puts.rb +5 -6
- data/lib/rubocop/cop/style/string_concatenation.rb +17 -3
- data/lib/rubocop/cop/style/string_hash_keys.rb +6 -7
- data/lib/rubocop/cop/style/string_methods.rb +7 -17
- data/lib/rubocop/cop/style/strip.rb +9 -14
- data/lib/rubocop/cop/style/struct_inheritance.rb +3 -6
- data/lib/rubocop/cop/style/symbol_array.rb +5 -16
- data/lib/rubocop/cop/style/symbol_literal.rb +4 -6
- data/lib/rubocop/cop/style/symbol_proc.rb +14 -18
- data/lib/rubocop/cop/style/ternary_parentheses.rb +22 -22
- data/lib/rubocop/cop/style/trailing_body_on_class.rb +3 -6
- data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +4 -7
- data/lib/rubocop/cop/style/trailing_body_on_module.rb +3 -6
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +2 -5
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +2 -5
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +11 -9
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +2 -5
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +8 -17
- data/lib/rubocop/cop/style/trivial_accessors.rb +26 -30
- data/lib/rubocop/cop/style/unless_else.rb +5 -8
- data/lib/rubocop/cop/style/unpack_first.rb +5 -8
- data/lib/rubocop/cop/style/variable_interpolation.rb +7 -10
- data/lib/rubocop/cop/style/when_then.rb +4 -6
- data/lib/rubocop/cop/style/while_until_do.rb +6 -16
- data/lib/rubocop/cop/style/while_until_modifier.rb +6 -20
- data/lib/rubocop/cop/style/word_array.rb +5 -23
- data/lib/rubocop/cop/style/yoda_condition.rb +4 -15
- data/lib/rubocop/cop/style/zero_length_predicate.rb +12 -18
- data/lib/rubocop/cop/team.rb +1 -0
- data/lib/rubocop/cop/util.rb +1 -2
- data/lib/rubocop/cop/utils/format_string.rb +3 -5
- data/lib/rubocop/cop/variable_force.rb +2 -0
- data/lib/rubocop/cop/variable_force/branch.rb +0 -4
- data/lib/rubocop/cops_documentation_generator.rb +4 -2
- data/lib/rubocop/core_ext/string.rb +2 -2
- data/lib/rubocop/directive_comment.rb +32 -0
- data/lib/rubocop/ext/regexp_node.rb +62 -0
- data/lib/rubocop/file_finder.rb +1 -0
- data/lib/rubocop/formatter/auto_gen_config_formatter.rb +2 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +12 -5
- data/lib/rubocop/formatter/html_formatter.rb +2 -0
- data/lib/rubocop/formatter/progress_formatter.rb +2 -1
- data/lib/rubocop/formatter/quiet_formatter.rb +1 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +36 -6
- data/lib/rubocop/name_similarity.rb +1 -0
- data/lib/rubocop/options.rb +40 -17
- data/lib/rubocop/remote_config.rb +1 -0
- data/lib/rubocop/result_cache.rb +39 -15
- data/lib/rubocop/rspec/cop_helper.rb +5 -2
- data/lib/rubocop/rspec/expect_offense.rb +14 -9
- data/lib/rubocop/rspec/shared_contexts.rb +12 -0
- data/lib/rubocop/runner.rb +38 -18
- data/lib/rubocop/string_interpreter.rb +3 -0
- data/lib/rubocop/target_finder.rb +28 -26
- data/lib/rubocop/target_ruby.rb +7 -1
- data/lib/rubocop/version.rb +7 -1
- data/lib/rubocop/yaml_duplication_checker.rb +1 -0
- metadata +31 -17
- data/lib/rubocop/cop/mixin/regexp_literal_help.rb +0 -43
- data/lib/rubocop/cop/tokens_util.rb +0 -84
@@ -13,8 +13,9 @@ module RuboCop
|
|
13
13
|
# # good
|
14
14
|
# x if y.z.nil?
|
15
15
|
#
|
16
|
-
class RedundantParentheses <
|
16
|
+
class RedundantParentheses < Base
|
17
17
|
include Parentheses
|
18
|
+
extend AutoCorrector
|
18
19
|
|
19
20
|
def_node_matcher :square_brackets?,
|
20
21
|
'(send {(send _recv _msg) str array hash} :[] ...)'
|
@@ -25,17 +26,11 @@ module RuboCop
|
|
25
26
|
'^^(block (send _ _ equal?(%0) ...) ...)'
|
26
27
|
|
27
28
|
def on_begin(node)
|
28
|
-
return if !parentheses?(node) || parens_allowed?(node)
|
29
|
-
return if node.parent && (node.parent.while_post_type? ||
|
30
|
-
node.parent.until_post_type?)
|
29
|
+
return if !parentheses?(node) || parens_allowed?(node) || ignore_syntax?(node)
|
31
30
|
|
32
31
|
check(node)
|
33
32
|
end
|
34
33
|
|
35
|
-
def autocorrect(node)
|
36
|
-
ParenthesesCorrector.correct(node)
|
37
|
-
end
|
38
|
-
|
39
34
|
private
|
40
35
|
|
41
36
|
def parens_allowed?(node)
|
@@ -45,6 +40,13 @@ module RuboCop
|
|
45
40
|
allowed_expression?(node)
|
46
41
|
end
|
47
42
|
|
43
|
+
def ignore_syntax?(node)
|
44
|
+
return false unless (parent = node.parent)
|
45
|
+
|
46
|
+
parent.while_post_type? || parent.until_post_type? ||
|
47
|
+
like_method_argument_parentheses?(parent)
|
48
|
+
end
|
49
|
+
|
48
50
|
def allowed_expression?(node)
|
49
51
|
allowed_ancestor?(node) ||
|
50
52
|
allowed_method_call?(node) ||
|
@@ -71,6 +73,10 @@ module RuboCop
|
|
71
73
|
!ancestor.begin_type? && !ancestor.def_type? && !ancestor.block_type?
|
72
74
|
end
|
73
75
|
|
76
|
+
def like_method_argument_parentheses?(node)
|
77
|
+
node.send_type? && node.arguments.size == 1 && !node.arithmetic_operation?
|
78
|
+
end
|
79
|
+
|
74
80
|
def empty_parentheses?(node)
|
75
81
|
# Don't flag `()`
|
76
82
|
node.children.empty?
|
@@ -115,15 +121,16 @@ module RuboCop
|
|
115
121
|
|
116
122
|
node = node.children.first while suspect_unary?(node)
|
117
123
|
|
118
|
-
if node.send_type?
|
119
|
-
|
120
|
-
end
|
124
|
+
return if node.send_type? &&
|
125
|
+
!method_call_with_redundant_parentheses?(node)
|
121
126
|
|
122
127
|
offense(begin_node, 'an unary operation')
|
123
128
|
end
|
124
129
|
|
125
130
|
def offense(node, msg)
|
126
|
-
add_offense(node, message: "Don't use parentheses around #{msg}.")
|
131
|
+
add_offense(node, message: "Don't use parentheses around #{msg}.") do |corrector|
|
132
|
+
ParenthesesCorrector.correct(corrector, node)
|
133
|
+
end
|
127
134
|
end
|
128
135
|
|
129
136
|
def suspect_unary?(node)
|
@@ -168,10 +175,9 @@ module RuboCop
|
|
168
175
|
def raised_to_power_negative_numeric?(begin_node, node)
|
169
176
|
return false unless node.numeric_type?
|
170
177
|
|
171
|
-
|
172
|
-
return false
|
178
|
+
next_sibling = begin_node.right_sibling
|
179
|
+
return false unless next_sibling
|
173
180
|
|
174
|
-
next_sibling = siblings[begin_node.sibling_index + 1]
|
175
181
|
base_value = node.children.first
|
176
182
|
|
177
183
|
base_value.negative? && next_sibling == :**
|
@@ -17,7 +17,9 @@ module RuboCop
|
|
17
17
|
# time = "8 o'clock"
|
18
18
|
# question = '"What did you say?"'
|
19
19
|
#
|
20
|
-
class RedundantPercentQ <
|
20
|
+
class RedundantPercentQ < Base
|
21
|
+
extend AutoCorrector
|
22
|
+
|
21
23
|
MSG = 'Use `%<q_type>s` only for strings that contain both ' \
|
22
24
|
'single quotes and double quotes%<extra>s.'
|
23
25
|
DYNAMIC_MSG = ', or for dynamic strings that contain ' \
|
@@ -45,22 +47,18 @@ module RuboCop
|
|
45
47
|
check(node)
|
46
48
|
end
|
47
49
|
|
48
|
-
def autocorrect(node)
|
49
|
-
delimiter =
|
50
|
-
/^%Q[^"]+$|'/.match?(node.source) ? QUOTE : SINGLE_QUOTE
|
51
|
-
lambda do |corrector|
|
52
|
-
corrector.replace(node.loc.begin, delimiter)
|
53
|
-
corrector.replace(node.loc.end, delimiter)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
50
|
private
|
58
51
|
|
59
52
|
def check(node)
|
60
53
|
return unless start_with_percent_q_variant?(node)
|
61
54
|
return if interpolated_quotes?(node) || allowed_percent_q?(node)
|
62
55
|
|
63
|
-
add_offense(node)
|
56
|
+
add_offense(node) do |corrector|
|
57
|
+
delimiter = /^%Q[^"]+$|'/.match?(node.source) ? QUOTE : SINGLE_QUOTE
|
58
|
+
|
59
|
+
corrector.replace(node.loc.begin, delimiter)
|
60
|
+
corrector.replace(node.loc.end, delimiter)
|
61
|
+
end
|
64
62
|
end
|
65
63
|
|
66
64
|
def interpolated_quotes?(node)
|
@@ -21,68 +21,76 @@ module RuboCop
|
|
21
21
|
#
|
22
22
|
# # good
|
23
23
|
# r = /[ab]/
|
24
|
-
class RedundantRegexpCharacterClass <
|
25
|
-
|
26
|
-
include RegexpLiteralHelp
|
24
|
+
class RedundantRegexpCharacterClass < Base
|
25
|
+
extend AutoCorrector
|
27
26
|
|
27
|
+
REQUIRES_ESCAPE_OUTSIDE_CHAR_CLASS_CHARS = '.*+?{}()|$'.chars.freeze
|
28
28
|
MSG_REDUNDANT_CHARACTER_CLASS = 'Redundant single-element character class, ' \
|
29
29
|
'`%<char_class>s` can be replaced with `%<element>s`.'
|
30
30
|
|
31
|
-
PATTERN = /
|
32
|
-
(
|
33
|
-
(?<!\\) # No \-prefix (i.e. not escaped)
|
34
|
-
\[ # Literal [
|
35
|
-
(?!\#\{) # Not (the start of) an interpolation
|
36
|
-
(?: # Either...
|
37
|
-
\\[^b] | # Any escaped character except b (which would change behaviour)
|
38
|
-
[^.*+?{}()|$] | # or one that doesn't require escaping outside the character class
|
39
|
-
\\[upP]\{[^}]+\} # or a unicode code-point or property
|
40
|
-
)
|
41
|
-
(?<!\\) # No \-prefix (i.e. not escaped)
|
42
|
-
\] # Literal ]
|
43
|
-
)
|
44
|
-
/x.freeze
|
45
|
-
|
46
31
|
def on_regexp(node)
|
47
32
|
each_redundant_character_class(node) do |loc|
|
48
|
-
next if whitespace_in_free_space_mode?(node, loc)
|
49
|
-
|
50
33
|
add_offense(
|
51
|
-
|
52
|
-
location: loc,
|
53
|
-
message: format(
|
34
|
+
loc, message: format(
|
54
35
|
MSG_REDUNDANT_CHARACTER_CLASS,
|
55
36
|
char_class: loc.source,
|
56
37
|
element: without_character_class(loc)
|
57
38
|
)
|
58
|
-
)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def autocorrect(node)
|
63
|
-
lambda do |corrector|
|
64
|
-
each_redundant_character_class(node) do |loc|
|
39
|
+
) do |corrector|
|
65
40
|
corrector.replace(loc, without_character_class(loc))
|
66
41
|
end
|
67
42
|
end
|
68
43
|
end
|
69
44
|
|
45
|
+
private
|
46
|
+
|
70
47
|
def each_redundant_character_class(node)
|
71
|
-
|
72
|
-
|
48
|
+
each_single_element_character_class(node) do |char_class|
|
49
|
+
next unless redundant_single_element_character_class?(node, char_class)
|
50
|
+
|
51
|
+
yield node.loc.begin.adjust(begin_pos: 1 + char_class.ts, end_pos: char_class.te)
|
73
52
|
end
|
74
53
|
end
|
75
54
|
|
76
|
-
|
55
|
+
def each_single_element_character_class(node)
|
56
|
+
node.parsed_tree&.each_expression do |expr|
|
57
|
+
next if expr.type != :set || expr.expressions.size != 1
|
58
|
+
next if expr.negative?
|
59
|
+
next if %i[set posixclass nonposixclass].include?(expr.expressions.first.type)
|
60
|
+
|
61
|
+
yield expr
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def redundant_single_element_character_class?(node, char_class)
|
66
|
+
class_elem = char_class.expressions.first.text
|
67
|
+
|
68
|
+
non_redundant =
|
69
|
+
whitespace_in_free_space_mode?(node, class_elem) ||
|
70
|
+
backslash_b?(class_elem) ||
|
71
|
+
requires_escape_outside_char_class?(class_elem)
|
72
|
+
|
73
|
+
!non_redundant
|
74
|
+
end
|
77
75
|
|
78
76
|
def without_character_class(loc)
|
79
77
|
loc.source[1..-2]
|
80
78
|
end
|
81
79
|
|
82
|
-
def whitespace_in_free_space_mode?(node,
|
83
|
-
return false unless
|
80
|
+
def whitespace_in_free_space_mode?(node, elem)
|
81
|
+
return false unless node.extended?
|
82
|
+
|
83
|
+
/\s/.match?(elem)
|
84
|
+
end
|
85
|
+
|
86
|
+
def backslash_b?(elem)
|
87
|
+
# \b's behaviour is different inside and outside of a character class, matching word
|
88
|
+
# boundaries outside but backspace (0x08) when inside.
|
89
|
+
elem == '\b'
|
90
|
+
end
|
84
91
|
|
85
|
-
|
92
|
+
def requires_escape_outside_char_class?(elem)
|
93
|
+
REQUIRES_ESCAPE_OUTSIDE_CHAR_CLASS_CHARS.include?(elem)
|
86
94
|
end
|
87
95
|
end
|
88
96
|
end
|
@@ -32,13 +32,13 @@ module RuboCop
|
|
32
32
|
#
|
33
33
|
# # good
|
34
34
|
# /[+\-]\d/
|
35
|
-
class RedundantRegexpEscape <
|
35
|
+
class RedundantRegexpEscape < Base
|
36
36
|
include RangeHelp
|
37
|
-
|
37
|
+
extend AutoCorrector
|
38
38
|
|
39
39
|
MSG_REDUNDANT_ESCAPE = 'Redundant escape inside regexp literal'
|
40
40
|
|
41
|
-
ALLOWED_ALWAYS_ESCAPES =
|
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
44
|
|
@@ -46,19 +46,9 @@ module RuboCop
|
|
46
46
|
each_escape(node) do |char, index, within_character_class|
|
47
47
|
next if allowed_escape?(node, char, within_character_class)
|
48
48
|
|
49
|
-
|
50
|
-
node,
|
51
|
-
location: escape_range_at_index(node, index),
|
52
|
-
message: MSG_REDUNDANT_ESCAPE
|
53
|
-
)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def autocorrect(node)
|
58
|
-
lambda do |corrector|
|
59
|
-
each_escape(node) do |char, index, within_character_class|
|
60
|
-
next if allowed_escape?(node, char, within_character_class)
|
49
|
+
location = escape_range_at_index(node, index)
|
61
50
|
|
51
|
+
add_offense(location, message: MSG_REDUNDANT_ESCAPE) do |corrector|
|
62
52
|
corrector.remove_leading(escape_range_at_index(node, index), 1)
|
63
53
|
end
|
64
54
|
end
|
@@ -68,9 +58,9 @@ module RuboCop
|
|
68
58
|
|
69
59
|
def allowed_escape?(node, char, within_character_class)
|
70
60
|
# Strictly speaking a few single-letter metachars are currently
|
71
|
-
# unnecessary to "escape", e.g.
|
61
|
+
# unnecessary to "escape", e.g. i, E, F, but enumerating them is
|
72
62
|
# rather difficult, and their behaviour could change over time with
|
73
|
-
# different versions of Ruby so that e.g. /\
|
63
|
+
# different versions of Ruby so that e.g. /\i/ != /i/
|
74
64
|
return true if /[[:alnum:]]/.match?(char)
|
75
65
|
return true if ALLOWED_ALWAYS_ESCAPES.include?(char) || delimiter?(node, char)
|
76
66
|
|
@@ -91,19 +81,13 @@ module RuboCop
|
|
91
81
|
end
|
92
82
|
|
93
83
|
def each_escape(node)
|
94
|
-
|
95
|
-
[
|
96
|
-
|
97
|
-
if
|
98
|
-
|
99
|
-
|
100
|
-
[nil, char_class_depth]
|
101
|
-
elsif previous == '['
|
102
|
-
[current, char_class_depth + 1]
|
103
|
-
elsif current == ']'
|
104
|
-
[current, char_class_depth - 1]
|
84
|
+
node.parsed_tree&.traverse&.reduce(0) do |char_class_depth, (event, expr)|
|
85
|
+
yield(expr.text[1], expr.ts, !char_class_depth.zero?) if expr.type == :escape
|
86
|
+
|
87
|
+
if expr.type == :set
|
88
|
+
char_class_depth + (event == :enter ? 1 : -1)
|
105
89
|
else
|
106
|
-
|
90
|
+
char_class_depth
|
107
91
|
end
|
108
92
|
end
|
109
93
|
end
|
@@ -47,8 +47,9 @@ module RuboCop
|
|
47
47
|
# return x, y
|
48
48
|
# end
|
49
49
|
#
|
50
|
-
class RedundantReturn <
|
50
|
+
class RedundantReturn < Base
|
51
51
|
include RangeHelp
|
52
|
+
extend AutoCorrector
|
52
53
|
|
53
54
|
MSG = 'Redundant `return` detected.'
|
54
55
|
MULTI_RETURN_MSG = 'To return multiple values, use an array.'
|
@@ -58,16 +59,6 @@ module RuboCop
|
|
58
59
|
end
|
59
60
|
alias on_defs on_def
|
60
61
|
|
61
|
-
def autocorrect(node)
|
62
|
-
lambda do |corrector|
|
63
|
-
if node.arguments?
|
64
|
-
correct_with_arguments(node, corrector)
|
65
|
-
else
|
66
|
-
correct_without_arguments(node, corrector)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
62
|
private
|
72
63
|
|
73
64
|
def correct_without_arguments(return_node, corrector)
|
@@ -108,8 +99,8 @@ module RuboCop
|
|
108
99
|
when :return then check_return_node(node)
|
109
100
|
when :case then check_case_node(node)
|
110
101
|
when :if then check_if_node(node)
|
111
|
-
when :rescue
|
112
|
-
|
102
|
+
when :rescue then check_rescue_node(node)
|
103
|
+
when :resbody then check_resbody_node(node)
|
113
104
|
when :ensure then check_ensure_node(node)
|
114
105
|
when :begin, :kwbegin
|
115
106
|
check_begin_node(node)
|
@@ -121,7 +112,13 @@ module RuboCop
|
|
121
112
|
return if cop_config['AllowMultipleReturnValues'] &&
|
122
113
|
node.children.size > 1
|
123
114
|
|
124
|
-
add_offense(node,
|
115
|
+
add_offense(node.loc.keyword, message: message(node)) do |corrector|
|
116
|
+
if node.arguments?
|
117
|
+
correct_with_arguments(node, corrector)
|
118
|
+
else
|
119
|
+
correct_without_arguments(node, corrector)
|
120
|
+
end
|
121
|
+
end
|
125
122
|
end
|
126
123
|
|
127
124
|
def check_case_node(node)
|
@@ -137,9 +134,12 @@ module RuboCop
|
|
137
134
|
end
|
138
135
|
|
139
136
|
def check_rescue_node(node)
|
140
|
-
node.
|
141
|
-
|
142
|
-
|
137
|
+
node.branches.each { |branch| check_branch(branch) }
|
138
|
+
check_branch(node.body) unless node.else?
|
139
|
+
end
|
140
|
+
|
141
|
+
def check_resbody_node(node)
|
142
|
+
check_branch(node.body)
|
143
143
|
end
|
144
144
|
|
145
145
|
def check_ensure_node(node)
|
@@ -41,7 +41,9 @@ module RuboCop
|
|
41
41
|
# self.bar == bar # Resolves name clash with argument of the block.
|
42
42
|
# end
|
43
43
|
# end
|
44
|
-
class RedundantSelf <
|
44
|
+
class RedundantSelf < Base
|
45
|
+
extend AutoCorrector
|
46
|
+
|
45
47
|
MSG = 'Redundant `self` detected.'
|
46
48
|
KERNEL_METHODS = Kernel.methods(false)
|
47
49
|
KEYWORDS = %i[alias and begin break case class def defined? do
|
@@ -57,7 +59,7 @@ module RuboCop
|
|
57
59
|
def initialize(config = nil, options = nil)
|
58
60
|
super
|
59
61
|
@allowed_send_nodes = []
|
60
|
-
@local_variables_scopes = Hash.new { |hash, key| hash[key] = [] }
|
62
|
+
@local_variables_scopes = Hash.new { |hash, key| hash[key] = [] }.compare_by_identity
|
61
63
|
end
|
62
64
|
|
63
65
|
# Assignment of self.x
|
@@ -106,24 +108,20 @@ module RuboCop
|
|
106
108
|
|
107
109
|
return if allowed_send_node?(node)
|
108
110
|
|
109
|
-
add_offense(node)
|
111
|
+
add_offense(node) do |corrector|
|
112
|
+
corrector.remove(node.receiver)
|
113
|
+
corrector.remove(node.loc.dot)
|
114
|
+
end
|
110
115
|
end
|
111
116
|
|
112
117
|
def on_block(node)
|
113
118
|
add_scope(node, @local_variables_scopes[node])
|
114
119
|
end
|
115
120
|
|
116
|
-
def autocorrect(node)
|
117
|
-
lambda do |corrector|
|
118
|
-
corrector.remove(node.receiver)
|
119
|
-
corrector.remove(node.loc.dot)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
121
|
private
|
124
122
|
|
125
123
|
def add_scope(node, local_variables = [])
|
126
|
-
node.
|
124
|
+
node.each_descendant do |child_node|
|
127
125
|
@local_variables_scopes[child_node] = local_variables
|
128
126
|
end
|
129
127
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for places where redundant assignments are made for in place
|
7
|
+
# modification methods.
|
8
|
+
#
|
9
|
+
# This cop is marked as unsafe, because it can produce false positives for
|
10
|
+
# user defined methods having one of the expected names, but not modifying
|
11
|
+
# its receiver in place.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# # bad
|
15
|
+
# args = args.concat(ary)
|
16
|
+
# hash = hash.merge!(other)
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
# args.concat(foo)
|
20
|
+
# args += foo
|
21
|
+
# hash.merge!(other)
|
22
|
+
#
|
23
|
+
# # bad
|
24
|
+
# self.foo = foo.concat(ary)
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# foo.concat(ary)
|
28
|
+
# self.foo += ary
|
29
|
+
#
|
30
|
+
class RedundantSelfAssignment < Base
|
31
|
+
include RangeHelp
|
32
|
+
extend AutoCorrector
|
33
|
+
|
34
|
+
MSG = 'Redundant self assignment detected. '\
|
35
|
+
'Method `%<method_name>s` modifies its receiver in place.'
|
36
|
+
|
37
|
+
METHODS_RETURNING_SELF = %i[
|
38
|
+
append clear collect! compare_by_identity concat delete_if
|
39
|
+
fill initialize_copy insert keep_if map! merge! prepend push
|
40
|
+
rehash replace reverse! rotate! shuffle! sort! sort_by!
|
41
|
+
transform_keys! transform_values! unshift update
|
42
|
+
].to_set.freeze
|
43
|
+
|
44
|
+
ASSIGNMENT_TYPE_TO_RECEIVER_TYPE = {
|
45
|
+
lvasgn: :lvar,
|
46
|
+
ivasgn: :ivar,
|
47
|
+
cvasgn: :cvar,
|
48
|
+
gvasgn: :gvar
|
49
|
+
}.freeze
|
50
|
+
|
51
|
+
def on_lvasgn(node)
|
52
|
+
lhs, rhs = *node
|
53
|
+
receiver, method_name, = *rhs
|
54
|
+
return unless receiver && method_returning_self?(method_name)
|
55
|
+
|
56
|
+
receiver_type = ASSIGNMENT_TYPE_TO_RECEIVER_TYPE[node.type]
|
57
|
+
return unless receiver.type == receiver_type && receiver.children.first == lhs
|
58
|
+
|
59
|
+
message = format(MSG, method_name: method_name)
|
60
|
+
add_offense(node.loc.operator, message: message) do |corrector|
|
61
|
+
corrector.replace(node, rhs.source)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
alias on_ivasgn on_lvasgn
|
65
|
+
alias on_cvasgn on_lvasgn
|
66
|
+
alias on_gvasgn on_lvasgn
|
67
|
+
|
68
|
+
def on_send(node)
|
69
|
+
# TODO: replace with #end_with? after supporting only ruby >= 2.7
|
70
|
+
return unless node.method_name.match?(/=$/)
|
71
|
+
return unless redundant_assignment?(node)
|
72
|
+
|
73
|
+
message = format(MSG, method_name: node.first_argument.method_name)
|
74
|
+
add_offense(node.loc.operator, message: message) do |corrector|
|
75
|
+
corrector.remove(correction_range(node))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def method_returning_self?(method_name)
|
82
|
+
METHODS_RETURNING_SELF.include?(method_name)
|
83
|
+
end
|
84
|
+
|
85
|
+
def_node_matcher :redundant_self_assignment?, <<~PATTERN
|
86
|
+
(send
|
87
|
+
(self) _
|
88
|
+
(send
|
89
|
+
(send
|
90
|
+
{(self) nil?} %1) #method_returning_self?
|
91
|
+
...))
|
92
|
+
PATTERN
|
93
|
+
|
94
|
+
def_node_matcher :redundant_nonself_assignment?, <<~PATTERN
|
95
|
+
(send
|
96
|
+
%1 _
|
97
|
+
(send
|
98
|
+
(send
|
99
|
+
%1 %2) #method_returning_self?
|
100
|
+
...))
|
101
|
+
PATTERN
|
102
|
+
|
103
|
+
def redundant_assignment?(node)
|
104
|
+
receiver_name = node.method_name.to_s[0...-1].to_sym
|
105
|
+
|
106
|
+
redundant_self_assignment?(node, receiver_name) ||
|
107
|
+
redundant_nonself_assignment?(node, node.receiver, receiver_name)
|
108
|
+
end
|
109
|
+
|
110
|
+
def correction_range(node)
|
111
|
+
range_between(node.source_range.begin_pos, node.first_argument.source_range.begin_pos)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|