rubocop 1.82.1 → 1.84.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +1 -1
  4. data/config/default.yml +44 -0
  5. data/lib/rubocop/cli/command/lsp.rb +1 -1
  6. data/lib/rubocop/cli.rb +2 -1
  7. data/lib/rubocop/comment_config.rb +1 -0
  8. data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
  9. data/lib/rubocop/cop/correctors/alignment_corrector.rb +20 -2
  10. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
  11. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +9 -9
  12. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
  13. data/lib/rubocop/cop/layout/case_indentation.rb +3 -1
  14. data/lib/rubocop/cop/layout/class_structure.rb +12 -5
  15. data/lib/rubocop/cop/layout/first_argument_indentation.rb +32 -1
  16. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
  17. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
  18. data/lib/rubocop/cop/layout/heredoc_indentation.rb +34 -1
  19. data/lib/rubocop/cop/layout/indentation_width.rb +102 -9
  20. data/lib/rubocop/cop/layout/line_length.rb +5 -2
  21. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
  22. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
  23. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +8 -8
  24. data/lib/rubocop/cop/lint/duplicate_methods.rb +57 -5
  25. data/lib/rubocop/cop/lint/float_comparison.rb +1 -1
  26. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
  27. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  28. data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
  29. data/lib/rubocop/cop/lint/to_json.rb +12 -16
  30. data/lib/rubocop/cop/lint/useless_or.rb +1 -1
  31. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +1 -1
  32. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +4 -4
  33. data/lib/rubocop/cop/naming/predicate_prefix.rb +11 -11
  34. data/lib/rubocop/cop/offense.rb +2 -1
  35. data/lib/rubocop/cop/security/json_load.rb +1 -1
  36. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -2
  37. data/lib/rubocop/cop/style/documentation.rb +6 -6
  38. data/lib/rubocop/cop/style/documentation_method.rb +8 -8
  39. data/lib/rubocop/cop/style/empty_class_definition.rb +144 -0
  40. data/lib/rubocop/cop/style/guard_clause.rb +7 -4
  41. data/lib/rubocop/cop/style/hash_lookup_method.rb +94 -0
  42. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12 -12
  43. data/lib/rubocop/cop/style/lambda_call.rb +8 -8
  44. data/lib/rubocop/cop/style/module_member_existence_check.rb +56 -13
  45. data/lib/rubocop/cop/style/negative_array_index.rb +218 -0
  46. data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
  47. data/lib/rubocop/cop/style/redundant_condition.rb +1 -1
  48. data/lib/rubocop/cop/style/reverse_find.rb +51 -0
  49. data/lib/rubocop/cop/team.rb +3 -3
  50. data/lib/rubocop/cop/variable_force/branch.rb +28 -4
  51. data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
  52. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  53. data/lib/rubocop/formatter/tap_formatter.rb +5 -2
  54. data/lib/rubocop/remote_config.rb +5 -2
  55. data/lib/rubocop/rspec/shared_contexts.rb +4 -0
  56. data/lib/rubocop/rspec/support.rb +1 -0
  57. data/lib/rubocop/target_ruby.rb +3 -1
  58. data/lib/rubocop/version.rb +1 -1
  59. data/lib/rubocop.rb +4 -0
  60. metadata +9 -5
@@ -5,6 +5,8 @@ module RuboCop
5
5
  module Layout
6
6
  # Checks for indentation that doesn't use the specified number of spaces.
7
7
  # The indentation width can be configured using the `Width` setting. The default width is 2.
8
+ # The block body indentation for method chain blocks can be configured using the
9
+ # `EnforcedStyleAlignWith` setting.
8
10
  #
9
11
  # See also the `Layout/IndentationConsistency` cop which is the companion to this one.
10
12
  #
@@ -41,7 +43,22 @@ module RuboCop
41
43
  # end
42
44
  # end
43
45
  # end
46
+ #
47
+ # @example EnforcedStyleAlignWith: start_of_line (default)
48
+ # # good
49
+ # records.uniq { |el| el[:profile_id] }
50
+ # .map do |message|
51
+ # SomeJob.perform_later(message[:id])
52
+ # end
53
+ #
54
+ # @example EnforcedStyleAlignWith: relative_to_receiver
55
+ # # good
56
+ # records.uniq { |el| el[:profile_id] }
57
+ # .map do |message|
58
+ # SomeJob.perform_later(message[:id])
59
+ # end
44
60
  class IndentationWidth < Base # rubocop:disable Metrics/ClassLength
61
+ include ConfigurableEnforcedStyle
45
62
  include EndKeywordAlignment
46
63
  include Alignment
47
64
  include CheckAssignment
@@ -50,7 +67,7 @@ module RuboCop
50
67
  extend AutoCorrector
51
68
 
52
69
  MSG = 'Use %<configured_indentation_width>d (not %<indentation>d) ' \
53
- 'spaces for%<name>s indentation.'
70
+ '%<indentation_type>s for%<name>s indentation.'
54
71
 
55
72
  # @!method access_modifier?(node)
56
73
  def_node_matcher :access_modifier?, <<~PATTERN
@@ -83,12 +100,11 @@ module RuboCop
83
100
 
84
101
  return unless begins_its_line?(end_loc)
85
102
 
86
- # For blocks where the dot is on a new line, use the dot position as the base.
87
- # Otherwise, use the end keyword position as the base.
88
- base_loc = dot_on_new_line?(node) ? node.send_node.loc.dot : end_loc
103
+ base_loc = block_body_indentation_base(node, end_loc)
89
104
  check_indentation(base_loc, node.body)
90
105
 
91
106
  return unless indented_internal_methods_style?
107
+ return unless contains_access_modifier?(node.body)
92
108
 
93
109
  check_members(end_loc, [node.body])
94
110
  end
@@ -148,7 +164,7 @@ module RuboCop
148
164
  end
149
165
 
150
166
  def on_case_match(case_match)
151
- case_match.each_in_pattern do |in_pattern_node|
167
+ case_match.in_pattern_branches.each do |in_pattern_node|
152
168
  check_indentation(in_pattern_node.loc.keyword, in_pattern_node.body)
153
169
  end
154
170
 
@@ -167,6 +183,8 @@ module RuboCop
167
183
  private
168
184
 
169
185
  def autocorrect(corrector, node)
186
+ return unless node
187
+
170
188
  AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
171
189
  end
172
190
 
@@ -175,7 +193,7 @@ module RuboCop
175
193
 
176
194
  return unless members.any? && members.first.begin_type?
177
195
 
178
- if indentation_consistency_style == 'indented_internal_methods'
196
+ if indented_internal_methods_style?
179
197
  check_members_for_indented_internal_methods_style(members)
180
198
  else
181
199
  check_members_for_normal_style(base, members)
@@ -304,10 +322,32 @@ module RuboCop
304
322
  end
305
323
 
306
324
  def message(configured_indentation_width, indentation, name)
325
+ if using_tabs?
326
+ message_for_tabs(configured_indentation_width, indentation, name)
327
+ else
328
+ message_for_spaces(configured_indentation_width, indentation, name)
329
+ end
330
+ end
331
+
332
+ def message_for_tabs(configured_indentation_width, indentation, name)
333
+ configured_tabs = 1
334
+ actual_tabs = indentation / configured_indentation_width
335
+
336
+ format(
337
+ MSG,
338
+ configured_indentation_width: configured_tabs,
339
+ indentation: actual_tabs,
340
+ indentation_type: 'tabs',
341
+ name: name
342
+ )
343
+ end
344
+
345
+ def message_for_spaces(configured_indentation_width, indentation, name)
307
346
  format(
308
347
  MSG,
309
348
  configured_indentation_width: configured_indentation_width,
310
349
  indentation: indentation,
350
+ indentation_type: 'spaces',
311
351
  name: name
312
352
  )
313
353
  end
@@ -363,7 +403,13 @@ module RuboCop
363
403
  def offending_range(body_node, indentation)
364
404
  expr = body_node.source_range
365
405
  begin_pos = expr.begin_pos
366
- ind = expr.begin_pos - indentation
406
+
407
+ ind = if using_tabs?
408
+ begin_pos - line_indentation(expr).length
409
+ else
410
+ begin_pos - indentation
411
+ end
412
+
367
413
  pos = indentation >= 0 ? ind..begin_pos : begin_pos..ind
368
414
  range_between(pos.begin, pos.end)
369
415
  end
@@ -377,8 +423,47 @@ module RuboCop
377
423
  starting_node.send_type? && starting_node.bare_access_modifier?
378
424
  end
379
425
 
380
- def configured_indentation_width
381
- cop_config['Width']
426
+ def contains_access_modifier?(body_node)
427
+ return false unless body_node.begin_type?
428
+
429
+ body_node.children.any? { |child| child.send_type? && child.bare_access_modifier? }
430
+ end
431
+
432
+ def indentation_style
433
+ config.for_cop('Layout/IndentationStyle')['EnforcedStyle'] || 'spaces'
434
+ end
435
+
436
+ def using_tabs?
437
+ indentation_style == 'tabs'
438
+ end
439
+
440
+ def column_offset_between(base_range, range)
441
+ return super unless using_tabs?
442
+
443
+ base_uses_tabs = line_uses_tabs?(base_range)
444
+ range_uses_tabs = line_uses_tabs?(range)
445
+
446
+ return super unless base_uses_tabs || range_uses_tabs
447
+
448
+ visual_column(base_range) - visual_column(range)
449
+ end
450
+
451
+ def line_indentation(range)
452
+ line = processed_source.lines[range.line - 1]
453
+ line[0...range.column]
454
+ end
455
+
456
+ def line_uses_tabs?(range)
457
+ line_indentation(range).include?("\t")
458
+ end
459
+
460
+ def visual_column(range)
461
+ indentation = line_indentation(range)
462
+
463
+ tab_count = indentation.count("\t")
464
+ space_count = indentation.count(' ')
465
+
466
+ (tab_count * configured_indentation_width) + space_count
382
467
  end
383
468
 
384
469
  def leftmost_modifier_of(node)
@@ -387,6 +472,14 @@ module RuboCop
387
472
  leftmost_modifier_of(node.parent)
388
473
  end
389
474
 
475
+ def block_body_indentation_base(node, end_loc)
476
+ if style != :relative_to_receiver || !dot_on_new_line?(node)
477
+ end_loc
478
+ else
479
+ node.send_node.loc.dot
480
+ end
481
+ end
482
+
390
483
  def dot_on_new_line?(node)
391
484
  send_node = node.send_node
392
485
  return false unless send_node.loc?(:dot)
@@ -418,8 +418,11 @@ module RuboCop
418
418
  # The maximum allowed length of a string value is:
419
419
  # `Max` - end delimiter (quote) - continuation characters (space and slash)
420
420
  max_length = max - 3
421
- # If the string doesn't start at the beginning of the line, the max length is offset
422
- max_length -= column_offset_between(node.loc, node.parent.loc) if node.parent
421
+ # If the string is on the same line as its parent, offset by the column difference
422
+ # (Only apply when on same line to avoid negative offsets for multi-line dstr)
423
+ if same_line?(node, node.parent)
424
+ max_length -= column_offset_between(node.loc, node.parent.loc)
425
+ end
423
426
  node.source[0...(max_length)]
424
427
  end
425
428
  end
@@ -27,67 +27,67 @@ module RuboCop
27
27
  # line as the last element of the array.
28
28
  #
29
29
  # @example EnforcedStyle: symmetrical (default)
30
- # # bad
31
- # [ :a,
32
- # :b
33
- # ]
34
- #
35
- # # bad
36
- # [
37
- # :a,
38
- # :b ]
39
- #
40
- # # good
41
- # [ :a,
42
- # :b ]
43
- #
44
- # # good
45
- # [
46
- # :a,
47
- # :b
48
- # ]
30
+ # # bad
31
+ # [ :a,
32
+ # :b
33
+ # ]
34
+ #
35
+ # # bad
36
+ # [
37
+ # :a,
38
+ # :b ]
39
+ #
40
+ # # good
41
+ # [ :a,
42
+ # :b ]
43
+ #
44
+ # # good
45
+ # [
46
+ # :a,
47
+ # :b
48
+ # ]
49
49
  #
50
50
  # @example EnforcedStyle: new_line
51
- # # bad
52
- # [
53
- # :a,
54
- # :b ]
55
- #
56
- # # bad
57
- # [ :a,
58
- # :b ]
59
- #
60
- # # good
61
- # [ :a,
62
- # :b
63
- # ]
64
- #
65
- # # good
66
- # [
67
- # :a,
68
- # :b
69
- # ]
51
+ # # bad
52
+ # [
53
+ # :a,
54
+ # :b ]
55
+ #
56
+ # # bad
57
+ # [ :a,
58
+ # :b ]
59
+ #
60
+ # # good
61
+ # [ :a,
62
+ # :b
63
+ # ]
64
+ #
65
+ # # good
66
+ # [
67
+ # :a,
68
+ # :b
69
+ # ]
70
70
  #
71
71
  # @example EnforcedStyle: same_line
72
- # # bad
73
- # [ :a,
74
- # :b
75
- # ]
76
- #
77
- # # bad
78
- # [
79
- # :a,
80
- # :b
81
- # ]
82
- #
83
- # # good
84
- # [
85
- # :a,
86
- # :b ]
87
- #
88
- # # good
89
- # [ :a,
90
- # :b ]
72
+ # # bad
73
+ # [ :a,
74
+ # :b
75
+ # ]
76
+ #
77
+ # # bad
78
+ # [
79
+ # :a,
80
+ # :b
81
+ # ]
82
+ #
83
+ # # good
84
+ # [
85
+ # :a,
86
+ # :b ]
87
+ #
88
+ # # good
89
+ # [ :a,
90
+ # :b ]
91
91
  class MultilineArrayBraceLayout < Base
92
92
  include MultilineLiteralBraceLayout
93
93
  extend AutoCorrector
@@ -28,66 +28,66 @@ module RuboCop
28
28
  #
29
29
  # @example EnforcedStyle: symmetrical (default)
30
30
  #
31
- # # bad
32
- # { a: 1,
33
- # b: 2
34
- # }
35
- # # bad
36
- # {
37
- # a: 1,
38
- # b: 2 }
39
- #
40
- # # good
41
- # { a: 1,
42
- # b: 2 }
43
- #
44
- # # good
45
- # {
46
- # a: 1,
47
- # b: 2
48
- # }
31
+ # # bad
32
+ # { a: 1,
33
+ # b: 2
34
+ # }
35
+ # # bad
36
+ # {
37
+ # a: 1,
38
+ # b: 2 }
39
+ #
40
+ # # good
41
+ # { a: 1,
42
+ # b: 2 }
43
+ #
44
+ # # good
45
+ # {
46
+ # a: 1,
47
+ # b: 2
48
+ # }
49
49
  #
50
50
  # @example EnforcedStyle: new_line
51
- # # bad
52
- # {
53
- # a: 1,
54
- # b: 2 }
55
- #
56
- # # bad
57
- # { a: 1,
58
- # b: 2 }
59
- #
60
- # # good
61
- # { a: 1,
62
- # b: 2
63
- # }
64
- #
65
- # # good
66
- # {
67
- # a: 1,
68
- # b: 2
69
- # }
51
+ # # bad
52
+ # {
53
+ # a: 1,
54
+ # b: 2 }
55
+ #
56
+ # # bad
57
+ # { a: 1,
58
+ # b: 2 }
59
+ #
60
+ # # good
61
+ # { a: 1,
62
+ # b: 2
63
+ # }
64
+ #
65
+ # # good
66
+ # {
67
+ # a: 1,
68
+ # b: 2
69
+ # }
70
70
  #
71
71
  # @example EnforcedStyle: same_line
72
- # # bad
73
- # { a: 1,
74
- # b: 2
75
- # }
76
- #
77
- # # bad
78
- # {
79
- # a: 1,
80
- # b: 2
81
- # }
82
- #
83
- # # good
84
- # {
85
- # a: 1,
86
- # b: 2 }
87
- #
88
- # # good
89
- # { a: 1,
90
- # b: 2 }
72
+ # # bad
73
+ # { a: 1,
74
+ # b: 2
75
+ # }
76
+ #
77
+ # # bad
78
+ # {
79
+ # a: 1,
80
+ # b: 2
81
+ # }
82
+ #
83
+ # # good
84
+ # {
85
+ # a: 1,
86
+ # b: 2 }
87
+ #
88
+ # # good
89
+ # { a: 1,
90
+ # b: 2 }
91
91
  class MultilineHashBraceLayout < Base
92
92
  include MultilineLiteralBraceLayout
93
93
  extend AutoCorrector
@@ -7,18 +7,18 @@ module RuboCop
7
7
  # parenthesis (`(`) in lambda literals.
8
8
  #
9
9
  # @example EnforcedStyle: require_no_space (default)
10
- # # bad
11
- # a = -> (x, y) { x + y }
10
+ # # bad
11
+ # a = -> (x, y) { x + y }
12
12
  #
13
- # # good
14
- # a = ->(x, y) { x + y }
13
+ # # good
14
+ # a = ->(x, y) { x + y }
15
15
  #
16
16
  # @example EnforcedStyle: require_space
17
- # # bad
18
- # a = ->(x, y) { x + y }
17
+ # # bad
18
+ # a = ->(x, y) { x + y }
19
19
  #
20
- # # good
21
- # a = -> (x, y) { x + y }
20
+ # # good
21
+ # a = -> (x, y) { x + y }
22
22
  class SpaceInLambdaLiteral < Base
23
23
  include ConfigurableEnforcedStyle
24
24
  include RangeHelp
@@ -56,6 +56,27 @@ module RuboCop
56
56
  # 1
57
57
  # end
58
58
  #
59
+ # # bad
60
+ # class MyClass
61
+ # extend Forwardable
62
+ #
63
+ # # or with: `def_instance_delegator`, `def_delegators`, `def_instance_delegators`
64
+ # def_delegator :delegation_target, :delegated_method_name
65
+ #
66
+ # def delegated_method_name
67
+ # end
68
+ # end
69
+ #
70
+ # # good
71
+ # class MyClass
72
+ # extend Forwardable
73
+ #
74
+ # def_delegator :delegation_target, :delegated_method_name
75
+ #
76
+ # def non_duplicated_delegated_method_name
77
+ # end
78
+ # end
79
+ #
59
80
  # @example AllCops:ActiveSupportExtensionsEnabled: false (default)
60
81
  #
61
82
  # # good
@@ -97,10 +118,11 @@ module RuboCop
97
118
  # delegate :foo, to: :bar
98
119
  # end
99
120
  #
100
- class DuplicateMethods < Base
121
+ class DuplicateMethods < Base # rubocop:disable Metrics/ClassLength
101
122
  MSG = 'Method `%<method>s` is defined at both %<defined>s and %<current>s.'
102
123
  RESTRICT_ON_SEND = %i[alias_method attr_reader attr_writer attr_accessor attr
103
- delegate].freeze
124
+ delegate def_delegator def_instance_delegator def_delegators
125
+ def_instance_delegators].freeze
104
126
 
105
127
  def initialize(config = nil, options = nil)
106
128
  super
@@ -154,23 +176,49 @@ module RuboCop
154
176
  )
155
177
  PATTERN
156
178
 
179
+ # @!method delegator?(node)
180
+ def_node_matcher :delegator?, <<~PATTERN
181
+ (send nil? {:def_delegator :def_instance_delegator}
182
+ {
183
+ {sym str} ({sym str} $_) |
184
+ {sym str} {sym str} ({sym str} $_)
185
+ }
186
+ )
187
+ PATTERN
188
+
189
+ # @!method delegators?(node)
190
+ def_node_matcher :delegators?, <<~PATTERN
191
+ (send nil? {:def_delegators :def_instance_delegators}
192
+ {sym str}
193
+ ({sym str} $_)+
194
+ )
195
+ PATTERN
196
+
157
197
  # @!method sym_name(node)
158
198
  def_node_matcher :sym_name, '(sym $_name)'
159
199
 
160
- def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
200
+ def on_send(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
161
201
  name, original_name = alias_method?(node)
162
202
 
163
203
  if name && original_name
164
204
  return if name == original_name
165
- return if node.ancestors.any?(&:if_type?)
205
+ return if inside_condition?(node)
166
206
 
167
207
  found_instance_method(node, name)
168
208
  elsif (attr = node.attribute_accessor?)
169
209
  on_attr(node, *attr)
170
210
  elsif active_support_extensions_enabled? && (names = delegate_method?(node))
171
- return if node.ancestors.any?(&:if_type?)
211
+ return if inside_condition?(node)
172
212
 
173
213
  on_delegate(node, names)
214
+ elsif (name = delegator?(node))
215
+ return if inside_condition?(node)
216
+
217
+ found_instance_method(node, name)
218
+ elsif (names = delegators?(node))
219
+ return if inside_condition?(node)
220
+
221
+ names.each { |name| found_instance_method(node, name) }
174
222
  end
175
223
  end
176
224
 
@@ -190,6 +238,10 @@ module RuboCop
190
238
  found_method(node, "#{enclosing}.#{name}")
191
239
  end
192
240
 
241
+ def inside_condition?(node)
242
+ node.ancestors.any?(&:if_type?)
243
+ end
244
+
193
245
  def message_for_dup(node, method_name, key)
194
246
  format(MSG, method: method_name, defined: source_location(@definitions[key]),
195
247
  current: source_location(node))
@@ -77,7 +77,7 @@ module RuboCop
77
77
 
78
78
  def on_case(node)
79
79
  node.when_branches.each do |when_branch|
80
- when_branch.each_condition do |condition|
80
+ when_branch.conditions.each do |condition|
81
81
  next if !float?(condition) || literal_safe?(condition)
82
82
 
83
83
  add_offense(condition, message: MSG_CASE)
@@ -157,7 +157,7 @@ module RuboCop
157
157
 
158
158
  check_case(case_match_node)
159
159
  else
160
- case_match_node.each_in_pattern do |in_pattern_node|
160
+ case_match_node.in_pattern_branches.each do |in_pattern_node|
161
161
  next unless in_pattern_node.condition.literal?
162
162
 
163
163
  add_offense(in_pattern_node)
@@ -77,7 +77,7 @@ module RuboCop
77
77
  PERCENT_CAPITAL_W = '%W'
78
78
  PERCENT_I = '%i'
79
79
  PERCENT_CAPITAL_I = '%I'
80
- ASSIGNMENT_TYPES = %i[lvasgn ivasgn cvasgn gvasgn].freeze
80
+ ASSIGNMENT_TYPES = %i[lvasgn ivasgn cvasgn gvasgn casgn].freeze
81
81
 
82
82
  # @!method array_new?(node)
83
83
  def_node_matcher :array_new?, <<~PATTERN
@@ -26,7 +26,23 @@ module RuboCop
26
26
  'and it may be unexpected.'
27
27
  RESTRICT_ON_SEND = %i[new].freeze
28
28
 
29
- STRUCT_METHOD_NAMES = Struct.instance_methods
29
+ # This is based on `Struct.instance_methods.sort` in Ruby 4.0.0.
30
+ STRUCT_METHOD_NAMES = %i[
31
+ ! != !~ <=> == === [] []= __id__ __send__ all? any? chain chunk chunk_while class clone
32
+ collect collect_concat compact count cycle deconstruct deconstruct_keys
33
+ define_singleton_method detect dig display drop drop_while dup each each_cons each_entry
34
+ each_pair each_slice each_with_index each_with_object entries enum_for eql? equal? extend
35
+ filter filter_map find find_all find_index first flat_map freeze frozen? grep grep_v
36
+ group_by hash include? inject inspect instance_eval instance_exec instance_of?
37
+ instance_variable_defined? instance_variable_get instance_variable_set instance_variables
38
+ is_a? itself kind_of? lazy length map max max_by member? members method methods
39
+ min min_by minmax minmax_by nil? none? object_id one? partition private_methods
40
+ protected_methods public_method public_methods public_send reduce reject
41
+ remove_instance_variable respond_to? reverse_each select send singleton_class
42
+ singleton_method singleton_methods size slice_after slice_before slice_when sort sort_by
43
+ sum take take_while tally tap then to_a to_enum to_h to_s to_set uniq values values_at
44
+ yield_self zip
45
+ ].freeze
30
46
  STRUCT_MEMBER_NAME_TYPES = %i[sym str].freeze
31
47
 
32
48
  # @!method struct_new(node)
@@ -5,27 +5,23 @@ module RuboCop
5
5
  module Lint
6
6
  # Checks to make sure `#to_json` includes an optional argument.
7
7
  # When overriding `#to_json`, callers may invoke JSON
8
- # generation via `JSON.generate(your_obj)`. Since `JSON#generate` allows
8
+ # generation via `JSON.generate(your_obj)`. Since `JSON#generate` allows
9
9
  # for an optional argument, your method should too.
10
10
  #
11
11
  # @example
12
- # class Point
13
- # attr_reader :x, :y
14
- #
15
- # # bad, incorrect arity
16
- # def to_json
17
- # JSON.generate([x, y])
18
- # end
12
+ # # bad - incorrect arity
13
+ # def to_json
14
+ # JSON.generate([x, y])
15
+ # end
19
16
  #
20
- # # good, preserving args
21
- # def to_json(*args)
22
- # JSON.generate([x, y], *args)
23
- # end
17
+ # # good - preserving args
18
+ # def to_json(*args)
19
+ # JSON.generate([x, y], *args)
20
+ # end
24
21
  #
25
- # # good, discarding args
26
- # def to_json(*_args)
27
- # JSON.generate([x, y])
28
- # end
22
+ # # good - discarding args
23
+ # def to_json(*_args)
24
+ # JSON.generate([x, y])
29
25
  # end
30
26
  #
31
27
  class ToJSON < Base