rubocop 0.86.0 → 0.89.1
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 +1 -1
- data/bin/rubocop-profile +32 -0
- data/config/default.yml +198 -25
- data/lib/rubocop.rb +30 -5
- data/lib/rubocop/cli.rb +2 -4
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +42 -7
- data/lib/rubocop/cli/command/base.rb +1 -0
- data/lib/rubocop/cli/command/execute_runner.rb +1 -1
- data/lib/rubocop/cli/command/show_cops.rb +3 -3
- data/lib/rubocop/cli/command/version.rb +2 -2
- data/lib/rubocop/comment_config.rb +5 -7
- data/lib/rubocop/config.rb +20 -3
- data/lib/rubocop/config_loader.rb +41 -69
- data/lib/rubocop/config_loader_resolver.rb +3 -3
- data/lib/rubocop/config_obsoletion.rb +6 -2
- data/lib/rubocop/config_store.rb +4 -0
- data/lib/rubocop/config_validator.rb +2 -4
- data/lib/rubocop/cop/autocorrect_logic.rb +14 -24
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/base.rb +407 -0
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +10 -20
- data/lib/rubocop/cop/commissioner.rb +47 -50
- data/lib/rubocop/cop/cop.rb +85 -236
- data/lib/rubocop/cop/corrector.rb +38 -115
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +26 -0
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/punctuation_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +15 -18
- data/lib/rubocop/cop/force.rb +1 -0
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +38 -12
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
- data/lib/rubocop/cop/generator.rb +1 -1
- data/lib/rubocop/cop/generator/configuration_injector.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +4 -12
- data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +11 -14
- data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +8 -8
- data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +10 -7
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +7 -8
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -2
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/case_indentation.rb +18 -19
- data/lib/rubocop/cop/layout/class_structure.rb +5 -44
- data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines.rb +0 -2
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -8
- data/lib/rubocop/cop/layout/end_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/extra_spacing.rb +22 -36
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -0
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/indentation_style.rb +0 -2
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +16 -6
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +0 -2
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +22 -27
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +33 -66
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +3 -2
- data/lib/rubocop/cop/legacy/corrections_proxy.rb +49 -0
- data/lib/rubocop/cop/legacy/corrector.rb +29 -0
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +7 -4
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +15 -10
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +11 -13
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
- data/lib/rubocop/cop/lint/big_decimal_new.rb +10 -10
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +50 -0
- data/lib/rubocop/cop/lint/boolean_symbol.rb +16 -11
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +1 -1
- data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +7 -1
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +9 -10
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +21 -17
- data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +8 -2
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_elsif_condition.rb +39 -0
- data/lib/rubocop/cop/lint/duplicate_hash_key.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +9 -6
- data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +60 -0
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
- data/lib/rubocop/cop/lint/else_layout.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +67 -0
- data/lib/rubocop/cop/lint/empty_ensure.rb +5 -5
- data/lib/rubocop/cop/lint/empty_expression.rb +2 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +5 -6
- data/lib/rubocop/cop/lint/empty_when.rb +2 -2
- data/lib/rubocop/cop/lint/ensure_return.rb +27 -29
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +11 -10
- data/lib/rubocop/cop/lint/flip_flop.rb +1 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +93 -0
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +5 -4
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +13 -14
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +5 -4
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +8 -8
- data/lib/rubocop/cop/lint/inherit_exception.rb +12 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +21 -5
- data/lib/rubocop/cop/lint/literal_as_condition.rb +14 -2
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -7
- data/lib/rubocop/cop/lint/loop.rb +23 -2
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +6 -5
- data/lib/rubocop/cop/lint/missing_super.rb +99 -0
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/multiple_comparison.rb +6 -9
- data/lib/rubocop/cop/lint/nested_method_definition.rb +15 -21
- data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +84 -13
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +2 -2
- data/lib/rubocop/cop/lint/number_conversion.rb +6 -9
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +11 -13
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +90 -0
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +12 -13
- data/lib/rubocop/cop/lint/percent_string_array.rb +13 -12
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +13 -12
- data/lib/rubocop/cop/lint/raise_exception.rb +12 -10
- data/lib/rubocop/cop/lint/rand_one.rb +3 -3
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +41 -40
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +7 -11
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -7
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +15 -11
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +6 -13
- data/lib/rubocop/cop/lint/redundant_with_index.rb +11 -14
- data/lib/rubocop/cop/lint/redundant_with_object.rb +11 -14
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +4 -6
- data/lib/rubocop/cop/lint/require_parentheses.rb +2 -2
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +8 -8
- data/lib/rubocop/cop/lint/return_in_void_context.rb +2 -4
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -6
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +14 -10
- data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +10 -2
- data/lib/rubocop/cop/lint/script_permission.rb +10 -7
- data/lib/rubocop/cop/lint/self_assignment.rb +78 -0
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +5 -11
- data/lib/rubocop/cop/lint/shadowed_argument.rb +3 -3
- data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -2
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +3 -3
- data/lib/rubocop/cop/lint/struct_new_override.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception.rb +4 -7
- data/lib/rubocop/cop/lint/syntax.rb +11 -26
- data/lib/rubocop/cop/lint/to_json.rb +4 -6
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +34 -0
- data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +4 -4
- data/lib/rubocop/cop/lint/unified_integer.rb +4 -6
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_loop.rb +174 -0
- data/lib/rubocop/cop/lint/unused_block_argument.rb +8 -3
- data/lib/rubocop/cop/lint/unused_method_argument.rb +9 -4
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -1
- data/lib/rubocop/cop/lint/uri_regexp.rb +11 -47
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +26 -16
- data/lib/rubocop/cop/lint/useless_assignment.rb +4 -4
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +6 -15
- data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -6
- data/lib/rubocop/cop/lint/void.rb +3 -7
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/block_length.rb +24 -2
- data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
- data/lib/rubocop/cop/metrics/class_length.rb +26 -3
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +2 -1
- data/lib/rubocop/cop/metrics/method_length.rb +25 -2
- data/lib/rubocop/cop/metrics/module_length.rb +26 -3
- data/lib/rubocop/cop/metrics/parameter_lists.rb +2 -6
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +7 -8
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +48 -5
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +157 -0
- data/lib/rubocop/cop/metrics/utils/repeated_csend_discount.rb +37 -0
- data/lib/rubocop/cop/migration/department_name.rb +14 -16
- data/lib/rubocop/cop/mixin/alignment.rb +2 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +19 -0
- data/lib/rubocop/cop/mixin/array_min_size.rb +1 -1
- data/lib/rubocop/cop/mixin/auto_corrector.rb +12 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
- data/lib/rubocop/cop/mixin/code_length.rb +26 -5
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -1
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +3 -1
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +5 -11
- data/lib/rubocop/cop/mixin/line_length_help.rb +1 -3
- data/lib/rubocop/cop/mixin/method_complexity.rb +10 -2
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -2
- data/lib/rubocop/cop/mixin/nil_methods.rb +3 -5
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +6 -1
- data/lib/rubocop/cop/mixin/percent_array.rb +2 -6
- data/lib/rubocop/cop/mixin/range_help.rb +18 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +39 -10
- data/lib/rubocop/cop/mixin/surrounding_space.rb +4 -24
- data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -4
- data/lib/rubocop/cop/mixin/uncommunicative_name.rb +10 -15
- data/lib/rubocop/cop/mixin/unused_argument.rb +4 -6
- data/lib/rubocop/cop/mixin/visibility_help.rb +50 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +4 -2
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +29 -6
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +3 -3
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +2 -2
- data/lib/rubocop/cop/naming/constant_name.rb +2 -2
- data/lib/rubocop/cop/naming/file_name.rb +3 -3
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +2 -2
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +2 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +2 -2
- data/lib/rubocop/cop/naming/method_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_parameter_name.rb +2 -2
- data/lib/rubocop/cop/naming/predicate_name.rb +6 -10
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -11
- data/lib/rubocop/cop/naming/variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/variable_number.rb +1 -1
- data/lib/rubocop/cop/offense.rb +16 -2
- data/lib/rubocop/cop/registry.rb +3 -3
- data/lib/rubocop/cop/security/eval.rb +2 -2
- data/lib/rubocop/cop/security/json_load.rb +6 -8
- data/lib/rubocop/cop/security/marshal_load.rb +2 -4
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/security/yaml_load.rb +6 -6
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +16 -9
- data/lib/rubocop/cop/style/accessor_grouping.rb +149 -0
- data/lib/rubocop/cop/style/alias.rb +41 -36
- data/lib/rubocop/cop/style/and_or.rb +9 -11
- data/lib/rubocop/cop/style/array_coercion.rb +63 -0
- data/lib/rubocop/cop/style/array_join.rb +6 -8
- data/lib/rubocop/cop/style/ascii_comments.rb +4 -4
- data/lib/rubocop/cop/style/attr.rb +11 -9
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +5 -7
- data/lib/rubocop/cop/style/bare_percent_literals.rb +10 -12
- data/lib/rubocop/cop/style/begin_block.rb +2 -2
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +141 -0
- data/lib/rubocop/cop/style/block_comments.rb +14 -18
- data/lib/rubocop/cop/style/block_delimiters.rb +23 -23
- data/lib/rubocop/cop/style/case_equality.rb +22 -3
- data/lib/rubocop/cop/style/case_like_if.rb +220 -0
- data/lib/rubocop/cop/style/class_and_module_children.rb +14 -11
- data/lib/rubocop/cop/style/class_check.rb +7 -9
- data/lib/rubocop/cop/style/class_methods.rb +7 -11
- data/lib/rubocop/cop/style/class_vars.rb +24 -7
- data/lib/rubocop/cop/style/collection_methods.rb +11 -17
- data/lib/rubocop/cop/style/colon_method_call.rb +8 -9
- data/lib/rubocop/cop/style/colon_method_definition.rb +6 -6
- data/lib/rubocop/cop/style/command_literal.rb +23 -24
- data/lib/rubocop/cop/style/comment_annotation.rb +15 -15
- data/lib/rubocop/cop/style/commented_keyword.rb +6 -3
- data/lib/rubocop/cop/style/conditional_assignment.rb +13 -4
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -2
- data/lib/rubocop/cop/style/copyright.rb +12 -12
- data/lib/rubocop/cop/style/date_time.rb +2 -2
- data/lib/rubocop/cop/style/def_with_parentheses.rb +8 -10
- data/lib/rubocop/cop/style/dir.rb +9 -12
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +7 -9
- data/lib/rubocop/cop/style/documentation.rb +6 -8
- data/lib/rubocop/cop/style/documentation_method.rb +1 -1
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +12 -15
- data/lib/rubocop/cop/style/double_negation.rb +2 -2
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +5 -8
- data/lib/rubocop/cop/style/each_with_object.rb +16 -19
- data/lib/rubocop/cop/style/empty_case_condition.rb +19 -20
- data/lib/rubocop/cop/style/empty_else.rb +17 -19
- data/lib/rubocop/cop/style/empty_literal.rb +20 -21
- data/lib/rubocop/cop/style/empty_method.rb +10 -13
- data/lib/rubocop/cop/style/encoding.rb +5 -9
- data/lib/rubocop/cop/style/end_block.rb +4 -6
- data/lib/rubocop/cop/style/eval_with_location.rb +9 -7
- data/lib/rubocop/cop/style/even_odd.rb +7 -11
- data/lib/rubocop/cop/style/expand_path_arguments.rb +23 -22
- data/lib/rubocop/cop/style/explicit_block_argument.rb +102 -0
- data/lib/rubocop/cop/style/exponential_notation.rb +7 -9
- data/lib/rubocop/cop/style/float_division.rb +8 -11
- data/lib/rubocop/cop/style/for.rb +11 -15
- data/lib/rubocop/cop/style/format_string.rb +21 -19
- data/lib/rubocop/cop/style/format_string_token.rb +10 -12
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +19 -41
- data/lib/rubocop/cop/style/global_std_stream.rb +65 -0
- data/lib/rubocop/cop/style/global_vars.rb +2 -2
- data/lib/rubocop/cop/style/guard_clause.rb +5 -6
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +69 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +5 -8
- data/lib/rubocop/cop/style/hash_like_case.rb +76 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +4 -3
- data/lib/rubocop/cop/style/hash_transform_keys.rb +3 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -1
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +2 -2
- data/lib/rubocop/cop/style/if_inside_else.rb +3 -3
- data/lib/rubocop/cop/style/if_unless_modifier.rb +18 -40
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +11 -3
- data/lib/rubocop/cop/style/if_with_semicolon.rb +3 -6
- data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -1
- data/lib/rubocop/cop/style/infinite_loop.rb +24 -24
- data/lib/rubocop/cop/style/inline_comment.rb +3 -3
- data/lib/rubocop/cop/style/inverse_methods.rb +22 -32
- data/lib/rubocop/cop/style/lambda.rb +7 -12
- data/lib/rubocop/cop/style/lambda_call.rb +14 -13
- data/lib/rubocop/cop/style/line_end_concatenation.rb +19 -16
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +16 -11
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +4 -8
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -7
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -2
- data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -16
- data/lib/rubocop/cop/style/min_max.rb +8 -12
- data/lib/rubocop/cop/style/missing_else.rb +11 -21
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +10 -3
- data/lib/rubocop/cop/style/mixin_grouping.rb +24 -27
- data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
- data/lib/rubocop/cop/style/module_function.rb +10 -13
- data/lib/rubocop/cop/style/multiline_block_chain.rb +10 -1
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +3 -10
- data/lib/rubocop/cop/style/multiline_if_then.rb +4 -10
- data/lib/rubocop/cop/style/multiline_memoization.rb +14 -12
- data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -2
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +4 -6
- data/lib/rubocop/cop/style/multiline_when_then.rb +7 -9
- data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +27 -24
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +5 -6
- data/lib/rubocop/cop/style/numeric_predicate.rb +7 -4
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +42 -0
- data/lib/rubocop/cop/style/parallel_assignment.rb +5 -5
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +1 -1
- data/lib/rubocop/cop/style/random_with_offset.rb +5 -10
- data/lib/rubocop/cop/style/redundant_assignment.rb +117 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +15 -3
- data/lib/rubocop/cop/style/redundant_exception.rb +18 -10
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +26 -7
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +50 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +7 -1
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +2 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +11 -11
- data/lib/rubocop/cop/style/redundant_sort.rb +26 -12
- data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +4 -4
- data/lib/rubocop/cop/style/signal_exception.rb +3 -1
- data/lib/rubocop/cop/style/single_argument_dig.rb +54 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +3 -2
- data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +92 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +3 -3
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -2
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +9 -32
- data/lib/rubocop/cop/style/trivial_accessors.rb +8 -7
- data/lib/rubocop/cop/style/zero_length_predicate.rb +12 -8
- data/lib/rubocop/cop/team.rb +98 -82
- data/lib/rubocop/cop/tokens_util.rb +84 -0
- data/lib/rubocop/cop/util.rb +3 -13
- data/lib/rubocop/cop/utils/format_string.rb +1 -2
- data/lib/rubocop/cop/variable_force.rb +0 -2
- data/lib/rubocop/cop/variable_force/branch.rb +1 -0
- data/lib/rubocop/cop/variable_force/variable.rb +7 -5
- data/lib/rubocop/cops_documentation_generator.rb +282 -0
- data/lib/rubocop/error.rb +1 -0
- data/lib/rubocop/file_finder.rb +12 -12
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -2
- data/lib/rubocop/formatter/formatter_set.rb +1 -0
- data/lib/rubocop/formatter/junit_formatter.rb +1 -1
- data/lib/rubocop/name_similarity.rb +1 -3
- data/lib/rubocop/options.rb +18 -11
- data/lib/rubocop/path_util.rb +17 -17
- data/lib/rubocop/rake_task.rb +7 -9
- data/lib/rubocop/result_cache.rb +12 -8
- data/lib/rubocop/rspec/cop_helper.rb +4 -4
- data/lib/rubocop/rspec/expect_offense.rb +53 -22
- data/lib/rubocop/rspec/shared_contexts.rb +16 -17
- data/lib/rubocop/runner.rb +35 -34
- data/lib/rubocop/target_finder.rb +13 -10
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +2 -2
- metadata +40 -11
- data/lib/rubocop/cop/lint/useless_comparison.rb +0 -28
- data/lib/rubocop/cop/mixin/classish_length.rb +0 -37
- data/lib/rubocop/cop/mixin/parser_diagnostic.rb +0 -37
- data/lib/rubocop/cop/mixin/too_many_lines.rb +0 -35
- data/lib/rubocop/cop/style/method_missing_super.rb +0 -34
@@ -30,11 +30,13 @@ module RuboCop
|
|
30
30
|
#
|
31
31
|
# puts 'hello, world'
|
32
32
|
#
|
33
|
-
class ScriptPermission <
|
33
|
+
class ScriptPermission < Base
|
34
|
+
extend AutoCorrector
|
35
|
+
|
34
36
|
MSG = "Script file %<file>s doesn't have execute permission."
|
35
37
|
SHEBANG = '#!'
|
36
38
|
|
37
|
-
def
|
39
|
+
def on_new_investigation
|
38
40
|
return if @options.key?(:stdin)
|
39
41
|
return if Platform.windows?
|
40
42
|
return unless processed_source.start_with?(SHEBANG)
|
@@ -42,17 +44,18 @@ module RuboCop
|
|
42
44
|
|
43
45
|
comment = processed_source.comments[0]
|
44
46
|
message = format_message_from(processed_source)
|
45
|
-
add_offense(comment, message: message)
|
46
|
-
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
FileUtils.chmod('+x', node.loc.expression.source_buffer.name)
|
48
|
+
add_offense(comment, message: message) do
|
49
|
+
autocorrect(comment) if autocorrect_requested?
|
51
50
|
end
|
52
51
|
end
|
53
52
|
|
54
53
|
private
|
55
54
|
|
55
|
+
def autocorrect(comment)
|
56
|
+
FileUtils.chmod('+x', comment.loc.expression.source_buffer.name)
|
57
|
+
end
|
58
|
+
|
56
59
|
def executable?(processed_source)
|
57
60
|
# Returns true if stat is executable or if the operating system
|
58
61
|
# doesn't distinguish executable files from nonexecutable files.
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks for self-assignments.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# foo = foo
|
11
|
+
# foo, bar = foo, bar
|
12
|
+
# Foo = Foo
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# foo = bar
|
16
|
+
# foo, bar = bar, foo
|
17
|
+
# Foo = Bar
|
18
|
+
#
|
19
|
+
class SelfAssignment < Base
|
20
|
+
MSG = 'Self-assignment detected.'
|
21
|
+
|
22
|
+
ASSIGNMENT_TYPE_TO_RHS_TYPE = {
|
23
|
+
lvasgn: :lvar,
|
24
|
+
ivasgn: :ivar,
|
25
|
+
cvasgn: :cvar,
|
26
|
+
gvasgn: :gvar
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
def on_lvasgn(node)
|
30
|
+
lhs, rhs = *node
|
31
|
+
return unless rhs
|
32
|
+
|
33
|
+
rhs_type = ASSIGNMENT_TYPE_TO_RHS_TYPE[node.type]
|
34
|
+
|
35
|
+
add_offense(node) if rhs.type == rhs_type && rhs.source == lhs.to_s
|
36
|
+
end
|
37
|
+
alias on_ivasgn on_lvasgn
|
38
|
+
alias on_cvasgn on_lvasgn
|
39
|
+
alias on_gvasgn on_lvasgn
|
40
|
+
|
41
|
+
def on_casgn(node)
|
42
|
+
lhs_scope, lhs_name, rhs = *node
|
43
|
+
return unless rhs&.const_type?
|
44
|
+
|
45
|
+
rhs_scope, rhs_name = *rhs
|
46
|
+
add_offense(node) if lhs_scope == rhs_scope && lhs_name == rhs_name
|
47
|
+
end
|
48
|
+
|
49
|
+
def on_masgn(node)
|
50
|
+
add_offense(node) if multiple_self_assignment?(node)
|
51
|
+
end
|
52
|
+
|
53
|
+
def on_or_asgn(node)
|
54
|
+
lhs, rhs = *node
|
55
|
+
add_offense(node) if rhs_matches_lhs?(rhs, lhs)
|
56
|
+
end
|
57
|
+
alias on_and_asgn on_or_asgn
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def multiple_self_assignment?(node)
|
62
|
+
lhs, rhs = *node
|
63
|
+
return false unless rhs.array_type?
|
64
|
+
return false unless lhs.children.size == rhs.children.size
|
65
|
+
|
66
|
+
lhs.children.zip(rhs.children).all? do |lhs_item, rhs_item|
|
67
|
+
rhs_matches_lhs?(rhs_item, lhs_item)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def rhs_matches_lhs?(rhs, lhs)
|
72
|
+
rhs.type == ASSIGNMENT_TYPE_TO_RHS_TYPE[lhs.type] &&
|
73
|
+
rhs.children.first == lhs.children.first
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -34,8 +34,9 @@ module RuboCop
|
|
34
34
|
# Foo.prepend Bar
|
35
35
|
# Foo.extend Bar
|
36
36
|
#
|
37
|
-
class SendWithMixinArgument <
|
37
|
+
class SendWithMixinArgument < Base
|
38
38
|
include RangeHelp
|
39
|
+
extend AutoCorrector
|
39
40
|
|
40
41
|
MSG = 'Use `%<method>s %<module_name>s` instead of `%<bad_method>s`.'
|
41
42
|
MIXIN_METHODS = %i[include prepend extend].freeze
|
@@ -53,16 +54,9 @@ module RuboCop
|
|
53
54
|
method, module_name.source, bad_location(node).source
|
54
55
|
)
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
def autocorrect(node)
|
61
|
-
send_with_mixin_argument?(node) do |method, module_name|
|
62
|
-
lambda do |corrector|
|
63
|
-
corrector.replace(
|
64
|
-
bad_location(node), "#{method} #{module_name.source}"
|
65
|
-
)
|
57
|
+
bad_location = bad_location(node)
|
58
|
+
add_offense(bad_location, message: message) do |corrector|
|
59
|
+
corrector.replace(bad_location, "#{method} #{module_name.source}")
|
66
60
|
end
|
67
61
|
end
|
68
62
|
end
|
@@ -63,14 +63,14 @@ module RuboCop
|
|
63
63
|
# bar
|
64
64
|
# end
|
65
65
|
#
|
66
|
-
class ShadowedArgument <
|
66
|
+
class ShadowedArgument < Base
|
67
67
|
MSG = 'Argument `%<argument>s` was shadowed by a local variable ' \
|
68
68
|
'before it was used.'
|
69
69
|
|
70
70
|
def_node_search :uses_var?, '(lvar %)'
|
71
71
|
|
72
|
-
def
|
73
|
-
|
72
|
+
def self.joining_forces
|
73
|
+
VariableForce
|
74
74
|
end
|
75
75
|
|
76
76
|
def after_leaving_scope(scope, _variable_table)
|
@@ -43,7 +43,7 @@ module RuboCop
|
|
43
43
|
# handle_standard_error
|
44
44
|
# end
|
45
45
|
#
|
46
|
-
class ShadowedException <
|
46
|
+
class ShadowedException < Base
|
47
47
|
include RescueNode
|
48
48
|
include RangeHelp
|
49
49
|
|
@@ -62,7 +62,7 @@ module RuboCop
|
|
62
62
|
return if !rescue_group_rescues_multiple_levels &&
|
63
63
|
sorted?(rescued_groups)
|
64
64
|
|
65
|
-
add_offense(
|
65
|
+
add_offense(offense_range(rescues))
|
66
66
|
end
|
67
67
|
|
68
68
|
private
|
@@ -31,11 +31,11 @@ module RuboCop
|
|
31
31
|
# do_something(bar)
|
32
32
|
# end
|
33
33
|
# end
|
34
|
-
class ShadowingOuterLocalVariable <
|
34
|
+
class ShadowingOuterLocalVariable < Base
|
35
35
|
MSG = 'Shadowing outer local variable - `%<variable>s`.'
|
36
36
|
|
37
|
-
def
|
38
|
-
|
37
|
+
def self.joining_forces
|
38
|
+
VariableForce
|
39
39
|
end
|
40
40
|
|
41
41
|
def before_declaring_variable(variable, variable_table)
|
@@ -21,7 +21,7 @@ module RuboCop
|
|
21
21
|
# g.clone #=> #<struct Good id=1, name="foo">
|
22
22
|
# g.count #=> 2
|
23
23
|
#
|
24
|
-
class StructNewOverride <
|
24
|
+
class StructNewOverride < Base
|
25
25
|
MSG = '`%<member_name>s` member overrides `Struct#%<method_name>s`' \
|
26
26
|
' and it may be unexpected.'
|
27
27
|
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
64
64
|
# rescue
|
65
65
|
# # do nothing
|
66
66
|
# end
|
67
|
-
class SuppressedException <
|
67
|
+
class SuppressedException < Base
|
68
68
|
MSG = 'Do not suppress exceptions.'
|
69
69
|
|
70
70
|
def on_resbody(node)
|
@@ -77,13 +77,10 @@ module RuboCop
|
|
77
77
|
private
|
78
78
|
|
79
79
|
def comment_between_rescue_and_end?(node)
|
80
|
-
|
81
|
-
|
82
|
-
end_line = ancestor.loc.end.line
|
83
|
-
break
|
84
|
-
end
|
85
|
-
return false unless end_line
|
80
|
+
ancestor = node.each_ancestor(:kwbegin, :def, :defs, :block).first
|
81
|
+
return unless ancestor
|
86
82
|
|
83
|
+
end_line = ancestor.loc.end.line
|
87
84
|
processed_source[node.first_line...end_line].any? { |line| comment_line?(line) }
|
88
85
|
end
|
89
86
|
end
|
@@ -3,49 +3,34 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# This
|
7
|
-
# provides methods to repack Parser's diagnostics/errors
|
6
|
+
# This cop repacks Parser's diagnostics/errors
|
8
7
|
# into RuboCop's offenses.
|
9
|
-
class Syntax <
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
ERROR_SOURCE_RANGE = PseudoSourceRange.new(1, 0, '', 0, 1).freeze
|
14
|
-
|
15
|
-
def self.offenses_from_processed_source(processed_source,
|
16
|
-
config, options)
|
17
|
-
cop = new(config, options)
|
18
|
-
|
19
|
-
cop.add_offense_from_error(processed_source.parser_error) if processed_source.parser_error
|
20
|
-
|
8
|
+
class Syntax < Base
|
9
|
+
def on_other_file
|
10
|
+
add_offense_from_error(processed_source.parser_error) if processed_source.parser_error
|
21
11
|
processed_source.diagnostics.each do |diagnostic|
|
22
|
-
|
23
|
-
|
12
|
+
add_offense_from_diagnostic(diagnostic,
|
13
|
+
processed_source.ruby_version)
|
24
14
|
end
|
25
|
-
|
26
|
-
cop.offenses
|
15
|
+
super
|
27
16
|
end
|
28
17
|
|
18
|
+
private
|
19
|
+
|
29
20
|
def add_offense_from_diagnostic(diagnostic, ruby_version)
|
30
21
|
message =
|
31
22
|
"#{diagnostic.message}\n(Using Ruby #{ruby_version} parser; " \
|
32
23
|
'configure using `TargetRubyVersion` parameter, under `AllCops`)'
|
33
|
-
add_offense(
|
34
|
-
location: diagnostic.location,
|
24
|
+
add_offense(diagnostic.location,
|
35
25
|
message: message,
|
36
26
|
severity: diagnostic.level)
|
37
27
|
end
|
38
28
|
|
39
29
|
def add_offense_from_error(error)
|
40
30
|
message = beautify_message(error.message)
|
41
|
-
|
42
|
-
location: ERROR_SOURCE_RANGE,
|
43
|
-
message: message,
|
44
|
-
severity: :fatal)
|
31
|
+
add_global_offense(message, severity: :fatal)
|
45
32
|
end
|
46
33
|
|
47
|
-
private
|
48
|
-
|
49
34
|
def beautify_message(message)
|
50
35
|
message = message.capitalize
|
51
36
|
message << '.' unless message.end_with?('.')
|
@@ -17,18 +17,16 @@ module RuboCop
|
|
17
17
|
# def to_json(*_args)
|
18
18
|
# end
|
19
19
|
#
|
20
|
-
class ToJSON <
|
20
|
+
class ToJSON < Base
|
21
|
+
extend AutoCorrector
|
22
|
+
|
21
23
|
MSG = ' `#to_json` requires an optional argument to be parsable ' \
|
22
24
|
'via JSON.generate(obj).'
|
23
25
|
|
24
26
|
def on_def(node)
|
25
27
|
return unless node.method?(:to_json) && node.arguments.empty?
|
26
28
|
|
27
|
-
add_offense(node)
|
28
|
-
end
|
29
|
-
|
30
|
-
def autocorrect(node)
|
31
|
-
lambda do |corrector|
|
29
|
+
add_offense(node) do |corrector|
|
32
30
|
# The following used `*_args` because `to_json(*args)` has
|
33
31
|
# an offense of `Lint/UnusedMethodArgument` cop if `*args`
|
34
32
|
# is not used.
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks for top level return with arguments. If there is a
|
7
|
+
# top-level return statement with an argument, then the argument is
|
8
|
+
# always ignored. This is detected automatically since Ruby 2.7.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
#
|
12
|
+
# # Detected since Ruby 2.7
|
13
|
+
# return 1 # 1 is always ignored.
|
14
|
+
class TopLevelReturnWithArgument < Cop
|
15
|
+
# This cop works by validating the ancestors of the return node. A
|
16
|
+
# top-level return node's ancestors should not be of block, def, or
|
17
|
+
# defs type.
|
18
|
+
|
19
|
+
MSG = 'Top level return with argument detected.'
|
20
|
+
|
21
|
+
def on_return(return_node)
|
22
|
+
add_offense(return_node) if return_node.arguments? && ancestors_valid?(return_node)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def ancestors_valid?(return_node)
|
28
|
+
prohibited_ancestors = return_node.each_ancestor(:block, :def, :defs)
|
29
|
+
prohibited_ancestors.none?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -40,11 +40,11 @@ module RuboCop
|
|
40
40
|
# {_id: _id, profit: revenue - cost}
|
41
41
|
# end
|
42
42
|
#
|
43
|
-
class UnderscorePrefixedVariableName <
|
43
|
+
class UnderscorePrefixedVariableName < Base
|
44
44
|
MSG = 'Do not use prefix `_` for a variable that is used.'
|
45
45
|
|
46
|
-
def
|
47
|
-
|
46
|
+
def self.joining_forces
|
47
|
+
VariableForce
|
48
48
|
end
|
49
49
|
|
50
50
|
def after_leaving_scope(scope, _variable_table)
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
66
66
|
node.loc.name
|
67
67
|
end
|
68
68
|
|
69
|
-
add_offense(
|
69
|
+
add_offense(location)
|
70
70
|
end
|
71
71
|
|
72
72
|
private
|
@@ -17,7 +17,9 @@ module RuboCop
|
|
17
17
|
# # good
|
18
18
|
#
|
19
19
|
# 1.is_a?(Integer)
|
20
|
-
class UnifiedInteger <
|
20
|
+
class UnifiedInteger < Base
|
21
|
+
extend AutoCorrector
|
22
|
+
|
21
23
|
MSG = 'Use `Integer` instead of `%<klass>s`.'
|
22
24
|
|
23
25
|
def_node_matcher :fixnum_or_bignum_const, <<~PATTERN
|
@@ -29,11 +31,7 @@ module RuboCop
|
|
29
31
|
|
30
32
|
return unless klass
|
31
33
|
|
32
|
-
add_offense(node, message: format(MSG, klass: klass))
|
33
|
-
end
|
34
|
-
|
35
|
-
def autocorrect(node)
|
36
|
-
lambda do |corrector|
|
34
|
+
add_offense(node, message: format(MSG, klass: klass)) do |corrector|
|
37
35
|
corrector.replace(node.loc.name, 'Integer')
|
38
36
|
end
|
39
37
|
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks for loops that will have at most one iteration.
|
7
|
+
#
|
8
|
+
# A loop that can never reach the second iteration is a possible error in the code.
|
9
|
+
# In rare cases where only one iteration (or at most one iteration) is intended behavior,
|
10
|
+
# the code should be refactored to use `if` conditionals.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# # bad
|
14
|
+
# while node
|
15
|
+
# do_something(node)
|
16
|
+
# node = node.parent
|
17
|
+
# break
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# while node
|
22
|
+
# do_something(node)
|
23
|
+
# node = node.parent
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # bad
|
27
|
+
# def verify_list(head)
|
28
|
+
# item = head
|
29
|
+
# begin
|
30
|
+
# if verify(item)
|
31
|
+
# return true
|
32
|
+
# else
|
33
|
+
# return false
|
34
|
+
# end
|
35
|
+
# end while(item)
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # good
|
39
|
+
# def verify_list(head)
|
40
|
+
# item = head
|
41
|
+
# begin
|
42
|
+
# if verify(item)
|
43
|
+
# item = item.next
|
44
|
+
# else
|
45
|
+
# return false
|
46
|
+
# end
|
47
|
+
# end while(item)
|
48
|
+
#
|
49
|
+
# true
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# # bad
|
53
|
+
# def find_something(items)
|
54
|
+
# items.each do |item|
|
55
|
+
# if something?(item)
|
56
|
+
# return item
|
57
|
+
# else
|
58
|
+
# raise NotFoundError
|
59
|
+
# end
|
60
|
+
# end
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# # good
|
64
|
+
# def find_something(items)
|
65
|
+
# items.each do |item|
|
66
|
+
# if something?(item)
|
67
|
+
# return item
|
68
|
+
# end
|
69
|
+
# end
|
70
|
+
# raise NotFoundError
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
class UnreachableLoop < Base
|
74
|
+
MSG = 'This loop will have at most one iteration.'
|
75
|
+
|
76
|
+
def on_while(node)
|
77
|
+
check(node)
|
78
|
+
end
|
79
|
+
alias on_until on_while
|
80
|
+
alias on_while_post on_while
|
81
|
+
alias on_until_post on_while
|
82
|
+
alias on_for on_while
|
83
|
+
|
84
|
+
def on_block(node)
|
85
|
+
check(node) if loop_method?(node)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def loop_method?(node)
|
91
|
+
return false unless node.block_type?
|
92
|
+
|
93
|
+
send_node = node.send_node
|
94
|
+
send_node.enumerable_method? || send_node.enumerator_method? || send_node.method?(:loop)
|
95
|
+
end
|
96
|
+
|
97
|
+
def check(node)
|
98
|
+
statements = statements(node)
|
99
|
+
break_statement = statements.find { |statement| break_statement?(statement) }
|
100
|
+
return unless break_statement
|
101
|
+
|
102
|
+
add_offense(node) unless preceded_by_continue_statement?(break_statement)
|
103
|
+
end
|
104
|
+
|
105
|
+
def statements(node)
|
106
|
+
body = node.body
|
107
|
+
|
108
|
+
if body.nil?
|
109
|
+
[]
|
110
|
+
elsif body.begin_type?
|
111
|
+
body.children
|
112
|
+
else
|
113
|
+
[body]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def_node_matcher :break_command?, <<~PATTERN
|
118
|
+
{
|
119
|
+
return break
|
120
|
+
(send
|
121
|
+
{nil? (const {nil? cbase} :Kernel)}
|
122
|
+
{:raise :fail :throw :exit :exit! :abort}
|
123
|
+
...)
|
124
|
+
}
|
125
|
+
PATTERN
|
126
|
+
|
127
|
+
def break_statement?(node)
|
128
|
+
return true if break_command?(node)
|
129
|
+
|
130
|
+
case node.type
|
131
|
+
when :begin, :kwbegin
|
132
|
+
statements = *node
|
133
|
+
statements.any? { |statement| break_statement?(statement) }
|
134
|
+
when :if
|
135
|
+
check_if(node)
|
136
|
+
when :case
|
137
|
+
check_case(node)
|
138
|
+
else
|
139
|
+
false
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def check_if(node)
|
144
|
+
if_branch = node.if_branch
|
145
|
+
else_branch = node.else_branch
|
146
|
+
if_branch && else_branch &&
|
147
|
+
break_statement?(if_branch) && break_statement?(else_branch)
|
148
|
+
end
|
149
|
+
|
150
|
+
def check_case(node)
|
151
|
+
else_branch = node.else_branch
|
152
|
+
return false unless else_branch
|
153
|
+
return false unless break_statement?(else_branch)
|
154
|
+
|
155
|
+
node.when_branches.all? do |branch|
|
156
|
+
branch.body && break_statement?(branch.body)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def preceded_by_continue_statement?(break_statement)
|
161
|
+
left_siblings_of(break_statement).any? do |sibling|
|
162
|
+
next if sibling.loop_keyword? || loop_method?(sibling)
|
163
|
+
|
164
|
+
sibling.each_descendant(:next, :redo).any?
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def left_siblings_of(node)
|
169
|
+
node.parent.children[0, node.sibling_index]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|