rubocop 1.74.0 → 1.75.2
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/config/default.yml +32 -6
- data/config/obsoletion.yml +3 -1
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/config.rb +35 -6
- data/lib/rubocop/config_loader.rb +4 -0
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +46 -2
- data/lib/rubocop/config_validator.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
- data/lib/rubocop/cop/layout/block_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +3 -3
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
- data/lib/rubocop/cop/layout/line_length.rb +5 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +9 -5
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -5
- data/lib/rubocop/cop/layout/space_around_operators.rb +4 -1
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
- data/lib/rubocop/cop/lint/debugger.rb +2 -2
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -3
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +2 -2
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
- data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +7 -4
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
- data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
- data/lib/rubocop/cop/lint/return_in_void_context.rb +7 -2
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +8 -1
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -0
- data/lib/rubocop/cop/lint/void.rb +1 -0
- data/lib/rubocop/cop/metrics/block_length.rb +1 -0
- data/lib/rubocop/cop/metrics/method_length.rb +1 -0
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +1 -1
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +0 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -0
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +64 -8
- data/lib/rubocop/cop/naming/variable_name.rb +6 -19
- data/lib/rubocop/cop/registry.rb +9 -6
- data/lib/rubocop/cop/style/array_intersect.rb +39 -28
- data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
- data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
- data/lib/rubocop/cop/style/collection_methods.rb +1 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +1 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +3 -0
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +4 -0
- data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
- data/lib/rubocop/cop/style/for.rb +1 -0
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
- data/lib/rubocop/cop/style/guard_clause.rb +2 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -2
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +105 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +3 -0
- data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
- data/lib/rubocop/cop/style/inverse_methods.rb +1 -0
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
- data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
- data/lib/rubocop/cop/style/it_block_parameter.rb +100 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
- data/lib/rubocop/cop/style/lambda.rb +1 -0
- data/lib/rubocop/cop/style/map_into_array.rb +1 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -0
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/object_then.rb +1 -0
- data/lib/rubocop/cop/style/proc.rb +1 -0
- data/lib/rubocop/cop/style/raise_args.rb +8 -8
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +13 -1
- data/lib/rubocop/cop/style/redundant_format.rb +10 -3
- data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/redundant_self.rb +1 -0
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/select_by_regexp.rb +4 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +3 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +41 -100
- data/lib/rubocop/cop/style/super_arguments.rb +1 -2
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -0
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +2 -7
- data/lib/rubocop/cop/variable_force.rb +1 -1
- data/lib/rubocop/lsp/runtime.rb +4 -4
- data/lib/rubocop/lsp/stdin_runner.rb +3 -1
- data/lib/rubocop/magic_comment.rb +8 -0
- data/lib/rubocop/rspec/cop_helper.rb +4 -1
- data/lib/rubocop/rspec/shared_contexts.rb +20 -0
- data/lib/rubocop/rspec/support.rb +2 -0
- data/lib/rubocop/runner.rb +5 -1
- data/lib/rubocop/server/cache.rb +13 -10
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +14 -7
- data/lib/rubocop.rb +4 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +20 -2
- metadata +10 -6
@@ -134,7 +134,7 @@ module RuboCop
|
|
134
134
|
if NO_ARG_ALGORITHM.include?(algorithm_parts.first.upcase) && no_arguments
|
135
135
|
"'#{algorithm_parts.first}'"
|
136
136
|
else
|
137
|
-
mode = 'cbc'
|
137
|
+
mode = 'cbc' if size_and_mode.empty?
|
138
138
|
|
139
139
|
"'#{(algorithm_parts + size_and_mode + [mode]).compact.take(3).join('-')}'"
|
140
140
|
end
|
@@ -42,7 +42,6 @@ module RuboCop
|
|
42
42
|
class DuplicateMethods < Base
|
43
43
|
MSG = 'Method `%<method>s` is defined at both %<defined>s and %<current>s.'
|
44
44
|
RESTRICT_ON_SEND = %i[alias_method attr_reader attr_writer attr_accessor attr].freeze
|
45
|
-
DEF_TYPES = %i[def defs].freeze
|
46
45
|
|
47
46
|
def initialize(config = nil, options = nil)
|
48
47
|
super
|
@@ -162,7 +161,7 @@ module RuboCop
|
|
162
161
|
end
|
163
162
|
|
164
163
|
def method_key(node, method_name)
|
165
|
-
if (ancestor_def = node.each_ancestor(
|
164
|
+
if (ancestor_def = node.each_ancestor(:any_def).first)
|
166
165
|
"#{ancestor_def.method_name}.#{method_name}"
|
167
166
|
else
|
168
167
|
method_name
|
@@ -170,7 +169,7 @@ module RuboCop
|
|
170
169
|
end
|
171
170
|
|
172
171
|
def location(node)
|
173
|
-
if
|
172
|
+
if node.any_def_type?
|
174
173
|
node.loc.keyword.join(node.loc.name)
|
175
174
|
else
|
176
175
|
node.source_range
|
@@ -98,7 +98,7 @@ module RuboCop
|
|
98
98
|
subject, = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
99
99
|
return if node.defs_type? && allowed_subject_type?(subject)
|
100
100
|
|
101
|
-
def_ancestor = node.each_ancestor(:
|
101
|
+
def_ancestor = node.each_ancestor(:any_def).first
|
102
102
|
return unless def_ancestor
|
103
103
|
|
104
104
|
within_scoping_def =
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
46
46
|
def on_return(return_node)
|
47
47
|
return if return_value?(return_node)
|
48
48
|
|
49
|
-
return_node.each_ancestor(:any_block, :
|
49
|
+
return_node.each_ancestor(:any_block, :any_def) do |node|
|
50
50
|
break if scoped_node?(node)
|
51
51
|
|
52
52
|
# if a proc is passed to `Module#define_method` or
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
66
66
|
private
|
67
67
|
|
68
68
|
def scoped_node?(node)
|
69
|
-
node.
|
69
|
+
node.any_def_type? || node.lambda?
|
70
70
|
end
|
71
71
|
|
72
72
|
def return_value?(return_node)
|
@@ -3,15 +3,18 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Checks for `raise` or `fail` statements which
|
7
|
-
#
|
6
|
+
# Checks for `raise` or `fail` statements which raise `Exception` or
|
7
|
+
# `Exception.new`. Use `StandardError` or a specific exception class instead.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
9
|
+
# If you have defined your own namespaced `Exception` class, it is possible
|
10
|
+
# to configure the cop to allow it by setting `AllowedImplicitNamespaces` to
|
11
|
+
# an array with the names of the namespaces to allow. By default, this is set to
|
12
|
+
# `['Gem']`, which allows `Gem::Exception` to be raised without an explicit namespace.
|
13
|
+
# If not allowed, a false positive may be registered if `raise Exception` is called
|
14
|
+
# within the namespace.
|
15
|
+
#
|
16
|
+
# Alternatively, use a fully qualified name with `raise`/`fail`
|
17
|
+
# (eg. `raise Namespace::Exception`).
|
15
18
|
#
|
16
19
|
# @safety
|
17
20
|
# This cop is unsafe because it will change the exception class being
|
@@ -20,15 +23,31 @@ module RuboCop
|
|
20
23
|
# @example
|
21
24
|
# # bad
|
22
25
|
# raise Exception, 'Error message here'
|
26
|
+
# raise Exception.new('Error message here')
|
23
27
|
#
|
24
28
|
# # good
|
25
29
|
# raise StandardError, 'Error message here'
|
30
|
+
# raise MyError.new, 'Error message here'
|
31
|
+
#
|
32
|
+
# @example AllowedImplicitNamespaces: ['Gem'] (default)
|
33
|
+
# # bad - `Foo` is not an allowed implicit namespace
|
34
|
+
# module Foo
|
35
|
+
# def self.foo
|
36
|
+
# raise Exception # This is qualified to `Foo::Exception`.
|
37
|
+
# end
|
38
|
+
# end
|
26
39
|
#
|
27
|
-
# @example AllowedImplicitNamespaces: ['Gem']
|
28
40
|
# # good
|
29
41
|
# module Gem
|
30
42
|
# def self.foo
|
31
|
-
# raise Exception # This
|
43
|
+
# raise Exception # This is qualified to `Gem::Exception`.
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# # good
|
48
|
+
# module Foo
|
49
|
+
# def self.foo
|
50
|
+
# raise Foo::Exception
|
32
51
|
# end
|
33
52
|
# end
|
34
53
|
class RaiseException < Base
|
@@ -27,7 +27,8 @@ module RuboCop
|
|
27
27
|
# In all cases, chaining one same `to_*` conversion methods listed above is redundant.
|
28
28
|
#
|
29
29
|
# The cop can also register an offense for chaining conversion methods on methods that are
|
30
|
-
# expected to return a specific type regardless of receiver (eg. `foo.inspect.to_s`
|
30
|
+
# expected to return a specific type regardless of receiver (eg. `foo.inspect.to_s` and
|
31
|
+
# `foo.to_json.to_s`).
|
31
32
|
#
|
32
33
|
# @example
|
33
34
|
# # bad
|
@@ -69,10 +70,12 @@ module RuboCop
|
|
69
70
|
# foo.to_s
|
70
71
|
#
|
71
72
|
# # bad - chaining a conversion to a method that is expected to return the same type
|
72
|
-
# inspect.to_s
|
73
|
+
# foo.inspect.to_s
|
74
|
+
# foo.to_json.to_s
|
73
75
|
#
|
74
76
|
# # good
|
75
|
-
# inspect
|
77
|
+
# foo.inspect
|
78
|
+
# foo.to_json
|
76
79
|
#
|
77
80
|
class RedundantTypeConversion < Base
|
78
81
|
extend AutoCorrector
|
@@ -108,7 +111,7 @@ module RuboCop
|
|
108
111
|
|
109
112
|
# Methods that already are expected to return a given type, which makes a further
|
110
113
|
# conversion redundant.
|
111
|
-
TYPED_METHODS = { to_s: %i[inspect] }.freeze
|
114
|
+
TYPED_METHODS = { to_s: %i[inspect to_json] }.freeze
|
112
115
|
|
113
116
|
CONVERSION_METHODS = Set[*LITERAL_NODE_TYPES.keys].freeze
|
114
117
|
RESTRICT_ON_SEND = CONVERSION_METHODS + [:to_d]
|
@@ -53,6 +53,7 @@ module RuboCop
|
|
53
53
|
# rubocop:enable Metrics/AbcSize
|
54
54
|
|
55
55
|
alias on_numblock on_block
|
56
|
+
alias on_itblock on_block
|
56
57
|
|
57
58
|
private
|
58
59
|
|
@@ -64,6 +65,8 @@ module RuboCop
|
|
64
65
|
(args (arg _)) ...)
|
65
66
|
(numblock
|
66
67
|
$(call _ {:each_with_index :with_index} ...) 1 ...)
|
68
|
+
(itblock
|
69
|
+
$(call _ {:each_with_index :with_index} ...) _ ...)
|
67
70
|
}
|
68
71
|
PATTERN
|
69
72
|
|
@@ -49,6 +49,7 @@ module RuboCop
|
|
49
49
|
end
|
50
50
|
|
51
51
|
alias on_numblock on_block
|
52
|
+
alias on_itblock on_block
|
52
53
|
|
53
54
|
private
|
54
55
|
|
@@ -59,6 +60,8 @@ module RuboCop
|
|
59
60
|
$(call _ {:each_with_object :with_object} _) (args (arg _)) ...)
|
60
61
|
(numblock
|
61
62
|
$(call _ {:each_with_object :with_object} _) 1 ...)
|
63
|
+
(itblock
|
64
|
+
$(call _ {:each_with_object :with_object} _) _ ...)
|
62
65
|
}
|
63
66
|
PATTERN
|
64
67
|
|
@@ -32,12 +32,17 @@ module RuboCop
|
|
32
32
|
class ReturnInVoidContext < Base
|
33
33
|
MSG = 'Do not return a value in `%<method>s`.'
|
34
34
|
|
35
|
+
# Returning out of these methods only exits the block itself.
|
36
|
+
SCOPE_CHANGING_METHODS = %i[lambda define_method define_singleton_method].freeze
|
37
|
+
|
35
38
|
def on_return(return_node)
|
36
39
|
return unless return_node.descendants.any?
|
37
40
|
|
38
|
-
def_node = return_node.each_ancestor(:
|
41
|
+
def_node = return_node.each_ancestor(:any_def).first
|
39
42
|
return unless def_node&.void_context?
|
40
|
-
return if return_node.each_ancestor(:any_block).any?
|
43
|
+
return if return_node.each_ancestor(:any_block).any? do |block_node|
|
44
|
+
SCOPE_CHANGING_METHODS.include?(block_node.method_name)
|
45
|
+
end
|
41
46
|
|
42
47
|
add_offense(
|
43
48
|
return_node.loc.keyword,
|
@@ -56,19 +56,26 @@ module RuboCop
|
|
56
56
|
|
57
57
|
outer_local_variable = variable_table.find_variable(variable.name)
|
58
58
|
return unless outer_local_variable
|
59
|
+
return if variable_used_in_declaration_of_outer?(variable, outer_local_variable)
|
59
60
|
return if same_conditions_node_different_branch?(variable, outer_local_variable)
|
60
61
|
|
61
62
|
message = format(MSG, variable: variable.name)
|
62
63
|
add_offense(variable.declaration_node, message: message)
|
63
64
|
end
|
64
65
|
|
66
|
+
private
|
67
|
+
|
68
|
+
def variable_used_in_declaration_of_outer?(variable, outer_local_variable)
|
69
|
+
variable.scope.node.each_ancestor.any?(outer_local_variable.declaration_node)
|
70
|
+
end
|
71
|
+
|
65
72
|
def same_conditions_node_different_branch?(variable, outer_local_variable)
|
66
73
|
variable_node = variable_node(variable)
|
67
74
|
return false unless node_or_its_ascendant_conditional?(variable_node)
|
68
75
|
|
69
76
|
outer_local_variable_node =
|
70
77
|
find_conditional_node_from_ascendant(outer_local_variable.declaration_node)
|
71
|
-
return
|
78
|
+
return false unless outer_local_variable_node
|
72
79
|
return false unless outer_local_variable_node.conditional?
|
73
80
|
return true if variable_node == outer_local_variable_node
|
74
81
|
|
@@ -116,7 +116,7 @@ module RuboCop
|
|
116
116
|
private
|
117
117
|
|
118
118
|
def comment_between_rescue_and_end?(node)
|
119
|
-
ancestor = node.each_ancestor(:kwbegin, :
|
119
|
+
ancestor = node.each_ancestor(:kwbegin, :any_def, :any_block).first
|
120
120
|
return false unless ancestor
|
121
121
|
|
122
122
|
end_line = ancestor.loc.end&.line || ancestor.loc.last_line
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
40
40
|
# top-level return node's ancestors should not be of block, def, or
|
41
41
|
# defs type.
|
42
42
|
def top_level_return?(return_node)
|
43
|
-
return_node.each_ancestor(:block, :
|
43
|
+
return_node.each_ancestor(:block, :any_def).none?
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -53,6 +53,7 @@ module RuboCop
|
|
53
53
|
end
|
54
54
|
|
55
55
|
alias on_numblock on_block
|
56
|
+
alias on_itblock on_block
|
56
57
|
|
57
58
|
private
|
58
59
|
|
@@ -74,6 +75,7 @@ module RuboCop
|
|
74
75
|
|
75
76
|
def arg_count(node)
|
76
77
|
return node.children[1] if node.numblock_type? # the maximum numbered param for the block
|
78
|
+
return 1 if node.itblock_type? # `it` block parameter is always one
|
77
79
|
|
78
80
|
# Only `arg`, `optarg` and `mlhs` (destructuring) count as arguments that
|
79
81
|
# can be used. Keyword arguments are not used for these methods so are
|
@@ -101,9 +101,8 @@ module RuboCop
|
|
101
101
|
check(node) if loop_method?(node)
|
102
102
|
end
|
103
103
|
|
104
|
-
|
105
|
-
|
106
|
-
end
|
104
|
+
alias on_numblock on_block
|
105
|
+
alias on_itblock on_block
|
107
106
|
|
108
107
|
private
|
109
108
|
|
@@ -189,8 +188,9 @@ module RuboCop
|
|
189
188
|
|
190
189
|
def preceded_by_continue_statement?(break_statement)
|
191
190
|
break_statement.left_siblings.any? do |sibling|
|
192
|
-
# Numblocks have the arguments count as a number
|
193
|
-
|
191
|
+
# Numblocks have the arguments count as a number or,
|
192
|
+
# itblocks have `:it` symbol in the AST.
|
193
|
+
next if sibling.is_a?(Integer) || sibling.is_a?(Symbol)
|
194
194
|
next if sibling.loop_keyword? || loop_method?(sibling)
|
195
195
|
|
196
196
|
sibling.each_descendant(*CONTINUE_KEYWORDS).any?
|
@@ -145,7 +145,7 @@ module RuboCop
|
|
145
145
|
|
146
146
|
def extract_body(node)
|
147
147
|
case node.type
|
148
|
-
when :class, :module, :sclass, :block, :numblock, :def, :defs
|
148
|
+
when :class, :module, :sclass, :block, :numblock, :itblock, :def, :defs
|
149
149
|
node.body
|
150
150
|
when :casgn
|
151
151
|
extract_body(node.expression)
|
@@ -48,7 +48,7 @@ module RuboCop
|
|
48
48
|
|
49
49
|
args = process_args(node.arguments)
|
50
50
|
return extract_breakable_node_from_elements(node, args, max)
|
51
|
-
elsif node.
|
51
|
+
elsif node.any_def_type?
|
52
52
|
return extract_breakable_node_from_elements(node, node.arguments, max)
|
53
53
|
elsif node.type?(:array, :hash)
|
54
54
|
return extract_breakable_node_from_elements(node, node.children, max)
|
@@ -220,7 +220,7 @@ module RuboCop
|
|
220
220
|
|
221
221
|
# @api private
|
222
222
|
def already_on_multiple_lines?(node)
|
223
|
-
return node.first_line != node.last_argument.last_line if node.
|
223
|
+
return node.first_line != node.last_argument.last_line if node.any_def_type?
|
224
224
|
|
225
225
|
!node.single_line?
|
226
226
|
end
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def safe_to_split?(node)
|
43
|
-
node.each_descendant(:if, :case, :kwbegin, :
|
43
|
+
node.each_descendant(:if, :case, :kwbegin, :any_def).none? &&
|
44
44
|
node.each_descendant(:dstr, :str).none? { |n| n.heredoc? || n.value.include?("\n") } &&
|
45
45
|
node.each_descendant(:begin, :sym).none? { |b| !b.single_line? }
|
46
46
|
end
|
@@ -19,7 +19,7 @@ module RuboCop
|
|
19
19
|
|
20
20
|
# @!method non_public_modifier?(node)
|
21
21
|
def_node_matcher :non_public_modifier?, <<~PATTERN
|
22
|
-
(send nil? {:private :protected :private_class_method} (
|
22
|
+
(send nil? {:private :protected :private_class_method} (any_def ...))
|
23
23
|
PATTERN
|
24
24
|
end
|
25
25
|
end
|
@@ -21,7 +21,7 @@ module RuboCop
|
|
21
21
|
|
22
22
|
# @!method empty_line_required?(node)
|
23
23
|
def_node_matcher :empty_line_required?,
|
24
|
-
'{
|
24
|
+
'{any_def class module (send nil? {:private :protected :public})}'
|
25
25
|
|
26
26
|
def check(node, body, adjusted_first_line: nil)
|
27
27
|
return if valid_body_style?(body)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This module encapsulates the ability to forbid certain identifiers in a cop.
|
6
|
+
module ForbiddenIdentifiers
|
7
|
+
SIGILS = '@$' # if a variable starts with a sigil it will be removed
|
8
|
+
|
9
|
+
def forbidden_identifier?(name)
|
10
|
+
name = name.to_s.delete(SIGILS)
|
11
|
+
|
12
|
+
forbidden_identifiers.any? && forbidden_identifiers.include?(name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def forbidden_identifiers
|
16
|
+
cop_config.fetch('ForbiddenIdentifiers', [])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This module encapsulates the ability to forbid certain patterns in a cop.
|
6
|
+
module ForbiddenPattern
|
7
|
+
def forbidden_pattern?(name)
|
8
|
+
forbidden_patterns.any? { |pattern| Regexp.new(pattern).match?(name) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def forbidden_patterns
|
12
|
+
cop_config.fetch('ForbiddenPatterns', [])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -6,7 +6,6 @@ module RuboCop
|
|
6
6
|
module FrozenStringLiteral
|
7
7
|
module_function
|
8
8
|
|
9
|
-
FROZEN_STRING_LITERAL_REGEXP = /#\s*frozen[-_]?string[-_]?literal:/i.freeze
|
10
9
|
FROZEN_STRING_LITERAL_ENABLED = '# frozen_string_literal: true'
|
11
10
|
FROZEN_STRING_LITERAL_TYPES_RUBY27 = %i[str dstr].freeze
|
12
11
|
|
@@ -242,7 +242,7 @@ module RuboCop
|
|
242
242
|
def find_definition(node)
|
243
243
|
# Methods can be defined in a `def` or `defs`,
|
244
244
|
# or dynamically via a `block` node.
|
245
|
-
node.each_ancestor(:
|
245
|
+
node.each_ancestor(:any_def, :block).each do |ancestor|
|
246
246
|
method_node, method_name = method_definition?(ancestor)
|
247
247
|
return [method_node, method_name] if method_node
|
248
248
|
end
|
@@ -6,14 +6,31 @@ module RuboCop
|
|
6
6
|
# Makes sure that all methods use the configured style,
|
7
7
|
# snake_case or camelCase, for their names.
|
8
8
|
#
|
9
|
-
#
|
9
|
+
# Method names matching patterns are always allowed.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
# AllowedPatterns:
|
13
|
-
# - '\AonSelectionBulkChange\z'
|
14
|
-
# - '\AonSelectionCleared\z'
|
11
|
+
# The cop can be configured with `AllowedPatterns` to allow certain regexp patterns:
|
15
12
|
#
|
16
|
-
#
|
13
|
+
# [source,yaml]
|
14
|
+
# ----
|
15
|
+
# Naming/MethodName:
|
16
|
+
# AllowedPatterns:
|
17
|
+
# - '\AonSelectionBulkChange\z'
|
18
|
+
# - '\AonSelectionCleared\z'
|
19
|
+
# ----
|
20
|
+
#
|
21
|
+
# As well, you can also forbid specific method names or regexp patterns
|
22
|
+
# using `ForbiddenIdentifiers` or `ForbiddenPatterns`:
|
23
|
+
#
|
24
|
+
# [source,yaml]
|
25
|
+
# ----
|
26
|
+
# Naming/MethodName:
|
27
|
+
# ForbiddenIdentifiers:
|
28
|
+
# - 'def'
|
29
|
+
# - 'super'
|
30
|
+
# ForbiddenPatterns:
|
31
|
+
# - '_v1\z'
|
32
|
+
# - '_gen1\z'
|
33
|
+
# ----
|
17
34
|
#
|
18
35
|
# @example EnforcedStyle: snake_case (default)
|
19
36
|
# # bad
|
@@ -28,12 +45,26 @@ module RuboCop
|
|
28
45
|
#
|
29
46
|
# # good
|
30
47
|
# def fooBar; end
|
48
|
+
#
|
49
|
+
# @example ForbiddenIdentifiers: ['def', 'super']
|
50
|
+
# # bad
|
51
|
+
# def def; end
|
52
|
+
# def super; end
|
53
|
+
#
|
54
|
+
# @example ForbiddenPatterns: ['_v1\z', '_gen1\z']
|
55
|
+
# # bad
|
56
|
+
# def release_v1; end
|
57
|
+
# def api_gen1; end
|
58
|
+
#
|
31
59
|
class MethodName < Base
|
32
60
|
include ConfigurableNaming
|
33
61
|
include AllowedPattern
|
34
62
|
include RangeHelp
|
63
|
+
include ForbiddenIdentifiers
|
64
|
+
include ForbiddenPattern
|
35
65
|
|
36
66
|
MSG = 'Use %<style>s for method names.'
|
67
|
+
MSG_FORBIDDEN = '`%<identifier>s` is forbidden, use another method name instead.'
|
37
68
|
|
38
69
|
# @!method sym_name(node)
|
39
70
|
def_node_matcher :sym_name, '(sym $_name)'
|
@@ -48,19 +79,44 @@ module RuboCop
|
|
48
79
|
name = attr_name(name_item)
|
49
80
|
next if !name || matches_allowed_pattern?(name)
|
50
81
|
|
51
|
-
|
82
|
+
if forbidden_name?(name.to_s)
|
83
|
+
register_forbidden_name(node)
|
84
|
+
else
|
85
|
+
check_name(node, name, range_position(node))
|
86
|
+
end
|
52
87
|
end
|
53
88
|
end
|
54
89
|
|
55
90
|
def on_def(node)
|
56
91
|
return if node.operator_method? || matches_allowed_pattern?(node.method_name)
|
57
92
|
|
58
|
-
|
93
|
+
if forbidden_name?(node.method_name.to_s)
|
94
|
+
register_forbidden_name(node)
|
95
|
+
else
|
96
|
+
check_name(node, node.method_name, node.loc.name)
|
97
|
+
end
|
59
98
|
end
|
60
99
|
alias on_defs on_def
|
61
100
|
|
62
101
|
private
|
63
102
|
|
103
|
+
def forbidden_name?(name)
|
104
|
+
forbidden_identifier?(name) || forbidden_pattern?(name)
|
105
|
+
end
|
106
|
+
|
107
|
+
def register_forbidden_name(node)
|
108
|
+
if node.any_def_type?
|
109
|
+
name_node = node.loc.name
|
110
|
+
method_name = node.method_name
|
111
|
+
else
|
112
|
+
attrs = node.attribute_accessor?
|
113
|
+
name_node = attrs.last.last
|
114
|
+
method_name = attr_name(name_node)
|
115
|
+
end
|
116
|
+
message = format(MSG_FORBIDDEN, identifier: method_name)
|
117
|
+
add_offense(name_node, message: message)
|
118
|
+
end
|
119
|
+
|
64
120
|
def attr_name(name_item)
|
65
121
|
sym_name(name_item) || str_name(name_item)
|
66
122
|
end
|
@@ -53,6 +53,8 @@ module RuboCop
|
|
53
53
|
include AllowedIdentifiers
|
54
54
|
include ConfigurableNaming
|
55
55
|
include AllowedPattern
|
56
|
+
include ForbiddenIdentifiers
|
57
|
+
include ForbiddenPattern
|
56
58
|
|
57
59
|
MSG = 'Use %<style>s for variable names.'
|
58
60
|
MSG_FORBIDDEN = '`%<identifier>s` is forbidden, use another name instead.'
|
@@ -92,27 +94,12 @@ module RuboCop
|
|
92
94
|
|
93
95
|
private
|
94
96
|
|
95
|
-
def message(style)
|
96
|
-
format(MSG, style: style)
|
97
|
-
end
|
98
|
-
|
99
|
-
def forbidden_identifiers
|
100
|
-
cop_config.fetch('ForbiddenIdentifiers', [])
|
101
|
-
end
|
102
|
-
|
103
|
-
def forbidden_patterns
|
104
|
-
cop_config.fetch('ForbiddenPatterns', [])
|
105
|
-
end
|
106
|
-
|
107
|
-
def matches_forbidden_pattern?(name)
|
108
|
-
forbidden_patterns.any? { |pattern| Regexp.new(pattern).match?(name) }
|
109
|
-
end
|
110
|
-
|
111
97
|
def forbidden_name?(name)
|
112
|
-
name
|
98
|
+
forbidden_identifier?(name) || forbidden_pattern?(name)
|
99
|
+
end
|
113
100
|
|
114
|
-
|
115
|
-
|
101
|
+
def message(style)
|
102
|
+
format(MSG, style: style)
|
116
103
|
end
|
117
104
|
|
118
105
|
def register_forbidden_name(node)
|