rubocop-rails 2.8.1 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +18 -2
  4. data/config/default.yml +144 -6
  5. data/config/obsoletion.yml +7 -0
  6. data/lib/rubocop/cop/mixin/active_record_helper.rb +15 -3
  7. data/lib/rubocop/cop/mixin/enforce_superclass.rb +40 -0
  8. data/lib/rubocop/cop/mixin/index_method.rb +8 -11
  9. data/lib/rubocop/cop/rails/action_filter.rb +10 -14
  10. data/lib/rubocop/cop/rails/active_record_aliases.rb +13 -17
  11. data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +17 -12
  12. data/lib/rubocop/cop/rails/active_record_override.rb +1 -1
  13. data/lib/rubocop/cop/rails/active_support_aliases.rb +12 -21
  14. data/lib/rubocop/cop/rails/add_column_index.rb +64 -0
  15. data/lib/rubocop/cop/rails/after_commit_override.rb +1 -1
  16. data/lib/rubocop/cop/rails/application_controller.rb +3 -7
  17. data/lib/rubocop/cop/rails/application_job.rb +2 -1
  18. data/lib/rubocop/cop/rails/application_mailer.rb +2 -7
  19. data/lib/rubocop/cop/rails/application_record.rb +2 -7
  20. data/lib/rubocop/cop/rails/arel_star.rb +41 -0
  21. data/lib/rubocop/cop/rails/assert_not.rb +8 -10
  22. data/lib/rubocop/cop/rails/attribute_default_block_value.rb +90 -0
  23. data/lib/rubocop/cop/rails/belongs_to.rb +10 -19
  24. data/lib/rubocop/cop/rails/blank.rb +31 -27
  25. data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -1
  26. data/lib/rubocop/cop/rails/content_tag.rb +33 -18
  27. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +2 -1
  28. data/lib/rubocop/cop/rails/date.rb +27 -17
  29. data/lib/rubocop/cop/rails/default_scope.rb +11 -4
  30. data/lib/rubocop/cop/rails/delegate.rb +9 -9
  31. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +7 -8
  32. data/lib/rubocop/cop/rails/dynamic_find_by.rb +16 -13
  33. data/lib/rubocop/cop/rails/eager_evaluation_log_message.rb +78 -0
  34. data/lib/rubocop/cop/rails/enum_hash.rb +11 -10
  35. data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -1
  36. data/lib/rubocop/cop/rails/environment_comparison.rb +18 -14
  37. data/lib/rubocop/cop/rails/environment_variable_access.rb +67 -0
  38. data/lib/rubocop/cop/rails/exit.rb +4 -10
  39. data/lib/rubocop/cop/rails/expanded_date_range.rb +86 -0
  40. data/lib/rubocop/cop/rails/file_path.rb +6 -7
  41. data/lib/rubocop/cop/rails/find_by.rb +32 -24
  42. data/lib/rubocop/cop/rails/find_by_id.rb +12 -21
  43. data/lib/rubocop/cop/rails/find_each.rb +19 -18
  44. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +3 -2
  45. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +37 -6
  46. data/lib/rubocop/cop/rails/helper_instance_variable.rb +29 -3
  47. data/lib/rubocop/cop/rails/http_positional_arguments.rb +26 -21
  48. data/lib/rubocop/cop/rails/http_status.rb +18 -11
  49. data/lib/rubocop/cop/rails/i18n_locale_assignment.rb +37 -0
  50. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +8 -6
  51. data/lib/rubocop/cop/rails/index_by.rb +2 -1
  52. data/lib/rubocop/cop/rails/index_with.rb +2 -1
  53. data/lib/rubocop/cop/rails/inquiry.rb +4 -3
  54. data/lib/rubocop/cop/rails/inverse_of.rb +3 -2
  55. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +17 -15
  56. data/lib/rubocop/cop/rails/link_to_blank.rb +25 -23
  57. data/lib/rubocop/cop/rails/mailer_name.rb +19 -13
  58. data/lib/rubocop/cop/rails/match_route.rb +14 -13
  59. data/lib/rubocop/cop/rails/negate_include.rb +10 -8
  60. data/lib/rubocop/cop/rails/not_null_column.rb +2 -1
  61. data/lib/rubocop/cop/rails/order_by_id.rb +1 -2
  62. data/lib/rubocop/cop/rails/output.rb +5 -2
  63. data/lib/rubocop/cop/rails/output_safety.rb +3 -2
  64. data/lib/rubocop/cop/rails/pick.rb +14 -12
  65. data/lib/rubocop/cop/rails/pluck.rb +6 -9
  66. data/lib/rubocop/cop/rails/pluck_id.rb +4 -6
  67. data/lib/rubocop/cop/rails/pluck_in_where.rb +7 -7
  68. data/lib/rubocop/cop/rails/pluralization_grammar.rb +10 -14
  69. data/lib/rubocop/cop/rails/presence.rb +12 -13
  70. data/lib/rubocop/cop/rails/present.rb +30 -24
  71. data/lib/rubocop/cop/rails/rake_environment.rb +8 -10
  72. data/lib/rubocop/cop/rails/read_write_attribute.rb +12 -11
  73. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +29 -31
  74. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +9 -12
  75. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +11 -10
  76. data/lib/rubocop/cop/rails/reflection_class_name.rb +17 -3
  77. data/lib/rubocop/cop/rails/refute_methods.rb +9 -10
  78. data/lib/rubocop/cop/rails/relative_date_constant.rb +34 -27
  79. data/lib/rubocop/cop/rails/render_inline.rb +2 -1
  80. data/lib/rubocop/cop/rails/render_plain_text.rb +9 -14
  81. data/lib/rubocop/cop/rails/request_referer.rb +7 -7
  82. data/lib/rubocop/cop/rails/require_dependency.rb +38 -0
  83. data/lib/rubocop/cop/rails/reversible_migration.rb +3 -7
  84. data/lib/rubocop/cop/rails/reversible_migration_method_definition.rb +75 -0
  85. data/lib/rubocop/cop/rails/safe_navigation.rb +30 -11
  86. data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +5 -10
  87. data/lib/rubocop/cop/rails/save_bang.rb +17 -20
  88. data/lib/rubocop/cop/rails/scope_args.rb +2 -1
  89. data/lib/rubocop/cop/rails/short_i18n.rb +7 -9
  90. data/lib/rubocop/cop/rails/skips_model_validations.rb +4 -4
  91. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +5 -6
  92. data/lib/rubocop/cop/rails/time_zone.rb +44 -42
  93. data/lib/rubocop/cop/rails/time_zone_assignment.rb +37 -0
  94. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +4 -6
  95. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +2 -2
  96. data/lib/rubocop/cop/rails/unknown_env.rb +3 -3
  97. data/lib/rubocop/cop/rails/unused_ignored_columns.rb +69 -0
  98. data/lib/rubocop/cop/rails/validation.rb +15 -14
  99. data/lib/rubocop/cop/rails/where_equals.rb +98 -0
  100. data/lib/rubocop/cop/rails/where_exists.rb +19 -13
  101. data/lib/rubocop/cop/rails/where_not.rb +10 -17
  102. data/lib/rubocop/cop/rails_cops.rb +13 -0
  103. data/lib/rubocop/rails.rb +2 -0
  104. data/lib/rubocop/rails/schema_loader.rb +4 -4
  105. data/lib/rubocop/rails/schema_loader/schema.rb +3 -5
  106. data/lib/rubocop/rails/version.rb +5 -1
  107. metadata +34 -14
@@ -24,30 +24,25 @@ module RuboCop
24
24
  # # bad - sets MIME type to `text/html`
25
25
  # render text: 'Ruby!'
26
26
  #
27
- class RenderPlainText < Cop
27
+ class RenderPlainText < Base
28
+ extend AutoCorrector
29
+
28
30
  MSG = 'Prefer `render plain:` over `render text:`.'
31
+ RESTRICT_ON_SEND = %i[render].freeze
29
32
 
30
33
  def_node_matcher :render_plain_text?, <<~PATTERN
31
34
  (send nil? :render $(hash <$(pair (sym :text) $_) ...>))
32
35
  PATTERN
33
36
 
34
37
  def on_send(node)
35
- render_plain_text?(node) do |options_node, _option_node, _option_value|
36
- content_type_node = find_content_type(options_node)
37
- add_offense(node) if compatible_content_type?(content_type_node)
38
- end
39
- end
40
-
41
- def autocorrect(node)
42
38
  render_plain_text?(node) do |options_node, option_node, option_value|
43
39
  content_type_node = find_content_type(options_node)
44
- rest_options = options_node.pairs - [option_node, content_type_node].compact
40
+ return unless compatible_content_type?(content_type_node)
41
+
42
+ add_offense(node) do |corrector|
43
+ rest_options = options_node.pairs - [option_node, content_type_node].compact
45
44
 
46
- lambda do |corrector|
47
- corrector.replace(
48
- node,
49
- replacement(rest_options, option_value)
50
- )
45
+ corrector.replace(node, replacement(rest_options, option_value))
51
46
  end
52
47
  end
53
48
  end
@@ -19,11 +19,13 @@ module RuboCop
19
19
  #
20
20
  # # good
21
21
  # request.referrer
22
- class RequestReferer < Cop
22
+ class RequestReferer < Base
23
23
  include ConfigurableEnforcedStyle
24
+ extend AutoCorrector
24
25
 
25
26
  MSG = 'Use `request.%<prefer>s` instead of ' \
26
27
  '`request.%<current>s`.'
28
+ RESTRICT_ON_SEND = %i[referer referrer].freeze
27
29
 
28
30
  def_node_matcher :referer?, <<~PATTERN
29
31
  (send (send nil? :request) {:referer :referrer})
@@ -33,17 +35,15 @@ module RuboCop
33
35
  referer?(node) do
34
36
  return unless node.method?(wrong_method_name)
35
37
 
36
- add_offense(node.source_range, location: node.source_range)
38
+ add_offense(node.source_range) do |corrector|
39
+ corrector.replace(node, "request.#{style}")
40
+ end
37
41
  end
38
42
  end
39
43
 
40
- def autocorrect(node)
41
- ->(corrector) { corrector.replace(node, "request.#{style}") }
42
- end
43
-
44
44
  private
45
45
 
46
- def message(_node)
46
+ def message(_range)
47
47
  format(MSG, prefer: style, current: wrong_method_name)
48
48
  end
49
49
 
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ # This cop checks for the usage of `require_dependency`.
7
+ #
8
+ # `require_dependency` is an obsolete method for Rails applications running in Zeitwerk mode.
9
+ # In Zeitwerk mode, the semantics should match Ruby's and no need to be defensive with load order,
10
+ # just refer to classes and modules normally.
11
+ # If the constant name is dynamic, camelize if needed, and constantize.
12
+ #
13
+ # Applications running in Zeitwerk mode should not use `require_dependency`.
14
+ #
15
+ # NOTE: This cop is disabled by default. Please enable it if you are using Zeitwerk mode.
16
+ #
17
+ # @example
18
+ # # bad
19
+ # require_dependency 'some_lib'
20
+ class RequireDependency < Base
21
+ extend TargetRailsVersion
22
+
23
+ minimum_target_rails_version 6.0
24
+
25
+ MSG = 'Do not use `require_dependency` with Zeitwerk mode.'
26
+ RESTRICT_ON_SEND = %i[require_dependency].freeze
27
+
28
+ def_node_matcher :require_dependency_call?, <<~PATTERN
29
+ (send {nil? (const _ :Kernel)} :require_dependency _)
30
+ PATTERN
31
+
32
+ def on_send(node)
33
+ require_dependency_call?(node) { add_offense(node) }
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -175,7 +175,7 @@ module RuboCop
175
175
  # end
176
176
  #
177
177
  # @see https://api.rubyonrails.org/classes/ActiveRecord/Migration/CommandRecorder.html
178
- class ReversibleMigration < Cop
178
+ class ReversibleMigration < Base
179
179
  MSG = '%<action>s is not reversible.'
180
180
 
181
181
  def_node_matcher :irreversible_schema_statement_call, <<~PATTERN
@@ -237,7 +237,7 @@ module RuboCop
237
237
 
238
238
  def check_drop_table_node(node)
239
239
  drop_table_call(node) do
240
- unless node.parent.block_type?
240
+ unless node.parent.block_type? || node.last_argument.block_pass_type?
241
241
  add_offense(
242
242
  node,
243
243
  message: format(MSG, action: 'drop_table(without block)')
@@ -271,11 +271,7 @@ module RuboCop
271
271
  def check_remove_foreign_key_node(node)
272
272
  remove_foreign_key_call(node) do |arg|
273
273
  if arg.hash_type? && !all_hash_key?(arg, :to_table)
274
- add_offense(
275
- node,
276
- message: format(MSG,
277
- action: 'remove_foreign_key(without table)')
278
- )
274
+ add_offense(node, message: format(MSG, action: 'remove_foreign_key(without table)'))
279
275
  end
280
276
  end
281
277
  end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ # This cop checks whether the migration implements
7
+ # either a `change` method or both an `up` and a `down`
8
+ # method.
9
+ #
10
+ # @example
11
+ # # bad
12
+ # class SomeMigration < ActiveRecord::Migration[6.0]
13
+ # def up
14
+ # # up migration
15
+ # end
16
+ #
17
+ # # <----- missing down method
18
+ # end
19
+ #
20
+ # class SomeMigration < ActiveRecord::Migration[6.0]
21
+ # # <----- missing up method
22
+ #
23
+ # def down
24
+ # # down migration
25
+ # end
26
+ # end
27
+ #
28
+ # # good
29
+ # class SomeMigration < ActiveRecord::Migration[6.0]
30
+ # def change
31
+ # # reversible migration
32
+ # end
33
+ # end
34
+ #
35
+ # # good
36
+ # class SomeMigration < ActiveRecord::Migration[6.0]
37
+ # def up
38
+ # # up migration
39
+ # end
40
+ #
41
+ # def down
42
+ # # down migration
43
+ # end
44
+ # end
45
+ class ReversibleMigrationMethodDefinition < Base
46
+ MSG = 'Migrations must contain either a `change` method, or ' \
47
+ 'both an `up` and a `down` method.'
48
+
49
+ def_node_matcher :migration_class?, <<~PATTERN
50
+ (class
51
+ (const nil? _)
52
+ (send
53
+ (const (const {nil? cbase} :ActiveRecord) :Migration)
54
+ :[]
55
+ (float _))
56
+ _)
57
+ PATTERN
58
+
59
+ def_node_matcher :change_method?, <<~PATTERN
60
+ [ #migration_class? `(def :change (args) _) ]
61
+ PATTERN
62
+
63
+ def_node_matcher :up_and_down_methods?, <<~PATTERN
64
+ [ #migration_class? `(def :up (args) _) `(def :down (args) _) ]
65
+ PATTERN
66
+
67
+ def on_class(node)
68
+ return if change_method?(node) || up_and_down_methods?(node)
69
+
70
+ add_offense(node)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -36,38 +36,57 @@ module RuboCop
36
36
  # foo&.bar
37
37
  # foo&.bar(baz)
38
38
  # foo&.bar { |e| e.baz }
39
- class SafeNavigation < Cop
39
+ class SafeNavigation < Base
40
40
  include RangeHelp
41
+ extend AutoCorrector
41
42
 
42
43
  MSG = 'Use safe navigation (`&.`) instead of `%<try>s`.'
44
+ RESTRICT_ON_SEND = %i[try try!].freeze
43
45
 
44
46
  def_node_matcher :try_call, <<~PATTERN
45
- (send !nil? ${:try :try!} $_ ...)
47
+ (send _ ${:try :try!} $_ ...)
46
48
  PATTERN
47
49
 
50
+ # Monkey patching for `Style/RedundantSelf` of RuboCop core.
51
+ # rubocop:disable Style/ClassAndModuleChildren
52
+ class Style::RedundantSelf
53
+ def self.autocorrect_incompatible_with
54
+ [Rails::SafeNavigation]
55
+ end
56
+ end
57
+ # rubocop:enable Style/ClassAndModuleChildren
58
+
59
+ def self.autocorrect_incompatible_with
60
+ [Style::RedundantSelf]
61
+ end
62
+
48
63
  def on_send(node)
49
64
  try_call(node) do |try_method, dispatch|
50
65
  return if try_method == :try && !cop_config['ConvertTry']
51
66
  return unless dispatch.sym_type? && dispatch.value.match?(/\w+[=!?]?/)
52
67
 
53
- add_offense(node, message: format(MSG, try: try_method))
68
+ add_offense(node, message: format(MSG, try: try_method)) do |corrector|
69
+ autocorrect(corrector, node)
70
+ end
54
71
  end
55
72
  end
56
73
 
57
- def autocorrect(node)
74
+ private
75
+
76
+ def autocorrect(corrector, node)
58
77
  method_node, *params = *node.arguments
59
78
  method = method_node.source[1..-1]
60
79
 
61
- range = range_between(node.loc.dot.begin_pos,
62
- node.loc.expression.end_pos)
80
+ range = if node.receiver
81
+ range_between(node.loc.dot.begin_pos, node.loc.expression.end_pos)
82
+ else
83
+ corrector.insert_before(node, 'self')
84
+ node
85
+ end
63
86
 
64
- lambda do |corrector|
65
- corrector.replace(range, replacement(method, params))
66
- end
87
+ corrector.replace(range, replacement(method, params))
67
88
  end
68
89
 
69
- private
70
-
71
90
  def replacement(method, params)
72
91
  new_params = params.map(&:source).join(', ')
73
92
 
@@ -19,7 +19,9 @@ module RuboCop
19
19
  # do_something if foo.blank?
20
20
  # do_something unless foo.blank?
21
21
  #
22
- class SafeNavigationWithBlank < Cop
22
+ class SafeNavigationWithBlank < Base
23
+ extend AutoCorrector
24
+
23
25
  MSG =
24
26
  'Avoid calling `blank?` with the safe navigation operator ' \
25
27
  'in conditionals.'
@@ -31,15 +33,8 @@ module RuboCop
31
33
  def on_if(node)
32
34
  return unless safe_navigation_blank_in_conditional?(node)
33
35
 
34
- add_offense(node)
35
- end
36
-
37
- def autocorrect(node)
38
- lambda do |corrector|
39
- corrector.replace(
40
- safe_navigation_blank_in_conditional?(node).location.dot,
41
- '.'
42
- )
36
+ add_offense(node) do |corrector|
37
+ corrector.replace(safe_navigation_blank_in_conditional?(node).location.dot, '.')
43
38
  end
44
39
  end
45
40
  end
@@ -98,8 +98,9 @@ module RuboCop
98
98
  # Services::Service::Mailer.update(message: 'Message')
99
99
  # Service::Mailer::update
100
100
  #
101
- class SaveBang < Cop
101
+ class SaveBang < Base
102
102
  include NegativeConditional
103
+ extend AutoCorrector
103
104
 
104
105
  MSG = 'Use `%<prefer>s` instead of `%<current>s` if the return ' \
105
106
  'value is not checked.'
@@ -113,11 +114,10 @@ module RuboCop
113
114
  first_or_create find_or_create_by].freeze
114
115
  MODIFY_PERSIST_METHODS = %i[save
115
116
  update update_attributes destroy].freeze
116
- PERSIST_METHODS = (CREATE_PERSIST_METHODS +
117
- MODIFY_PERSIST_METHODS).freeze
117
+ RESTRICT_ON_SEND = (CREATE_PERSIST_METHODS + MODIFY_PERSIST_METHODS).freeze
118
118
 
119
- def join_force?(force_class)
120
- force_class == VariableForce
119
+ def self.joining_forces
120
+ VariableForce
121
121
  end
122
122
 
123
123
  def after_leaving_scope(scope, _variable_table)
@@ -135,7 +135,7 @@ module RuboCop
135
135
  return unless persist_method?(node, CREATE_PERSIST_METHODS)
136
136
  return if persisted_referenced?(assignment)
137
137
 
138
- add_offense_for_node(node, CREATE_MSG)
138
+ register_offense(node, CREATE_MSG)
139
139
  end
140
140
 
141
141
  # rubocop:disable Metrics/CyclomaticComplexity
@@ -148,25 +148,22 @@ module RuboCop
148
148
  return if explicit_return?(node)
149
149
  return if checked_immediately?(node)
150
150
 
151
- add_offense_for_node(node)
151
+ register_offense(node, MSG)
152
152
  end
153
153
  # rubocop:enable Metrics/CyclomaticComplexity
154
154
  alias on_csend on_send
155
155
 
156
- def autocorrect(node)
157
- save_loc = node.loc.selector
158
- new_method = "#{node.method_name}!"
159
-
160
- ->(corrector) { corrector.replace(save_loc, new_method) }
161
- end
162
-
163
156
  private
164
157
 
165
- def add_offense_for_node(node, msg = MSG)
166
- name = node.method_name
167
- full_message = format(msg, prefer: "#{name}!", current: name.to_s)
158
+ def register_offense(node, msg)
159
+ current_method = node.method_name
160
+ bang_method = "#{current_method}!"
161
+ full_message = format(msg, prefer: bang_method, current: current_method)
168
162
 
169
- add_offense(node, location: :selector, message: full_message)
163
+ range = node.loc.selector
164
+ add_offense(range, message: full_message) do |corrector|
165
+ corrector.replace(range, bang_method)
166
+ end
170
167
  end
171
168
 
172
169
  def right_assignment_node(assignment)
@@ -218,7 +215,7 @@ module RuboCop
218
215
  def check_used_in_condition_or_compound_boolean(node)
219
216
  return false unless in_condition_or_compound_boolean?(node)
220
217
 
221
- add_offense_for_node(node, CREATE_CONDITIONAL_MSG) unless MODIFY_PERSIST_METHODS.include?(node.method_name)
218
+ register_offense(node, CREATE_CONDITIONAL_MSG) unless MODIFY_PERSIST_METHODS.include?(node.method_name)
222
219
 
223
220
  true
224
221
  end
@@ -318,7 +315,7 @@ module RuboCop
318
315
  assignment&.lvasgn_type?
319
316
  end
320
317
 
321
- def persist_method?(node, methods = PERSIST_METHODS)
318
+ def persist_method?(node, methods = RESTRICT_ON_SEND)
322
319
  methods.include?(node.method_name) &&
323
320
  expected_signature?(node) &&
324
321
  !allowed_receiver?(node)
@@ -13,8 +13,9 @@ module RuboCop
13
13
  #
14
14
  # # good
15
15
  # scope :something, -> { where(something: true) }
16
- class ScopeArgs < Cop
16
+ class ScopeArgs < Base
17
17
  MSG = 'Use `lambda`/`proc` instead of a plain method call.'
18
+ RESTRICT_ON_SEND = %i[scope].freeze
18
19
 
19
20
  def_node_matcher :scope?, '(send nil? :scope _ $send)'
20
21
 
@@ -38,8 +38,9 @@ module RuboCop
38
38
  # t :key
39
39
  # l Time.now
40
40
  #
41
- class ShortI18n < Cop
41
+ class ShortI18n < Base
42
42
  include ConfigurableEnforcedStyle
43
+ extend AutoCorrector
43
44
 
44
45
  MSG = 'Use `%<good_method>s` instead of `%<bad_method>s`.'
45
46
 
@@ -48,6 +49,8 @@ module RuboCop
48
49
  localize: :l
49
50
  }.freeze
50
51
 
52
+ RESTRICT_ON_SEND = PREFERRED_METHODS.keys.freeze
53
+
51
54
  def_node_matcher :long_i18n?, <<~PATTERN
52
55
  (send {nil? (const nil? :I18n)} ${:translate :localize} ...)
53
56
  PATTERN
@@ -58,15 +61,10 @@ module RuboCop
58
61
  long_i18n?(node) do |method_name|
59
62
  good_method = PREFERRED_METHODS[method_name]
60
63
  message = format(MSG, good_method: good_method, bad_method: method_name)
64
+ range = node.loc.selector
61
65
 
62
- add_offense(node, location: :selector, message: message)
63
- end
64
- end
65
-
66
- def autocorrect(node)
67
- long_i18n?(node) do |method_name|
68
- lambda do |corrector|
69
- corrector.replace(node.loc.selector, PREFERRED_METHODS[method_name])
66
+ add_offense(range, message: message) do |corrector|
67
+ corrector.replace(range, PREFERRED_METHODS[method_name])
70
68
  end
71
69
  end
72
70
  end