rubocop-rails 2.7.0 → 2.9.1

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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -0
  3. data/config/default.yml +78 -4
  4. data/lib/rubocop/cop/mixin/active_record_helper.rb +5 -3
  5. data/lib/rubocop/cop/mixin/enforce_superclass.rb +40 -0
  6. data/lib/rubocop/cop/mixin/index_method.rb +25 -11
  7. data/lib/rubocop/cop/rails/action_filter.rb +10 -14
  8. data/lib/rubocop/cop/rails/active_record_aliases.rb +13 -17
  9. data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +19 -16
  10. data/lib/rubocop/cop/rails/active_record_override.rb +1 -1
  11. data/lib/rubocop/cop/rails/active_support_aliases.rb +12 -21
  12. data/lib/rubocop/cop/rails/after_commit_override.rb +91 -0
  13. data/lib/rubocop/cop/rails/application_controller.rb +3 -7
  14. data/lib/rubocop/cop/rails/application_job.rb +2 -1
  15. data/lib/rubocop/cop/rails/application_mailer.rb +2 -7
  16. data/lib/rubocop/cop/rails/application_record.rb +2 -7
  17. data/lib/rubocop/cop/rails/arel_star.rb +41 -0
  18. data/lib/rubocop/cop/rails/assert_not.rb +8 -10
  19. data/lib/rubocop/cop/rails/attribute_default_block_value.rb +90 -0
  20. data/lib/rubocop/cop/rails/belongs_to.rb +9 -18
  21. data/lib/rubocop/cop/rails/blank.rb +27 -27
  22. data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -1
  23. data/lib/rubocop/cop/rails/content_tag.rb +17 -17
  24. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +2 -1
  25. data/lib/rubocop/cop/rails/date.rb +10 -11
  26. data/lib/rubocop/cop/rails/default_scope.rb +11 -4
  27. data/lib/rubocop/cop/rails/delegate.rb +9 -9
  28. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +7 -8
  29. data/lib/rubocop/cop/rails/dynamic_find_by.rb +13 -11
  30. data/lib/rubocop/cop/rails/enum_hash.rb +11 -10
  31. data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -1
  32. data/lib/rubocop/cop/rails/environment_comparison.rb +18 -14
  33. data/lib/rubocop/cop/rails/exit.rb +4 -10
  34. data/lib/rubocop/cop/rails/file_path.rb +5 -4
  35. data/lib/rubocop/cop/rails/find_by.rb +13 -13
  36. data/lib/rubocop/cop/rails/find_by_id.rb +12 -21
  37. data/lib/rubocop/cop/rails/find_each.rb +17 -18
  38. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +3 -2
  39. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +4 -7
  40. data/lib/rubocop/cop/rails/helper_instance_variable.rb +30 -2
  41. data/lib/rubocop/cop/rails/http_positional_arguments.rb +25 -21
  42. data/lib/rubocop/cop/rails/http_status.rb +7 -9
  43. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +8 -6
  44. data/lib/rubocop/cop/rails/index_by.rb +11 -2
  45. data/lib/rubocop/cop/rails/index_with.rb +11 -2
  46. data/lib/rubocop/cop/rails/inquiry.rb +7 -2
  47. data/lib/rubocop/cop/rails/inverse_of.rb +3 -2
  48. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +17 -15
  49. data/lib/rubocop/cop/rails/link_to_blank.rb +20 -22
  50. data/lib/rubocop/cop/rails/mailer_name.rb +19 -13
  51. data/lib/rubocop/cop/rails/match_route.rb +16 -13
  52. data/lib/rubocop/cop/rails/negate_include.rb +10 -8
  53. data/lib/rubocop/cop/rails/not_null_column.rb +2 -1
  54. data/lib/rubocop/cop/rails/order_by_id.rb +52 -0
  55. data/lib/rubocop/cop/rails/output.rb +5 -2
  56. data/lib/rubocop/cop/rails/output_safety.rb +3 -2
  57. data/lib/rubocop/cop/rails/pick.rb +14 -12
  58. data/lib/rubocop/cop/rails/pluck.rb +6 -9
  59. data/lib/rubocop/cop/rails/pluck_id.rb +4 -6
  60. data/lib/rubocop/cop/rails/pluck_in_where.rb +39 -5
  61. data/lib/rubocop/cop/rails/pluralization_grammar.rb +10 -14
  62. data/lib/rubocop/cop/rails/presence.rb +12 -13
  63. data/lib/rubocop/cop/rails/present.rb +30 -24
  64. data/lib/rubocop/cop/rails/rake_environment.rb +9 -11
  65. data/lib/rubocop/cop/rails/read_write_attribute.rb +12 -11
  66. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +29 -31
  67. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +9 -12
  68. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +11 -10
  69. data/lib/rubocop/cop/rails/reflection_class_name.rb +4 -3
  70. data/lib/rubocop/cop/rails/refute_methods.rb +9 -10
  71. data/lib/rubocop/cop/rails/relative_date_constant.rb +20 -9
  72. data/lib/rubocop/cop/rails/render_inline.rb +5 -12
  73. data/lib/rubocop/cop/rails/render_plain_text.rb +9 -14
  74. data/lib/rubocop/cop/rails/request_referer.rb +7 -7
  75. data/lib/rubocop/cop/rails/reversible_migration.rb +82 -7
  76. data/lib/rubocop/cop/rails/safe_navigation.rb +11 -10
  77. data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +5 -10
  78. data/lib/rubocop/cop/rails/save_bang.rb +19 -22
  79. data/lib/rubocop/cop/rails/scope_args.rb +2 -1
  80. data/lib/rubocop/cop/rails/short_i18n.rb +7 -9
  81. data/lib/rubocop/cop/rails/skips_model_validations.rb +4 -4
  82. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +82 -0
  83. data/lib/rubocop/cop/rails/time_zone.rb +22 -20
  84. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +6 -6
  85. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +18 -8
  86. data/lib/rubocop/cop/rails/unknown_env.rb +15 -4
  87. data/lib/rubocop/cop/rails/validation.rb +15 -14
  88. data/lib/rubocop/cop/rails/where_equals.rb +98 -0
  89. data/lib/rubocop/cop/rails/where_exists.rb +74 -16
  90. data/lib/rubocop/cop/rails/where_not.rb +97 -0
  91. data/lib/rubocop/cop/rails_cops.rb +8 -0
  92. data/lib/rubocop/rails/schema_loader.rb +4 -4
  93. data/lib/rubocop/rails/schema_loader/schema.rb +5 -5
  94. data/lib/rubocop/rails/version.rb +5 -1
  95. metadata +23 -9
@@ -50,7 +50,8 @@ module RuboCop
50
50
  #
51
51
  # @see https://guides.rubyonrails.org/5_0_release_notes.html
52
52
  # @see https://github.com/rails/rails/pull/18937
53
- class BelongsTo < Cop
53
+ class BelongsTo < Base
54
+ extend AutoCorrector
54
55
  extend TargetRailsVersion
55
56
 
56
57
  minimum_target_rails_version 5.0
@@ -64,6 +65,7 @@ module RuboCop
64
65
  'option is deprecated and you want to use `optional: false`. ' \
65
66
  'In most configurations, this is the default and you can omit ' \
66
67
  'this option altogether'
68
+ RESTRICT_ON_SEND = %i[belongs_to].freeze
67
69
 
68
70
  def_node_matcher :match_belongs_to_with_options, <<~PATTERN
69
71
  (send _ :belongs_to _
@@ -72,27 +74,16 @@ module RuboCop
72
74
  PATTERN
73
75
 
74
76
  def on_send(node)
75
- match_belongs_to_with_options(node) do |_option_node, option_value|
76
- message =
77
+ match_belongs_to_with_options(node) do |option_node, option_value|
78
+ message, replacement =
77
79
  if option_value.true_type?
78
- SUPERFLOUS_REQUIRE_TRUE_MSG
80
+ [SUPERFLOUS_REQUIRE_TRUE_MSG, 'optional: false']
79
81
  elsif option_value.false_type?
80
- SUPERFLOUS_REQUIRE_FALSE_MSG
82
+ [SUPERFLOUS_REQUIRE_FALSE_MSG, 'optional: true']
81
83
  end
82
84
 
83
- add_offense(node, message: message, location: :selector)
84
- end
85
- end
86
-
87
- def autocorrect(node)
88
- option_node, option_value = match_belongs_to_with_options(node)
89
- return unless option_node
90
-
91
- lambda do |corrector|
92
- if option_value.true_type?
93
- corrector.replace(option_node.loc.expression, 'optional: false')
94
- elsif option_value.false_type?
95
- corrector.replace(option_node.loc.expression, 'optional: true')
85
+ add_offense(node.loc.selector, message: message) do |corrector|
86
+ corrector.replace(option_node.loc.expression, replacement)
96
87
  end
97
88
  end
98
89
  end
@@ -53,11 +53,14 @@ module RuboCop
53
53
  # def blank?
54
54
  # !present?
55
55
  # end
56
- class Blank < Cop
56
+ class Blank < Base
57
+ extend AutoCorrector
58
+
57
59
  MSG_NIL_OR_EMPTY = 'Use `%<prefer>s` instead of `%<current>s`.'
58
60
  MSG_NOT_PRESENT = 'Use `%<prefer>s` instead of `%<current>s`.'
59
61
  MSG_UNLESS_PRESENT = 'Use `if %<prefer>s` instead of ' \
60
62
  '`%<current>s`.'
63
+ RESTRICT_ON_SEND = %i[!].freeze
61
64
 
62
65
  # `(send nil $_)` is not actually a valid match for an offense. Nodes
63
66
  # that have a single method call on the left hand side
@@ -93,10 +96,10 @@ module RuboCop
93
96
  # accepts !present? if its in the body of a `blank?` method
94
97
  next if defining_blank?(node.parent)
95
98
 
96
- add_offense(node,
97
- message: format(MSG_NOT_PRESENT,
98
- prefer: replacement(receiver),
99
- current: node.source))
99
+ message = format(MSG_NOT_PRESENT, prefer: replacement(receiver), current: node.source)
100
+ add_offense(node, message: message) do |corrector|
101
+ autocorrect(corrector, node)
102
+ end
100
103
  end
101
104
  end
102
105
 
@@ -106,10 +109,10 @@ module RuboCop
106
109
  nil_or_empty?(node) do |var1, var2|
107
110
  return unless var1 == var2
108
111
 
109
- add_offense(node,
110
- message: format(MSG_NIL_OR_EMPTY,
111
- prefer: replacement(var1),
112
- current: node.source))
112
+ message = format(MSG_NIL_OR_EMPTY, prefer: replacement(var1), current: node.source)
113
+ add_offense(node, message: message) do |corrector|
114
+ autocorrect(corrector, node)
115
+ end
113
116
  end
114
117
  end
115
118
 
@@ -121,31 +124,28 @@ module RuboCop
121
124
  unless_present?(node) do |method_call, receiver|
122
125
  range = unless_condition(node, method_call)
123
126
 
124
- add_offense(node,
125
- location: range,
126
- message: format(MSG_UNLESS_PRESENT,
127
- prefer: replacement(receiver),
128
- current: range.source))
127
+ message = format(MSG_UNLESS_PRESENT, prefer: replacement(receiver), current: range.source)
128
+ add_offense(range, message: message) do |corrector|
129
+ autocorrect(corrector, node)
130
+ end
129
131
  end
130
132
  end
131
133
 
132
- def autocorrect(node)
133
- lambda do |corrector|
134
- method_call, variable1 = unless_present?(node)
134
+ private
135
135
 
136
- if method_call
137
- corrector.replace(node.loc.keyword, 'if')
138
- range = method_call.loc.expression
139
- else
140
- variable1, _variable2 = nil_or_empty?(node) || not_present?(node)
141
- range = node.loc.expression
142
- end
136
+ def autocorrect(corrector, node)
137
+ method_call, variable1 = unless_present?(node)
143
138
 
144
- corrector.replace(range, replacement(variable1))
139
+ if method_call
140
+ corrector.replace(node.loc.keyword, 'if')
141
+ range = method_call.loc.expression
142
+ else
143
+ variable1, _variable2 = nil_or_empty?(node) || not_present?(node)
144
+ range = node.loc.expression
145
145
  end
146
- end
147
146
 
148
- private
147
+ corrector.replace(range, replacement(variable1))
148
+ end
149
149
 
150
150
  def unless_condition(node, method_call)
151
151
  if node.modifier_form?
@@ -65,7 +65,7 @@ module RuboCop
65
65
  #
66
66
  # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-change_table
67
67
  # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html
68
- class BulkChangeTable < Cop
68
+ class BulkChangeTable < Base
69
69
  MSG_FOR_CHANGE_TABLE = <<~MSG.chomp
70
70
  You can combine alter queries using `bulk: true` options.
71
71
  MSG
@@ -18,46 +18,46 @@ module RuboCop
18
18
  # tag.p('Hello world!')
19
19
  # tag.br
20
20
  # content_tag(name, 'Hello world!')
21
- class ContentTag < Cop
21
+ class ContentTag < Base
22
22
  include RangeHelp
23
+ extend AutoCorrector
23
24
  extend TargetRailsVersion
24
25
 
25
26
  minimum_target_rails_version 5.1
26
27
 
27
28
  MSG = 'Use `tag` instead of `content_tag`.'
29
+ RESTRICT_ON_SEND = %i[content_tag].freeze
28
30
 
29
31
  def on_send(node)
30
- return unless node.method?(:content_tag)
31
-
32
32
  first_argument = node.first_argument
33
33
  return unless first_argument
34
34
 
35
35
  return if first_argument.variable? || first_argument.send_type? || first_argument.const_type?
36
36
 
37
- add_offense(node)
37
+ add_offense(node) do |corrector|
38
+ autocorrect(corrector, node)
39
+ end
38
40
  end
39
41
 
40
- def autocorrect(node)
41
- lambda do |corrector|
42
- if method_name?(node.first_argument)
43
- range = correction_range(node)
42
+ private
43
+
44
+ def autocorrect(corrector, node)
45
+ if method_name?(node.first_argument)
46
+ range = correction_range(node)
44
47
 
45
- rest_args = node.arguments.drop(1)
46
- replacement = "tag.#{node.first_argument.value}(#{rest_args.map(&:source).join(', ')})"
48
+ rest_args = node.arguments.drop(1)
49
+ replacement = "tag.#{node.first_argument.value.to_s.underscore}(#{rest_args.map(&:source).join(', ')})"
47
50
 
48
- corrector.replace(range, replacement)
49
- else
50
- corrector.replace(node.loc.selector, 'tag')
51
- end
51
+ corrector.replace(range, replacement)
52
+ else
53
+ corrector.replace(node.loc.selector, 'tag')
52
54
  end
53
55
  end
54
56
 
55
- private
56
-
57
57
  def method_name?(node)
58
58
  return false unless node.str_type? || node.sym_type?
59
59
 
60
- /^[a-zA-Z_][a-zA-Z_0-9]*$/.match?(node.value)
60
+ /^[a-zA-Z_][a-zA-Z_\-0-9]*$/.match?(node.value)
61
61
  end
62
62
 
63
63
  def correction_range(node)
@@ -40,8 +40,9 @@ module RuboCop
40
40
  #
41
41
  # t.datetime :updated_at, default: -> { 'CURRENT_TIMESTAMP' }
42
42
  # end
43
- class CreateTableWithTimestamps < Cop
43
+ class CreateTableWithTimestamps < Base
44
44
  MSG = 'Add timestamps when creating a new table.'
45
+ RESTRICT_ON_SEND = %i[create_table].freeze
45
46
 
46
47
  def_node_matcher :create_table_with_block?, <<~PATTERN
47
48
  (block
@@ -43,7 +43,7 @@ module RuboCop
43
43
  # Date.yesterday
44
44
  # date.in_time_zone
45
45
  #
46
- class Date < Cop
46
+ class Date < Base
47
47
  include ConfigurableEnforcedStyle
48
48
 
49
49
  MSG = 'Do not use `Date.%<method_called>s` without zone. Use ' \
@@ -52,6 +52,8 @@ module RuboCop
52
52
  MSG_SEND = 'Do not use `%<method>s` on Date objects, because they ' \
53
53
  'know nothing about the time zone in use.'
54
54
 
55
+ RESTRICT_ON_SEND = %i[to_time to_time_in_current_zone].freeze
56
+
55
57
  BAD_DAYS = %i[today current yesterday tomorrow].freeze
56
58
 
57
59
  DEPRECATED_METHODS = [
@@ -76,8 +78,7 @@ module RuboCop
76
78
 
77
79
  check_deprecated_methods(node)
78
80
 
79
- add_offense(node, location: :selector,
80
- message: format(MSG_SEND, method: node.method_name))
81
+ add_offense(node.loc.selector, message: format(MSG_SEND, method: node.method_name))
81
82
  end
82
83
  alias on_csend on_send
83
84
 
@@ -87,10 +88,9 @@ module RuboCop
87
88
  DEPRECATED_METHODS.each do |method|
88
89
  next unless node.method?(method[:deprecated].to_sym)
89
90
 
90
- add_offense(node, location: :selector,
91
- message: format(DEPRECATED_MSG,
92
- deprecated: method[:deprecated],
93
- relevant: method[:relevant]))
91
+ message = format(DEPRECATED_MSG, deprecated: method[:deprecated], relevant: method[:relevant])
92
+
93
+ add_offense(node.loc.selector, message: message)
94
94
  end
95
95
  end
96
96
 
@@ -104,10 +104,9 @@ module RuboCop
104
104
  day = method_name
105
105
  day = 'today' if method_name == 'current'
106
106
 
107
- add_offense(node, location: :selector,
108
- message: format(MSG,
109
- method_called: method_name,
110
- day: day))
107
+ message = format(MSG, method_called: method_name, day: day)
108
+
109
+ add_offense(node.loc.selector, message: message)
111
110
  end
112
111
 
113
112
  def extract_method_chain(node)
@@ -22,8 +22,9 @@ module RuboCop
22
22
  # where(hidden: false)
23
23
  # end
24
24
  #
25
- class DefaultScope < Cop
25
+ class DefaultScope < Base
26
26
  MSG = 'Avoid use of `default_scope`. It is better to use explicitly named scopes.'
27
+ RESTRICT_ON_SEND = %i[default_scope].freeze
27
28
 
28
29
  def_node_matcher :method_call?, <<~PATTERN
29
30
  (send nil? :default_scope ...)
@@ -38,15 +39,21 @@ module RuboCop
38
39
  PATTERN
39
40
 
40
41
  def on_send(node)
41
- add_offense(node, location: :selector) if method_call?(node)
42
+ return unless method_call?(node)
43
+
44
+ add_offense(node.loc.selector)
42
45
  end
43
46
 
44
47
  def on_defs(node)
45
- add_offense(node, location: :name) if class_method_definition?(node)
48
+ return unless class_method_definition?(node)
49
+
50
+ add_offense(node.loc.name)
46
51
  end
47
52
 
48
53
  def on_sclass(node)
49
- eigenclass_method_definition?(node) { |default_scope| add_offense(default_scope, location: :name) }
54
+ eigenclass_method_definition?(node) do |default_scope|
55
+ add_offense(default_scope.loc.name)
56
+ end
50
57
  end
51
58
  end
52
59
  end
@@ -52,7 +52,9 @@ module RuboCop
52
52
  #
53
53
  # # good
54
54
  # delegate :bar, to: :foo, prefix: true
55
- class Delegate < Cop
55
+ class Delegate < Base
56
+ extend AutoCorrector
57
+
56
58
  MSG = 'Use `delegate` to define delegations.'
57
59
 
58
60
  def_node_matcher :delegate?, <<~PATTERN
@@ -64,22 +66,20 @@ module RuboCop
64
66
  return unless trivial_delegate?(node)
65
67
  return if private_or_protected_delegation(node)
66
68
 
67
- add_offense(node, location: :keyword)
69
+ register_offense(node)
68
70
  end
69
71
 
70
- def autocorrect(node)
71
- delegation = ["delegate :#{node.body.method_name}",
72
- "to: :#{node.body.receiver.method_name}"]
72
+ private
73
73
 
74
- delegation << ['prefix: true'] if node.method?(prefixed_method_name(node.body))
74
+ def register_offense(node)
75
+ add_offense(node.loc.keyword) do |corrector|
76
+ delegation = ["delegate :#{node.body.method_name}", "to: :#{node.body.receiver.method_name}"]
77
+ delegation << ['prefix: true'] if node.method?(prefixed_method_name(node.body))
75
78
 
76
- lambda do |corrector|
77
79
  corrector.replace(node.source_range, delegation.join(', '))
78
80
  end
79
81
  end
80
82
 
81
- private
82
-
83
83
  def trivial_delegate?(def_node)
84
84
  delegate?(def_node) &&
85
85
  method_name_matches?(def_node.method_name, def_node.body) &&
@@ -13,22 +13,21 @@ module RuboCop
13
13
  #
14
14
  # # good
15
15
  # delegate :foo, to: :bar, allow_nil: true
16
- class DelegateAllowBlank < Cop
16
+ class DelegateAllowBlank < Base
17
+ extend AutoCorrector
18
+
17
19
  MSG = '`allow_blank` is not a valid option, use `allow_nil`.'
20
+ RESTRICT_ON_SEND = %i[delegate].freeze
18
21
 
19
22
  def_node_matcher :allow_blank_option, <<~PATTERN
20
23
  (send nil? :delegate _ (hash <$(pair (sym :allow_blank) true) ...>))
21
24
  PATTERN
22
25
 
23
26
  def on_send(node)
24
- allow_blank_option(node) do |offending_node|
25
- add_offense(offending_node)
26
- end
27
- end
27
+ return unless (offending_node = allow_blank_option(node))
28
28
 
29
- def autocorrect(pair_node)
30
- lambda do |corrector|
31
- corrector.replace(pair_node.key.source_range, 'allow_nil')
29
+ add_offense(offending_node) do |corrector|
30
+ corrector.replace(offending_node.key.source_range, 'allow_nil')
32
31
  end
33
32
  end
34
33
  end
@@ -31,7 +31,9 @@ module RuboCop
31
31
  #
32
32
  # # good
33
33
  # Gem::Specification.find_by_name('backend').gem_dir
34
- class DynamicFindBy < Cop
34
+ class DynamicFindBy < Base
35
+ extend AutoCorrector
36
+
35
37
  MSG = 'Use `%<static_name>s` instead of dynamic `%<method>s`.'
36
38
  METHOD_PATTERN = /^find_by_(.+?)(!)?$/.freeze
37
39
 
@@ -41,26 +43,26 @@ module RuboCop
41
43
  method_name = node.method_name
42
44
  static_name = static_method_name(method_name)
43
45
  return unless static_name
46
+ return if node.arguments.any?(&:splat_type?)
44
47
 
45
- add_offense(node,
46
- message: format(MSG, static_name: static_name,
47
- method: method_name))
48
+ message = format(MSG, static_name: static_name, method: method_name)
49
+ add_offense(node, message: message) do |corrector|
50
+ autocorrect(corrector, node)
51
+ end
48
52
  end
49
53
  alias on_csend on_send
50
54
 
51
- def autocorrect(node)
55
+ private
56
+
57
+ def autocorrect(corrector, node)
52
58
  keywords = column_keywords(node.method_name)
53
59
 
54
60
  return if keywords.size != node.arguments.size
55
61
 
56
- lambda do |corrector|
57
- autocorrect_method_name(corrector, node)
58
- autocorrect_argument_keywords(corrector, node, keywords)
59
- end
62
+ autocorrect_method_name(corrector, node)
63
+ autocorrect_argument_keywords(corrector, node, keywords)
60
64
  end
61
65
 
62
- private
63
-
64
66
  def allowed_invocation?(node)
65
67
  allowed_method?(node) || allowed_receiver?(node) ||
66
68
  whitelisted?(node)
@@ -17,9 +17,12 @@ module RuboCop
17
17
  # # good
18
18
  # enum status: { active: 0, archived: 1 }
19
19
  #
20
- class EnumHash < Cop
20
+ class EnumHash < Base
21
+ extend AutoCorrector
22
+
21
23
  MSG = 'Enum defined as an array found in `%<enum>s` enum declaration. '\
22
24
  'Use hash syntax instead.'
25
+ RESTRICT_ON_SEND = %i[enum].freeze
23
26
 
24
27
  def_node_matcher :enum?, <<~PATTERN
25
28
  (send nil? :enum (hash $...))
@@ -35,19 +38,17 @@ module RuboCop
35
38
  key, array = array_pair?(pair)
36
39
  next unless key
37
40
 
38
- add_offense(array, message: format(MSG, enum: enum_name(key)))
41
+ add_offense(array, message: format(MSG, enum: enum_name(key))) do |corrector|
42
+ hash = array.children.each_with_index.map do |elem, index|
43
+ "#{source(elem)} => #{index}"
44
+ end.join(', ')
45
+
46
+ corrector.replace(array.loc.expression, "{#{hash}}")
47
+ end
39
48
  end
40
49
  end
41
50
  end
42
51
 
43
- def autocorrect(node)
44
- hash = node.children.each_with_index.map do |elem, index|
45
- "#{source(elem)} => #{index}"
46
- end.join(', ')
47
-
48
- ->(corrector) { corrector.replace(node.loc.expression, "{#{hash}}") }
49
- end
50
-
51
52
  private
52
53
 
53
54
  def enum_name(key)