rubocop 1.46.0 → 1.52.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 +3 -3
- data/config/default.yml +83 -11
- data/lib/rubocop/cli/command/auto_generate_config.rb +7 -0
- data/lib/rubocop/cli/command/execute_runner.rb +7 -2
- data/lib/rubocop/cli.rb +6 -6
- data/lib/rubocop/comment_config.rb +2 -0
- data/lib/rubocop/config.rb +7 -3
- data/lib/rubocop/config_loader.rb +8 -8
- data/lib/rubocop/config_obsoletion.rb +2 -2
- data/lib/rubocop/cop/autocorrect_logic.rb +29 -13
- data/lib/rubocop/cop/base.rb +6 -2
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/cop.rb +2 -2
- data/lib/rubocop/cop/corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -3
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +3 -3
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +3 -3
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/gemspec/dependency_version.rb +1 -1
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -1
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +37 -13
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +3 -3
- data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +3 -3
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +66 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/block_end_newline.rb +7 -21
- data/lib/rubocop/cop/layout/class_structure.rb +6 -3
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
- data/lib/rubocop/cop/layout/empty_comment.rb +3 -3
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -0
- data/lib/rubocop/cop/layout/end_alignment.rb +5 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +6 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +7 -2
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +25 -34
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +7 -19
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +42 -52
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +38 -55
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -4
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -3
- data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +8 -27
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +7 -26
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -21
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +6 -30
- data/lib/rubocop/cop/layout/redundant_line_break.rb +6 -7
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -1
- data/lib/rubocop/cop/layout/space_inside_parens.rb +2 -2
- data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -1
- data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -3
- data/lib/rubocop/cop/lint/else_layout.rb +1 -1
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +4 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +3 -4
- data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
- data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +46 -4
- data/lib/rubocop/cop/lint/missing_super.rb +34 -2
- data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -2
- data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +4 -4
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
- data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
- data/lib/rubocop/cop/lint/script_permission.rb +1 -1
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
- data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -12
- data/lib/rubocop/cop/lint/syntax.rb +4 -0
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +7 -1
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
- data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -3
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +9 -1
- data/lib/rubocop/cop/lint/useless_assignment.rb +59 -1
- data/lib/rubocop/cop/lint/useless_method_definition.rb +10 -2
- data/lib/rubocop/cop/lint/useless_rescue.rb +4 -1
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +69 -9
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +1 -0
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -3
- data/lib/rubocop/cop/migration/department_name.rb +1 -1
- data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +9 -5
- data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +4 -2
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
- data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +1 -6
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -3
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
- data/lib/rubocop/cop/naming/inclusive_language.rb +23 -4
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +22 -7
- data/lib/rubocop/cop/naming/method_name.rb +3 -3
- data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -4
- data/lib/rubocop/cop/naming/variable_name.rb +6 -1
- data/lib/rubocop/cop/registry.rb +3 -1
- data/lib/rubocop/cop/style/accessor_grouping.rb +32 -7
- data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -3
- data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
- data/lib/rubocop/cop/style/attr.rb +11 -1
- data/lib/rubocop/cop/style/begin_block.rb +1 -2
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
- data/lib/rubocop/cop/style/block_comments.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +11 -2
- data/lib/rubocop/cop/style/case_like_if.rb +20 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +2 -2
- data/lib/rubocop/cop/style/class_equality_comparison.rb +51 -40
- data/lib/rubocop/cop/style/collection_compact.rb +20 -7
- data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
- data/lib/rubocop/cop/style/combinable_loops.rb +26 -6
- data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +10 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +8 -8
- data/lib/rubocop/cop/style/copyright.rb +6 -3
- data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
- data/lib/rubocop/cop/style/dir.rb +1 -1
- data/lib/rubocop/cop/style/dir_empty.rb +54 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +2 -2
- data/lib/rubocop/cop/style/documentation.rb +11 -5
- data/lib/rubocop/cop/style/double_negation.rb +2 -2
- data/lib/rubocop/cop/style/each_with_object.rb +1 -1
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +8 -8
- data/lib/rubocop/cop/style/exact_regexp_match.rb +68 -0
- data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
- data/lib/rubocop/cop/style/file_empty.rb +71 -0
- data/lib/rubocop/cop/style/file_read.rb +3 -3
- data/lib/rubocop/cop/style/file_write.rb +1 -1
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/guard_clause.rb +3 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -22
- data/lib/rubocop/cop/style/hash_except.rb +23 -12
- data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
- data/lib/rubocop/cop/style/hash_syntax.rb +5 -2
- 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/if_inside_else.rb +6 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +111 -15
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
- data/lib/rubocop/cop/style/inverse_methods.rb +5 -5
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +9 -5
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +2 -2
- data/lib/rubocop/cop/style/map_to_hash.rb +4 -1
- data/lib/rubocop/cop/style/map_to_set.rb +4 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +4 -9
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +44 -37
- data/lib/rubocop/cop/style/min_max.rb +3 -3
- data/lib/rubocop/cop/style/mixin_grouping.rb +4 -4
- data/lib/rubocop/cop/style/multiline_method_signature.rb +7 -4
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
- data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +12 -7
- data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
- data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
- data/lib/rubocop/cop/style/parallel_assignment.rb +26 -18
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -2
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +2 -2
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +6 -4
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +101 -0
- data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +183 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +2 -2
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +11 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
- data/lib/rubocop/cop/style/redundant_string_escape.rb +3 -4
- data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
- data/lib/rubocop/cop/style/require_order.rb +12 -8
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
- data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
- data/lib/rubocop/cop/style/select_by_regexp.rb +15 -5
- data/lib/rubocop/cop/style/semicolon.rb +12 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +6 -4
- data/lib/rubocop/cop/style/special_global_vars.rb +3 -4
- data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
- data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
- data/lib/rubocop/cop/style/unpack_first.rb +3 -3
- data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +9 -5
- data/lib/rubocop/cop/team.rb +2 -2
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/variable_force/assignment.rb +33 -1
- data/lib/rubocop/cop/variable_force/variable.rb +5 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
- data/lib/rubocop/cop/variable_force.rb +1 -0
- data/lib/rubocop/cops_documentation_generator.rb +10 -3
- data/lib/rubocop/directive_comment.rb +3 -3
- data/lib/rubocop/ext/comment.rb +18 -0
- data/lib/rubocop/ext/regexp_node.rb +1 -1
- data/lib/rubocop/ext/regexp_parser.rb +1 -1
- data/lib/rubocop/formatter/junit_formatter.rb +4 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
- data/lib/rubocop/options.rb +4 -1
- data/lib/rubocop/result_cache.rb +2 -2
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/server/cache.rb +1 -1
- data/lib/rubocop/server/client_command/exec.rb +2 -1
- data/lib/rubocop/server/core.rb +1 -1
- data/lib/rubocop/server/helper.rb +1 -1
- data/lib/rubocop/server/server_command/exec.rb +1 -1
- data/lib/rubocop/target_ruby.rb +3 -2
- data/lib/rubocop/version.rb +10 -6
- data/lib/rubocop.rb +13 -0
- metadata +23 -8
@@ -41,15 +41,23 @@ module RuboCop
|
|
41
41
|
MSG = 'Useless method definition detected.'
|
42
42
|
|
43
43
|
def on_def(node)
|
44
|
-
return if use_rest_or_optional_args?(node)
|
44
|
+
return if method_definition_with_modifier?(node) || use_rest_or_optional_args?(node)
|
45
45
|
return unless delegating?(node.body, node)
|
46
46
|
|
47
|
-
add_offense(node)
|
47
|
+
add_offense(node) do |corrector|
|
48
|
+
range = node.parent&.send_type? ? node.parent : node
|
49
|
+
|
50
|
+
corrector.remove(range)
|
51
|
+
end
|
48
52
|
end
|
49
53
|
alias on_defs on_def
|
50
54
|
|
51
55
|
private
|
52
56
|
|
57
|
+
def method_definition_with_modifier?(node)
|
58
|
+
node.parent&.send_type? && !node.parent&.non_bare_access_modifier?
|
59
|
+
end
|
60
|
+
|
53
61
|
def use_rest_or_optional_args?(node)
|
54
62
|
node.arguments.any? { |arg| arg.restarg_type? || arg.optarg_type? || arg.kwoptarg_type? }
|
55
63
|
end
|
@@ -56,11 +56,13 @@ module RuboCop
|
|
56
56
|
|
57
57
|
private
|
58
58
|
|
59
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
59
60
|
def only_reraising?(resbody_node)
|
60
61
|
return false if use_exception_variable_in_ensure?(resbody_node)
|
61
62
|
|
62
63
|
body = resbody_node.body
|
63
|
-
|
64
|
+
|
65
|
+
return false if body.nil? || !body.send_type? || !body.method?(:raise) || body.receiver
|
64
66
|
return true unless body.arguments?
|
65
67
|
return false if body.arguments.size > 1
|
66
68
|
|
@@ -68,6 +70,7 @@ module RuboCop
|
|
68
70
|
|
69
71
|
exception_objects(resbody_node).include?(exception_name)
|
70
72
|
end
|
73
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
71
74
|
|
72
75
|
def use_exception_variable_in_ensure?(resbody_node)
|
73
76
|
return false unless (exception_variable = resbody_node.exception_variable)
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def remove_node(corrector, node)
|
77
|
-
corrector.remove(range_by_whole_lines(node.
|
77
|
+
corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true))
|
78
78
|
end
|
79
79
|
|
80
80
|
def autocorrect_block_pass(corrector, node, proc_name)
|
@@ -41,6 +41,10 @@ module RuboCop
|
|
41
41
|
# do_something(some_array)
|
42
42
|
# end
|
43
43
|
class Void < Base
|
44
|
+
extend AutoCorrector
|
45
|
+
|
46
|
+
include RangeHelp
|
47
|
+
|
44
48
|
OP_MSG = 'Operator `%<op>s` used in void context.'
|
45
49
|
VAR_MSG = 'Variable `%<var>s` used in void context.'
|
46
50
|
LIT_MSG = 'Literal `%<lit>s` used in void context.'
|
@@ -59,10 +63,10 @@ module RuboCop
|
|
59
63
|
shuffle slice sort sort_by squeeze strip sub
|
60
64
|
succ swapcase tr tr_s transform_values
|
61
65
|
unicode_normalize uniq upcase].freeze
|
62
|
-
|
66
|
+
METHODS_REPLACEABLE_BY_EACH = %i[collect map].freeze
|
63
67
|
|
64
68
|
NONMUTATING_METHODS = (NONMUTATING_METHODS_WITH_BANG_VERSION +
|
65
|
-
|
69
|
+
METHODS_REPLACEABLE_BY_EACH).freeze
|
66
70
|
|
67
71
|
def on_block(node)
|
68
72
|
return unless node.body && !node.body.begin_type?
|
@@ -100,31 +104,43 @@ module RuboCop
|
|
100
104
|
def check_void_op(node)
|
101
105
|
return unless node.send_type? && OPERATORS.include?(node.method_name)
|
102
106
|
|
103
|
-
add_offense(node.loc.selector,
|
107
|
+
add_offense(node.loc.selector,
|
108
|
+
message: format(OP_MSG, op: node.method_name)) do |corrector|
|
109
|
+
autocorrect_void_op(corrector, node)
|
110
|
+
end
|
104
111
|
end
|
105
112
|
|
106
113
|
def check_var(node)
|
107
114
|
return unless node.variable? || node.const_type?
|
108
115
|
|
109
|
-
add_offense(node.loc.name,
|
116
|
+
add_offense(node.loc.name,
|
117
|
+
message: format(VAR_MSG, var: node.loc.name.source)) do |corrector|
|
118
|
+
autocorrect_void_var(corrector, node)
|
119
|
+
end
|
110
120
|
end
|
111
121
|
|
112
122
|
def check_literal(node)
|
113
123
|
return if !node.literal? || node.xstr_type? || node.range_type?
|
114
124
|
|
115
|
-
add_offense(node, message: format(LIT_MSG, lit: node.source))
|
125
|
+
add_offense(node, message: format(LIT_MSG, lit: node.source)) do |corrector|
|
126
|
+
autocorrect_void_literal(corrector, node)
|
127
|
+
end
|
116
128
|
end
|
117
129
|
|
118
130
|
def check_self(node)
|
119
131
|
return unless node.self_type?
|
120
132
|
|
121
|
-
add_offense(node, message: SELF_MSG)
|
133
|
+
add_offense(node, message: SELF_MSG) do |corrector|
|
134
|
+
autocorrect_void_self(corrector, node)
|
135
|
+
end
|
122
136
|
end
|
123
137
|
|
124
138
|
def check_void_expression(node)
|
125
139
|
return unless node.defined_type? || node.lambda_or_proc?
|
126
140
|
|
127
|
-
add_offense(node, message: format(EXPRESSION_MSG, expression: node.source))
|
141
|
+
add_offense(node, message: format(EXPRESSION_MSG, expression: node.source)) do |corrector|
|
142
|
+
autocorrect_void_expression(corrector, node)
|
143
|
+
end
|
128
144
|
end
|
129
145
|
|
130
146
|
def check_nonmutating(node)
|
@@ -133,9 +149,16 @@ module RuboCop
|
|
133
149
|
method_name = node.method_name
|
134
150
|
return unless NONMUTATING_METHODS.include?(method_name)
|
135
151
|
|
136
|
-
suggestion =
|
152
|
+
suggestion = if METHODS_REPLACEABLE_BY_EACH.include?(method_name)
|
153
|
+
'each'
|
154
|
+
else
|
155
|
+
"#{method_name}!"
|
156
|
+
end
|
137
157
|
add_offense(node,
|
138
|
-
message: format(NONMUTATING_MSG, method: method_name,
|
158
|
+
message: format(NONMUTATING_MSG, method: method_name,
|
159
|
+
suggest: suggestion)) do |corrector|
|
160
|
+
autocorrect_nonmutating_send(corrector, node, suggestion)
|
161
|
+
end
|
139
162
|
end
|
140
163
|
|
141
164
|
def in_void_context?(node)
|
@@ -145,6 +168,43 @@ module RuboCop
|
|
145
168
|
|
146
169
|
VOID_CONTEXT_TYPES.include?(parent.type) && parent.void_context?
|
147
170
|
end
|
171
|
+
|
172
|
+
def autocorrect_void_op(corrector, node)
|
173
|
+
if node.arguments.empty?
|
174
|
+
corrector.replace(node, node.receiver.source)
|
175
|
+
else
|
176
|
+
corrector.replace(
|
177
|
+
range_with_surrounding_space(range: node.loc.selector, side: :both,
|
178
|
+
newlines: false),
|
179
|
+
"\n"
|
180
|
+
)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def autocorrect_void_var(corrector, node)
|
185
|
+
corrector.remove(range_with_surrounding_space(range: node.loc.name, side: :left))
|
186
|
+
end
|
187
|
+
|
188
|
+
def autocorrect_void_literal(corrector, node)
|
189
|
+
corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
|
190
|
+
end
|
191
|
+
|
192
|
+
def autocorrect_void_self(corrector, node)
|
193
|
+
corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
|
194
|
+
end
|
195
|
+
|
196
|
+
def autocorrect_void_expression(corrector, node)
|
197
|
+
corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
|
198
|
+
end
|
199
|
+
|
200
|
+
def autocorrect_nonmutating_send(corrector, node, suggestion)
|
201
|
+
send_node = if node.send_type?
|
202
|
+
node
|
203
|
+
else
|
204
|
+
node.send_node
|
205
|
+
end
|
206
|
+
corrector.replace(send_node.loc.selector, suggestion)
|
207
|
+
end
|
148
208
|
end
|
149
209
|
end
|
150
210
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Metrics
|
6
|
+
# Checks for literals with extremely many entries. This is indicative of
|
7
|
+
# configuration or data that may be better extracted somewhere else, like
|
8
|
+
# a database, fetched from an API, or read from a non-code file (CSV,
|
9
|
+
# JSON, YAML, etc.).
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# # Huge Array literal
|
14
|
+
# [1, 2, '...', 999_999_999]
|
15
|
+
#
|
16
|
+
# # bad
|
17
|
+
# # Huge Hash literal
|
18
|
+
# { 1 => 1, 2 => 2, '...' => '...', 999_999_999 => 999_999_999}
|
19
|
+
#
|
20
|
+
# # bad
|
21
|
+
# # Huge Set "literal"
|
22
|
+
# Set[1, 2, '...', 999_999_999]
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# # Reasonably sized Array literal
|
26
|
+
# [1, 2, '...', 10]
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# # Reading huge Array from external data source
|
30
|
+
# # File.readlines('numbers.txt', chomp: true).map!(&:to_i)
|
31
|
+
#
|
32
|
+
# # good
|
33
|
+
# # Reasonably sized Hash literal
|
34
|
+
# { 1 => 1, 2 => 2, '...' => '...', 10 => 10}
|
35
|
+
#
|
36
|
+
# # good
|
37
|
+
# # Reading huge Hash from external data source
|
38
|
+
# CSV.foreach('numbers.csv', headers: true).each_with_object({}) do |row, hash|
|
39
|
+
# hash[row["key"].to_i] = row["value"].to_i
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# # good
|
43
|
+
# # Reasonably sized Set "literal"
|
44
|
+
# Set[1, 2, '...', 10]
|
45
|
+
#
|
46
|
+
# # good
|
47
|
+
# # Reading huge Set from external data source
|
48
|
+
# SomeFramework.config_for(:something)[:numbers].to_set
|
49
|
+
#
|
50
|
+
class CollectionLiteralLength < Base
|
51
|
+
MSG = 'Avoid hard coding large quantities of data in code. ' \
|
52
|
+
'Prefer reading the data from an external source.'
|
53
|
+
RESTRICT_ON_SEND = [:[]].freeze
|
54
|
+
|
55
|
+
def on_array(node)
|
56
|
+
add_offense(node) if node.children.length >= collection_threshold
|
57
|
+
end
|
58
|
+
alias on_hash on_array
|
59
|
+
|
60
|
+
def on_index(node)
|
61
|
+
add_offense(node) if node.arguments.length >= collection_threshold
|
62
|
+
end
|
63
|
+
|
64
|
+
def on_send(node)
|
65
|
+
on_index(node) if node.method?(:[])
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def collection_threshold
|
71
|
+
cop_config.fetch('LengthThreshold', Float::INFINITY)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
include Util
|
11
11
|
|
12
12
|
FOLDABLE_TYPES = %i[array hash heredoc send csend].freeze
|
13
|
-
CLASSLIKE_TYPES = %i[class module].freeze
|
13
|
+
CLASSLIKE_TYPES = %i[class module sclass].freeze
|
14
14
|
private_constant :FOLDABLE_TYPES, :CLASSLIKE_TYPES
|
15
15
|
|
16
16
|
def initialize(node, processed_source, count_comments: false, foldable_types: [])
|
@@ -163,8 +163,8 @@ module RuboCop
|
|
163
163
|
return 0 unless parenthesized?(parent)
|
164
164
|
|
165
165
|
[
|
166
|
-
parent.loc.begin.end_pos != descendant.
|
167
|
-
parent.loc.end.begin_pos != descendant.
|
166
|
+
parent.loc.begin.end_pos != descendant.source_range.begin_pos,
|
167
|
+
parent.loc.end.begin_pos != descendant.source_range.end_pos
|
168
168
|
].count(true)
|
169
169
|
end
|
170
170
|
|
@@ -45,7 +45,7 @@ module RuboCop
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def check_cop_name(name, comment, offset)
|
48
|
-
start = comment.
|
48
|
+
start = comment.source_range.begin_pos + offset
|
49
49
|
range = range_between(start, start + name.length)
|
50
50
|
|
51
51
|
add_offense(range) do |corrector|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This module encapsulates the ability to allow certain receivers in a cop.
|
6
|
+
module AllowedReceivers
|
7
|
+
def allowed_receiver?(receiver)
|
8
|
+
receiver_name = receiver_name(receiver)
|
9
|
+
|
10
|
+
allowed_receivers.include?(receiver_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def receiver_name(receiver)
|
14
|
+
if receiver.receiver && !receiver.receiver.const_type?
|
15
|
+
return receiver_name(receiver.receiver)
|
16
|
+
end
|
17
|
+
|
18
|
+
if receiver.send_type?
|
19
|
+
if receiver.receiver
|
20
|
+
"#{receiver_name(receiver.receiver)}.#{receiver.method_name}"
|
21
|
+
else
|
22
|
+
receiver.method_name.to_s
|
23
|
+
end
|
24
|
+
else
|
25
|
+
receiver.source
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def allowed_receivers
|
30
|
+
cop_config.fetch('AllowedReceivers', [])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
|
30
30
|
# Returns the range bounds for just the annotation
|
31
31
|
def bounds
|
32
|
-
start = comment.
|
32
|
+
start = comment.source_range.begin_pos + margin.length
|
33
33
|
length = [keyword, colon, space].reduce(0) { |len, elem| len + elem.to_s.length }
|
34
34
|
[start, start + length]
|
35
35
|
end
|
@@ -36,7 +36,7 @@ module RuboCop
|
|
36
36
|
length = calculator.calculate
|
37
37
|
return if length <= max_length
|
38
38
|
|
39
|
-
location = node.casgn_type? ? node.loc.name : node.
|
39
|
+
location = node.casgn_type? ? node.loc.name : node.source_range
|
40
40
|
|
41
41
|
add_offense(location, message: message(length, max_length)) { self.max = length }
|
42
42
|
end
|
@@ -37,7 +37,7 @@ module RuboCop
|
|
37
37
|
private
|
38
38
|
|
39
39
|
def end_position_for(node)
|
40
|
-
end_line = buffer.line_for_position(node.
|
40
|
+
end_line = buffer.line_for_position(node.source_range.end_pos)
|
41
41
|
buffer.line_range(end_line).end_pos
|
42
42
|
end
|
43
43
|
|
@@ -62,21 +62,25 @@ module RuboCop
|
|
62
62
|
# Returns the end line of a node, which might be a comment and not part of the AST
|
63
63
|
# End line is considered either the line at which another node starts, or
|
64
64
|
# the line at which the parent node ends.
|
65
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
65
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Lint/DuplicateBranch
|
66
66
|
def find_end_line(node)
|
67
67
|
if node.if_type? && node.else?
|
68
68
|
node.loc.else.line
|
69
69
|
elsif node.if_type? && node.ternary?
|
70
70
|
node.else_branch.loc.line
|
71
|
-
elsif
|
71
|
+
elsif node.if_type? && node.elsif?
|
72
|
+
node.each_ancestor(:if).find(&:if?).loc.end.line
|
73
|
+
elsif node.block_type? || node.numblock_type?
|
74
|
+
node.loc.end.line
|
75
|
+
elsif (next_sibling = node.right_sibling) && next_sibling.is_a?(AST::Node)
|
72
76
|
next_sibling.loc.line
|
73
77
|
elsif (parent = node.parent)
|
74
|
-
parent.loc.end ? parent.loc.end.line : parent.loc.line
|
78
|
+
parent.loc.respond_to?(:end) && parent.loc.end ? parent.loc.end.line : parent.loc.line
|
75
79
|
else
|
76
80
|
node.loc.end.line
|
77
81
|
end
|
78
82
|
end
|
79
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
83
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Lint/DuplicateBranch
|
80
84
|
end
|
81
85
|
end
|
82
86
|
end
|
@@ -23,7 +23,7 @@ module RuboCop
|
|
23
23
|
# The args node1 & node2 may represent a RuboCop::AST::Node
|
24
24
|
# or a Parser::Source::Comment. Both respond to #loc.
|
25
25
|
def preceding_comment?(node1, node2)
|
26
|
-
node1 && node2 && precede?(node2, node1) && comment_line?(node2.
|
26
|
+
node1 && node2 && precede?(node2, node1) && comment_line?(node2.source)
|
27
27
|
end
|
28
28
|
|
29
29
|
# The args node1 & node2 may represent a RuboCop::AST::Node
|
@@ -33,7 +33,7 @@ module RuboCop
|
|
33
33
|
|
34
34
|
def separator_delta(pair)
|
35
35
|
if pair.hash_rocket?
|
36
|
-
correct_separator_column = pair.key.
|
36
|
+
correct_separator_column = pair.key.source_range.end.column + 1
|
37
37
|
actual_separator_column = pair.loc.operator.column
|
38
38
|
|
39
39
|
correct_separator_column - actual_separator_column
|
@@ -95,19 +95,21 @@ module RuboCop
|
|
95
95
|
use_modifier_form_without_parenthesized_method_call?(method_dispatch_node)
|
96
96
|
end
|
97
97
|
|
98
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
98
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
99
99
|
def def_node_that_require_parentheses(node)
|
100
100
|
last_pair = node.parent.pairs.last
|
101
101
|
return unless last_pair.key.source == last_pair.value.source
|
102
102
|
return unless (dispatch_node = find_ancestor_method_dispatch_node(node))
|
103
|
+
return if dispatch_node.assignment_method?
|
103
104
|
return if dispatch_node.parenthesized?
|
105
|
+
return if dispatch_node.parent && parentheses?(dispatch_node.parent)
|
104
106
|
return if last_expression?(dispatch_node) && !method_dispatch_as_argument?(dispatch_node)
|
105
107
|
|
106
108
|
def_node = node.each_ancestor(:send, :csend, :super, :yield).first
|
107
109
|
|
108
110
|
DefNode.new(def_node) unless def_node && def_node.arguments.empty?
|
109
111
|
end
|
110
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
112
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
111
113
|
|
112
114
|
def find_ancestor_method_dispatch_node(node)
|
113
115
|
return unless (ancestor = node.parent.parent)
|
@@ -159,7 +159,7 @@ module RuboCop
|
|
159
159
|
end
|
160
160
|
|
161
161
|
def strip_prefix_and_suffix(node, corrector)
|
162
|
-
expression = node.
|
162
|
+
expression = node.source_range
|
163
163
|
corrector.remove_leading(expression, leading)
|
164
164
|
corrector.remove_trailing(expression, trailing)
|
165
165
|
end
|
@@ -175,11 +175,11 @@ module RuboCop
|
|
175
175
|
end
|
176
176
|
|
177
177
|
def set_new_arg_name(transformed_argname, corrector)
|
178
|
-
corrector.replace(block_node.arguments
|
178
|
+
corrector.replace(block_node.arguments, "|#{transformed_argname}|")
|
179
179
|
end
|
180
180
|
|
181
181
|
def set_new_body_expression(transforming_body_expr, corrector)
|
182
|
-
body_source = transforming_body_expr.
|
182
|
+
body_source = transforming_body_expr.source
|
183
183
|
if transforming_body_expr.hash_type? && !transforming_body_expr.braces?
|
184
184
|
body_source = "{ #{body_source} }"
|
185
185
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Common functionality for checking minimum branches count.
|
6
|
+
module MinBranchesCount
|
7
|
+
private
|
8
|
+
|
9
|
+
def min_branches_count?(node)
|
10
|
+
branches =
|
11
|
+
if node.case_type?
|
12
|
+
node.when_branches
|
13
|
+
elsif node.if_type?
|
14
|
+
if_conditional_branches(node)
|
15
|
+
else
|
16
|
+
raise ArgumentError, "Unsupported #{node.type.inspect} node type"
|
17
|
+
end
|
18
|
+
|
19
|
+
branches.size >= min_branches_count
|
20
|
+
end
|
21
|
+
|
22
|
+
def min_branches_count
|
23
|
+
length = cop_config['MinBranchesCount'] || 3
|
24
|
+
return length if length.is_a?(Integer) && length.positive?
|
25
|
+
|
26
|
+
raise 'MinBranchesCount needs to be a positive integer!'
|
27
|
+
end
|
28
|
+
|
29
|
+
def if_conditional_branches(node, branches = [])
|
30
|
+
return [] if node.nil? || !node.if_type?
|
31
|
+
|
32
|
+
branches << node.if_branch
|
33
|
+
|
34
|
+
else_branch = node.else_branch
|
35
|
+
if_conditional_branches(else_branch, branches) if else_branch&.if_type?
|
36
|
+
branches
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
def get_source_range(node, comments_as_separators)
|
11
11
|
unless comments_as_separators
|
12
12
|
first_comment = processed_source.ast_with_comments[node].first
|
13
|
-
return first_comment.
|
13
|
+
return first_comment.source_range unless first_comment.nil?
|
14
14
|
end
|
15
15
|
node.source_range
|
16
16
|
end
|
@@ -132,12 +132,7 @@ module RuboCop
|
|
132
132
|
end
|
133
133
|
|
134
134
|
def range_with_comments(node)
|
135
|
-
ranges = [
|
136
|
-
node,
|
137
|
-
*@processed_source.ast_with_comments[node]
|
138
|
-
].map do |element|
|
139
|
-
element.location.expression
|
140
|
-
end
|
135
|
+
ranges = [node, *@processed_source.ast_with_comments[node]].map(&:source_range)
|
141
136
|
ranges.reduce do |result, range|
|
142
137
|
add_range(result, range)
|
143
138
|
end
|
@@ -65,14 +65,14 @@ module RuboCop
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def method_source(if_body)
|
68
|
-
range_between(if_body.
|
68
|
+
range_between(if_body.source_range.begin_pos, if_body.loc.selector.end_pos).source
|
69
69
|
end
|
70
70
|
|
71
71
|
def first_line_comment(node)
|
72
|
-
comment = processed_source.
|
72
|
+
comment = processed_source.comments.find { |c| same_line?(c, node) }
|
73
73
|
return unless comment
|
74
74
|
|
75
|
-
comment_source = comment.
|
75
|
+
comment_source = comment.source
|
76
76
|
comment_source unless comment_disables_cop?(comment_source)
|
77
77
|
end
|
78
78
|
|
@@ -75,7 +75,7 @@ module RuboCop
|
|
75
75
|
|
76
76
|
def inside_comment?(range, comma_offset)
|
77
77
|
comment = processed_source.comment_at_line(range.line)
|
78
|
-
comment && comment.
|
78
|
+
comment && comment.source_range.begin_pos < range.begin_pos + comma_offset
|
79
79
|
end
|
80
80
|
|
81
81
|
# Returns true if the node has round/square/curly brackets.
|
@@ -57,7 +57,7 @@ module RuboCop
|
|
57
57
|
CONSTANT_MSG = 'Use only ascii symbols in constants.'
|
58
58
|
|
59
59
|
def on_new_investigation
|
60
|
-
processed_source.
|
60
|
+
processed_source.tokens.each do |token|
|
61
61
|
next if !should_check?(token) || token.text.ascii_only?
|
62
62
|
|
63
63
|
message = token.type == :tIDENTIFIER ? IDENTIFIER_MSG : CONSTANT_MSG
|
@@ -38,7 +38,7 @@ module RuboCop
|
|
38
38
|
return if correct_case_delimiters?(node)
|
39
39
|
|
40
40
|
add_offense(node.loc.heredoc_end) do |corrector|
|
41
|
-
expr = node.
|
41
|
+
expr = node.source_range
|
42
42
|
|
43
43
|
corrector.replace(expr, correct_delimiters(expr.source))
|
44
44
|
corrector.replace(node.loc.heredoc_end, correct_delimiters(delimiter_string(expr)))
|