rubocop 1.80.2 → 1.81.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 +10 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
- data/lib/rubocop/cli.rb +1 -2
- data/lib/rubocop/config_loader.rb +3 -1
- data/lib/rubocop/config_store.rb +5 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +2 -2
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
- data/lib/rubocop/cop/layout/class_structure.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +30 -12
- data/lib/rubocop/cop/layout/line_length.rb +9 -1
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +6 -4
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +8 -0
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
- data/lib/rubocop/cop/lint/void.rb +7 -0
- data/lib/rubocop/cop/message_annotator.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/naming/predicate_method.rb +12 -0
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/it_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
- data/lib/rubocop/cop/style/numbered_parameters.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +18 -3
- data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -0
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -0
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45 -0
- data/lib/rubocop/cop/style/unless_else.rb +10 -9
- data/lib/rubocop/cop/utils/format_string.rb +10 -0
- data/lib/rubocop/lsp/diagnostic.rb +21 -20
- data/lib/rubocop/lsp/routes.rb +36 -9
- data/lib/rubocop/lsp/runtime.rb +2 -2
- data/lib/rubocop/lsp/server.rb +2 -2
- data/lib/rubocop/lsp/stdin_runner.rb +0 -16
- data/lib/rubocop/target_ruby.rb +10 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +1 -0
- data/lib/ruby_lsp/rubocop/addon.rb +23 -8
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +49 -15
- metadata +11 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 740da46aac4303ae1e22af254e9e3032b28d1348feab710e3b7d7670b0803178
|
4
|
+
data.tar.gz: bdb0f8b8612d6f2576f3497bc07f879b6abeb755d6654428a7df0fc8a8c93a31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f71823ab8429f83de38d37f56b9fceabec9fba2b119b8525e6dd0bc49082be3c3e94ea6b1a1f9eb5c63a9bf1d27e70bceb26eedade472a9723631c93ce82b7b8
|
7
|
+
data.tar.gz: 209b99bda6d9d1c140cb1959e33ef84eca2a9791dd97e91c8cba3de172a4f5fa8d3bd8feec7e397c35ea120f084e2f8bd95881bfa69cc8e6832812253d56f045
|
data/README.md
CHANGED
@@ -51,7 +51,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
51
51
|
in your `Gemfile`:
|
52
52
|
|
53
53
|
```rb
|
54
|
-
gem 'rubocop', '~> 1.
|
54
|
+
gem 'rubocop', '~> 1.81', require: false
|
55
55
|
```
|
56
56
|
|
57
57
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
data/config/default.yml
CHANGED
@@ -3341,6 +3341,12 @@ Style/ArrayIntersect:
|
|
3341
3341
|
Safe: false
|
3342
3342
|
VersionAdded: '1.40'
|
3343
3343
|
|
3344
|
+
Style/ArrayIntersectWithSingleElement:
|
3345
|
+
Description: 'Use `include?(element)` instead of `intersect?([element])`.'
|
3346
|
+
Enabled: 'pending'
|
3347
|
+
Safe: false
|
3348
|
+
VersionAdded: '1.81'
|
3349
|
+
|
3344
3350
|
Style/ArrayJoin:
|
3345
3351
|
Description: 'Use Array#join instead of Array#*.'
|
3346
3352
|
StyleGuide: '#array-join'
|
@@ -5844,10 +5850,14 @@ Style/TrailingCommaInArguments:
|
|
5844
5850
|
# parenthesized method calls where each argument is on its own line.
|
5845
5851
|
# If `consistent_comma`, the cop requires a comma after the last argument,
|
5846
5852
|
# for all parenthesized method calls with arguments.
|
5853
|
+
# If `diff_comma`, the cop requires a comma after the last argument, but only
|
5854
|
+
# when that argument is followed by an immediate newline, even if
|
5855
|
+
# there is an inline comment.
|
5847
5856
|
EnforcedStyleForMultiline: no_comma
|
5848
5857
|
SupportedStylesForMultiline:
|
5849
5858
|
- comma
|
5850
5859
|
- consistent_comma
|
5860
|
+
- diff_comma
|
5851
5861
|
- no_comma
|
5852
5862
|
|
5853
5863
|
Style/TrailingCommaInArrayLiteral:
|
@@ -83,7 +83,7 @@ module RuboCop
|
|
83
83
|
execute_runner
|
84
84
|
@options.delete(:only)
|
85
85
|
@config_store = ConfigStore.new
|
86
|
-
@config_store.
|
86
|
+
@config_store.apply_options!(@options)
|
87
87
|
# Save the todo configuration of the LineLength cop.
|
88
88
|
File.read(AUTO_GENERATED_FILE).lines.drop_while { |line| line.start_with?('#') }.join
|
89
89
|
end
|
@@ -99,7 +99,7 @@ module RuboCop
|
|
99
99
|
|
100
100
|
def reset_config_and_auto_gen_file
|
101
101
|
@config_store = ConfigStore.new
|
102
|
-
@config_store.
|
102
|
+
@config_store.apply_options!(@options)
|
103
103
|
File.open(AUTO_GENERATED_FILE, 'w') {} # create or truncate if exists
|
104
104
|
add_inheritance_from_auto_generated_file(@options[:config])
|
105
105
|
end
|
data/lib/rubocop/cli.rb
CHANGED
@@ -164,8 +164,7 @@ module RuboCop
|
|
164
164
|
set_options_to_pending_cops_reporter
|
165
165
|
handle_editor_mode
|
166
166
|
|
167
|
-
@config_store.
|
168
|
-
@config_store.force_default_config! if @options[:force_default_config]
|
167
|
+
@config_store.apply_options!(@options)
|
169
168
|
|
170
169
|
handle_exiting_options
|
171
170
|
|
@@ -75,7 +75,9 @@ module RuboCop
|
|
75
75
|
|
76
76
|
puts "configuration from #{absolute_path}" if debug?
|
77
77
|
|
78
|
-
|
78
|
+
unless hash.is_a?(Hash)
|
79
|
+
raise(ValidationError, "Malformed configuration in #{absolute_path}")
|
80
|
+
end
|
79
81
|
|
80
82
|
hash
|
81
83
|
end
|
data/lib/rubocop/config_store.rb
CHANGED
@@ -25,6 +25,11 @@ module RuboCop
|
|
25
25
|
@validated = true
|
26
26
|
end
|
27
27
|
|
28
|
+
def apply_options!(options)
|
29
|
+
self.options_config = options[:config] if options[:config]
|
30
|
+
force_default_config! if options[:force_default_config]
|
31
|
+
end
|
32
|
+
|
28
33
|
def options_config=(options_config)
|
29
34
|
loaded_config = ConfigLoader.load_file(options_config)
|
30
35
|
@options_config = ConfigLoader.merge_with_default(loaded_config, options_config)
|
@@ -94,7 +94,7 @@ module RuboCop
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def surrounding_heredoc?(node)
|
97
|
-
node.
|
97
|
+
node.any_str_type? && node.heredoc?
|
98
98
|
end
|
99
99
|
|
100
100
|
def heredoc_range(node)
|
@@ -106,7 +106,7 @@ module RuboCop
|
|
106
106
|
end
|
107
107
|
|
108
108
|
def string_continuation?(node)
|
109
|
-
node.
|
109
|
+
node.any_str_type? && node.source.match?(/\\\s*$/)
|
110
110
|
end
|
111
111
|
|
112
112
|
def multiline_string?(node)
|
@@ -57,7 +57,7 @@ module RuboCop
|
|
57
57
|
def inside_string_ranges(node)
|
58
58
|
return [] unless node.is_a?(Parser::AST::Node)
|
59
59
|
|
60
|
-
node.each_node(:
|
60
|
+
node.each_node(:any_str).filter_map { |n| inside_string_range(n) }
|
61
61
|
end
|
62
62
|
|
63
63
|
def inside_string_range(node)
|
@@ -30,6 +30,8 @@ module RuboCop
|
|
30
30
|
any_block: %i[block numblock itblock],
|
31
31
|
any_def: %i[def defs],
|
32
32
|
any_match_pattern: %i[match_pattern match_pattern_p],
|
33
|
+
any_str: %i[str dstr xstr],
|
34
|
+
any_sym: %i[sym dsym],
|
33
35
|
argument: %i[arg optarg restarg kwarg kwoptarg kwrestarg blockarg forward_arg shadowarg],
|
34
36
|
boolean: %i[true false],
|
35
37
|
call: %i[send csend],
|
@@ -210,7 +212,7 @@ module RuboCop
|
|
210
212
|
# A heredoc can be a `dstr` without interpolation, but if there is interpolation
|
211
213
|
# there'll be a `begin` node, in which case, we cannot evaluate the pattern.
|
212
214
|
def acceptable_heredoc?(node)
|
213
|
-
node.
|
215
|
+
node.any_str_type? && node.heredoc? && node.each_child_node(:begin).none?
|
214
216
|
end
|
215
217
|
|
216
218
|
def process_pattern(pattern_node)
|
@@ -76,7 +76,7 @@ module RuboCop
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def on_send(node) # rubocop:disable InternalAffairs/OnSendWithoutOnCSend
|
79
|
-
new_identifier = node.first_argument
|
79
|
+
return unless (new_identifier = node.first_argument)
|
80
80
|
return unless new_identifier.basic_literal?
|
81
81
|
|
82
82
|
new_identifier = new_identifier.value
|
@@ -76,28 +76,40 @@ module RuboCop
|
|
76
76
|
# # good
|
77
77
|
# class ErrorA < BaseError; end
|
78
78
|
# class ErrorB < BaseError; end
|
79
|
-
# class ErrorC < BaseError; end
|
80
79
|
#
|
81
80
|
# # good
|
82
81
|
# class ErrorA < BaseError; end
|
83
82
|
#
|
84
83
|
# class ErrorB < BaseError; end
|
85
84
|
#
|
86
|
-
#
|
85
|
+
# # good - DefLikeMacros: [memoize]
|
86
|
+
# memoize :attribute_a
|
87
|
+
# memoize :attribute_b
|
88
|
+
#
|
89
|
+
# # good
|
90
|
+
# memoize :attribute_a
|
91
|
+
#
|
92
|
+
# memoize :attribute_b
|
87
93
|
#
|
88
94
|
# @example AllowAdjacentOneLineDefs: false
|
89
95
|
#
|
90
96
|
# # bad
|
91
97
|
# class ErrorA < BaseError; end
|
92
98
|
# class ErrorB < BaseError; end
|
93
|
-
# class ErrorC < BaseError; end
|
94
99
|
#
|
95
100
|
# # good
|
96
101
|
# class ErrorA < BaseError; end
|
97
102
|
#
|
98
103
|
# class ErrorB < BaseError; end
|
99
104
|
#
|
100
|
-
#
|
105
|
+
# # bad - DefLikeMacros: [memoize]
|
106
|
+
# memoize :attribute_a
|
107
|
+
# memoize :attribute_b
|
108
|
+
#
|
109
|
+
# # good
|
110
|
+
# memoize :attribute_a
|
111
|
+
#
|
112
|
+
# memoize :attribute_b
|
101
113
|
#
|
102
114
|
class EmptyLineBetweenDefs < Base
|
103
115
|
include RangeHelp
|
@@ -158,6 +170,8 @@ module RuboCop
|
|
158
170
|
def def_location(correction_node)
|
159
171
|
if correction_node.any_block_type?
|
160
172
|
correction_node.source_range.join(correction_node.children.first.source_range)
|
173
|
+
elsif correction_node.send_type?
|
174
|
+
correction_node.source_range
|
161
175
|
else
|
162
176
|
correction_node.loc.keyword.join(correction_node.loc.name)
|
163
177
|
end
|
@@ -175,8 +189,14 @@ module RuboCop
|
|
175
189
|
end
|
176
190
|
|
177
191
|
def macro_candidate?(node)
|
178
|
-
|
179
|
-
|
192
|
+
macro_candidate = if node.any_block_type?
|
193
|
+
node.send_node
|
194
|
+
elsif node.send_type?
|
195
|
+
node
|
196
|
+
end
|
197
|
+
return false unless macro_candidate
|
198
|
+
|
199
|
+
macro_candidate.macro? && empty_line_between_macros.include?(macro_candidate.method_name)
|
180
200
|
end
|
181
201
|
|
182
202
|
def method_candidate?(node)
|
@@ -240,7 +260,9 @@ module RuboCop
|
|
240
260
|
end
|
241
261
|
|
242
262
|
def def_start(node)
|
243
|
-
|
263
|
+
node = node.send_node if node.any_block_type?
|
264
|
+
|
265
|
+
if node.send_type?
|
244
266
|
node.source_range.line
|
245
267
|
else
|
246
268
|
node.loc.keyword.line
|
@@ -252,11 +274,7 @@ module RuboCop
|
|
252
274
|
end
|
253
275
|
|
254
276
|
def end_loc(node)
|
255
|
-
|
256
|
-
node.source_range.end
|
257
|
-
else
|
258
|
-
node.loc.end
|
259
|
-
end
|
277
|
+
node.source_range.end
|
260
278
|
end
|
261
279
|
|
262
280
|
def autocorrect_remove_lines(corrector, newline_pos, count)
|
@@ -134,6 +134,7 @@ module RuboCop
|
|
134
134
|
|
135
135
|
def check_for_breakable_block(block_node)
|
136
136
|
return unless block_node.single_line?
|
137
|
+
return if receiver_contains_heredoc?(block_node)
|
137
138
|
|
138
139
|
line_index = block_node.loc.line - 1
|
139
140
|
range = breakable_block_range(block_node)
|
@@ -321,7 +322,7 @@ module RuboCop
|
|
321
322
|
def extract_heredocs(ast)
|
322
323
|
return [] unless ast
|
323
324
|
|
324
|
-
ast.each_node(:
|
325
|
+
ast.each_node(:any_str).select(&:heredoc?).map do |node|
|
325
326
|
body = node.location.heredoc_body
|
326
327
|
delimiter = node.location.heredoc_end.source.strip
|
327
328
|
[body.first_line...body.last_line, delimiter]
|
@@ -341,6 +342,13 @@ module RuboCop
|
|
341
342
|
heredocs.any? { |range, _delimiter| range.cover?(line_number) }
|
342
343
|
end
|
343
344
|
|
345
|
+
def receiver_contains_heredoc?(node)
|
346
|
+
return false unless (receiver = node.receiver)
|
347
|
+
return true if receiver.any_str_type? && receiver.heredoc?
|
348
|
+
|
349
|
+
receiver.each_descendant(:any_str).any?(&:heredoc?)
|
350
|
+
end
|
351
|
+
|
344
352
|
def check_directive_line(line, line_index)
|
345
353
|
length_without_directive = line_length_without_directive(line)
|
346
354
|
return if length_without_directive <= max
|
@@ -102,10 +102,12 @@ module RuboCop
|
|
102
102
|
return true if begins_its_line?(assignment_rhs.source_range)
|
103
103
|
end
|
104
104
|
|
105
|
-
given_style == :aligned
|
106
|
-
|
107
|
-
|
108
|
-
|
105
|
+
return false unless given_style == :aligned
|
106
|
+
return true if kw_node_with_special_indentation(node) || assignment_node
|
107
|
+
|
108
|
+
node = argument_in_method_call(node, :with_or_without_parentheses)
|
109
|
+
|
110
|
+
node.respond_to?(:def_modifier?) && !node.def_modifier?
|
109
111
|
end
|
110
112
|
|
111
113
|
def message(node, lhs, rhs)
|
@@ -194,6 +194,14 @@ module RuboCop
|
|
194
194
|
def alignment_location(alignment_node)
|
195
195
|
if begin_end_alignment_style == 'start_of_line'
|
196
196
|
start_line_range(alignment_node)
|
197
|
+
elsif alignment_node.any_block_type?
|
198
|
+
# If the alignment node is a block, the `rescue`/`ensure` keyword should
|
199
|
+
# be aligned to the start of the block. It is possible that the block's
|
200
|
+
# `send_node` spans multiple lines, in which case it should align to the
|
201
|
+
# start of the last line.
|
202
|
+
send_node = alignment_node.send_node
|
203
|
+
range = processed_source.buffer.line_range(send_node.last_line)
|
204
|
+
range.adjust(begin_pos: range.source =~ /\S/)
|
197
205
|
else
|
198
206
|
alignment_node.source_range
|
199
207
|
end
|
@@ -125,13 +125,13 @@ module RuboCop
|
|
125
125
|
next false if assignment_node.shorthand_asgn?
|
126
126
|
next false unless assignment_node.parent
|
127
127
|
|
128
|
-
|
129
|
-
|
128
|
+
conditional_assignment =
|
129
|
+
conditional_assignment?(assignment_node.parent, argument.scope.node)
|
130
130
|
|
131
131
|
unless uses_var?(assignment_node, argument.name)
|
132
132
|
# It's impossible to decide whether a branch or block is executed,
|
133
133
|
# so the precise reassignment location is undecidable.
|
134
|
-
next false if
|
134
|
+
next false if conditional_assignment
|
135
135
|
|
136
136
|
yield(assignment.node, location_known)
|
137
137
|
break
|
@@ -147,13 +147,13 @@ module RuboCop
|
|
147
147
|
node.source_range.begin_pos
|
148
148
|
end
|
149
149
|
|
150
|
-
# Check whether the given node is
|
150
|
+
# Check whether the given node is always executed or not
|
151
151
|
#
|
152
|
-
def
|
152
|
+
def conditional_assignment?(node, stop_search_node)
|
153
153
|
return false if node == stop_search_node
|
154
154
|
|
155
|
-
node.conditional? || node.
|
156
|
-
|
155
|
+
node.conditional? || node.type?(:block, :rescue) ||
|
156
|
+
conditional_assignment?(node.parent, stop_search_node)
|
157
157
|
end
|
158
158
|
|
159
159
|
# Get argument references without assignments' references
|
@@ -16,6 +16,12 @@ module RuboCop
|
|
16
16
|
# enumerator.each { |item| item >= 2 } #=> [2, 3]
|
17
17
|
# ----
|
18
18
|
#
|
19
|
+
# NOTE: Return values in assignment method definitions such as `def foo=(arg)` are
|
20
|
+
# detected because they are in a void context. However, autocorrection does not remove
|
21
|
+
# the return value, as that would change behavior. In such cases, whether to remove
|
22
|
+
# the return value or rename the method to something more appropriate should be left to
|
23
|
+
# the user.
|
24
|
+
#
|
19
25
|
# @example CheckForMethodsWithNoSideEffects: false (default)
|
20
26
|
# # bad
|
21
27
|
# def some_method
|
@@ -233,6 +239,7 @@ module RuboCop
|
|
233
239
|
|
234
240
|
def autocorrect_void_expression(corrector, node)
|
235
241
|
return if node.parent.if_type?
|
242
|
+
return if (def_node = node.each_ancestor(:any_def).first) && def_node.assignment_method?
|
236
243
|
|
237
244
|
corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
|
238
245
|
end
|
@@ -140,7 +140,7 @@ module RuboCop
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def last_item_precedes_newline?(node)
|
143
|
-
after_last_item = node.children.last.source_range.end.join(node.
|
143
|
+
after_last_item = node.children.last.source_range.end.join(node.source_range.end)
|
144
144
|
|
145
145
|
after_last_item.source.start_with?(/,?\s*(#.*)?\n/)
|
146
146
|
end
|
@@ -113,6 +113,18 @@ module RuboCop
|
|
113
113
|
# true
|
114
114
|
# end
|
115
115
|
#
|
116
|
+
# @example AllowedMethods: [call] (default)
|
117
|
+
# # good
|
118
|
+
# def call
|
119
|
+
# foo == bar
|
120
|
+
# end
|
121
|
+
#
|
122
|
+
# @example AllowedPatterns: [\Afoo]
|
123
|
+
# # good
|
124
|
+
# def foo?
|
125
|
+
# 'foo'
|
126
|
+
# end
|
127
|
+
#
|
116
128
|
# @example AllowBangMethods: false (default)
|
117
129
|
# # bad
|
118
130
|
# def save!
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Use `include?(element)` instead of `intersect?([element])`.
|
7
|
+
#
|
8
|
+
# @safety
|
9
|
+
# The receiver might not be an array.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# array.intersect?([element])
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# array.include?(element)
|
17
|
+
class ArrayIntersectWithSingleElement < Base
|
18
|
+
extend AutoCorrector
|
19
|
+
|
20
|
+
MSG = 'Use `include?(element)` instead of `intersect?([element])`.'
|
21
|
+
|
22
|
+
RESTRICT_ON_SEND = %i[intersect?].freeze
|
23
|
+
|
24
|
+
# @!method single_element(node)
|
25
|
+
def_node_matcher :single_element, <<~PATTERN
|
26
|
+
(send _ _ $(array $_))
|
27
|
+
PATTERN
|
28
|
+
|
29
|
+
def on_send(node)
|
30
|
+
array, element = single_element(node)
|
31
|
+
return unless array
|
32
|
+
|
33
|
+
add_offense(
|
34
|
+
node.source_range.with(begin_pos: node.loc.selector.begin_pos)
|
35
|
+
) do |corrector|
|
36
|
+
corrector.replace(node.loc.selector, 'include?')
|
37
|
+
corrector.replace(
|
38
|
+
array,
|
39
|
+
array.percent_literal? ? element.value.inspect : element.source
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
alias on_csend on_send
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -94,7 +94,7 @@ module RuboCop
|
|
94
94
|
def on_itblock(node)
|
95
95
|
case style
|
96
96
|
when :allow_single_line
|
97
|
-
return if node.
|
97
|
+
return if same_line?(node.source_range.begin, node.source_range.end)
|
98
98
|
|
99
99
|
add_offense(node, message: MSG_AVOID_IT_PARAMETER_MULTILINE)
|
100
100
|
when :disallow
|
@@ -43,24 +43,26 @@ module RuboCop
|
|
43
43
|
# @!method nil_check?(node)
|
44
44
|
def_node_matcher :nil_check?, '(send _ :nil?)'
|
45
45
|
|
46
|
+
# rubocop:disable Metrics/AbcSize
|
46
47
|
def on_send(node)
|
47
48
|
return unless node.receiver
|
48
49
|
|
49
50
|
style_check?(node) do
|
50
51
|
add_offense(node.loc.selector) do |corrector|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
if prefer_comparison?
|
53
|
+
range = node.loc.dot.join(node.loc.selector.end)
|
54
|
+
corrector.replace(range, ' == nil')
|
55
|
+
else
|
56
|
+
range = node.receiver.source_range.end.join(node.source_range.end)
|
57
|
+
corrector.replace(range, '.nil?')
|
58
|
+
end
|
58
59
|
|
59
60
|
parent = node.parent
|
60
61
|
corrector.wrap(node, '(', ')') if parent.respond_to?(:method?) && parent.method?(:!)
|
61
62
|
end
|
62
63
|
end
|
63
64
|
end
|
65
|
+
# rubocop:enable Metrics/AbcSize
|
64
66
|
|
65
67
|
private
|
66
68
|
|
@@ -36,7 +36,7 @@ module RuboCop
|
|
36
36
|
def on_numblock(node)
|
37
37
|
if style == :disallow
|
38
38
|
add_offense(node, message: MSG_DISALLOW)
|
39
|
-
elsif node.
|
39
|
+
elsif !same_line?(node.source_range.begin, node.source_range.end)
|
40
40
|
add_offense(node, message: MSG_MULTI_LINE)
|
41
41
|
end
|
42
42
|
end
|
@@ -134,6 +134,7 @@ module RuboCop
|
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
137
138
|
def all_fields_literal?(string, arguments)
|
138
139
|
count = 0
|
139
140
|
sequences = RuboCop::Cop::Utils::FormatString.new(string).format_sequences
|
@@ -141,6 +142,7 @@ module RuboCop
|
|
141
142
|
|
142
143
|
sequences.each do |sequence|
|
143
144
|
next if sequence.percent?
|
145
|
+
next if unknown_variable_width?(sequence, arguments)
|
144
146
|
|
145
147
|
hash = arguments.detect(&:hash_type?)
|
146
148
|
next unless (argument = find_argument(sequence, arguments, hash))
|
@@ -151,19 +153,32 @@ module RuboCop
|
|
151
153
|
|
152
154
|
sequences.size == count
|
153
155
|
end
|
156
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
154
157
|
|
158
|
+
# If the sequence has a variable (`*`) width, it cannot be autocorrected
|
159
|
+
# if the width is not given as a numeric literal argument
|
160
|
+
def unknown_variable_width?(sequence, arguments)
|
161
|
+
return false unless sequence.variable_width?
|
162
|
+
|
163
|
+
argument = arguments[sequence.variable_width_argument_number - 1]
|
164
|
+
!numeric?(argument)
|
165
|
+
end
|
166
|
+
|
167
|
+
# rubocop:disable Metrics/AbcSize
|
155
168
|
def find_argument(sequence, arguments, hash)
|
156
169
|
if hash && (sequence.annotated? || sequence.template?)
|
157
170
|
find_hash_value_node(hash, sequence.name.to_sym).first
|
171
|
+
elsif sequence.variable_width?
|
172
|
+
# If the specifier contains `*`, the argument for the width can be ignored.
|
173
|
+
arguments.delete_at(sequence.variable_width_argument_number - 1)
|
174
|
+
arguments.shift
|
158
175
|
elsif sequence.arg_number
|
159
176
|
arguments[sequence.arg_number.to_i - 1]
|
160
177
|
else
|
161
|
-
# If the specifier contains `*`, the following arguments will be used
|
162
|
-
# to specify the width and can be ignored.
|
163
|
-
(sequence.arity - 1).times { arguments.shift }
|
164
178
|
arguments.shift
|
165
179
|
end
|
166
180
|
end
|
181
|
+
# rubocop:enable Metrics/AbcSize
|
167
182
|
|
168
183
|
def matching_argument?(sequence, argument)
|
169
184
|
# Template specifiers don't give a type, any acceptable literal type is ok.
|