rubocop 1.31.0 → 1.32.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +23 -0
  4. data/lib/rubocop/cli.rb +1 -0
  5. data/lib/rubocop/config.rb +1 -1
  6. data/lib/rubocop/config_loader_resolver.rb +1 -1
  7. data/lib/rubocop/cop/base.rb +1 -1
  8. data/lib/rubocop/cop/generator.rb +4 -0
  9. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +60 -0
  10. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  11. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +4 -3
  12. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +3 -3
  13. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +57 -13
  14. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +10 -0
  15. data/lib/rubocop/cop/layout/line_length.rb +2 -0
  16. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -1
  17. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +45 -0
  18. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +7 -0
  19. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +10 -4
  20. data/lib/rubocop/cop/lint/literal_as_condition.rb +5 -0
  21. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +60 -24
  22. data/lib/rubocop/cop/lint/number_conversion.rb +7 -1
  23. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +7 -0
  24. data/lib/rubocop/cop/lint/require_range_parentheses.rb +57 -0
  25. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +35 -1
  26. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  27. data/lib/rubocop/cop/metrics/method_length.rb +1 -0
  28. data/lib/rubocop/cop/mixin/check_line_breakable.rb +4 -0
  29. data/lib/rubocop/cop/mixin/def_node.rb +2 -7
  30. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +12 -14
  31. data/lib/rubocop/cop/mixin/percent_array.rb +60 -1
  32. data/lib/rubocop/cop/naming/predicate_name.rb +8 -0
  33. data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -0
  34. data/lib/rubocop/cop/style/empty_else.rb +37 -0
  35. data/lib/rubocop/cop/style/empty_heredoc.rb +59 -0
  36. data/lib/rubocop/cop/style/fetch_env_var.rb +10 -177
  37. data/lib/rubocop/cop/style/format_string_token.rb +6 -0
  38. data/lib/rubocop/cop/style/hash_except.rb +1 -1
  39. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
  40. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +12 -0
  41. data/lib/rubocop/cop/style/module_function.rb +2 -2
  42. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +9 -0
  43. data/lib/rubocop/cop/style/numeric_predicate.rb +20 -6
  44. data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -1
  45. data/lib/rubocop/cop/style/semicolon.rb +27 -3
  46. data/lib/rubocop/cop/style/symbol_array.rb +2 -3
  47. data/lib/rubocop/cop/style/symbol_proc.rb +9 -1
  48. data/lib/rubocop/cop/style/trivial_accessors.rb +3 -0
  49. data/lib/rubocop/cop/style/word_array.rb +2 -3
  50. data/lib/rubocop/formatter/simple_text_formatter.rb +2 -0
  51. data/lib/rubocop/formatter.rb +21 -21
  52. data/lib/rubocop/options.rb +3 -6
  53. data/lib/rubocop/rake_task.rb +5 -1
  54. data/lib/rubocop/rspec/shared_contexts.rb +14 -14
  55. data/lib/rubocop/rspec/support.rb +14 -0
  56. data/lib/rubocop/runner.rb +4 -0
  57. data/lib/rubocop/server/client_command/base.rb +1 -1
  58. data/lib/rubocop/version.rb +1 -1
  59. data/lib/rubocop.rb +4 -1
  60. metadata +23 -5
@@ -9,32 +9,15 @@ module RuboCop
9
9
  # On the other hand, `ENV.fetch` raises KeyError or returns the explicitly
10
10
  # specified default value.
11
11
  #
12
- # When an `ENV[]` is the LHS of `||`, the autocorrect makes the RHS
13
- # the default value of `ENV.fetch`.
14
- #
15
12
  # @example
16
13
  # # bad
17
14
  # ENV['X']
18
- # ENV['X'] || 'string literal'
19
- # ENV['X'] || some_method
20
15
  # x = ENV['X']
21
16
  #
22
- # ENV['X'] || y.map do |a|
23
- # puts a * 2
24
- # end
25
- #
26
17
  # # good
27
18
  # ENV.fetch('X')
28
- # ENV.fetch('X', 'string literal')
29
- # ENV.fetch('X') { some_method }
30
19
  # x = ENV.fetch('X')
31
20
  #
32
- # ENV.fetch('X') do
33
- # y.map do |a|
34
- # puts a * 2
35
- # end
36
- # end
37
- #
38
21
  # # also good
39
22
  # !ENV['X']
40
23
  # ENV['X'].some_method # (e.g. `.nil?`)
@@ -42,48 +25,20 @@ module RuboCop
42
25
  class FetchEnvVar < Base
43
26
  extend AutoCorrector
44
27
 
45
- # rubocop:disable Layout/LineLength
46
- MSG_DEFAULT_NIL = 'Use `ENV.fetch(%<key>s)` or `ENV.fetch(%<key>s, nil)` instead of `ENV[%<key>s]`.'
47
- MSG_DEFAULT_RHS_SECOND_ARG_OF_FETCH = 'Use `ENV.fetch(%<key>s, %<default>s)` instead of `ENV[%<key>s] || %<default>s`.'
48
- MSG_DEFAULT_RHS_SINGLE_LINE_BLOCK = 'Use `ENV.fetch(%<key>s) { %<default>s }` instead of `ENV[%<key>s] || %<default>s`.'
49
- MSG_DEFAULT_RHS_MULTILINE_BLOCK = 'Use `ENV.fetch(%<key>s)` with a block containing `%<default>s ...`'
50
- # rubocop:enable Layout/LineLength
28
+ MSG = 'Use `ENV.fetch(%<key>s)` or `ENV.fetch(%<key>s, nil)` instead of `ENV[%<key>s]`.'
51
29
 
52
30
  # @!method env_with_bracket?(node)
53
31
  def_node_matcher :env_with_bracket?, <<~PATTERN
54
32
  (send (const nil? :ENV) :[] $_)
55
33
  PATTERN
56
34
 
57
- # @!method operand_of_or?(node)
58
- def_node_matcher :operand_of_or?, <<~PATTERN
59
- (^or ...)
60
- PATTERN
61
-
62
- # @!method block_control?(node)
63
- def_node_matcher :block_control?, <<~PATTERN
64
- ({next | break | retry | redo})
65
- PATTERN
66
-
67
- # @!method offensive_nodes(node)
68
- def_node_search :offensive_nodes, <<~PATTERN
69
- [#env_with_bracket? #offensive?]
70
- PATTERN
71
-
72
35
  def on_send(node)
73
36
  env_with_bracket?(node) do |name_node|
74
37
  break unless offensive?(node)
75
38
 
76
- if operand_of_or?(node)
77
- target_node = offensive_nodes(or_chain_root(node)).to_a.last
78
- target_name_node = env_with_bracket?(target_node)
79
-
80
- if default_to_rhs?(target_node)
81
- default_rhs(target_node, target_name_node)
82
- else
83
- default_nil(target_node, target_name_node)
84
- end
85
- else
86
- default_nil(node, name_node)
39
+ message = format(MSG, key: name_node.source)
40
+ add_offense(node, message: message) do |corrector|
41
+ corrector.replace(node, new_code(name_node))
87
42
  end
88
43
  end
89
44
  end
@@ -130,17 +85,6 @@ module RuboCop
130
85
  !(allowed_var?(node) || allowable_use?(node))
131
86
  end
132
87
 
133
- def or_chain_root(node)
134
- while operand_of_or?(ancestor_or ||= node.parent)
135
- ancestor_or = ancestor_or.parent
136
- end
137
- ancestor_or
138
- end
139
-
140
- def default_to_rhs?(node)
141
- operand_of_or?(node) && !right_end_of_or_chains?(node) && rhs_can_be_default_value?(node)
142
- end
143
-
144
88
  # Check if the node is a receiver and receives a message with dot syntax.
145
89
  def message_chained_with_dot?(node)
146
90
  return false if node.root?
@@ -157,8 +101,9 @@ module RuboCop
157
101
  # it simply checks whether the variable is set.
158
102
  # - Receiving a message with dot syntax, e.g. `ENV['X'].nil?`.
159
103
  # - `ENV['key']` assigned by logical AND/OR assignment.
104
+ # - `ENV['key']` is the LHS of a `||`.
160
105
  def allowable_use?(node)
161
- used_as_flag?(node) || message_chained_with_dot?(node) || assigned?(node)
106
+ used_as_flag?(node) || message_chained_with_dot?(node) || assigned?(node) || or_lhs?(node)
162
107
  end
163
108
 
164
109
  # The following are allowed cases:
@@ -172,127 +117,15 @@ module RuboCop
172
117
  node == lhs
173
118
  end
174
119
 
175
- def left_end_of_or_chains?(node)
176
- return false unless operand_of_or?(node)
177
-
178
- node.parent.lhs == node
179
- end
180
-
181
- def right_end_of_or_chains?(node)
182
- !(left_end_of_or_chains?(node) || node.parent&.parent&.or_type?)
183
- end
184
-
185
- def conterpart_rhs_of(node)
186
- left_end_of_or_chains?(node) ? node.parent.rhs : node.parent.parent.rhs
187
- end
188
-
189
- def rhs_can_be_default_value?(node)
190
- !rhs_is_block_control?(node)
191
- end
120
+ def or_lhs?(node)
121
+ return false unless (parent = node.parent)&.or_type?
192
122
 
193
- def rhs_is_block_control?(node)
194
- block_control?(conterpart_rhs_of(node))
123
+ parent.lhs == node || parent.parent&.or_type?
195
124
  end
196
125
 
197
- def new_code_default_nil(name_node)
126
+ def new_code(name_node)
198
127
  "ENV.fetch(#{name_node.source}, nil)"
199
128
  end
200
-
201
- def new_code_default_rhs_single_line(node, name_node)
202
- parent = node.parent
203
- if parent.rhs.basic_literal?
204
- "ENV.fetch(#{name_node.source}, #{parent.rhs.source})"
205
- else
206
- "ENV.fetch(#{name_node.source}) { #{parent.rhs.source} }"
207
- end
208
- end
209
-
210
- def new_code_default_rhs_multiline(node, name_node)
211
- env_indent = indent(node.parent)
212
- default = node.parent.rhs.source.split("\n").map do |line|
213
- "#{env_indent}#{line}"
214
- end.join("\n")
215
- <<~NEW_CODE.chomp
216
- ENV.fetch(#{name_node.source}) do
217
- #{configured_indentation}#{default}
218
- #{env_indent}end
219
- NEW_CODE
220
- end
221
-
222
- def new_code_default_rhs(node, name_node)
223
- if node.parent.rhs.single_line?
224
- new_code_default_rhs_single_line(node, name_node)
225
- else
226
- new_code_default_rhs_multiline(node, name_node)
227
- end
228
- end
229
-
230
- def default_rhs(node, name_node)
231
- if left_end_of_or_chains?(node)
232
- default_rhs_in_same_or(node, name_node)
233
- else
234
- default_rhs_in_outer_or(node, name_node)
235
- end
236
- end
237
-
238
- # Adds an offense and sets `nil` to the default value of `ENV.fetch`.
239
- # `ENV['X']` --> `ENV.fetch('X', nil)`
240
- def default_nil(node, name_node)
241
- message = format(MSG_DEFAULT_NIL, key: name_node.source)
242
-
243
- add_offense(node, message: message) do |corrector|
244
- corrector.replace(node, new_code_default_nil(name_node))
245
- end
246
- end
247
-
248
- # Adds an offense and makes the RHS the default value of `ENV.fetch`.
249
- # `ENV['X'] || y` --> `ENV.fetch('X') { y }`
250
- def default_rhs_in_same_or(node, name_node)
251
- template = message_template_for(node.parent.rhs)
252
- message = format(template,
253
- key: name_node.source,
254
- default: first_line_of(node.parent.rhs.source))
255
-
256
- add_offense(node, message: message) do |corrector|
257
- corrector.replace(node.parent, new_code_default_rhs(node, name_node))
258
- end
259
- end
260
-
261
- # Adds an offense and makes the RHS the default value of `ENV.fetch`.
262
- # `z || ENV['X'] || y` --> `z || ENV.fetch('X') { y }`
263
- def default_rhs_in_outer_or(node, name_node)
264
- parent = node.parent
265
- grand_parent = parent.parent
266
-
267
- template = message_template_for(grand_parent.rhs)
268
- message = format(template,
269
- key: name_node.source,
270
- default: first_line_of(grand_parent.rhs.source))
271
-
272
- add_offense(node, message: message) do |corrector|
273
- lhs_code = parent.lhs.source
274
- rhs_code = new_code_default_rhs(parent, name_node)
275
- corrector.replace(grand_parent, "#{lhs_code} || #{rhs_code}")
276
- end
277
- end
278
-
279
- def message_template_for(rhs)
280
- if rhs.multiline?
281
- MSG_DEFAULT_RHS_MULTILINE_BLOCK
282
- elsif rhs.basic_literal?
283
- MSG_DEFAULT_RHS_SECOND_ARG_OF_FETCH
284
- else
285
- MSG_DEFAULT_RHS_SINGLE_LINE_BLOCK
286
- end
287
- end
288
-
289
- def configured_indentation
290
- ' ' * (config.for_cop('Layout/IndentationWidth')['Width'] || 2)
291
- end
292
-
293
- def first_line_of(source)
294
- source.split("\n").first
295
- end
296
129
  end
297
130
  end
298
131
  end
@@ -12,6 +12,7 @@ module RuboCop
12
12
  # to encoded URLs or Date/Time formatting strings.
13
13
  #
14
14
  # This cop can be customized ignored methods with `IgnoredMethods`.
15
+ # By default, there are no methods to ignored.
15
16
  #
16
17
  # @example EnforcedStyle: annotated (default)
17
18
  #
@@ -61,6 +62,11 @@ module RuboCop
61
62
  # # good
62
63
  # format('%06d', 10)
63
64
  #
65
+ # @example IgnoredMethods: [] (default)
66
+ #
67
+ # # bad
68
+ # redirect('foo/%{bar_id}')
69
+ #
64
70
  # @example IgnoredMethods: [redirect]
65
71
  #
66
72
  # # good
@@ -144,7 +144,7 @@ module RuboCop
144
144
  return key.join(', ')
145
145
  end
146
146
 
147
- key.source
147
+ key.literal? ? key.source : "*#{key.source}"
148
148
  end
149
149
 
150
150
  def decorate_source(value)
@@ -6,6 +6,8 @@ module RuboCop
6
6
  # Checks for redundant `if` with boolean literal branches.
7
7
  # It checks only conditions to return boolean value (`true` or `false`) for safe detection.
8
8
  # The conditions to be checked are comparison methods, predicate methods, and double negative.
9
+ # `nonzero?` method is allowed by default.
10
+ # These are customizable with `AllowedMethods` option.
9
11
  #
10
12
  # @safety
11
13
  # Autocorrection is unsafe because there is no guarantee that all predicate methods
@@ -5,12 +5,24 @@ module RuboCop
5
5
  module Style
6
6
  # Checks for unwanted parentheses in parameterless method calls.
7
7
  #
8
+ # This cop can be customized ignored methods with `IgnoredMethods`.
9
+ # By default, there are no methods to ignored.
10
+ #
8
11
  # @example
9
12
  # # bad
10
13
  # object.some_method()
11
14
  #
12
15
  # # good
13
16
  # object.some_method
17
+ #
18
+ # @example IgnoredMethods: [] (default)
19
+ # # bad
20
+ # object.foo()
21
+ #
22
+ # @example IgnoredMethods: [foo]
23
+ # # good
24
+ # object.foo()
25
+ #
14
26
  class MethodCallWithoutArgsParentheses < Base
15
27
  include IgnoredMethods
16
28
  extend AutoCorrector
@@ -117,10 +117,10 @@ module RuboCop
117
117
  end
118
118
 
119
119
  def check_module_function(nodes)
120
- private_directive = nodes.any? { |node| private_directive?(node) }
120
+ return if nodes.any? { |node| private_directive?(node) }
121
121
 
122
122
  nodes.each do |node|
123
- yield node if extend_self_node?(node) && !private_directive
123
+ yield node if extend_self_node?(node)
124
124
  end
125
125
  end
126
126
 
@@ -5,6 +5,10 @@ module RuboCop
5
5
  module Style
6
6
  # Checks for unparenthesized method calls in the argument list
7
7
  # of a parenthesized method call.
8
+ # `be`, `be_a`, `be_an`, `be_between`, `be_falsey`, `be_kind_of`, `be_instance_of`,
9
+ # `be_truthy`, `be_within`, `eq`, `eql`, `end_with`, `include`, `match`, `raise_error`,
10
+ # `respond_to`, and `start_with` methods are allowed by default.
11
+ # These are customizable with `AllowedMethods` option.
8
12
  #
9
13
  # @example
10
14
  # # good
@@ -12,6 +16,11 @@ module RuboCop
12
16
  #
13
17
  # # bad
14
18
  # method1(method2 arg)
19
+ #
20
+ # @example AllowedMethods: [foo]
21
+ # # good
22
+ # method1(foo arg)
23
+ #
15
24
  class NestedParenthesizedCalls < Base
16
25
  include RangeHelp
17
26
  include AllowedMethods
@@ -6,13 +6,16 @@ module RuboCop
6
6
  # Checks for usage of comparison operators (`==`,
7
7
  # `>`, `<`) to test numbers as zero, positive, or negative.
8
8
  # These can be replaced by their respective predicate methods.
9
- # The cop can also be configured to do the reverse.
9
+ # This cop can also be configured to do the reverse.
10
10
  #
11
- # The cop disregards `#nonzero?` as its value is truthy or falsey,
11
+ # This cop can be customized ignored methods with `IgnoredMethods`.
12
+ # By default, there are no methods to ignored.
13
+ #
14
+ # This cop disregards `#nonzero?` as its value is truthy or falsey,
12
15
  # but not `true` and `false`, and thus not always interchangeable with
13
16
  # `!= 0`.
14
17
  #
15
- # The cop ignores comparisons to global variables, since they are often
18
+ # This cop ignores comparisons to global variables, since they are often
16
19
  # populated with objects which can be compared with integers, but are
17
20
  # not themselves `Integer` polymorphic.
18
21
  #
@@ -23,29 +26,40 @@ module RuboCop
23
26
  #
24
27
  # @example EnforcedStyle: predicate (default)
25
28
  # # bad
26
- #
27
29
  # foo == 0
28
30
  # 0 > foo
29
31
  # bar.baz > 0
30
32
  #
31
33
  # # good
32
- #
33
34
  # foo.zero?
34
35
  # foo.negative?
35
36
  # bar.baz.positive?
36
37
  #
37
38
  # @example EnforcedStyle: comparison
38
39
  # # bad
39
- #
40
40
  # foo.zero?
41
41
  # foo.negative?
42
42
  # bar.baz.positive?
43
43
  #
44
44
  # # good
45
+ # foo == 0
46
+ # 0 > foo
47
+ # bar.baz > 0
48
+ #
49
+ # @example IgnoredMethods: [] (default) with EnforcedStyle: predicate
50
+ # # bad
51
+ # foo == 0
52
+ # 0 > foo
53
+ # bar.baz > 0
45
54
  #
55
+ # @example IgnoredMethods: [==] with EnforcedStyle: predicate
56
+ # # good
46
57
  # foo == 0
58
+ #
59
+ # # bad
47
60
  # 0 > foo
48
61
  # bar.baz > 0
62
+ #
49
63
  class NumericPredicate < Base
50
64
  include ConfigurableEnforcedStyle
51
65
  include IgnoredMethods
@@ -81,7 +81,8 @@ module RuboCop
81
81
  end
82
82
 
83
83
  def like_method_argument_parentheses?(node)
84
- node.send_type? && node.arguments.size == 1 && !node.arithmetic_operation?
84
+ node.send_type? && node.arguments.one? &&
85
+ !node.arithmetic_operation? && node.first_argument.begin_type?
85
86
  end
86
87
 
87
88
  def empty_parentheses?(node)
@@ -64,12 +64,14 @@ module RuboCop
64
64
  # Make the obvious check first
65
65
  return unless processed_source.raw_source.include?(';')
66
66
 
67
- each_semicolon { |line, column| register_semicolon(line, column, false) }
67
+ each_semicolon do |line, column, token_before_semicolon|
68
+ register_semicolon(line, column, false, token_before_semicolon)
69
+ end
68
70
  end
69
71
 
70
72
  def each_semicolon
71
73
  tokens_for_lines.each do |line, tokens|
72
- yield line, tokens.last.column if tokens.last.semicolon?
74
+ yield line, tokens.last.column, tokens[-2] if tokens.last.semicolon?
73
75
  yield line, tokens.first.column if tokens.first.semicolon?
74
76
  end
75
77
  end
@@ -78,13 +80,21 @@ module RuboCop
78
80
  processed_source.tokens.group_by(&:line)
79
81
  end
80
82
 
81
- def register_semicolon(line, column, after_expression)
83
+ def register_semicolon(line, column, after_expression, token_before_semicolon = nil)
82
84
  range = source_range(processed_source.buffer, line, column)
83
85
 
84
86
  add_offense(range) do |corrector|
85
87
  if after_expression
86
88
  corrector.replace(range, "\n")
87
89
  else
90
+ # Prevents becoming one range instance with subsequent line when endless range
91
+ # without parentheses.
92
+ # See: https://github.com/rubocop/rubocop/issues/10791
93
+ if token_before_semicolon&.regexp_dots?
94
+ range_node = find_range_node(token_before_semicolon)
95
+ corrector.wrap(range_node, '(', ')') if range_node
96
+ end
97
+
88
98
  corrector.remove(range)
89
99
  end
90
100
  end
@@ -103,6 +113,20 @@ module RuboCop
103
113
  yield Regexp.last_match.begin(0)
104
114
  end
105
115
  end
116
+
117
+ def find_range_node(token_before_semicolon)
118
+ range_nodes.detect do |range_node|
119
+ range_node.source_range.contains?(token_before_semicolon.pos)
120
+ end
121
+ end
122
+
123
+ def range_nodes
124
+ return @range_nodes if instance_variable_defined?(:@range_nodes)
125
+
126
+ ast = processed_source.ast
127
+ @range_nodes = ast.range_type? ? [ast] : []
128
+ @range_nodes.concat(ast.each_descendant(:irange, :erange).to_a)
129
+ end
106
130
  end
107
131
  end
108
132
  end
@@ -39,7 +39,7 @@ module RuboCop
39
39
  minimum_target_ruby_version 2.0
40
40
 
41
41
  PERCENT_MSG = 'Use `%i` or `%I` for an array of symbols.'
42
- ARRAY_MSG = 'Use `%<prefer>s` for an array of symbols.'
42
+ ARRAY_MSG = 'Use %<prefer>s for an array of symbols.'
43
43
 
44
44
  class << self
45
45
  attr_accessor :largest_brackets
@@ -74,8 +74,7 @@ module RuboCop
74
74
  to_symbol_literal(c.value.to_s)
75
75
  end
76
76
  end
77
-
78
- "[#{syms.join(', ')}]"
77
+ build_bracketed_array_with_appropriate_whitespace(elements: syms, node: node)
79
78
  end
80
79
 
81
80
  def to_symbol_literal(string)
@@ -7,6 +7,8 @@ module RuboCop
7
7
  #
8
8
  # If you prefer a style that allows block for method with arguments,
9
9
  # please set `true` to `AllowMethodsWithArguments`.
10
+ # respond_to , and `define_method?` methods are ignored by default.
11
+ # These are customizable with `IgnoredMethods` option.
10
12
  #
11
13
  # @safety
12
14
  # This cop is unsafe because `proc`s and blocks work differently
@@ -68,6 +70,12 @@ module RuboCop
68
70
  # s.upcase # some comment
69
71
  # # some comment
70
72
  # end
73
+ #
74
+ # @example IgnoredMethods: [respond_to, define_method] (default)
75
+ # # good
76
+ # respond_to { |foo| foo.bar }
77
+ # define_method(:foo) { |foo| foo.bar }
78
+ #
71
79
  class SymbolProc < Base
72
80
  include CommentsHelp
73
81
  include RangeHelp
@@ -81,7 +89,7 @@ module RuboCop
81
89
  def_node_matcher :proc_node?, '(send (const {nil? cbase} :Proc) :new)'
82
90
 
83
91
  # @!method symbol_proc_receiver?(node)
84
- def_node_matcher :symbol_proc_receiver?, '{(send ...) (super ...) zsuper}'
92
+ def_node_matcher :symbol_proc_receiver?, '{(call ...) (super ...) zsuper}'
85
93
 
86
94
  # @!method symbol_proc?(node)
87
95
  def_node_matcher :symbol_proc?, <<~PATTERN
@@ -5,6 +5,9 @@ module RuboCop
5
5
  module Style
6
6
  # Looks for trivial reader/writer methods, that could
7
7
  # have been created with the attr_* family of functions automatically.
8
+ # `to_ary`, `to_a`, `to_c`, `to_enum`, `to_h`, `to_hash`, `to_i`, `to_int`, `to_io`,
9
+ # `to_open`, `to_path`, `to_proc`, `to_r`, `to_regexp`, `to_str`, `to_s`, and `to_sym` methods
10
+ # are allowed by default. These are customizable with `AllowedMethods` option.
8
11
  #
9
12
  # @example
10
13
  # # bad
@@ -44,7 +44,7 @@ module RuboCop
44
44
  extend AutoCorrector
45
45
 
46
46
  PERCENT_MSG = 'Use `%w` or `%W` for an array of words.'
47
- ARRAY_MSG = 'Use `%<prefer>s` for an array of words.'
47
+ ARRAY_MSG = 'Use %<prefer>s for an array of words.'
48
48
 
49
49
  class << self
50
50
  attr_accessor :largest_brackets
@@ -92,8 +92,7 @@ module RuboCop
92
92
  to_string_literal(word.children[0])
93
93
  end
94
94
  end
95
-
96
- "[#{words.join(', ')}]"
95
+ build_bracketed_array_with_appropriate_whitespace(elements: words, node: node)
97
96
  end
98
97
  end
99
98
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'colorizable'
4
+
3
5
  module RuboCop
4
6
  module Formatter
5
7
  # A basic formatter that displays only files with offenses.
@@ -2,30 +2,30 @@
2
2
 
3
3
  module RuboCop
4
4
  module Formatter
5
- autoload :BaseFormatter, 'rubocop/formatter/base_formatter'
6
- autoload :SimpleTextFormatter, 'rubocop/formatter/simple_text_formatter'
5
+ require_relative 'formatter/text_util'
6
+
7
+ require_relative 'formatter/base_formatter'
8
+ require_relative 'formatter/simple_text_formatter'
7
9
  # relies on simple text
8
- autoload :ClangStyleFormatter, 'rubocop/formatter/clang_style_formatter'
9
- autoload :DisabledConfigFormatter, 'rubocop/formatter/disabled_config_formatter'
10
- autoload :EmacsStyleFormatter, 'rubocop/formatter/emacs_style_formatter'
11
- autoload :FileListFormatter, 'rubocop/formatter/file_list_formatter'
12
- autoload :FuubarStyleFormatter, 'rubocop/formatter/fuubar_style_formatter'
13
- autoload :GitHubActionsFormatter, 'rubocop/formatter/git_hub_actions_formatter'
14
- autoload :HTMLFormatter, 'rubocop/formatter/html_formatter'
15
- autoload :JSONFormatter, 'rubocop/formatter/json_formatter'
16
- autoload :JUnitFormatter, 'rubocop/formatter/junit_formatter'
17
- autoload :MarkdownFormatter, 'rubocop/formatter/markdown_formatter'
18
- autoload :OffenseCountFormatter, 'rubocop/formatter/offense_count_formatter'
19
- autoload :ProgressFormatter, 'rubocop/formatter/progress_formatter'
20
- autoload :QuietFormatter, 'rubocop/formatter/quiet_formatter'
21
- autoload :TapFormatter, 'rubocop/formatter/tap_formatter'
22
- autoload :WorstOffendersFormatter, 'rubocop/formatter/worst_offenders_formatter'
23
- autoload :PacmanFormatter, 'rubocop/formatter/pacman_formatter'
10
+ require_relative 'formatter/clang_style_formatter'
11
+ require_relative 'formatter/disabled_config_formatter'
12
+ require_relative 'formatter/emacs_style_formatter'
13
+ require_relative 'formatter/file_list_formatter'
14
+ require_relative 'formatter/fuubar_style_formatter'
15
+ require_relative 'formatter/git_hub_actions_formatter'
16
+ require_relative 'formatter/html_formatter'
17
+ require_relative 'formatter/json_formatter'
18
+ require_relative 'formatter/junit_formatter'
19
+ require_relative 'formatter/markdown_formatter'
20
+ require_relative 'formatter/offense_count_formatter'
21
+ require_relative 'formatter/progress_formatter'
22
+ require_relative 'formatter/quiet_formatter'
23
+ require_relative 'formatter/tap_formatter'
24
+ require_relative 'formatter/worst_offenders_formatter'
25
+ require_relative 'formatter/pacman_formatter'
24
26
  # relies on progress formatter
25
- autoload :AutoGenConfigFormatter, 'rubocop/formatter/auto_gen_config_formatter'
26
- autoload :Colorizable, 'rubocop/formatter/colorizable'
27
+ require_relative 'formatter/auto_gen_config_formatter'
27
28
 
28
29
  require_relative 'formatter/formatter_set'
29
- require_relative 'formatter/text_util'
30
30
  end
31
31
  end
@@ -421,12 +421,9 @@ module RuboCop
421
421
  end
422
422
 
423
423
  def invalid_arguments_for_parallel
424
- [('--auto-gen-config' if @options.key?(:auto_gen_config)),
425
- ('-F/--fail-fast' if @options.key?(:fail_fast)),
426
- ('-x/--fix-layout' if @options.key?(:fix_layout)),
427
- ('-a/--autocorrect' if @options.key?(:safe_autocorrect)),
428
- ('-A/--autocorrect-all' if @options.key?(:autocorrect_all)),
429
- ('--cache false' if @options > { cache: 'false' })].compact
424
+ [('--auto-gen-config' if @options.key?(:auto_gen_config)),
425
+ ('-F/--fail-fast' if @options.key?(:fail_fast)),
426
+ ('--cache false' if @options > { cache: 'false' })].compact
430
427
  end
431
428
 
432
429
  def only_includes_redundant_disable?
@@ -73,11 +73,15 @@ module RuboCop
73
73
  namespace(name) do
74
74
  # rubocop:todo Naming/InclusiveLanguage
75
75
  task(:auto_correct, *args) do
76
+ require 'rainbow'
76
77
  warn Rainbow(
77
78
  'rubocop:auto_correct task is deprecated; ' \
78
79
  'use rubocop:autocorrect task or rubocop:autocorrect_all task instead.'
79
80
  ).yellow
80
- ::Rake::Task['rubocop:autocorrect'].invoke
81
+ RakeFileUtils.verbose(verbose) do
82
+ yield(*[self, task_args].slice(0, task_block.arity)) if task_block
83
+ perform('--autocorrect')
84
+ end
81
85
  end
82
86
  # rubocop:enable Naming/InclusiveLanguage
83
87