rubocop 0.73.0 → 0.74.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/bin/console +1 -0
- data/config/default.yml +2 -1
- data/lib/rubocop.rb +3 -0
- data/lib/rubocop/ast/node.rb +1 -7
- data/lib/rubocop/config.rb +17 -537
- data/lib/rubocop/config_obsoletion.rb +201 -0
- data/lib/rubocop/config_validator.rb +239 -0
- data/lib/rubocop/cop/layout/extra_spacing.rb +14 -53
- data/lib/rubocop/cop/layout/indentation_width.rb +19 -5
- data/lib/rubocop/cop/layout/space_around_operators.rb +42 -23
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +22 -40
- data/lib/rubocop/cop/lint/debugger.rb +0 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +56 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
- data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -6
- data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +6 -1
- data/lib/rubocop/cop/metrics/line_length.rb +6 -0
- data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
- data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
- data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
- data/lib/rubocop/cop/style/commented_keyword.rb +8 -28
- data/lib/rubocop/cop/style/conditional_assignment.rb +1 -3
- data/lib/rubocop/cop/style/constant_visibility.rb +13 -2
- data/lib/rubocop/cop/style/guard_clause.rb +39 -10
- data/lib/rubocop/cop/style/lambda.rb +0 -2
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
- data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
- data/lib/rubocop/path_util.rb +1 -1
- data/lib/rubocop/processed_source.rb +4 -0
- data/lib/rubocop/rspec/expect_offense.rb +4 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +5 -2
@@ -158,11 +158,7 @@ module RuboCop
|
|
158
158
|
if indentation_consistency_style == 'indented_internal_methods'
|
159
159
|
check_members_for_indented_internal_methods_style(members)
|
160
160
|
else
|
161
|
-
members
|
162
|
-
next if member.send_type? && member.access_modifier?
|
163
|
-
|
164
|
-
check_indentation(base, member)
|
165
|
-
end
|
161
|
+
check_members_for_normal_style(base, members)
|
166
162
|
end
|
167
163
|
end
|
168
164
|
|
@@ -170,6 +166,8 @@ module RuboCop
|
|
170
166
|
return unless member
|
171
167
|
|
172
168
|
if access_modifier?(member.children.first)
|
169
|
+
return if access_modifier_indentation_style == 'outdent'
|
170
|
+
|
173
171
|
member.children.first
|
174
172
|
else
|
175
173
|
member
|
@@ -183,6 +181,14 @@ module RuboCop
|
|
183
181
|
end
|
184
182
|
end
|
185
183
|
|
184
|
+
def check_members_for_normal_style(base, members)
|
185
|
+
members.first.children.each do |member|
|
186
|
+
next if member.send_type? && member.access_modifier?
|
187
|
+
|
188
|
+
check_indentation(base, member)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
186
192
|
def each_member(members)
|
187
193
|
previous_modifier = nil
|
188
194
|
members.first.children.each do |member|
|
@@ -199,6 +205,14 @@ module RuboCop
|
|
199
205
|
indentation_consistency_style == 'indented_internal_methods'
|
200
206
|
end
|
201
207
|
|
208
|
+
def special_modifier?(node)
|
209
|
+
node.bare_access_modifier? && SPECIAL_MODIFIERS.include?(node.source)
|
210
|
+
end
|
211
|
+
|
212
|
+
def access_modifier_indentation_style
|
213
|
+
config.for_cop('Layout/AccessModifierIndentation')['EnforcedStyle']
|
214
|
+
end
|
215
|
+
|
202
216
|
def indentation_consistency_style
|
203
217
|
config.for_cop('Layout/IndentationConsistency')['EnforcedStyle']
|
204
218
|
end
|
@@ -34,14 +34,14 @@ module RuboCop
|
|
34
34
|
|
35
35
|
return if hash_table_style? && !node.parent.pairs_on_same_line?
|
36
36
|
|
37
|
-
check_operator(node.loc.operator, node.source_range)
|
37
|
+
check_operator(:pair, node.loc.operator, node.source_range)
|
38
38
|
end
|
39
39
|
|
40
40
|
def on_if(node)
|
41
41
|
return unless node.ternary?
|
42
42
|
|
43
|
-
check_operator(node.loc.question, node.if_branch.source_range)
|
44
|
-
check_operator(node.loc.colon, node.else_branch.source_range)
|
43
|
+
check_operator(:if, node.loc.question, node.if_branch.source_range)
|
44
|
+
check_operator(:if, node.loc.colon, node.else_branch.source_range)
|
45
45
|
end
|
46
46
|
|
47
47
|
def on_resbody(node)
|
@@ -49,23 +49,33 @@ module RuboCop
|
|
49
49
|
|
50
50
|
_, variable, = *node
|
51
51
|
|
52
|
-
check_operator(node.loc.assoc, variable.source_range)
|
52
|
+
check_operator(:resbody, node.loc.assoc, variable.source_range)
|
53
53
|
end
|
54
54
|
|
55
55
|
def on_send(node)
|
56
56
|
if node.setter_method?
|
57
57
|
on_special_asgn(node)
|
58
58
|
elsif regular_operator?(node)
|
59
|
-
check_operator(
|
59
|
+
check_operator(:send,
|
60
|
+
node.loc.selector,
|
61
|
+
node.first_argument.source_range)
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
65
|
+
def on_assignment(node)
|
66
|
+
_, rhs, = *node
|
67
|
+
|
68
|
+
return unless rhs
|
69
|
+
|
70
|
+
check_operator(:assignment, node.loc.operator, rhs.source_range)
|
71
|
+
end
|
72
|
+
|
63
73
|
def on_binary(node)
|
64
74
|
_, rhs, = *node
|
65
75
|
|
66
76
|
return unless rhs
|
67
77
|
|
68
|
-
check_operator(node.loc.operator, rhs.source_range)
|
78
|
+
check_operator(:binary, node.loc.operator, rhs.source_range)
|
69
79
|
end
|
70
80
|
|
71
81
|
def on_special_asgn(node)
|
@@ -73,20 +83,20 @@ module RuboCop
|
|
73
83
|
|
74
84
|
return unless right
|
75
85
|
|
76
|
-
check_operator(node.loc.operator, right.source_range)
|
86
|
+
check_operator(:special_asgn, node.loc.operator, right.source_range)
|
77
87
|
end
|
78
88
|
|
79
89
|
alias on_or on_binary
|
80
90
|
alias on_and on_binary
|
81
|
-
alias on_lvasgn
|
82
|
-
alias on_masgn
|
91
|
+
alias on_lvasgn on_assignment
|
92
|
+
alias on_masgn on_assignment
|
83
93
|
alias on_casgn on_special_asgn
|
84
|
-
alias on_ivasgn
|
85
|
-
alias on_cvasgn
|
86
|
-
alias on_gvasgn
|
94
|
+
alias on_ivasgn on_assignment
|
95
|
+
alias on_cvasgn on_assignment
|
96
|
+
alias on_gvasgn on_assignment
|
87
97
|
alias on_class on_binary
|
88
|
-
alias on_or_asgn
|
89
|
-
alias on_and_asgn
|
98
|
+
alias on_or_asgn on_assignment
|
99
|
+
alias on_and_asgn on_assignment
|
90
100
|
alias on_op_asgn on_special_asgn
|
91
101
|
|
92
102
|
def autocorrect(range)
|
@@ -113,35 +123,44 @@ module RuboCop
|
|
113
123
|
!IRREGULAR_METHODS.include?(send_node.method_name)
|
114
124
|
end
|
115
125
|
|
116
|
-
def check_operator(operator, right_operand)
|
126
|
+
def check_operator(type, operator, right_operand)
|
117
127
|
with_space = range_with_surrounding_space(range: operator)
|
118
128
|
return if with_space.source.start_with?("\n")
|
119
129
|
|
120
|
-
offense(operator, with_space, right_operand) do |msg|
|
130
|
+
offense(type, operator, with_space, right_operand) do |msg|
|
121
131
|
add_offense(with_space, location: operator, message: msg)
|
122
132
|
end
|
123
133
|
end
|
124
134
|
|
125
|
-
def offense(operator, with_space, right_operand)
|
126
|
-
msg = offense_message(operator, with_space, right_operand)
|
135
|
+
def offense(type, operator, with_space, right_operand)
|
136
|
+
msg = offense_message(type, operator, with_space, right_operand)
|
127
137
|
yield msg if msg
|
128
138
|
end
|
129
139
|
|
130
|
-
def offense_message(operator, with_space, right_operand)
|
140
|
+
def offense_message(type, operator, with_space, right_operand)
|
131
141
|
if operator.is?('**')
|
132
142
|
'Space around operator `**` detected.' unless with_space.is?('**')
|
133
143
|
elsif with_space.source !~ /^\s.*\s$/
|
134
144
|
"Surrounding space missing for operator `#{operator.source}`."
|
135
|
-
elsif excess_leading_space?(operator, with_space) ||
|
145
|
+
elsif excess_leading_space?(type, operator, with_space) ||
|
136
146
|
excess_trailing_space?(right_operand, with_space)
|
137
147
|
"Operator `#{operator.source}` should be surrounded " \
|
138
148
|
'by a single space.'
|
139
149
|
end
|
140
150
|
end
|
141
151
|
|
142
|
-
def excess_leading_space?(operator, with_space)
|
143
|
-
|
144
|
-
|
152
|
+
def excess_leading_space?(type, operator, with_space)
|
153
|
+
return false unless allow_for_alignment?
|
154
|
+
return false unless with_space.source.start_with?(EXCESSIVE_SPACE)
|
155
|
+
|
156
|
+
return !aligned_with_operator?(operator) unless type == :assignment
|
157
|
+
|
158
|
+
token = Token.new(operator, nil, operator.source)
|
159
|
+
align_preceding = aligned_with_preceding_assignment(token)
|
160
|
+
|
161
|
+
return align_preceding == :no unless align_preceding == :none
|
162
|
+
|
163
|
+
aligned_with_subsequent_assignment(token) != :yes
|
145
164
|
end
|
146
165
|
|
147
166
|
def excess_trailing_space?(right_operand, with_space)
|
@@ -19,61 +19,43 @@ module RuboCop
|
|
19
19
|
# # good
|
20
20
|
# var = "This is the #{ space } example"
|
21
21
|
class SpaceInsideStringInterpolation < Cop
|
22
|
+
include Interpolation
|
23
|
+
include SurroundingSpace
|
22
24
|
include ConfigurableEnforcedStyle
|
23
25
|
include RangeHelp
|
24
26
|
|
25
27
|
NO_SPACE_MSG = 'Space inside string interpolation detected.'
|
26
|
-
SPACE_MSG = 'Missing space
|
28
|
+
SPACE_MSG = 'Missing space inside string interpolation detected.'
|
27
29
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
30
|
+
def on_interpolation(begin_node)
|
31
|
+
delims = delimiters(begin_node)
|
32
|
+
return if empty_brackets?(*delims)
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
range_with_surrounding_space(range: node.source_range),
|
39
|
-
new_source
|
40
|
-
)
|
34
|
+
if style == :no_space
|
35
|
+
no_space_offenses(begin_node, *delims, NO_SPACE_MSG)
|
36
|
+
else
|
37
|
+
space_offenses(begin_node, *delims, SPACE_MSG)
|
41
38
|
end
|
42
39
|
end
|
43
40
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
node.each_child_node(:begin) do |begin_node|
|
48
|
-
final_node = begin_node.children.last
|
49
|
-
next unless final_node
|
41
|
+
def autocorrect(begin_node)
|
42
|
+
lambda do |corrector|
|
43
|
+
delims = delimiters(begin_node)
|
50
44
|
|
51
|
-
if style == :no_space
|
52
|
-
|
53
|
-
|
54
|
-
|
45
|
+
if style == :no_space
|
46
|
+
SpaceCorrector.remove_space(processed_source, corrector, *delims)
|
47
|
+
else
|
48
|
+
SpaceCorrector.add_space(processed_source, corrector, *delims)
|
55
49
|
end
|
56
50
|
end
|
57
51
|
end
|
58
52
|
|
59
|
-
|
60
|
-
style == :no_space ? NO_SPACE_MSG : SPACE_MSG
|
61
|
-
end
|
62
|
-
|
63
|
-
def space_on_any_side?(node)
|
64
|
-
interp = node.source_range
|
65
|
-
interp_with_surrounding_space =
|
66
|
-
range_with_surrounding_space(range: interp)
|
67
|
-
|
68
|
-
interp_with_surrounding_space != interp
|
69
|
-
end
|
70
|
-
|
71
|
-
def space_on_each_side?(node)
|
72
|
-
interp = node.source_range
|
73
|
-
interp_with_surrounding_space =
|
74
|
-
range_with_surrounding_space(range: interp)
|
53
|
+
private
|
75
54
|
|
76
|
-
|
55
|
+
def delimiters(begin_node)
|
56
|
+
left = processed_source.tokens[index_of_first_token(begin_node)]
|
57
|
+
right = processed_source.tokens[index_of_last_token(begin_node)]
|
58
|
+
[left, right]
|
77
59
|
end
|
78
60
|
end
|
79
61
|
end
|
@@ -17,12 +17,12 @@ module RuboCop
|
|
17
17
|
#
|
18
18
|
# "result is #{some_result}"
|
19
19
|
class EmptyInterpolation < Cop
|
20
|
+
include Interpolation
|
21
|
+
|
20
22
|
MSG = 'Empty interpolation detected.'
|
21
23
|
|
22
|
-
def
|
23
|
-
|
24
|
-
add_offense(begin_node) if begin_node.children.empty?
|
25
|
-
end
|
24
|
+
def on_interpolation(begin_node)
|
25
|
+
add_offense(begin_node) if begin_node.children.empty?
|
26
26
|
end
|
27
27
|
|
28
28
|
def autocorrect(node)
|
@@ -61,6 +61,7 @@ module RuboCop
|
|
61
61
|
#
|
62
62
|
class ErbNewArguments < Cop
|
63
63
|
extend TargetRubyVersion
|
64
|
+
include RangeHelp
|
64
65
|
|
65
66
|
minimum_target_ruby_version 2.6
|
66
67
|
|
@@ -97,10 +98,65 @@ module RuboCop
|
|
97
98
|
end
|
98
99
|
end
|
99
100
|
|
101
|
+
def autocorrect(node)
|
102
|
+
str_arg = node.arguments[0].source
|
103
|
+
|
104
|
+
kwargs = build_kwargs(node)
|
105
|
+
overridden_kwargs = override_by_legacy_args(kwargs, node)
|
106
|
+
|
107
|
+
good_arguments = [
|
108
|
+
str_arg, overridden_kwargs
|
109
|
+
].flatten.compact.join(', ')
|
110
|
+
|
111
|
+
lambda do |corrector|
|
112
|
+
corrector.replace(arguments_range(node), good_arguments)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
100
118
|
def correct_arguments?(arguments)
|
101
119
|
arguments.size == 1 ||
|
102
120
|
arguments.size == 2 && arguments[1].hash_type?
|
103
121
|
end
|
122
|
+
|
123
|
+
def build_kwargs(node)
|
124
|
+
return [nil, nil] unless node.arguments.last.hash_type?
|
125
|
+
|
126
|
+
trim_mode_arg, eoutvar_arg = nil
|
127
|
+
|
128
|
+
node.arguments.last.pairs.each do |pair|
|
129
|
+
case pair.key.source
|
130
|
+
when 'trim_mode'
|
131
|
+
trim_mode_arg = "trim_mode: #{pair.value.source}"
|
132
|
+
when 'eoutvar'
|
133
|
+
eoutvar_arg = "eoutvar: #{pair.value.source}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
[trim_mode_arg, eoutvar_arg]
|
138
|
+
end
|
139
|
+
|
140
|
+
def override_by_legacy_args(kwargs, node)
|
141
|
+
overridden_kwargs = kwargs.dup
|
142
|
+
|
143
|
+
if node.arguments[2]
|
144
|
+
overridden_kwargs[0] = "trim_mode: #{node.arguments[2].source}"
|
145
|
+
end
|
146
|
+
|
147
|
+
if node.arguments[3] && !node.arguments[3].hash_type?
|
148
|
+
overridden_kwargs[1] = "eoutvar: #{node.arguments[3].source}"
|
149
|
+
end
|
150
|
+
|
151
|
+
overridden_kwargs
|
152
|
+
end
|
153
|
+
|
154
|
+
def arguments_range(node)
|
155
|
+
arguments = node.arguments
|
156
|
+
|
157
|
+
range_between(arguments.first.source_range.begin_pos,
|
158
|
+
arguments.last.source_range.end_pos)
|
159
|
+
end
|
104
160
|
end
|
105
161
|
end
|
106
162
|
end
|
@@ -17,21 +17,20 @@ module RuboCop
|
|
17
17
|
#
|
18
18
|
# "result is 10"
|
19
19
|
class LiteralInInterpolation < Cop
|
20
|
+
include Interpolation
|
20
21
|
include RangeHelp
|
21
22
|
include PercentLiteral
|
22
23
|
|
23
24
|
MSG = 'Literal interpolation detected.'
|
24
25
|
COMPOSITE = %i[array hash pair irange erange].freeze
|
25
26
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
next unless prints_as_self?(final_node)
|
27
|
+
def on_interpolation(begin_node)
|
28
|
+
final_node = begin_node.children.last
|
29
|
+
return unless final_node
|
30
|
+
return if special_keyword?(final_node)
|
31
|
+
return unless prints_as_self?(final_node)
|
32
32
|
|
33
|
-
|
34
|
-
end
|
33
|
+
add_offense(final_node)
|
35
34
|
end
|
36
35
|
|
37
36
|
def autocorrect(node)
|
@@ -18,20 +18,20 @@ module RuboCop
|
|
18
18
|
#
|
19
19
|
# "result is #{something}"
|
20
20
|
class StringConversionInInterpolation < Cop
|
21
|
+
include Interpolation
|
22
|
+
|
21
23
|
MSG_DEFAULT = 'Redundant use of `Object#to_s` in interpolation.'
|
22
24
|
MSG_SELF = 'Use `self` instead of `Object#to_s` in ' \
|
23
25
|
'interpolation.'
|
24
26
|
|
25
27
|
def_node_matcher :to_s_without_args?, '(send _ :to_s)'
|
26
28
|
|
27
|
-
def
|
28
|
-
|
29
|
-
final_node = begin_node.children.last
|
29
|
+
def on_interpolation(begin_node)
|
30
|
+
final_node = begin_node.children.last
|
30
31
|
|
31
|
-
|
32
|
+
return unless to_s_without_args?(final_node)
|
32
33
|
|
33
|
-
|
34
|
-
end
|
34
|
+
add_offense(final_node, location: :selector)
|
35
35
|
end
|
36
36
|
|
37
37
|
def autocorrect(node)
|
@@ -58,7 +58,12 @@ module RuboCop
|
|
58
58
|
PERCENT_CAPITAL_I = '%I'
|
59
59
|
ASSIGNMENT_TYPES = %i[lvasgn ivasgn cvasgn gvasgn].freeze
|
60
60
|
|
61
|
-
def_node_matcher :array_new?,
|
61
|
+
def_node_matcher :array_new?, <<~PATTERN
|
62
|
+
{
|
63
|
+
$(send (const nil? :Array) :new ...)
|
64
|
+
$(block (send (const nil? :Array) :new ...) ...)
|
65
|
+
}
|
66
|
+
PATTERN
|
62
67
|
|
63
68
|
def_node_matcher :literal_expansion, <<~PATTERN
|
64
69
|
(splat {$({str dstr int float array} ...) (block $#array_new? ...) $#array_new?} ...)
|
@@ -10,6 +10,7 @@ module RuboCop
|
|
10
10
|
# The maximum length is configurable.
|
11
11
|
# The tab size is configured in the `IndentationWidth`
|
12
12
|
# of the `Layout/Tab` cop.
|
13
|
+
# It also ignores a shebang line by default.
|
13
14
|
#
|
14
15
|
# This cop has some autocorrection capabilities.
|
15
16
|
# It can programmatically shorten certain long lines by
|
@@ -138,9 +139,14 @@ module RuboCop
|
|
138
139
|
|
139
140
|
def ignored_line?(line, line_index)
|
140
141
|
matches_ignored_pattern?(line) ||
|
142
|
+
shebang?(line, line_index) ||
|
141
143
|
heredocs && line_in_permitted_heredoc?(line_index.succ)
|
142
144
|
end
|
143
145
|
|
146
|
+
def shebang?(line, line_index)
|
147
|
+
line_index.zero? && line.start_with?('#!')
|
148
|
+
end
|
149
|
+
|
144
150
|
def register_offense(loc, line, line_index)
|
145
151
|
message = format(MSG, length: line_length(line), max: max)
|
146
152
|
|