rubocop 1.32.0 → 1.37.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 +104 -16
- data/config/obsoletion.yml +23 -1
- data/lib/rubocop/arguments_env.rb +17 -0
- data/lib/rubocop/arguments_file.rb +17 -0
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +2 -2
- data/lib/rubocop/cli/command/execute_runner.rb +7 -7
- data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
- data/lib/rubocop/cli/command/suggest_extensions.rb +53 -15
- data/lib/rubocop/config.rb +1 -1
- data/lib/rubocop/config_finder.rb +68 -0
- data/lib/rubocop/config_loader.rb +12 -40
- data/lib/rubocop/config_loader_resolver.rb +1 -5
- data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
- data/lib/rubocop/config_obsoletion.rb +7 -2
- data/lib/rubocop/cop/cop.rb +1 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +58 -0
- data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
- data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
- data/lib/rubocop/cop/generator.rb +1 -2
- data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +69 -0
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +62 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/block_alignment.rb +16 -12
- data/lib/rubocop/cop/layout/block_end_newline.rb +35 -5
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -0
- data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +7 -1
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +6 -2
- data/lib/rubocop/cop/layout/line_length.rb +4 -1
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +13 -9
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +25 -9
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +28 -3
- data/lib/rubocop/cop/legacy/corrections_proxy.rb +1 -1
- data/lib/rubocop/cop/legacy/corrector.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +21 -8
- data/lib/rubocop/cop/lint/debugger.rb +26 -16
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_magic_comment.rb +73 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +11 -1
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +25 -6
- data/lib/rubocop/cop/lint/duplicate_require.rb +1 -1
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/empty_class.rb +3 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +107 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -9
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +50 -1
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +25 -6
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +6 -6
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +12 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +24 -8
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +4 -5
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +12 -1
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +7 -0
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +29 -9
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +9 -3
- data/lib/rubocop/cop/lint/redundant_with_index.rb +13 -10
- data/lib/rubocop/cop/lint/redundant_with_object.rb +12 -11
- data/lib/rubocop/cop/lint/require_parentheses.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -2
- data/lib/rubocop/cop/lint/shadowed_exception.rb +15 -10
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -3
- data/lib/rubocop/cop/lint/unreachable_loop.rb +9 -3
- data/lib/rubocop/cop/lint/unused_method_argument.rb +4 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +8 -6
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +2 -0
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -1
- data/lib/rubocop/cop/metrics/block_length.rb +6 -7
- data/lib/rubocop/cop/metrics/method_length.rb +8 -8
- data/lib/rubocop/cop/mixin/allowed_methods.rb +20 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +17 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +17 -1
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +82 -4
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -6
- data/lib/rubocop/cop/mixin/method_complexity.rb +8 -13
- data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +4 -5
- data/lib/rubocop/cop/mixin/rescue_node.rb +3 -1
- data/lib/rubocop/cop/mixin/surrounding_space.rb +6 -5
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +2 -2
- data/lib/rubocop/cop/naming/inclusive_language.rb +1 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +24 -3
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +97 -1
- data/lib/rubocop/cop/style/accessor_grouping.rb +7 -3
- data/lib/rubocop/cop/style/arguments_forwarding.rb +2 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +26 -7
- data/lib/rubocop/cop/style/case_equality.rb +40 -10
- data/lib/rubocop/cop/style/class_and_module_children.rb +4 -4
- data/lib/rubocop/cop/style/class_equality_comparison.rb +32 -7
- data/lib/rubocop/cop/style/class_methods_definitions.rb +2 -1
- data/lib/rubocop/cop/style/collection_compact.rb +6 -1
- data/lib/rubocop/cop/style/collection_methods.rb +2 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -1
- data/lib/rubocop/cop/style/double_negation.rb +2 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +41 -6
- data/lib/rubocop/cop/style/each_with_object.rb +39 -8
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_heredoc.rb +15 -1
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/endless_method.rb +1 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +4 -0
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/format_string_token.rb +21 -8
- data/lib/rubocop/cop/style/guard_clause.rb +27 -16
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -1
- data/lib/rubocop/cop/style/hash_except.rb +0 -4
- data/lib/rubocop/cop/style/hash_syntax.rb +17 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +8 -6
- data/lib/rubocop/cop/style/magic_comment_format.rb +307 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +15 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -7
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -6
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
- data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -1
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -1
- data/lib/rubocop/cop/style/next.rb +3 -5
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/numeric_literals.rb +16 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +28 -8
- data/lib/rubocop/cop/style/object_then.rb +2 -0
- data/lib/rubocop/cop/style/operator_method_call.rb +39 -0
- data/lib/rubocop/cop/style/perl_backrefs.rb +22 -1
- data/lib/rubocop/cop/style/proc.rb +4 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +3 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +24 -6
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_initialize.rb +3 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +19 -22
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +8 -1
- data/lib/rubocop/cop/style/redundant_self.rb +2 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +21 -6
- data/lib/rubocop/cop/style/redundant_sort_by.rb +24 -8
- data/lib/rubocop/cop/style/redundant_string_escape.rb +173 -0
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +4 -2
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +14 -5
- data/lib/rubocop/cop/style/static_class.rb +32 -1
- data/lib/rubocop/cop/style/symbol_array.rb +3 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +38 -12
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -13
- data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -1
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +3 -1
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/ext/range.rb +15 -0
- data/lib/rubocop/feature_loader.rb +94 -0
- data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +9 -3
- data/lib/rubocop/formatter/html_formatter.rb +3 -3
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -1
- data/lib/rubocop/formatter/tap_formatter.rb +1 -1
- data/lib/rubocop/options.rb +13 -13
- data/lib/rubocop/result_cache.rb +22 -20
- data/lib/rubocop/rspec/shared_contexts.rb +13 -1
- data/lib/rubocop/runner.rb +4 -0
- data/lib/rubocop/server/cache.rb +41 -2
- data/lib/rubocop/server/cli.rb +26 -2
- data/lib/rubocop/server/client_command/exec.rb +5 -0
- data/lib/rubocop/server/core.rb +2 -1
- data/lib/rubocop/server/socket_reader.rb +5 -1
- data/lib/rubocop/server.rb +1 -1
- data/lib/rubocop/version.rb +8 -2
- data/lib/rubocop.rb +8 -3
- metadata +20 -9
- data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
@@ -31,19 +31,8 @@ module RuboCop
|
|
31
31
|
extend AutoCorrector
|
32
32
|
|
33
33
|
MSG_EACH_WITH_OBJECT = 'Use `each` instead of `each_with_object`.'
|
34
|
-
|
35
34
|
MSG_WITH_OBJECT = 'Remove redundant `with_object`.'
|
36
35
|
|
37
|
-
# @!method redundant_with_object?(node)
|
38
|
-
def_node_matcher :redundant_with_object?, <<~PATTERN
|
39
|
-
(block
|
40
|
-
$(send _ {:each_with_object :with_object}
|
41
|
-
_)
|
42
|
-
(args
|
43
|
-
(arg _))
|
44
|
-
...)
|
45
|
-
PATTERN
|
46
|
-
|
47
36
|
def on_block(node)
|
48
37
|
return unless (send = redundant_with_object?(node))
|
49
38
|
|
@@ -59,8 +48,20 @@ module RuboCop
|
|
59
48
|
end
|
60
49
|
end
|
61
50
|
|
51
|
+
alias on_numblock on_block
|
52
|
+
|
62
53
|
private
|
63
54
|
|
55
|
+
# @!method redundant_with_object?(node)
|
56
|
+
def_node_matcher :redundant_with_object?, <<~PATTERN
|
57
|
+
{
|
58
|
+
(block
|
59
|
+
$(send _ {:each_with_object :with_object} _) (args (arg _)) ...)
|
60
|
+
(numblock
|
61
|
+
$(send _ {:each_with_object :with_object} _) 1 ...)
|
62
|
+
}
|
63
|
+
PATTERN
|
64
|
+
|
64
65
|
def message(node)
|
65
66
|
if node.method?(:each_with_object)
|
66
67
|
MSG_EACH_WITH_OBJECT
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
46
46
|
private
|
47
47
|
|
48
48
|
def check_ternary(ternary, node)
|
49
|
-
return
|
49
|
+
return if node.method?(:[]) || !ternary.condition.operator_keyword?
|
50
50
|
|
51
51
|
range = range_between(node.source_range.begin_pos, ternary.condition.source_range.end_pos)
|
52
52
|
|
@@ -31,6 +31,7 @@ module RuboCop
|
|
31
31
|
minimum_target_ruby_version 2.3
|
32
32
|
|
33
33
|
MSG = 'Do not chain ordinary method call after safe navigation operator.'
|
34
|
+
PLUS_MINUS_METHODS = %i[+@ -@].freeze
|
34
35
|
|
35
36
|
# @!method bad_method?(node)
|
36
37
|
def_node_matcher :bad_method?, <<~PATTERN
|
@@ -42,7 +43,7 @@ module RuboCop
|
|
42
43
|
|
43
44
|
def on_send(node)
|
44
45
|
bad_method?(node) do |safe_nav, method|
|
45
|
-
return if nil_methods.include?(method)
|
46
|
+
return if nil_methods.include?(method) || PLUS_MINUS_METHODS.include?(node.method_name)
|
46
47
|
|
47
48
|
method_chain = method_chain(node)
|
48
49
|
location =
|
@@ -71,7 +72,7 @@ module RuboCop
|
|
71
72
|
else
|
72
73
|
offense_range.source.dup
|
73
74
|
end
|
74
|
-
source.prepend('.') unless
|
75
|
+
source.prepend('.') unless source.start_with?('.')
|
75
76
|
source.prepend('&')
|
76
77
|
end
|
77
78
|
|
@@ -7,6 +7,14 @@ module RuboCop
|
|
7
7
|
# less specific exception being rescued before a more specific
|
8
8
|
# exception is rescued.
|
9
9
|
#
|
10
|
+
# An exception is considered shadowed if it is rescued after its
|
11
|
+
# ancestor is, or if it and its ancestor are both rescued in the
|
12
|
+
# same `rescue` statement. In both cases, the more specific rescue is
|
13
|
+
# unnecessary because it is covered by rescuing the less specific
|
14
|
+
# exception. (ie. `rescue Exception, StandardError` has the same behavior
|
15
|
+
# whether `StandardError` is included or not, because all ``StandardError``s
|
16
|
+
# are rescued by `rescue Exception`).
|
17
|
+
#
|
10
18
|
# @example
|
11
19
|
#
|
12
20
|
# # bad
|
@@ -19,6 +27,13 @@ module RuboCop
|
|
19
27
|
# handle_standard_error
|
20
28
|
# end
|
21
29
|
#
|
30
|
+
# # bad
|
31
|
+
# begin
|
32
|
+
# something
|
33
|
+
# rescue Exception, StandardError
|
34
|
+
# handle_error
|
35
|
+
# end
|
36
|
+
#
|
22
37
|
# # good
|
23
38
|
#
|
24
39
|
# begin
|
@@ -140,16 +155,6 @@ module RuboCop
|
|
140
155
|
end
|
141
156
|
end
|
142
157
|
|
143
|
-
# @param [RuboCop::AST::Node] rescue_group is a node of array_type
|
144
|
-
def rescued_exceptions(rescue_group)
|
145
|
-
klasses = *rescue_group
|
146
|
-
klasses.map do |klass|
|
147
|
-
next unless klass.const_type?
|
148
|
-
|
149
|
-
klass.source
|
150
|
-
end.compact
|
151
|
-
end
|
152
|
-
|
153
158
|
def find_shadowing_rescue(rescues)
|
154
159
|
rescued_groups = rescued_groups_for(rescues)
|
155
160
|
rescued_groups.zip(rescues).each do |group, res|
|
@@ -12,9 +12,12 @@ module RuboCop
|
|
12
12
|
# because `Ractor` should not access outer variables.
|
13
13
|
# eg. following style is encouraged:
|
14
14
|
#
|
15
|
+
# [source,ruby]
|
16
|
+
# ----
|
15
17
|
# worker_id, pipe = env
|
16
18
|
# Ractor.new(worker_id, pipe) do |worker_id, pipe|
|
17
19
|
# end
|
20
|
+
# ----
|
18
21
|
#
|
19
22
|
# @example
|
20
23
|
#
|
@@ -64,12 +67,33 @@ module RuboCop
|
|
64
67
|
end
|
65
68
|
|
66
69
|
def same_conditions_node_different_branch?(variable, outer_local_variable)
|
67
|
-
variable_node = variable
|
70
|
+
variable_node = variable_node(variable)
|
68
71
|
return false unless variable_node.conditional?
|
69
72
|
|
70
|
-
outer_local_variable_node =
|
73
|
+
outer_local_variable_node =
|
74
|
+
find_conditional_node_from_ascendant(outer_local_variable.declaration_node)
|
75
|
+
return true unless outer_local_variable_node
|
71
76
|
|
72
|
-
outer_local_variable_node.conditional? &&
|
77
|
+
outer_local_variable_node.conditional? &&
|
78
|
+
(variable_node == outer_local_variable_node ||
|
79
|
+
variable_node == outer_local_variable_node.else_branch)
|
80
|
+
end
|
81
|
+
|
82
|
+
def variable_node(variable)
|
83
|
+
parent_node = variable.scope.node.parent
|
84
|
+
|
85
|
+
if parent_node.when_type?
|
86
|
+
parent_node.parent
|
87
|
+
else
|
88
|
+
parent_node
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def find_conditional_node_from_ascendant(node)
|
93
|
+
return unless (parent = node.parent)
|
94
|
+
return parent if parent.conditional?
|
95
|
+
|
96
|
+
find_conditional_node_from_ascendant(parent)
|
73
97
|
end
|
74
98
|
end
|
75
99
|
end
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
9
9
|
# In rare cases where only one iteration (or at most one iteration) is intended behavior,
|
10
10
|
# the code should be refactored to use `if` conditionals.
|
11
11
|
#
|
12
|
-
# NOTE: Block methods that are used with
|
12
|
+
# NOTE: Block methods that are used with ``Enumerable``s are considered to be loops.
|
13
13
|
#
|
14
14
|
# `AllowedPatterns` can be used to match against the block receiver in order to allow
|
15
15
|
# code that would otherwise be registered as an offense (eg. `times` used not in an
|
@@ -79,7 +79,7 @@ module RuboCop
|
|
79
79
|
# # bad
|
80
80
|
# 2.times { raise ArgumentError }
|
81
81
|
#
|
82
|
-
# @example AllowedPatterns: [
|
82
|
+
# @example AllowedPatterns: ['(exactly|at_least|at_most)\(\d+\)\.times'] (default)
|
83
83
|
#
|
84
84
|
# # good
|
85
85
|
# exactly(2).times { raise StandardError }
|
@@ -101,10 +101,14 @@ module RuboCop
|
|
101
101
|
check(node) if loop_method?(node)
|
102
102
|
end
|
103
103
|
|
104
|
+
def on_numblock(node)
|
105
|
+
check(node) if loop_method?(node)
|
106
|
+
end
|
107
|
+
|
104
108
|
private
|
105
109
|
|
106
110
|
def loop_method?(node)
|
107
|
-
return false unless node.block_type?
|
111
|
+
return false unless node.block_type? || node.numblock_type?
|
108
112
|
|
109
113
|
send_node = node.send_node
|
110
114
|
return false if matches_allowed_pattern?(send_node.source)
|
@@ -179,6 +183,8 @@ module RuboCop
|
|
179
183
|
|
180
184
|
def preceded_by_continue_statement?(break_statement)
|
181
185
|
break_statement.left_siblings.any? do |sibling|
|
186
|
+
# Numblocks have the arguments count as a number in the AST.
|
187
|
+
next if sibling.is_a?(Integer)
|
182
188
|
next if sibling.loop_keyword? || loop_method?(sibling)
|
183
189
|
|
184
190
|
sibling.each_descendant(*CONTINUE_KEYWORDS).any?
|
@@ -31,8 +31,8 @@ module RuboCop
|
|
31
31
|
# # bad
|
32
32
|
# class Foo
|
33
33
|
# # The following is redundant (methods defined on the class'
|
34
|
-
# # singleton class are not affected by the
|
35
|
-
#
|
34
|
+
# # singleton class are not affected by the private modifier)
|
35
|
+
# private
|
36
36
|
#
|
37
37
|
# def self.method3
|
38
38
|
# end
|
@@ -142,6 +142,8 @@ module RuboCop
|
|
142
142
|
check_node(node.body)
|
143
143
|
end
|
144
144
|
|
145
|
+
alias on_numblock on_block
|
146
|
+
|
145
147
|
private
|
146
148
|
|
147
149
|
def autocorrect(corrector, node)
|
@@ -157,17 +159,17 @@ module RuboCop
|
|
157
159
|
|
158
160
|
# @!method dynamic_method_definition?(node)
|
159
161
|
def_node_matcher :dynamic_method_definition?, <<~PATTERN
|
160
|
-
{(send nil? :define_method ...) (block (send nil? :define_method ...) ...)}
|
162
|
+
{(send nil? :define_method ...) ({block numblock} (send nil? :define_method ...) ...)}
|
161
163
|
PATTERN
|
162
164
|
|
163
165
|
# @!method class_or_instance_eval?(node)
|
164
166
|
def_node_matcher :class_or_instance_eval?, <<~PATTERN
|
165
|
-
(block (send _ {:class_eval :instance_eval}) ...)
|
167
|
+
({block numblock} (send _ {:class_eval :instance_eval}) ...)
|
166
168
|
PATTERN
|
167
169
|
|
168
170
|
# @!method class_or_module_or_struct_new_call?(node)
|
169
171
|
def_node_matcher :class_or_module_or_struct_new_call?, <<~PATTERN
|
170
|
-
(block (send (const {nil? cbase} {:Class :Module :Struct}) :new ...) ...)
|
172
|
+
({block numblock} (send (const {nil? cbase} {:Class :Module :Struct}) :new ...) ...)
|
171
173
|
PATTERN
|
172
174
|
|
173
175
|
def check_node(node)
|
@@ -277,7 +279,7 @@ module RuboCop
|
|
277
279
|
matcher_name = "#{m}_block?".to_sym
|
278
280
|
unless respond_to?(matcher_name)
|
279
281
|
self.class.def_node_matcher matcher_name, <<~PATTERN
|
280
|
-
(block (send {nil? const} {:#{m}} ...) ...)
|
282
|
+
({block numblock} (send {nil? const} {:#{m}} ...) ...)
|
281
283
|
PATTERN
|
282
284
|
end
|
283
285
|
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# Looks for `ruby2_keywords` calls for methods that do not need it.
|
7
7
|
#
|
8
8
|
# `ruby2_keywords` should only be called on methods that accept an argument splat
|
9
|
-
# (
|
9
|
+
# (`\*args`) but do not explicit keyword arguments (`k:` or `k: true`) or
|
10
10
|
# a keyword splat (`**kwargs`).
|
11
11
|
#
|
12
12
|
# @example
|
@@ -33,7 +33,9 @@ module RuboCop
|
|
33
33
|
# render 'pages/search/page'
|
34
34
|
# end
|
35
35
|
#
|
36
|
-
# This cop also takes into account `
|
36
|
+
# This cop also takes into account `AllowedMethods` (defaults to `[]`)
|
37
|
+
# And `AllowedPatterns` (defaults to `[]`)
|
38
|
+
#
|
37
39
|
class AbcSize < Base
|
38
40
|
include MethodComplexity
|
39
41
|
|
@@ -14,8 +14,8 @@ module RuboCop
|
|
14
14
|
#
|
15
15
|
#
|
16
16
|
# NOTE: The `ExcludedMethods` configuration is deprecated and only kept
|
17
|
-
# for backwards compatibility. Please use `
|
18
|
-
# By default, there are no methods to
|
17
|
+
# for backwards compatibility. Please use `AllowedMethods` and `AllowedPatterns`
|
18
|
+
# instead. By default, there are no methods to allowed.
|
19
19
|
#
|
20
20
|
# @example CountAsOne: ['array', 'heredoc']
|
21
21
|
#
|
@@ -38,14 +38,13 @@ module RuboCop
|
|
38
38
|
# NOTE: This cop does not apply for `Struct` definitions.
|
39
39
|
class BlockLength < Base
|
40
40
|
include CodeLength
|
41
|
-
include
|
42
|
-
|
43
|
-
ignored_methods deprecated_key: 'ExcludedMethods'
|
41
|
+
include AllowedMethods
|
42
|
+
include AllowedPattern
|
44
43
|
|
45
44
|
LABEL = 'Block'
|
46
45
|
|
47
46
|
def on_block(node)
|
48
|
-
return if
|
47
|
+
return if allowed_method?(node.method_name) || matches_allowed_pattern?(node.method_name)
|
49
48
|
return if method_receiver_excluded?(node)
|
50
49
|
return if node.class_constructor? || node.struct_constructor?
|
51
50
|
|
@@ -59,7 +58,7 @@ module RuboCop
|
|
59
58
|
node_receiver = node.receiver&.source&.gsub(/\s+/, '')
|
60
59
|
node_method = String(node.method_name)
|
61
60
|
|
62
|
-
|
61
|
+
allowed_methods.any? do |config|
|
63
62
|
next unless config.is_a?(String)
|
64
63
|
|
65
64
|
receiver, method = config.split('.')
|
@@ -4,16 +4,17 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Metrics
|
6
6
|
# Checks if the length of a method exceeds some maximum value.
|
7
|
-
# Comment lines can optionally be
|
7
|
+
# Comment lines can optionally be allowed.
|
8
8
|
# The maximum allowed length is configurable.
|
9
9
|
#
|
10
10
|
# You can set literals you want to fold with `CountAsOne`.
|
11
11
|
# Available are: 'array', 'hash', and 'heredoc'. Each literal
|
12
12
|
# will be counted as one line regardless of its actual size.
|
13
13
|
#
|
14
|
-
# NOTE: The `ExcludedMethods` configuration is
|
15
|
-
#
|
16
|
-
#
|
14
|
+
# NOTE: The `ExcludedMethods` and `IgnoredMethods` configuration is
|
15
|
+
# deprecated and only kept for backwards compatibility.
|
16
|
+
# Please use `AllowedMethods` and `AllowedPatterns` instead.
|
17
|
+
# By default, there are no methods to allowed.
|
17
18
|
#
|
18
19
|
# @example CountAsOne: ['array', 'heredoc']
|
19
20
|
#
|
@@ -35,14 +36,13 @@ module RuboCop
|
|
35
36
|
#
|
36
37
|
class MethodLength < Base
|
37
38
|
include CodeLength
|
38
|
-
include
|
39
|
-
|
40
|
-
ignored_methods deprecated_key: 'ExcludedMethods'
|
39
|
+
include AllowedMethods
|
40
|
+
include AllowedPattern
|
41
41
|
|
42
42
|
LABEL = 'Method'
|
43
43
|
|
44
44
|
def on_def(node)
|
45
|
-
return if
|
45
|
+
return if allowed_method?(node.method_name) || matches_allowed_pattern?(node.method_name)
|
46
46
|
|
47
47
|
check_code_length(node)
|
48
48
|
end
|
@@ -12,10 +12,29 @@ module RuboCop
|
|
12
12
|
allowed_methods.include?(name.to_s)
|
13
13
|
end
|
14
14
|
|
15
|
+
# @deprecated Use allowed_method? instead
|
16
|
+
alias ignored_method? allowed_method?
|
17
|
+
|
15
18
|
# @api public
|
16
19
|
def allowed_methods
|
17
|
-
|
20
|
+
if cop_config_deprecated_values.any?(Regexp)
|
21
|
+
cop_config_allowed_methods
|
22
|
+
else
|
23
|
+
cop_config_allowed_methods + cop_config_deprecated_values
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def cop_config_allowed_methods
|
28
|
+
@cop_config_allowed_methods ||= Array(cop_config.fetch('AllowedMethods', []))
|
29
|
+
end
|
30
|
+
|
31
|
+
def cop_config_deprecated_values
|
32
|
+
@cop_config_deprecated_values ||=
|
33
|
+
Array(cop_config.fetch('IgnoredMethods', [])) +
|
34
|
+
Array(cop_config.fetch('ExcludedMethods', []))
|
18
35
|
end
|
19
36
|
end
|
37
|
+
# @deprecated IgnoredMethods class has been replaced with AllowedMethods.
|
38
|
+
IgnoredMethods = AllowedMethods
|
20
39
|
end
|
21
40
|
end
|
@@ -30,7 +30,23 @@ module RuboCop
|
|
30
30
|
def allowed_patterns
|
31
31
|
# Since there could be a pattern specified in the default config, merge the two
|
32
32
|
# arrays together.
|
33
|
-
|
33
|
+
if cop_config_deprecated_methods_values.any?(Regexp)
|
34
|
+
cop_config_patterns_values + cop_config_deprecated_methods_values
|
35
|
+
else
|
36
|
+
cop_config_patterns_values
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def cop_config_patterns_values
|
41
|
+
@cop_config_patterns_values ||=
|
42
|
+
Array(cop_config.fetch('AllowedPatterns', [])) +
|
43
|
+
Array(cop_config.fetch('IgnoredPatterns', []))
|
44
|
+
end
|
45
|
+
|
46
|
+
def cop_config_deprecated_methods_values
|
47
|
+
@cop_config_deprecated_methods_values ||=
|
48
|
+
Array(cop_config.fetch('IgnoredMethods', [])) +
|
49
|
+
Array(cop_config.fetch('ExcludedMethods', []))
|
34
50
|
end
|
35
51
|
end
|
36
52
|
|
@@ -12,10 +12,26 @@ module RuboCop
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def contains_comments?(node)
|
15
|
+
comments_in_range(node).any?
|
16
|
+
end
|
17
|
+
|
18
|
+
def comments_in_range(node)
|
15
19
|
start_line = node.source_range.line
|
16
20
|
end_line = find_end_line(node)
|
17
21
|
|
18
|
-
processed_source.each_comment_in_lines(start_line...end_line)
|
22
|
+
processed_source.each_comment_in_lines(start_line...end_line)
|
23
|
+
end
|
24
|
+
|
25
|
+
def comments_contain_disables?(node, cop_name)
|
26
|
+
disabled_ranges = processed_source.disabled_line_ranges[cop_name]
|
27
|
+
|
28
|
+
return unless disabled_ranges
|
29
|
+
|
30
|
+
node_range = node.source_range.line...find_end_line(node)
|
31
|
+
|
32
|
+
disabled_ranges.any? do |disable_range|
|
33
|
+
disable_range.cover?(node_range) || node_range.cover?(disable_range)
|
34
|
+
end
|
19
35
|
end
|
20
36
|
|
21
37
|
private
|
@@ -6,7 +6,8 @@ module RuboCop
|
|
6
6
|
#
|
7
7
|
# IMPORTANT: RuboCop core depended on this module when it supported Rails department.
|
8
8
|
# Rails department has been extracted to RuboCop Rails gem.
|
9
|
-
#
|
9
|
+
#
|
10
|
+
# @deprecated This module is deprecated and will be removed by RuboCop 2.0.
|
10
11
|
# It will not be updated to `RuboCop::Cop::Base` v1 API to maintain compatibility
|
11
12
|
# with existing RuboCop Rails 2.8 or lower.
|
12
13
|
#
|
@@ -5,7 +5,22 @@ module RuboCop
|
|
5
5
|
# This module checks for Ruby 3.1's hash value omission syntax.
|
6
6
|
module HashShorthandSyntax
|
7
7
|
OMIT_HASH_VALUE_MSG = 'Omit the hash value.'
|
8
|
-
EXPLICIT_HASH_VALUE_MSG = '
|
8
|
+
EXPLICIT_HASH_VALUE_MSG = 'Include the hash value.'
|
9
|
+
DO_NOT_MIX_MSG_PREFIX = 'Do not mix explicit and implicit hash values.'
|
10
|
+
DO_NOT_MIX_OMIT_VALUE_MSG = "#{DO_NOT_MIX_MSG_PREFIX} #{OMIT_HASH_VALUE_MSG}"
|
11
|
+
DO_NOT_MIX_EXPLICIT_VALUE_MSG = "#{DO_NOT_MIX_MSG_PREFIX} #{EXPLICIT_HASH_VALUE_MSG}"
|
12
|
+
|
13
|
+
def on_hash_for_mixed_shorthand(hash_node)
|
14
|
+
return if ignore_mixed_hash_shorthand_syntax?(hash_node)
|
15
|
+
|
16
|
+
hash_value_type_breakdown = breakdown_value_types_of_hash(hash_node)
|
17
|
+
|
18
|
+
if hash_with_mixed_shorthand_syntax?(hash_value_type_breakdown)
|
19
|
+
mixed_shorthand_syntax_check(hash_value_type_breakdown)
|
20
|
+
else
|
21
|
+
no_mixed_shorthand_syntax_check(hash_value_type_breakdown)
|
22
|
+
end
|
23
|
+
end
|
9
24
|
|
10
25
|
def on_pair(node)
|
11
26
|
return if ignore_hash_shorthand_syntax?(node)
|
@@ -36,8 +51,14 @@ module RuboCop
|
|
36
51
|
end
|
37
52
|
end
|
38
53
|
|
54
|
+
def ignore_mixed_hash_shorthand_syntax?(hash_node)
|
55
|
+
target_ruby_version <= 3.0 || enforced_shorthand_syntax != 'consistent' ||
|
56
|
+
!hash_node.hash_type?
|
57
|
+
end
|
58
|
+
|
39
59
|
def ignore_hash_shorthand_syntax?(pair_node)
|
40
60
|
target_ruby_version <= 3.0 || enforced_shorthand_syntax == 'either' ||
|
61
|
+
enforced_shorthand_syntax == 'consistent' ||
|
41
62
|
!pair_node.parent.hash_type?
|
42
63
|
end
|
43
64
|
|
@@ -75,11 +96,68 @@ module RuboCop
|
|
75
96
|
end
|
76
97
|
|
77
98
|
def without_parentheses_call_expr_follows?(ancestor)
|
99
|
+
return false unless ancestor.respond_to?(:parenthesized?) && !ancestor.parenthesized?
|
100
|
+
|
78
101
|
right_sibling = ancestor.right_sibling
|
79
|
-
right_sibling ||= ancestor.each_ancestor.find
|
80
|
-
|
102
|
+
right_sibling ||= ancestor.each_ancestor.find do |node|
|
103
|
+
node.assignment? || node.send_type?
|
104
|
+
end&.right_sibling
|
105
|
+
|
106
|
+
!!right_sibling
|
107
|
+
end
|
81
108
|
|
82
|
-
|
109
|
+
def breakdown_value_types_of_hash(hash_node)
|
110
|
+
hash_node.pairs.group_by do |pair_node|
|
111
|
+
if pair_node.value_omission?
|
112
|
+
:value_omitted
|
113
|
+
elsif require_hash_value?(pair_node.key.source, pair_node)
|
114
|
+
:value_needed
|
115
|
+
else
|
116
|
+
:value_omittable
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def hash_with_mixed_shorthand_syntax?(hash_value_type_breakdown)
|
122
|
+
hash_value_type_breakdown.keys.size > 1
|
123
|
+
end
|
124
|
+
|
125
|
+
def hash_with_values_that_cant_be_omitted?(hash_value_type_breakdown)
|
126
|
+
hash_value_type_breakdown[:value_needed]&.any?
|
127
|
+
end
|
128
|
+
|
129
|
+
def each_omitted_value_pair(hash_value_type_breakdown, &block)
|
130
|
+
hash_value_type_breakdown[:value_omitted]&.each(&block)
|
131
|
+
end
|
132
|
+
|
133
|
+
def each_omittable_value_pair(hash_value_type_breakdown, &block)
|
134
|
+
hash_value_type_breakdown[:value_omittable]&.each(&block)
|
135
|
+
end
|
136
|
+
|
137
|
+
def mixed_shorthand_syntax_check(hash_value_type_breakdown)
|
138
|
+
if hash_with_values_that_cant_be_omitted?(hash_value_type_breakdown)
|
139
|
+
each_omitted_value_pair(hash_value_type_breakdown) do |pair_node|
|
140
|
+
hash_key_source = pair_node.key.source
|
141
|
+
replacement = "#{hash_key_source}: #{hash_key_source}"
|
142
|
+
register_offense(pair_node, DO_NOT_MIX_EXPLICIT_VALUE_MSG, replacement)
|
143
|
+
end
|
144
|
+
else
|
145
|
+
each_omittable_value_pair(hash_value_type_breakdown) do |pair_node|
|
146
|
+
hash_key_source = pair_node.key.source
|
147
|
+
replacement = "#{hash_key_source}:"
|
148
|
+
register_offense(pair_node, DO_NOT_MIX_OMIT_VALUE_MSG, replacement)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def no_mixed_shorthand_syntax_check(hash_value_type_breakdown)
|
154
|
+
return if hash_with_values_that_cant_be_omitted?(hash_value_type_breakdown)
|
155
|
+
|
156
|
+
each_omittable_value_pair(hash_value_type_breakdown) do |pair_node|
|
157
|
+
hash_key_source = pair_node.key.source
|
158
|
+
replacement = "#{hash_key_source}:"
|
159
|
+
register_offense(pair_node, OMIT_HASH_VALUE_MSG, replacement)
|
160
|
+
end
|
83
161
|
end
|
84
162
|
end
|
85
163
|
end
|
@@ -14,7 +14,7 @@ module RuboCop
|
|
14
14
|
{(array ...) (send _ :each_with_index) (send _ :with_index _ ?) (send _ :zip ...)}
|
15
15
|
PATTERN
|
16
16
|
|
17
|
-
def on_block(node)
|
17
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
18
18
|
on_bad_each_with_object(node) do |*match|
|
19
19
|
handle_possible_offense(node, match, 'each_with_object')
|
20
20
|
end
|
@@ -68,6 +68,8 @@ module RuboCop
|
|
68
68
|
# `transform_values` if value transformation uses key.
|
69
69
|
return if captures.transformation_uses_both_args?
|
70
70
|
|
71
|
+
return unless captures.use_transformed_argname?
|
72
|
+
|
71
73
|
message = "Prefer `#{new_method_name}` over `#{match_desc}`."
|
72
74
|
add_offense(node, message: message) do |corrector|
|
73
75
|
correction = prepare_correction(node)
|
@@ -113,11 +115,7 @@ module RuboCop
|
|
113
115
|
end
|
114
116
|
|
115
117
|
# Internal helper class to hold match data
|
116
|
-
Captures = Struct.new(
|
117
|
-
:transformed_argname,
|
118
|
-
:transforming_body_expr,
|
119
|
-
:unchanged_body_expr
|
120
|
-
) do
|
118
|
+
Captures = Struct.new(:transformed_argname, :transforming_body_expr, :unchanged_body_expr) do
|
121
119
|
def noop_transformation?
|
122
120
|
transforming_body_expr.lvar_type? &&
|
123
121
|
transforming_body_expr.children == [transformed_argname]
|
@@ -126,6 +124,12 @@ module RuboCop
|
|
126
124
|
def transformation_uses_both_args?
|
127
125
|
transforming_body_expr.descendants.include?(unchanged_body_expr)
|
128
126
|
end
|
127
|
+
|
128
|
+
def use_transformed_argname?
|
129
|
+
transforming_body_expr.each_descendant(:lvar).any? do |node|
|
130
|
+
node.source == transformed_argname.to_s
|
131
|
+
end
|
132
|
+
end
|
129
133
|
end
|
130
134
|
|
131
135
|
# Internal helper class to hold autocorrect data
|