rubocop 1.35.1 → 1.36.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 +1 -1
- data/config/default.yml +11 -0
- data/lib/rubocop/cop/layout/block_alignment.rb +14 -12
- data/lib/rubocop/cop/layout/indentation_width.rb +3 -1
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +25 -9
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_require.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +31 -1
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +1 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +10 -5
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +13 -5
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +9 -5
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +77 -1
- data/lib/rubocop/cop/style/case_equality.rb +40 -10
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +40 -5
- data/lib/rubocop/cop/style/perl_backrefs.rb +22 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +4 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +5 -4
- data/lib/rubocop/runner.rb +4 -0
- data/lib/rubocop/version.rb +3 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bc2d4bd29fd7e81f4d7118fef9f55bcd2f086fd20ce383d85c2a1b7b26ea4e9
|
4
|
+
data.tar.gz: 9cb3cef8736b03dd0834b94fefe4415a301d78d842df184a1a1d290973376070
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abeba580bae46458f6427c3d21c6532e95ff88e7d981d196f5013fee29c8f911146f229daa8e6f92d2f28bb14790edc46373a4366f9881700df18a7f5a1352fa
|
7
|
+
data.tar.gz: 4bee5fc42db940e95cd6e3fba83680e6d7fd573a8ed3b7c65136a48d5f3b67ba8d299ecdd30a422afb95961d84c9b0452e3d1b6c1952e0edee1cea97ca704952
|
data/README.md
CHANGED
@@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
53
53
|
in your `Gemfile`:
|
54
54
|
|
55
55
|
```rb
|
56
|
-
gem 'rubocop', '~> 1.
|
56
|
+
gem 'rubocop', '~> 1.36', require: false
|
57
57
|
```
|
58
58
|
|
59
59
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
data/config/default.yml
CHANGED
@@ -2794,6 +2794,7 @@ Naming/MethodParameterName:
|
|
2794
2794
|
AllowNamesEndingInNumbers: true
|
2795
2795
|
# Allowed names that will not register an offense
|
2796
2796
|
AllowedNames:
|
2797
|
+
- as
|
2797
2798
|
- at
|
2798
2799
|
- by
|
2799
2800
|
- db
|
@@ -2948,6 +2949,7 @@ Style/AccessModifierDeclarations:
|
|
2948
2949
|
- inline
|
2949
2950
|
- group
|
2950
2951
|
AllowModifiersOnSymbols: true
|
2952
|
+
SafeAutoCorrect: false
|
2951
2953
|
|
2952
2954
|
Style/AccessorGrouping:
|
2953
2955
|
Description: 'Checks for grouping of accessors in `class` and `module` bodies.'
|
@@ -3186,6 +3188,15 @@ Style/CaseEquality:
|
|
3186
3188
|
# # good
|
3187
3189
|
# String === "string"
|
3188
3190
|
AllowOnConstant: false
|
3191
|
+
# If `AllowOnSelfClass` option is enabled, the cop will ignore violations when the receiver of
|
3192
|
+
# the case equality operator is `self.class`.
|
3193
|
+
#
|
3194
|
+
# # bad
|
3195
|
+
# some_class === object
|
3196
|
+
#
|
3197
|
+
# # good
|
3198
|
+
# self.class === object
|
3199
|
+
AllowOnSelfClass: false
|
3189
3200
|
|
3190
3201
|
Style/CaseLikeIf:
|
3191
3202
|
Description: 'Identifies places where `if-elsif` constructions can be replaced with `case-when`.'
|
@@ -22,23 +22,24 @@ module RuboCop
|
|
22
22
|
# # bad
|
23
23
|
#
|
24
24
|
# foo.bar
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
25
|
+
# .each do
|
26
|
+
# baz
|
27
|
+
# end
|
28
28
|
#
|
29
29
|
# # good
|
30
30
|
#
|
31
|
-
#
|
32
|
-
#
|
31
|
+
# foo.bar
|
32
|
+
# .each do
|
33
|
+
# baz
|
33
34
|
# end
|
34
35
|
#
|
35
36
|
# @example EnforcedStyleAlignWith: start_of_block
|
36
37
|
# # bad
|
37
38
|
#
|
38
39
|
# foo.bar
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
40
|
+
# .each do
|
41
|
+
# baz
|
42
|
+
# end
|
42
43
|
#
|
43
44
|
# # good
|
44
45
|
#
|
@@ -51,16 +52,17 @@ module RuboCop
|
|
51
52
|
# # bad
|
52
53
|
#
|
53
54
|
# foo.bar
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
55
|
+
# .each do
|
56
|
+
# baz
|
57
|
+
# end
|
57
58
|
#
|
58
59
|
# # good
|
59
60
|
#
|
60
61
|
# foo.bar
|
61
62
|
# .each do
|
62
|
-
#
|
63
|
+
# baz
|
63
64
|
# end
|
65
|
+
#
|
64
66
|
class BlockAlignment < Base
|
65
67
|
include ConfigurableEnforcedStyle
|
66
68
|
include RangeHelp
|
@@ -148,7 +148,9 @@ module RuboCop
|
|
148
148
|
check_indentation(in_pattern_node.loc.keyword, in_pattern_node.body)
|
149
149
|
end
|
150
150
|
|
151
|
-
|
151
|
+
else_branch = case_match.else_branch&.empty_else_type? ? nil : case_match.else_branch
|
152
|
+
|
153
|
+
check_indentation(case_match.in_pattern_branches.last.loc.keyword, else_branch)
|
152
154
|
end
|
153
155
|
|
154
156
|
def on_if(node, base = node)
|
@@ -131,7 +131,7 @@ module RuboCop
|
|
131
131
|
args_delimiter = node.arguments.loc.begin if node.block_type? # Can be ( | or nil.
|
132
132
|
|
133
133
|
check_left_brace(inner, node.loc.begin, args_delimiter)
|
134
|
-
check_right_brace(inner, node.loc.begin, node.loc.end, node.single_line?)
|
134
|
+
check_right_brace(node, inner, node.loc.begin, node.loc.end, node.single_line?)
|
135
135
|
end
|
136
136
|
|
137
137
|
def check_left_brace(inner, left_brace, args_delimiter)
|
@@ -142,14 +142,15 @@ module RuboCop
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
-
def check_right_brace(inner, left_brace, right_brace, single_line)
|
145
|
+
def check_right_brace(node, inner, left_brace, right_brace, single_line)
|
146
146
|
if single_line && /\S$/.match?(inner)
|
147
147
|
no_space(right_brace.begin_pos, right_brace.end_pos, 'Space missing inside }.')
|
148
148
|
else
|
149
|
+
column = node.loc.expression.column
|
149
150
|
return if multiline_block?(left_brace, right_brace) &&
|
150
|
-
aligned_braces?(
|
151
|
+
aligned_braces?(inner, right_brace, column)
|
151
152
|
|
152
|
-
space_inside_right_brace(right_brace)
|
153
|
+
space_inside_right_brace(inner, right_brace, column)
|
153
154
|
end
|
154
155
|
end
|
155
156
|
|
@@ -157,8 +158,12 @@ module RuboCop
|
|
157
158
|
left_brace.first_line != right_brace.first_line
|
158
159
|
end
|
159
160
|
|
160
|
-
def aligned_braces?(
|
161
|
-
|
161
|
+
def aligned_braces?(inner, right_brace, column)
|
162
|
+
column == right_brace.column || column == inner_last_space_count(inner)
|
163
|
+
end
|
164
|
+
|
165
|
+
def inner_last_space_count(inner)
|
166
|
+
inner.split("\n").last.count(' ')
|
162
167
|
end
|
163
168
|
|
164
169
|
def no_space_inside_left_brace(left_brace, args_delimiter)
|
@@ -197,10 +202,21 @@ module RuboCop
|
|
197
202
|
args_delimiter&.is?('|')
|
198
203
|
end
|
199
204
|
|
200
|
-
def space_inside_right_brace(right_brace)
|
205
|
+
def space_inside_right_brace(inner, right_brace, column)
|
201
206
|
brace_with_space = range_with_surrounding_space(right_brace, side: :left)
|
202
|
-
|
203
|
-
|
207
|
+
begin_pos = brace_with_space.begin_pos
|
208
|
+
end_pos = brace_with_space.end_pos - 1
|
209
|
+
|
210
|
+
if brace_with_space.source.match?(/\R/)
|
211
|
+
begin_pos = end_pos - (right_brace.column - column)
|
212
|
+
end
|
213
|
+
|
214
|
+
if inner.end_with?(']')
|
215
|
+
end_pos -= 1
|
216
|
+
begin_pos = end_pos - (inner_last_space_count(inner) - column)
|
217
|
+
end
|
218
|
+
|
219
|
+
space(begin_pos, end_pos, 'Space inside } detected.')
|
204
220
|
end
|
205
221
|
|
206
222
|
def no_space(begin_pos, end_pos, msg)
|
@@ -81,7 +81,7 @@ module RuboCop
|
|
81
81
|
def allowed_method_pattern?(node)
|
82
82
|
node.assignment? || node.operator_method? || node.method?(:[]) ||
|
83
83
|
allowed_method?(node.last_argument.method_name) ||
|
84
|
-
matches_allowed_pattern?(node.last_argument.
|
84
|
+
matches_allowed_pattern?(node.last_argument.send_node.source)
|
85
85
|
end
|
86
86
|
|
87
87
|
def message(send_node)
|
@@ -96,7 +96,7 @@ module RuboCop
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def correct_other_branches(corrector, node)
|
99
|
-
return unless (node
|
99
|
+
return unless require_other_branches_correction?(node)
|
100
100
|
|
101
101
|
if node.else_branch.if_type?
|
102
102
|
# Replace an orphaned `elsif` with `if`
|
@@ -107,13 +107,43 @@ module RuboCop
|
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
|
+
def require_other_branches_correction?(node)
|
111
|
+
return false unless node.if_type? && node.else_branch
|
112
|
+
return false if !empty_if_branch?(node) && node.elsif?
|
113
|
+
|
114
|
+
!empty_else_branch?(node)
|
115
|
+
end
|
116
|
+
|
117
|
+
def empty_if_branch?(node)
|
118
|
+
return false unless (parent = node.parent)
|
119
|
+
return true unless parent.if_type?
|
120
|
+
return true unless (if_branch = parent.if_branch)
|
121
|
+
|
122
|
+
if_branch.if_type? && !if_branch.body
|
123
|
+
end
|
124
|
+
|
125
|
+
def empty_else_branch?(node)
|
126
|
+
node.else_branch.if_type? && !node.else_branch.body
|
127
|
+
end
|
128
|
+
|
129
|
+
# rubocop:disable Metrics/AbcSize
|
110
130
|
def branch_range(node)
|
111
131
|
if node.loc.else
|
112
132
|
node.source_range.with(end_pos: node.loc.else.begin_pos - 1)
|
133
|
+
elsif all_branches_body_missing?(node)
|
134
|
+
if_node = node.ancestors.detect(&:if?)
|
135
|
+
node.source_range.with(end_pos: if_node.loc.end.end_pos)
|
113
136
|
else
|
114
137
|
node.source_range
|
115
138
|
end
|
116
139
|
end
|
140
|
+
# rubocop:enable Metrics/AbcSize
|
141
|
+
|
142
|
+
def all_branches_body_missing?(node)
|
143
|
+
return false unless node.parent&.if_type?
|
144
|
+
|
145
|
+
node.parent.branches.compact.empty?
|
146
|
+
end
|
117
147
|
|
118
148
|
def deletion_range(range)
|
119
149
|
# Collect a range between the start of the `if` node and the next relevant node,
|
@@ -12,7 +12,7 @@ module RuboCop
|
|
12
12
|
# same `rescue` statement. In both cases, the more specific rescue is
|
13
13
|
# unnecessary because it is covered by rescuing the less specific
|
14
14
|
# exception. (ie. `rescue Exception, StandardError` has the same behavior
|
15
|
-
# whether `StandardError` is included or not, because all
|
15
|
+
# whether `StandardError` is included or not, because all ``StandardError``s
|
16
16
|
# are rescued by `rescue Exception`).
|
17
17
|
#
|
18
18
|
# @example
|
@@ -64,14 +64,26 @@ module RuboCop
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def same_conditions_node_different_branch?(variable, outer_local_variable)
|
67
|
-
variable_node = variable
|
67
|
+
variable_node = variable_node(variable)
|
68
68
|
return false unless variable_node.conditional?
|
69
69
|
|
70
70
|
outer_local_variable_node =
|
71
71
|
find_conditional_node_from_ascendant(outer_local_variable.declaration_node)
|
72
72
|
return true unless outer_local_variable_node
|
73
73
|
|
74
|
-
outer_local_variable_node.conditional? &&
|
74
|
+
outer_local_variable_node.conditional? &&
|
75
|
+
(variable_node == outer_local_variable_node ||
|
76
|
+
variable_node == outer_local_variable_node.else_branch)
|
77
|
+
end
|
78
|
+
|
79
|
+
def variable_node(variable)
|
80
|
+
parent_node = variable.scope.node.parent
|
81
|
+
|
82
|
+
if parent_node.when_type?
|
83
|
+
parent_node.parent
|
84
|
+
else
|
85
|
+
parent_node
|
86
|
+
end
|
75
87
|
end
|
76
88
|
|
77
89
|
def find_conditional_node_from_ascendant(node)
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -17,16 +17,21 @@ module RuboCop
|
|
17
17
|
|
18
18
|
# @api public
|
19
19
|
def allowed_methods
|
20
|
-
|
21
|
-
|
22
|
-
cop_config.fetch('AllowedMethods', [])
|
20
|
+
if cop_config_deprecated_values.any?(Regexp)
|
21
|
+
cop_config_allowed_methods
|
23
22
|
else
|
24
|
-
|
23
|
+
cop_config_allowed_methods + cop_config_deprecated_values
|
25
24
|
end
|
26
25
|
end
|
27
26
|
|
27
|
+
def cop_config_allowed_methods
|
28
|
+
@cop_config_allowed_methods ||= Array(cop_config.fetch('AllowedMethods', []))
|
29
|
+
end
|
30
|
+
|
28
31
|
def cop_config_deprecated_values
|
29
|
-
|
32
|
+
@cop_config_deprecated_values ||=
|
33
|
+
Array(cop_config.fetch('IgnoredMethods', [])) +
|
34
|
+
Array(cop_config.fetch('ExcludedMethods', []))
|
30
35
|
end
|
31
36
|
end
|
32
37
|
# @deprecated IgnoredMethods class has been replaced with AllowedMethods.
|
@@ -30,15 +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
|
-
|
34
|
-
|
35
|
-
|
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
|
36
39
|
|
37
|
-
|
40
|
+
def cop_config_patterns_values
|
41
|
+
@cop_config_patterns_values ||=
|
42
|
+
Array(cop_config.fetch('AllowedPatterns', [])) +
|
43
|
+
Array(cop_config.fetch('IgnoredPatterns', []))
|
38
44
|
end
|
39
45
|
|
40
46
|
def cop_config_deprecated_methods_values
|
41
|
-
|
47
|
+
@cop_config_deprecated_methods_values ||=
|
48
|
+
Array(cop_config.fetch('IgnoredMethods', [])) +
|
49
|
+
Array(cop_config.fetch('ExcludedMethods', []))
|
42
50
|
end
|
43
51
|
end
|
44
52
|
|
@@ -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
|
@@ -9,6 +9,11 @@ module RuboCop
|
|
9
9
|
# Applications of visibility methods to symbols can be controlled
|
10
10
|
# using AllowModifiersOnSymbols config.
|
11
11
|
#
|
12
|
+
# @safety
|
13
|
+
# Autocorrection is not safe, because the visibility of dynamically
|
14
|
+
# defined methods can vary depending on the state determined by
|
15
|
+
# the group access modifier.
|
16
|
+
#
|
12
17
|
# @example EnforcedStyle: group (default)
|
13
18
|
# # bad
|
14
19
|
# class Foo
|
@@ -63,7 +68,10 @@ module RuboCop
|
|
63
68
|
#
|
64
69
|
# end
|
65
70
|
class AccessModifierDeclarations < Base
|
71
|
+
extend AutoCorrector
|
72
|
+
|
66
73
|
include ConfigurableEnforcedStyle
|
74
|
+
include RangeHelp
|
67
75
|
|
68
76
|
GROUP_STYLE_MESSAGE = [
|
69
77
|
'`%<access_modifier>s` should not be',
|
@@ -88,7 +96,10 @@ module RuboCop
|
|
88
96
|
return if allow_modifiers_on_symbols?(node)
|
89
97
|
|
90
98
|
if offense?(node)
|
91
|
-
add_offense(node.loc.selector)
|
99
|
+
add_offense(node.loc.selector) do |corrector|
|
100
|
+
autocorrect(corrector, node)
|
101
|
+
end
|
102
|
+
opposite_style_detected
|
92
103
|
else
|
93
104
|
correct_style_detected
|
94
105
|
end
|
@@ -96,6 +107,23 @@ module RuboCop
|
|
96
107
|
|
97
108
|
private
|
98
109
|
|
110
|
+
def autocorrect(corrector, node)
|
111
|
+
case style
|
112
|
+
when :group
|
113
|
+
def_node = find_corresponding_def_node(node)
|
114
|
+
return unless def_node
|
115
|
+
|
116
|
+
remove_node(corrector, def_node)
|
117
|
+
remove_node(corrector, node)
|
118
|
+
insert_def(corrector, node, def_node.source)
|
119
|
+
when :inline
|
120
|
+
remove_node(corrector, node)
|
121
|
+
select_grouped_def_nodes(node).each do |grouped_def_node|
|
122
|
+
insert_inline_modifier(corrector, grouped_def_node, node.method_name)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
99
127
|
def allow_modifiers_on_symbols?(node)
|
100
128
|
cop_config['AllowModifiersOnSymbols'] && access_modifier_with_symbol?(node)
|
101
129
|
end
|
@@ -130,6 +158,54 @@ module RuboCop
|
|
130
158
|
format(INLINE_STYLE_MESSAGE, access_modifier: access_modifier)
|
131
159
|
end
|
132
160
|
end
|
161
|
+
|
162
|
+
def find_corresponding_def_node(node)
|
163
|
+
if access_modifier_with_symbol?(node)
|
164
|
+
method_name = node.arguments.first.value
|
165
|
+
node.parent.each_child_node(:def).find do |child|
|
166
|
+
child.method?(method_name)
|
167
|
+
end
|
168
|
+
else
|
169
|
+
node.arguments.first
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def find_argument_less_modifier_node(node)
|
174
|
+
node.parent.each_child_node(:send).find do |child|
|
175
|
+
child.method?(node.method_name) && child.arguments.empty?
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def select_grouped_def_nodes(node)
|
180
|
+
node.right_siblings.take_while do |sibling|
|
181
|
+
!(sibling.send_type? && sibling.bare_access_modifier_declaration?)
|
182
|
+
end.select(&:def_type?)
|
183
|
+
end
|
184
|
+
|
185
|
+
def insert_def(corrector, node, source)
|
186
|
+
argument_less_modifier_node = find_argument_less_modifier_node(node)
|
187
|
+
if argument_less_modifier_node
|
188
|
+
corrector.insert_after(argument_less_modifier_node, "\n\n#{source}")
|
189
|
+
else
|
190
|
+
corrector.insert_before(
|
191
|
+
node.each_ancestor(:block, :class, :module).first.location.end,
|
192
|
+
"#{node.method_name}\n\n#{source}\n"
|
193
|
+
)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def insert_inline_modifier(corrector, node, modifier_name)
|
198
|
+
corrector.insert_before(node, "#{modifier_name} ")
|
199
|
+
end
|
200
|
+
|
201
|
+
def remove_node(corrector, node)
|
202
|
+
corrector.remove(
|
203
|
+
range_by_whole_lines(
|
204
|
+
node.location.expression,
|
205
|
+
include_final_newline: true
|
206
|
+
)
|
207
|
+
)
|
208
|
+
end
|
133
209
|
end
|
134
210
|
end
|
135
211
|
end
|
@@ -7,6 +7,9 @@ module RuboCop
|
|
7
7
|
#
|
8
8
|
# If `AllowOnConstant` option is enabled, the cop will ignore violations when the receiver of
|
9
9
|
# the case equality operator is a constant.
|
10
|
+
|
11
|
+
# If `AllowOnSelfClass` option is enabled, the cop will ignore violations when the receiver of
|
12
|
+
# the case equality operator is `self.class`. Note intermediate variables are not accepted.
|
10
13
|
#
|
11
14
|
# @example
|
12
15
|
# # bad
|
@@ -26,6 +29,14 @@ module RuboCop
|
|
26
29
|
# # good
|
27
30
|
# Array === something
|
28
31
|
#
|
32
|
+
# @example AllowOnSelfClass: false (default)
|
33
|
+
# # bad
|
34
|
+
# self.class === something
|
35
|
+
#
|
36
|
+
# @example AllowOnSelfClass: true
|
37
|
+
# # good
|
38
|
+
# self.class === something
|
39
|
+
#
|
29
40
|
class CaseEquality < Base
|
30
41
|
extend AutoCorrector
|
31
42
|
|
@@ -33,7 +44,10 @@ module RuboCop
|
|
33
44
|
RESTRICT_ON_SEND = %i[===].freeze
|
34
45
|
|
35
46
|
# @!method case_equality?(node)
|
36
|
-
def_node_matcher :case_equality?, '(send $#
|
47
|
+
def_node_matcher :case_equality?, '(send $#offending_receiver? :=== $_)'
|
48
|
+
|
49
|
+
# @!method self_class?(node)
|
50
|
+
def_node_matcher :self_class?, '(send (self) :class)'
|
37
51
|
|
38
52
|
def on_send(node)
|
39
53
|
case_equality?(node) do |lhs, rhs|
|
@@ -48,12 +62,11 @@ module RuboCop
|
|
48
62
|
|
49
63
|
private
|
50
64
|
|
51
|
-
def
|
52
|
-
if cop_config.fetch('AllowOnConstant', false)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
65
|
+
def offending_receiver?(node)
|
66
|
+
return false if node&.const_type? && cop_config.fetch('AllowOnConstant', false)
|
67
|
+
return false if self_class?(node) && cop_config.fetch('AllowOnSelfClass', false)
|
68
|
+
|
69
|
+
true
|
57
70
|
end
|
58
71
|
|
59
72
|
def replacement(lhs, rhs)
|
@@ -66,12 +79,29 @@ module RuboCop
|
|
66
79
|
#
|
67
80
|
# So here is noop.
|
68
81
|
when :begin
|
69
|
-
|
70
|
-
"#{lhs.source}.include?(#{rhs.source})" if child&.range_type?
|
82
|
+
begin_replacement(lhs, rhs)
|
71
83
|
when :const
|
72
|
-
|
84
|
+
const_replacement(lhs, rhs)
|
85
|
+
when :send
|
86
|
+
send_replacement(lhs, rhs)
|
73
87
|
end
|
74
88
|
end
|
89
|
+
|
90
|
+
def begin_replacement(lhs, rhs)
|
91
|
+
return unless lhs.children.first&.range_type?
|
92
|
+
|
93
|
+
"#{lhs.source}.include?(#{rhs.source})"
|
94
|
+
end
|
95
|
+
|
96
|
+
def const_replacement(lhs, rhs)
|
97
|
+
"#{rhs.source}.is_a?(#{lhs.source})"
|
98
|
+
end
|
99
|
+
|
100
|
+
def send_replacement(lhs, rhs)
|
101
|
+
return unless self_class?(lhs)
|
102
|
+
|
103
|
+
"#{rhs.source}.is_a?(#{lhs.source})"
|
104
|
+
end
|
75
105
|
end
|
76
106
|
end
|
77
107
|
end
|
@@ -28,14 +28,14 @@ module RuboCop
|
|
28
28
|
MSG = 'Use `Integer#times` for a simple loop which iterates a fixed number of times.'
|
29
29
|
|
30
30
|
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
31
|
-
return unless
|
31
|
+
return unless offending?(node)
|
32
32
|
|
33
33
|
send_node = node.send_node
|
34
34
|
|
35
35
|
range = send_node.receiver.source_range.join(send_node.loc.selector)
|
36
36
|
|
37
37
|
add_offense(range) do |corrector|
|
38
|
-
range_type, min, max =
|
38
|
+
range_type, min, max = each_range(node)
|
39
39
|
|
40
40
|
max += 1 if range_type == :irange
|
41
41
|
|
@@ -45,9 +45,44 @@ module RuboCop
|
|
45
45
|
|
46
46
|
private
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
def offending?(node)
|
49
|
+
each_range_with_zero_origin?(node) || each_range_without_block_argument?(node)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @!method each_range(node)
|
53
|
+
def_node_matcher :each_range, <<~PATTERN
|
54
|
+
(block
|
55
|
+
(send
|
56
|
+
(begin
|
57
|
+
(${irange erange}
|
58
|
+
(int $_) (int $_)))
|
59
|
+
:each)
|
60
|
+
(args ...)
|
61
|
+
...)
|
62
|
+
PATTERN
|
63
|
+
|
64
|
+
# @!method each_range_with_zero_origin?(node)
|
65
|
+
def_node_matcher :each_range_with_zero_origin?, <<~PATTERN
|
66
|
+
(block
|
67
|
+
(send
|
68
|
+
(begin
|
69
|
+
({irange erange}
|
70
|
+
(int 0) (int _)))
|
71
|
+
:each)
|
72
|
+
(args ...)
|
73
|
+
...)
|
74
|
+
PATTERN
|
75
|
+
|
76
|
+
# @!method each_range_without_block_argument?(node)
|
77
|
+
def_node_matcher :each_range_without_block_argument?, <<~PATTERN
|
78
|
+
(block
|
79
|
+
(send
|
80
|
+
(begin
|
81
|
+
({irange erange}
|
82
|
+
(int _) (int _)))
|
83
|
+
:each)
|
84
|
+
(args)
|
85
|
+
...)
|
51
86
|
PATTERN
|
52
87
|
end
|
53
88
|
end
|
@@ -83,10 +83,31 @@ module RuboCop
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
# @private
|
87
|
+
# @param [RuboCop::AST::Node] node
|
88
|
+
# @return [String, nil]
|
89
|
+
def preferred_expression_to_node_with_constant_prefix(node)
|
90
|
+
expression = preferred_expression_to(node)
|
91
|
+
return unless expression
|
92
|
+
|
93
|
+
"#{constant_prefix(node)}#{expression}"
|
94
|
+
end
|
95
|
+
|
96
|
+
# @private
|
97
|
+
# @param [RuboCop::AST::Node] node
|
98
|
+
# @return [String]
|
99
|
+
def constant_prefix(node)
|
100
|
+
if node.each_ancestor(:class, :module).any?
|
101
|
+
'::'
|
102
|
+
else
|
103
|
+
''
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
86
107
|
# @private
|
87
108
|
# @param [RuboCop::AST::Node] node
|
88
109
|
def on_back_ref_or_gvar_or_nth_ref(node)
|
89
|
-
preferred_expression =
|
110
|
+
preferred_expression = preferred_expression_to_node_with_constant_prefix(node)
|
90
111
|
return unless preferred_expression
|
91
112
|
|
92
113
|
add_offense(
|
@@ -29,6 +29,9 @@ module RuboCop
|
|
29
29
|
# @!method rescue?(node)
|
30
30
|
def_node_matcher :rescue?, '{^resbody ^^resbody}'
|
31
31
|
|
32
|
+
# @!method allowed_pin_operator?(node)
|
33
|
+
def_node_matcher :allowed_pin_operator?, '^(pin (begin !{lvar ivar cvar gvar}))'
|
34
|
+
|
32
35
|
# @!method arg_in_call_with_block?(node)
|
33
36
|
def_node_matcher :arg_in_call_with_block?, '^^(block (send _ _ equal?(%0) ...) ...)'
|
34
37
|
|
@@ -44,6 +47,7 @@ module RuboCop
|
|
44
47
|
empty_parentheses?(node) ||
|
45
48
|
first_arg_begins_with_hash_literal?(node) ||
|
46
49
|
rescue?(node) ||
|
50
|
+
allowed_pin_operator?(node) ||
|
47
51
|
allowed_expression?(node)
|
48
52
|
end
|
49
53
|
|
@@ -11,10 +11,11 @@ module RuboCop
|
|
11
11
|
# These are customizable with `AllowedMethods` option.
|
12
12
|
#
|
13
13
|
# @safety
|
14
|
-
# This cop is unsafe because
|
15
|
-
#
|
16
|
-
#
|
17
|
-
# an `ArgumentError
|
14
|
+
# This cop is unsafe because there is a difference that a `Proc`
|
15
|
+
# generated from `Symbol#to_proc` behaves as a lambda, while
|
16
|
+
# a `Proc` generated from a block does not.
|
17
|
+
# For example, a lambda will raise an `ArgumentError` if the
|
18
|
+
# number of arguments is wrong, but a non-lambda `Proc` will not.
|
18
19
|
#
|
19
20
|
# For example:
|
20
21
|
#
|
data/lib/rubocop/runner.rb
CHANGED
@@ -64,6 +64,10 @@ module RuboCop
|
|
64
64
|
# instances that each inspects its allotted group of files.
|
65
65
|
def warm_cache(target_files)
|
66
66
|
saved_options = @options.dup
|
67
|
+
if target_files.length <= 1
|
68
|
+
puts 'Skipping parallel inspection: only a single file needs inspection' if @options[:debug]
|
69
|
+
return
|
70
|
+
end
|
67
71
|
puts 'Running parallel inspection' if @options[:debug]
|
68
72
|
%i[autocorrect safe_autocorrect].each { |opt| @options[opt] = false }
|
69
73
|
Parallel.each(target_files) { |target_file| file_offenses(target_file) }
|
data/lib/rubocop/version.rb
CHANGED
@@ -3,11 +3,11 @@
|
|
3
3
|
module RuboCop
|
4
4
|
# This module holds the RuboCop version information.
|
5
5
|
module Version
|
6
|
-
STRING = '1.
|
6
|
+
STRING = '1.36.0'
|
7
7
|
|
8
8
|
MSG = '%<version>s (using Parser %<parser_version>s, ' \
|
9
9
|
'rubocop-ast %<rubocop_ast_version>s, ' \
|
10
|
-
'running on %<ruby_engine>s %<ruby_version>s %<ruby_platform>s
|
10
|
+
'running on %<ruby_engine>s %<ruby_version>s)%<server>s [%<ruby_platform>s]'
|
11
11
|
|
12
12
|
CANONICAL_FEATURE_NAMES = { 'Rspec' => 'RSpec', 'Graphql' => 'GraphQL', 'Md' => 'Markdown',
|
13
13
|
'Thread_safety' => 'ThreadSafety' }.freeze
|
@@ -19,6 +19,7 @@ module RuboCop
|
|
19
19
|
verbose_version = format(MSG, version: STRING, parser_version: Parser::VERSION,
|
20
20
|
rubocop_ast_version: RuboCop::AST::Version::STRING,
|
21
21
|
ruby_engine: RUBY_ENGINE, ruby_version: RUBY_VERSION,
|
22
|
+
server: Server.running? ? ' +server' : '',
|
22
23
|
ruby_platform: RUBY_PLATFORM)
|
23
24
|
return verbose_version unless env
|
24
25
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.36.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-
|
13
|
+
date: 2022-09-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -977,7 +977,7 @@ metadata:
|
|
977
977
|
homepage_uri: https://rubocop.org/
|
978
978
|
changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
|
979
979
|
source_code_uri: https://github.com/rubocop/rubocop/
|
980
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
980
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.36/
|
981
981
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
982
982
|
rubygems_mfa_required: 'true'
|
983
983
|
post_install_message:
|