rubocop-rails 2.8.0 → 2.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +18 -2
  4. data/config/default.yml +101 -5
  5. data/config/obsoletion.yml +7 -0
  6. data/lib/rubocop/cop/mixin/active_record_helper.rb +16 -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/after_commit_override.rb +9 -2
  15. data/lib/rubocop/cop/rails/application_controller.rb +3 -7
  16. data/lib/rubocop/cop/rails/application_job.rb +2 -1
  17. data/lib/rubocop/cop/rails/application_mailer.rb +2 -7
  18. data/lib/rubocop/cop/rails/application_record.rb +2 -7
  19. data/lib/rubocop/cop/rails/arel_star.rb +41 -0
  20. data/lib/rubocop/cop/rails/assert_not.rb +8 -10
  21. data/lib/rubocop/cop/rails/attribute_default_block_value.rb +90 -0
  22. data/lib/rubocop/cop/rails/belongs_to.rb +10 -19
  23. data/lib/rubocop/cop/rails/blank.rb +31 -27
  24. data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -1
  25. data/lib/rubocop/cop/rails/content_tag.rb +33 -18
  26. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +2 -1
  27. data/lib/rubocop/cop/rails/date.rb +10 -11
  28. data/lib/rubocop/cop/rails/default_scope.rb +11 -4
  29. data/lib/rubocop/cop/rails/delegate.rb +9 -9
  30. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +7 -8
  31. data/lib/rubocop/cop/rails/dynamic_find_by.rb +15 -12
  32. data/lib/rubocop/cop/rails/enum_hash.rb +11 -10
  33. data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -1
  34. data/lib/rubocop/cop/rails/environment_comparison.rb +18 -14
  35. data/lib/rubocop/cop/rails/environment_variable_access.rb +67 -0
  36. data/lib/rubocop/cop/rails/exit.rb +4 -10
  37. data/lib/rubocop/cop/rails/file_path.rb +6 -7
  38. data/lib/rubocop/cop/rails/find_by.rb +13 -13
  39. data/lib/rubocop/cop/rails/find_by_id.rb +12 -21
  40. data/lib/rubocop/cop/rails/find_each.rb +19 -18
  41. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +3 -2
  42. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +37 -6
  43. data/lib/rubocop/cop/rails/helper_instance_variable.rb +29 -3
  44. data/lib/rubocop/cop/rails/http_positional_arguments.rb +32 -21
  45. data/lib/rubocop/cop/rails/http_status.rb +7 -9
  46. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +8 -6
  47. data/lib/rubocop/cop/rails/index_by.rb +3 -2
  48. data/lib/rubocop/cop/rails/index_with.rb +3 -2
  49. data/lib/rubocop/cop/rails/inquiry.rb +4 -3
  50. data/lib/rubocop/cop/rails/inverse_of.rb +3 -2
  51. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +17 -15
  52. data/lib/rubocop/cop/rails/link_to_blank.rb +25 -23
  53. data/lib/rubocop/cop/rails/mailer_name.rb +19 -13
  54. data/lib/rubocop/cop/rails/match_route.rb +14 -13
  55. data/lib/rubocop/cop/rails/negate_include.rb +10 -8
  56. data/lib/rubocop/cop/rails/not_null_column.rb +2 -1
  57. data/lib/rubocop/cop/rails/order_by_id.rb +1 -2
  58. data/lib/rubocop/cop/rails/output.rb +5 -2
  59. data/lib/rubocop/cop/rails/output_safety.rb +3 -2
  60. data/lib/rubocop/cop/rails/pick.rb +14 -12
  61. data/lib/rubocop/cop/rails/pluck.rb +6 -9
  62. data/lib/rubocop/cop/rails/pluck_id.rb +4 -6
  63. data/lib/rubocop/cop/rails/pluck_in_where.rb +7 -7
  64. data/lib/rubocop/cop/rails/pluralization_grammar.rb +10 -14
  65. data/lib/rubocop/cop/rails/presence.rb +12 -13
  66. data/lib/rubocop/cop/rails/present.rb +30 -24
  67. data/lib/rubocop/cop/rails/rake_environment.rb +8 -10
  68. data/lib/rubocop/cop/rails/read_write_attribute.rb +12 -11
  69. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +29 -31
  70. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +9 -12
  71. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +11 -10
  72. data/lib/rubocop/cop/rails/reflection_class_name.rb +17 -3
  73. data/lib/rubocop/cop/rails/refute_methods.rb +9 -10
  74. data/lib/rubocop/cop/rails/relative_date_constant.rb +30 -21
  75. data/lib/rubocop/cop/rails/render_inline.rb +2 -1
  76. data/lib/rubocop/cop/rails/render_plain_text.rb +9 -14
  77. data/lib/rubocop/cop/rails/request_referer.rb +7 -7
  78. data/lib/rubocop/cop/rails/require_dependency.rb +38 -0
  79. data/lib/rubocop/cop/rails/reversible_migration.rb +4 -8
  80. data/lib/rubocop/cop/rails/reversible_migration_method_definition.rb +75 -0
  81. data/lib/rubocop/cop/rails/safe_navigation.rb +30 -11
  82. data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +5 -10
  83. data/lib/rubocop/cop/rails/save_bang.rb +17 -20
  84. data/lib/rubocop/cop/rails/scope_args.rb +2 -1
  85. data/lib/rubocop/cop/rails/short_i18n.rb +7 -9
  86. data/lib/rubocop/cop/rails/skips_model_validations.rb +4 -4
  87. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +5 -6
  88. data/lib/rubocop/cop/rails/time_zone.rb +35 -25
  89. data/lib/rubocop/cop/rails/time_zone_assignment.rb +37 -0
  90. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +4 -6
  91. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +4 -2
  92. data/lib/rubocop/cop/rails/unknown_env.rb +3 -3
  93. data/lib/rubocop/cop/rails/validation.rb +15 -14
  94. data/lib/rubocop/cop/rails/where_equals.rb +98 -0
  95. data/lib/rubocop/cop/rails/where_exists.rb +19 -13
  96. data/lib/rubocop/cop/rails/where_not.rb +14 -19
  97. data/lib/rubocop/cop/rails_cops.rb +8 -0
  98. data/lib/rubocop/rails.rb +2 -0
  99. data/lib/rubocop/rails/schema_loader.rb +4 -4
  100. data/lib/rubocop/rails/schema_loader/schema.rb +2 -4
  101. data/lib/rubocop/rails/version.rb +5 -1
  102. metadata +29 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e89f00783e4dce6642e43ba4a4bf8ee29d078131f71404230db8fd2a1f87248
4
- data.tar.gz: bfbca38eb400e89e260b572babc327afec01b25bad89178179e8276ef7ce651c
3
+ metadata.gz: 79de98cdd4ff48a6ee51c47f2a0bdb76e2393aac1b7974b9181e66723922c148
4
+ data.tar.gz: 85c6c566a98c399bcc73b555187e37d8270975cfde4c5bc067726ee61d6c3704
5
5
  SHA512:
6
- metadata.gz: 241d43809d5cbfa4684fa83c1b92c9069447bae05ca0235d137e6934a2a9ad35ff3e00fba46928e793045ee1cf35dc3a520cca9f177e8c3280530282eb52ac06
7
- data.tar.gz: 7019b400331651ad86a94e9562f93e31c32025ae5ed9c8c5da0f62c65974b21052438908a535da9314a6b903ea3ff6815dc7a0a6350ce3db9d6ab1d0ac18d015
6
+ metadata.gz: 7cf4cddba4e79e79579415bb93aed3bc75e8571a862f32727edc56ffbe5580ba4f5781cf7205c84dbdf1cae9979c7c4b500c227f82ba1a5d476af279a8a9f575
7
+ data.tar.gz: c3591c01fe64b61de0ea39d136a57697b90deb71c90c7738de7c4eb8102f0b6a03548c2e2add574d343ce025d087150d57f7b51860d7471f85943fda125fc7e4
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-20 Bozhidar Batsov
1
+ Copyright (c) 2012-21 Bozhidar Batsov
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # RuboCop Rails
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/rubocop-rails.svg)](https://badge.fury.io/rb/rubocop-rails)
4
- [![CircleCI](https://circleci.com/gh/rubocop-hq/rubocop-rails.svg?style=svg)](https://circleci.com/gh/rubocop-hq/rubocop-rails)
4
+ [![CircleCI](https://circleci.com/gh/rubocop/rubocop-rails.svg?style=svg)](https://circleci.com/gh/rubocop/rubocop-rails)
5
5
 
6
- A [RuboCop](https://github.com/rubocop-hq/rubocop) extension focused on enforcing Rails best practices and coding conventions.
6
+ A [RuboCop](https://github.com/rubocop/rubocop) extension focused on enforcing Rails best practices and coding conventions.
7
7
 
8
8
  Note: This repository manages rubocop-rails gem (>= 2.0.0). rubocop-rails gem (<= 1.5.0) has been renamed to [rubocop-rails_config](https://rubygems.org/gems/rubocop-rails_config) gem.
9
9
 
@@ -86,6 +86,22 @@ Rails cops support the following versions:
86
86
 
87
87
  - Rails 4.2+
88
88
 
89
+ ## Readme Badge
90
+
91
+ If you use RuboCop Rails in your project, you can include one of these badges in your readme to let people know that your code is written following the community Rails Style Guide.
92
+
93
+ [![Rails Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop-rails)
94
+
95
+ [![Rails Style Guide](https://img.shields.io/badge/code_style-community-brightgreen.svg)](https://rails.rubystyle.guide)
96
+
97
+ Here are the Markdown snippets for the two badges:
98
+
99
+ ``` markdown
100
+ [![Rails Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop-rails)
101
+
102
+ [![Rails Style Guide](https://img.shields.io/badge/code_style-community-brightgreen.svg)](https://rails.rubystyle.guide)
103
+ ```
104
+
89
105
  ## Contributing
90
106
 
91
107
  Checkout the [contribution guidelines](CONTRIBUTING.md).
data/config/default.yml CHANGED
@@ -17,6 +17,27 @@ AllCops:
17
17
  # as the default.
18
18
  TargetRailsVersion: ~
19
19
 
20
+ Lint/NumberConversion:
21
+ # Add Rails' duration methods to the ignore list for `Lint/NumberConversion`
22
+ # so that calling `to_i` on one of these does not register an offense.
23
+ # See: https://github.com/rubocop/rubocop/issues/8950
24
+ IgnoredMethods:
25
+ - ago
26
+ - from_now
27
+ - second
28
+ - seconds
29
+ - minute
30
+ - minutes
31
+ - hour
32
+ - hours
33
+ - day
34
+ - days
35
+ - week
36
+ - weeks
37
+ - fortnight
38
+ - fortnights
39
+ - in_milliseconds
40
+
20
41
  Rails/ActionFilter:
21
42
  Description: 'Enforces consistent use of action filter methods.'
22
43
  Enabled: true
@@ -98,6 +119,12 @@ Rails/ApplicationRecord:
98
119
  VersionAdded: '0.49'
99
120
  VersionChanged: '2.5'
100
121
 
122
+ Rails/ArelStar:
123
+ Description: 'Enforces `Arel.star` instead of `"*"` for expanded columns.'
124
+ Enabled: true
125
+ SafeAutoCorrect: false
126
+ VersionAdded: '2.9'
127
+
101
128
  Rails/AssertNot:
102
129
  Description: 'Use `assert_not` instead of `assert !`.'
103
130
  Enabled: true
@@ -105,6 +132,13 @@ Rails/AssertNot:
105
132
  Include:
106
133
  - '**/test/**/*'
107
134
 
135
+ Rails/AttributeDefaultBlockValue:
136
+ Description: 'Pass method call in block for attribute option `default`.'
137
+ Enabled: pending
138
+ VersionAdded: '2.9'
139
+ Include:
140
+ - 'models/**/*'
141
+
108
142
  Rails/BelongsTo:
109
143
  Description: >-
110
144
  Use `optional: true` instead of `required: false` for
@@ -115,8 +149,9 @@ Rails/BelongsTo:
115
149
  Rails/Blank:
116
150
  Description: 'Enforces use of `blank?`.'
117
151
  Enabled: true
152
+ SafeAutoCorrect: false
118
153
  VersionAdded: '0.48'
119
- VersionChanged: '0.67'
154
+ VersionChanged: '2.10'
120
155
  # Convert usages of `nil? || empty?` to `blank?`
121
156
  NilOrEmpty: true
122
157
  # Convert usages of `!present?` to `blank?`
@@ -194,8 +229,9 @@ Rails/DynamicFindBy:
194
229
  Description: 'Use `find_by` instead of dynamic `find_by_*`.'
195
230
  StyleGuide: 'https://rails.rubystyle.guide#find_by'
196
231
  Enabled: true
232
+ Safe: false
197
233
  VersionAdded: '0.44'
198
- VersionChanged: '2.6'
234
+ VersionChanged: '2.10'
199
235
  # The `Whitelist` has been deprecated, Please use `AllowedMethods` instead.
200
236
  Whitelist:
201
237
  - find_by_sql
@@ -224,6 +260,18 @@ Rails/EnvironmentComparison:
224
260
  Enabled: true
225
261
  VersionAdded: '0.52'
226
262
 
263
+ Rails/EnvironmentVariableAccess:
264
+ Description: 'Do not access `ENV` directly after initialization.'
265
+ Enabled: pending
266
+ VersionAdded: '2.10'
267
+ Include:
268
+ - app/**/*.rb
269
+ - lib/**/*.rb
270
+ Exclude:
271
+ - lib/**/*.rake
272
+ AllowReads: false
273
+ AllowWrites: false
274
+
227
275
  Rails/Exit:
228
276
  Description: >-
229
277
  Favor `fail`, `break`, `return`, etc. over `exit` in
@@ -269,8 +317,15 @@ Rails/FindEach:
269
317
  StyleGuide: 'https://rails.rubystyle.guide#find-each'
270
318
  Enabled: true
271
319
  VersionAdded: '0.30'
320
+ VersionChanged: '2.9'
272
321
  Include:
273
322
  - app/models/**/*.rb
323
+ IgnoredMethods:
324
+ # Methods that don't work well with `find_each`.
325
+ - order
326
+ - limit
327
+ - select
328
+ - lock
274
329
 
275
330
  Rails/HasAndBelongsToMany:
276
331
  Description: 'Prefer has_many :through to has_and_belongs_to_many.'
@@ -387,7 +442,9 @@ Rails/NegateInclude:
387
442
  Description: 'Prefer `collection.exclude?(obj)` over `!collection.include?(obj)`.'
388
443
  StyleGuide: 'https://rails.rubystyle.guide#exclude'
389
444
  Enabled: 'pending'
445
+ Safe: false
390
446
  VersionAdded: '2.7'
447
+ VersionChanged: '2.9'
391
448
 
392
449
  Rails/NotNullColumn:
393
450
  Description: 'Do not add a NOT NULL column without a default value.'
@@ -518,7 +575,9 @@ Rails/RedundantReceiverInWithOptions:
518
575
  Rails/ReflectionClassName:
519
576
  Description: 'Use a string for `class_name` option value in the definition of a reflection.'
520
577
  Enabled: true
578
+ Safe: false
521
579
  VersionAdded: '0.64'
580
+ VersionChanged: '2.10'
522
581
 
523
582
  Rails/RefuteMethods:
524
583
  Description: 'Use `assert_not` methods instead of `refute` methods.'
@@ -561,6 +620,12 @@ Rails/RequestReferer:
561
620
  - referer
562
621
  - referrer
563
622
 
623
+ Rails/RequireDependency:
624
+ Description: 'Do not use `require_dependency` when running in Zeitwerk mode. `require_dependency` is for autoloading in classic mode.'
625
+ Reference: 'https://guides.rubyonrails.org/autoloading_and_reloading_constants.html'
626
+ Enabled: false
627
+ VersionAdded: '2.10'
628
+
564
629
  Rails/ReversibleMigration:
565
630
  Description: 'Checks whether the change method of the migration file is reversible.'
566
631
  StyleGuide: 'https://rails.rubystyle.guide#reversible-migration'
@@ -570,6 +635,13 @@ Rails/ReversibleMigration:
570
635
  Include:
571
636
  - db/migrate/*.rb
572
637
 
638
+ Rails/ReversibleMigrationMethodDefinition:
639
+ Description: 'Checks whether the migration implements either a `change` method or both an `up` and a `down` method.'
640
+ Enabled: false
641
+ VersionAdded: '2.10'
642
+ Include:
643
+ - db/migrate/*.rb
644
+
573
645
  Rails/SafeNavigation:
574
646
  Description: "Use Ruby's safe navigation operator (`&.`) instead of `try!`."
575
647
  Enabled: true
@@ -653,6 +725,10 @@ Rails/SquishedSQLHeredocs:
653
725
  StyleGuide: 'https://rails.rubystyle.guide/#squished-heredocs'
654
726
  Enabled: 'pending'
655
727
  VersionAdded: '2.8'
728
+ VersionChanged: '2.9'
729
+ # Some SQL syntax (e.g. PostgreSQL comments and functions) requires newlines
730
+ # to be preserved in order to work, thus auto-correction is not safe.
731
+ SafeAutoCorrect: false
656
732
 
657
733
  Rails/TimeZone:
658
734
  Description: 'Checks the correct usage of time zone aware methods.'
@@ -661,13 +737,24 @@ Rails/TimeZone:
661
737
  Enabled: true
662
738
  Safe: false
663
739
  VersionAdded: '0.30'
664
- VersionChanged: '0.68'
740
+ VersionChanged: '2.10'
665
741
  # The value `strict` means that `Time` should be used with `zone`.
666
742
  # The value `flexible` allows usage of `in_time_zone` instead of `zone`.
667
743
  EnforcedStyle: flexible
668
744
  SupportedStyles:
669
745
  - strict
670
746
  - flexible
747
+ Exclude:
748
+ - '**/*.gemspec'
749
+
750
+ Rails/TimeZoneAssignment:
751
+ Description: 'Prefer the usage of `Time.use_zone` instead of manually updating `Time.zone` value.'
752
+ Reference: 'https://thoughtbot.com/blog/its-about-time-zones'
753
+ Enabled: 'pending'
754
+ VersionAdded: '2.10'
755
+ Include:
756
+ - spec/**/*.rb
757
+ - test/**/*.rb
671
758
 
672
759
  Rails/UniqBeforePluck:
673
760
  Description: 'Prefer the use of uniq or distinct before pluck.'
@@ -705,19 +792,28 @@ Rails/Validation:
705
792
  Include:
706
793
  - app/models/**/*.rb
707
794
 
795
+ Rails/WhereEquals:
796
+ Description: 'Pass conditions to `where` as a hash instead of manually constructing SQL.'
797
+ StyleGuide: 'https://rails.rubystyle.guide/#hash-conditions'
798
+ Enabled: 'pending'
799
+ SafeAutoCorrect: false
800
+ VersionAdded: '2.9'
801
+ VersionChanged: '2.10'
802
+
708
803
  Rails/WhereExists:
709
804
  Description: 'Prefer `exists?(...)` over `where(...).exists?`.'
710
805
  Enabled: 'pending'
806
+ SafeAutoCorrect: false
711
807
  EnforcedStyle: exists
712
808
  SupportedStyles:
713
809
  - exists
714
810
  - where
715
811
  VersionAdded: '2.7'
716
- VersionChanged: '2.8'
812
+ VersionChanged: '2.10'
717
813
 
718
814
  Rails/WhereNot:
719
815
  Description: 'Use `where.not(...)` instead of manually constructing negated SQL in `where`.'
720
- StyleGuide: 'https://rails.rubystyle.guide/#where-not'
816
+ StyleGuide: 'https://rails.rubystyle.guide/#hash-conditions'
721
817
  Enabled: 'pending'
722
818
  VersionAdded: '2.8'
723
819
 
@@ -0,0 +1,7 @@
1
+ #
2
+ # Configuration for obsoletion.
3
+ #
4
+ # See: https://docs.rubocop.org/rubocop/extensions.html#config-obsoletions
5
+ #
6
+ extracted:
7
+ Rails/*: ~
@@ -8,6 +8,13 @@ module RuboCop
8
8
 
9
9
  WHERE_METHODS = %i[where rewhere].freeze
10
10
 
11
+ def_node_matcher :active_record?, <<~PATTERN
12
+ {
13
+ (const nil? :ApplicationRecord)
14
+ (const (const nil? :ActiveRecord) :Base)
15
+ }
16
+ PATTERN
17
+
11
18
  def_node_search :find_set_table_name, <<~PATTERN
12
19
  (send self :table_name= {str sym})
13
20
  PATTERN
@@ -16,6 +23,10 @@ module RuboCop
16
23
  (send nil? :belongs_to {str sym} ...)
17
24
  PATTERN
18
25
 
26
+ def inherit_active_record_base?(node)
27
+ node.each_ancestor(:class).any? { |class_node| active_record?(class_node.parent_class) }
28
+ end
29
+
19
30
  def external_dependency_checksum
20
31
  return @external_dependency_checksum if defined?(@external_dependency_checksum)
21
32
 
@@ -35,10 +46,11 @@ module RuboCop
35
46
  table_name = find_set_table_name(class_node).to_a.last&.first_argument
36
47
  return table_name.value.to_s if table_name
37
48
 
38
- namespaces = class_node.each_ancestor(:class, :module)
39
- [class_node, *namespaces]
49
+ class_nodes = class_node.defined_module.each_node
50
+ namespaces = class_node.each_ancestor(:class, :module).map(&:identifier)
51
+ [*class_nodes, *namespaces]
40
52
  .reverse
41
- .map { |klass| klass.identifier.children[1] }.join('_')
53
+ .map { |node| node.children[1] }.join('_')
42
54
  .tableize
43
55
  end
44
56
 
@@ -52,6 +64,7 @@ module RuboCop
52
64
  # @param table [RuboCop::Rails::SchemaLoader::Table]
53
65
  # @return [String, nil]
54
66
  def resolve_relation_into_column(name:, class_node:, table:)
67
+ return unless table
55
68
  return name if table.with_column?(name: name)
56
69
 
57
70
  find_belongs_to(class_node) do |belongs_to|
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Common functionality for enforcing a specific superclass.
6
+ module EnforceSuperclass
7
+ def self.included(base)
8
+ base.def_node_matcher :class_definition, <<~PATTERN
9
+ (class (const _ !:#{base::SUPERCLASS}) #{base::BASE_PATTERN} ...)
10
+ PATTERN
11
+
12
+ base.def_node_matcher :class_new_definition, <<~PATTERN
13
+ [!^(casgn {nil? cbase} :#{base::SUPERCLASS} ...)
14
+ !^^(casgn {nil? cbase} :#{base::SUPERCLASS} (block ...))
15
+ (send (const {nil? cbase} :Class) :new #{base::BASE_PATTERN})]
16
+ PATTERN
17
+ end
18
+
19
+ def on_class(node)
20
+ class_definition(node) do
21
+ register_offense(node.children[1])
22
+ end
23
+ end
24
+
25
+ def on_send(node)
26
+ class_new_definition(node) do
27
+ register_offense(node.children.last)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def register_offense(offense_node)
34
+ add_offense(offense_node) do |corrector|
35
+ corrector.replace(offense_node.source_range, self.class::SUPERCLASS)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -4,6 +4,8 @@ module RuboCop
4
4
  module Cop
5
5
  # Common functionality for Rails/IndexBy and Rails/IndexWith
6
6
  module IndexMethod # rubocop:disable Metrics/ModuleLength
7
+ RESTRICT_ON_SEND = %i[each_with_object to_h map collect []].freeze
8
+
7
9
  def on_block(node)
8
10
  on_bad_each_with_object(node) do |*match|
9
11
  handle_possible_offense(node, match, 'each_with_object')
@@ -32,13 +34,6 @@ module RuboCop
32
34
  end
33
35
  end
34
36
 
35
- def autocorrect(node)
36
- lambda do |corrector|
37
- correction = prepare_correction(node)
38
- execute_correction(corrector, node, correction)
39
- end
40
- end
41
-
42
37
  private
43
38
 
44
39
  # @abstract Implemented with `def_node_matcher`
@@ -67,9 +62,11 @@ module RuboCop
67
62
  return if captures.noop_transformation?
68
63
 
69
64
  add_offense(
70
- node,
71
- message: "Prefer `#{new_method_name}` over `#{match_desc}`."
72
- )
65
+ node, message: "Prefer `#{new_method_name}` over `#{match_desc}`."
66
+ ) do |corrector|
67
+ correction = prepare_correction(node)
68
+ execute_correction(corrector, node, correction)
69
+ end
73
70
  end
74
71
 
75
72
  def extract_captures(match)
@@ -119,7 +116,7 @@ module RuboCop
119
116
  end
120
117
 
121
118
  # Internal helper class to hold autocorrect data
122
- Autocorrection = Struct.new(:match, :block_node, :leading, :trailing) do # rubocop:disable Metrics/BlockLength
119
+ Autocorrection = Struct.new(:match, :block_node, :leading, :trailing) do
123
120
  def self.from_each_with_object(node, match)
124
121
  new(match, node, 0, 0)
125
122
  end
@@ -29,8 +29,9 @@ module RuboCop
29
29
  # after_filter :do_stuff
30
30
  # append_around_filter :do_stuff
31
31
  # skip_after_filter :do_stuff
32
- class ActionFilter < Cop
32
+ class ActionFilter < Base
33
33
  include ConfigurableEnforcedStyle
34
+ extend AutoCorrector
34
35
 
35
36
  MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
36
37
 
@@ -66,6 +67,8 @@ module RuboCop
66
67
  skip_action_callback
67
68
  ].freeze
68
69
 
70
+ RESTRICT_ON_SEND = FILTER_METHODS + ACTION_METHODS
71
+
69
72
  def on_block(node)
70
73
  check_method_node(node.send_node)
71
74
  end
@@ -74,24 +77,17 @@ module RuboCop
74
77
  check_method_node(node) unless node.receiver
75
78
  end
76
79
 
77
- def autocorrect(node)
78
- lambda do |corrector|
79
- corrector.replace(node.loc.selector,
80
- preferred_method(node.loc.selector.source).to_s)
81
- end
82
- end
83
-
84
80
  private
85
81
 
86
82
  def check_method_node(node)
87
- return unless bad_methods.include?(node.method_name)
83
+ method_name = node.method_name
84
+ return unless bad_methods.include?(method_name)
88
85
 
89
- add_offense(node, location: :selector)
90
- end
86
+ message = format(MSG, prefer: preferred_method(method_name), current: method_name)
91
87
 
92
- def message(node)
93
- format(MSG, prefer: preferred_method(node.method_name),
94
- current: node.method_name)
88
+ add_offense(node.loc.selector, message: message) do |corrector|
89
+ corrector.replace(node.loc.selector, preferred_method(node.loc.selector.source))
90
+ end
95
91
  end
96
92
 
97
93
  def bad_methods