rubocop-rails 2.5.1 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +192 -11
  5. data/lib/rubocop/cop/mixin/active_record_helper.rb +22 -0
  6. data/lib/rubocop/cop/mixin/index_method.rb +25 -1
  7. data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +143 -0
  8. data/lib/rubocop/cop/rails/after_commit_override.rb +84 -0
  9. data/lib/rubocop/cop/rails/content_tag.rb +69 -0
  10. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +1 -3
  11. data/lib/rubocop/cop/rails/default_scope.rb +54 -0
  12. data/lib/rubocop/cop/rails/delegate.rb +2 -4
  13. data/lib/rubocop/cop/rails/dynamic_find_by.rb +40 -15
  14. data/lib/rubocop/cop/rails/exit.rb +2 -2
  15. data/lib/rubocop/cop/rails/file_path.rb +2 -1
  16. data/lib/rubocop/cop/rails/find_by_id.rb +103 -0
  17. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +1 -5
  18. data/lib/rubocop/cop/rails/helper_instance_variable.rb +2 -0
  19. data/lib/rubocop/cop/rails/http_positional_arguments.rb +1 -1
  20. data/lib/rubocop/cop/rails/http_status.rb +2 -0
  21. data/lib/rubocop/cop/rails/index_by.rb +8 -0
  22. data/lib/rubocop/cop/rails/index_with.rb +8 -0
  23. data/lib/rubocop/cop/rails/inquiry.rb +38 -0
  24. data/lib/rubocop/cop/rails/inverse_of.rb +0 -4
  25. data/lib/rubocop/cop/rails/link_to_blank.rb +3 -3
  26. data/lib/rubocop/cop/rails/mailer_name.rb +80 -0
  27. data/lib/rubocop/cop/rails/match_route.rb +119 -0
  28. data/lib/rubocop/cop/rails/negate_include.rb +39 -0
  29. data/lib/rubocop/cop/rails/order_by_id.rb +53 -0
  30. data/lib/rubocop/cop/rails/pick.rb +55 -0
  31. data/lib/rubocop/cop/rails/pluck.rb +59 -0
  32. data/lib/rubocop/cop/rails/pluck_id.rb +58 -0
  33. data/lib/rubocop/cop/rails/pluck_in_where.rb +70 -0
  34. data/lib/rubocop/cop/rails/presence.rb +2 -6
  35. data/lib/rubocop/cop/rails/rake_environment.rb +17 -0
  36. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +80 -0
  37. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -3
  38. data/lib/rubocop/cop/rails/reflection_class_name.rb +1 -1
  39. data/lib/rubocop/cop/rails/relative_date_constant.rb +5 -2
  40. data/lib/rubocop/cop/rails/render_inline.rb +40 -0
  41. data/lib/rubocop/cop/rails/render_plain_text.rb +76 -0
  42. data/lib/rubocop/cop/rails/reversible_migration.rb +79 -0
  43. data/lib/rubocop/cop/rails/safe_navigation.rb +1 -1
  44. data/lib/rubocop/cop/rails/save_bang.rb +8 -9
  45. data/lib/rubocop/cop/rails/short_i18n.rb +76 -0
  46. data/lib/rubocop/cop/rails/skips_model_validations.rb +46 -8
  47. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +83 -0
  48. data/lib/rubocop/cop/rails/time_zone.rb +1 -3
  49. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +14 -12
  50. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +15 -11
  51. data/lib/rubocop/cop/rails/unknown_env.rb +18 -6
  52. data/lib/rubocop/cop/rails/where_exists.rb +131 -0
  53. data/lib/rubocop/cop/rails/where_not.rb +106 -0
  54. data/lib/rubocop/cop/rails_cops.rb +21 -0
  55. data/lib/rubocop/rails/schema_loader.rb +10 -10
  56. data/lib/rubocop/rails/schema_loader/schema.rb +4 -4
  57. data/lib/rubocop/rails/version.rb +1 -1
  58. metadata +31 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ad01eddf8f7245cdbba5eef8c2c7f73656707bde4dd3e1dc08e6604284e2c5b
4
- data.tar.gz: b4542ee0b28af39310b2fbf6e5b7e276249144050edf90208036b8b9dafe64da
3
+ metadata.gz: 6e89f00783e4dce6642e43ba4a4bf8ee29d078131f71404230db8fd2a1f87248
4
+ data.tar.gz: bfbca38eb400e89e260b572babc327afec01b25bad89178179e8276ef7ce651c
5
5
  SHA512:
6
- metadata.gz: d3c643803fcbeb378b60bf8c811bda542445d03ded462975d2c89f3a49e3f36b0c4f46468adbbbc768923a4f01545e5b03159ee2a675687bd49906b81dd28912
7
- data.tar.gz: a471837a24adbb346243c23a2e88d0daceb2214632e7b92fc075b4936897fec91b06cb56d6131e65ea9716a643f3a635317357053364f29f6a7663ccefd62f32
6
+ metadata.gz: 241d43809d5cbfa4684fa83c1b92c9069447bae05ca0235d137e6934a2a9ad35ff3e00fba46928e793045ee1cf35dc3a520cca9f177e8c3280530282eb52ac06
7
+ data.tar.gz: 7019b400331651ad86a94e9562f93e31c32025ae5ed9c8c5da0f62c65974b21052438908a535da9314a6b903ea3ff6815dc7a0a6350ce3db9d6ab1d0ac18d015
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-18 Bozhidar Batsov
1
+ Copyright (c) 2012-20 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
@@ -78,13 +78,13 @@ Rails/FindBy:
78
78
 
79
79
  ## Documentation
80
80
 
81
- You can read a lot more about RuboCop Rails in its [official docs](https://docs.rubocop.org/projects/rails/).
81
+ You can read a lot more about RuboCop Rails in its [official docs](https://docs.rubocop.org/rubocop-rails/).
82
82
 
83
83
  ## Compatibility
84
84
 
85
85
  Rails cops support the following versions:
86
86
 
87
- - Rails 4.0+
87
+ - Rails 4.2+
88
88
 
89
89
  ## Contributing
90
90
 
@@ -37,6 +37,14 @@ Rails/ActiveRecordAliases:
37
37
  VersionAdded: '0.53'
38
38
  SafeAutoCorrect: false
39
39
 
40
+ Rails/ActiveRecordCallbacksOrder:
41
+ Description: 'Order callback declarations in the order in which they will be executed.'
42
+ StyleGuide: 'https://rails.rubystyle.guide/#callbacks-order'
43
+ Enabled: 'pending'
44
+ VersionAdded: '2.7'
45
+ Include:
46
+ - app/models/**/*.rb
47
+
40
48
  Rails/ActiveRecordOverride:
41
49
  Description: >-
42
50
  Check for overriding Active Record methods instead of using
@@ -54,6 +62,14 @@ Rails/ActiveSupportAliases:
54
62
  Enabled: true
55
63
  VersionAdded: '0.48'
56
64
 
65
+ Rails/AfterCommitOverride:
66
+ Description: >-
67
+ This cop enforces that there is only one call to `after_commit`
68
+ (and its aliases - `after_create_commit`, `after_update_commit`,
69
+ and `after_destroy_commit`) with the same callback name per model.
70
+ Enabled: 'pending'
71
+ VersionAdded: '2.8'
72
+
57
73
  Rails/ApplicationController:
58
74
  Description: 'Check that controllers subclass ApplicationController.'
59
75
  Enabled: true
@@ -92,7 +108,7 @@ Rails/AssertNot:
92
108
  Rails/BelongsTo:
93
109
  Description: >-
94
110
  Use `optional: true` instead of `required: false` for
95
- `belongs_to` relations'
111
+ `belongs_to` relations.
96
112
  Enabled: true
97
113
  VersionAdded: '0.62'
98
114
 
@@ -119,6 +135,14 @@ Rails/BulkChangeTable:
119
135
  Include:
120
136
  - db/migrate/*.rb
121
137
 
138
+ Rails/ContentTag:
139
+ Description: 'Use `tag` instead of `content_tag`.'
140
+ Reference:
141
+ - 'https://github.com/rails/rails/issues/25195'
142
+ - 'https://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-content_tag'
143
+ Enabled: true
144
+ VersionAdded: '2.6'
145
+
122
146
  Rails/CreateTableWithTimestamps:
123
147
  Description: >-
124
148
  Checks the migration for which timestamps are not included
@@ -145,6 +169,12 @@ Rails/Date:
145
169
  - strict
146
170
  - flexible
147
171
 
172
+ Rails/DefaultScope:
173
+ Description: 'Avoid use of `default_scope`.'
174
+ StyleGuide: 'https://rails.rubystyle.guide#avoid-default-scope'
175
+ Enabled: false
176
+ VersionAdded: '2.7'
177
+
148
178
  Rails/Delegate:
149
179
  Description: 'Prefer delegate method for delegations.'
150
180
  Enabled: true
@@ -165,8 +195,14 @@ Rails/DynamicFindBy:
165
195
  StyleGuide: 'https://rails.rubystyle.guide#find_by'
166
196
  Enabled: true
167
197
  VersionAdded: '0.44'
198
+ VersionChanged: '2.6'
199
+ # The `Whitelist` has been deprecated, Please use `AllowedMethods` instead.
168
200
  Whitelist:
169
201
  - find_by_sql
202
+ AllowedMethods:
203
+ - find_by_sql
204
+ AllowedReceivers:
205
+ - Gem::Specification
170
206
 
171
207
  Rails/EnumHash:
172
208
  Description: 'Prefer hash syntax over array syntax when defining enums.'
@@ -184,7 +220,7 @@ Rails/EnumUniqueness:
184
220
  - app/models/**/*.rb
185
221
 
186
222
  Rails/EnvironmentComparison:
187
- Description: "Favor `Rails.env.production?` over `Rails.env == 'production'`"
223
+ Description: "Favor `Rails.env.production?` over `Rails.env == 'production'`."
188
224
  Enabled: true
189
225
  VersionAdded: '0.52'
190
226
 
@@ -220,6 +256,14 @@ Rails/FindBy:
220
256
  Include:
221
257
  - app/models/**/*.rb
222
258
 
259
+ Rails/FindById:
260
+ Description: >-
261
+ Favor the use of `find` over `where.take!`, `find_by!`, and `find_by_id!` when you
262
+ need to retrieve a single record by primary key when you expect it to be found.
263
+ StyleGuide: 'https://rails.rubystyle.guide/#find'
264
+ Enabled: 'pending'
265
+ VersionAdded: '2.7'
266
+
223
267
  Rails/FindEach:
224
268
  Description: 'Prefer all.find_each over all.find.'
225
269
  StyleGuide: 'https://rails.rubystyle.guide#find-each'
@@ -245,7 +289,7 @@ Rails/HasManyOrHasOneDependent:
245
289
  - app/models/**/*.rb
246
290
 
247
291
  Rails/HelperInstanceVariable:
248
- Description: 'Do not use instance variables in helpers'
292
+ Description: 'Do not use instance variables in helpers.'
249
293
  Enabled: true
250
294
  VersionAdded: '2.0'
251
295
  Include:
@@ -277,14 +321,22 @@ Rails/IgnoredSkipActionFilterOption:
277
321
  - app/controllers/**/*.rb
278
322
 
279
323
  Rails/IndexBy:
280
- Description: 'Prefer `index_by` over `each_with_object` or `map`.'
324
+ Description: 'Prefer `index_by` over `each_with_object`, `to_h`, or `map`.'
281
325
  Enabled: true
282
326
  VersionAdded: '2.5'
327
+ VersionChanged: '2.8'
283
328
 
284
329
  Rails/IndexWith:
285
- Description: 'Prefer `index_with` over `each_with_object` or `map`.'
330
+ Description: 'Prefer `index_with` over `each_with_object`, `to_h`, or `map`.'
286
331
  Enabled: true
287
332
  VersionAdded: '2.5'
333
+ VersionChanged: '2.8'
334
+
335
+ Rails/Inquiry:
336
+ Description: "Prefer Ruby's comparison operators over Active Support's `Array#inquiry` and `String#inquiry`."
337
+ StyleGuide: 'https://rails.rubystyle.guide/#inquiry'
338
+ Enabled: 'pending'
339
+ VersionAdded: '2.7'
288
340
 
289
341
  Rails/InverseOf:
290
342
  Description: 'Checks for associations where the inverse cannot be determined automatically.'
@@ -311,13 +363,47 @@ Rails/LinkToBlank:
311
363
  Enabled: true
312
364
  VersionAdded: '0.62'
313
365
 
366
+ Rails/MailerName:
367
+ Description: 'Mailer should end with `Mailer` suffix.'
368
+ StyleGuide: 'https://rails.rubystyle.guide/#mailer-name'
369
+ Enabled: 'pending'
370
+ SafeAutoCorrect: false
371
+ VersionAdded: '2.7'
372
+ Include:
373
+ - app/mailers/**/*.rb
374
+
375
+ Rails/MatchRoute:
376
+ Description: >-
377
+ Don't use `match` to define any routes unless there is a need to map multiple request types
378
+ among [:get, :post, :patch, :put, :delete] to a single action using the `:via` option.
379
+ StyleGuide: 'https://rails.rubystyle.guide/#no-match-routes'
380
+ Enabled: 'pending'
381
+ VersionAdded: '2.7'
382
+ Include:
383
+ - config/routes.rb
384
+ - config/routes/**/*.rb
385
+
386
+ Rails/NegateInclude:
387
+ Description: 'Prefer `collection.exclude?(obj)` over `!collection.include?(obj)`.'
388
+ StyleGuide: 'https://rails.rubystyle.guide#exclude'
389
+ Enabled: 'pending'
390
+ VersionAdded: '2.7'
391
+
314
392
  Rails/NotNullColumn:
315
- Description: 'Do not add a NOT NULL column without a default value'
393
+ Description: 'Do not add a NOT NULL column without a default value.'
316
394
  Enabled: true
317
395
  VersionAdded: '0.43'
318
396
  Include:
319
397
  - db/migrate/*.rb
320
398
 
399
+ Rails/OrderById:
400
+ Description: >-
401
+ Do not use the `id` column for ordering.
402
+ Use a timestamp column to order chronologically.
403
+ StyleGuide: 'https://rails.rubystyle.guide/#order-by-id'
404
+ Enabled: false
405
+ VersionAdded: '2.8'
406
+
321
407
  Rails/Output:
322
408
  Description: 'Checks for calls to puts, print, etc.'
323
409
  Enabled: true
@@ -334,6 +420,37 @@ Rails/OutputSafety:
334
420
  Enabled: true
335
421
  VersionAdded: '0.41'
336
422
 
423
+ Rails/Pick:
424
+ Description: 'Prefer `pick` over `pluck(...).first`.'
425
+ StyleGuide: 'https://rails.rubystyle.guide#pick'
426
+ Enabled: true
427
+ Safe: false
428
+ VersionAdded: '2.6'
429
+
430
+ Rails/Pluck:
431
+ Description: 'Prefer `pluck` over `map { ... }`.'
432
+ StyleGuide: 'https://rails.rubystyle.guide#pluck'
433
+ Enabled: 'pending'
434
+ VersionAdded: '2.7'
435
+
436
+ Rails/PluckId:
437
+ Description: 'Use `ids` instead of `pluck(:id)` or `pluck(primary_key)`.'
438
+ StyleGuide: 'https://rails.rubystyle.guide/#ids'
439
+ Enabled: false
440
+ Safe: false
441
+ VersionAdded: '2.7'
442
+
443
+ Rails/PluckInWhere:
444
+ Description: 'Use `select` instead of `pluck` in `where` query methods.'
445
+ Enabled: 'pending'
446
+ Safe: false
447
+ VersionAdded: '2.7'
448
+ VersionChanged: '2.8'
449
+ EnforcedStyle: conservative
450
+ SupportedStyles:
451
+ - conservative
452
+ - aggressive
453
+
337
454
  Rails/PluralizationGrammar:
338
455
  Description: 'Checks for incorrect grammar when using methods like `3.day.ago`.'
339
456
  Enabled: true
@@ -361,6 +478,7 @@ Rails/RakeEnvironment:
361
478
  Enabled: true
362
479
  Safe: false
363
480
  VersionAdded: '2.4'
481
+ VersionChanged: '2.6'
364
482
  Include:
365
483
  - '**/Rakefile'
366
484
  - '**/*.rake'
@@ -387,6 +505,11 @@ Rails/RedundantAllowNil:
387
505
  Include:
388
506
  - app/models/**/*.rb
389
507
 
508
+ Rails/RedundantForeignKey:
509
+ Description: 'Checks for associations where the `:foreign_key` option is redundant.'
510
+ Enabled: true
511
+ VersionAdded: '2.6'
512
+
390
513
  Rails/RedundantReceiverInWithOptions:
391
514
  Description: 'Checks for redundant receiver in `with_options`.'
392
515
  Enabled: true
@@ -415,6 +538,20 @@ Rails/RelativeDateConstant:
415
538
  VersionChanged: '0.59'
416
539
  AutoCorrect: false
417
540
 
541
+ Rails/RenderInline:
542
+ Description: 'Prefer using a template over inline rendering.'
543
+ StyleGuide: 'https://rails.rubystyle.guide/#inline-rendering'
544
+ Enabled: 'pending'
545
+ VersionAdded: '2.7'
546
+
547
+ Rails/RenderPlainText:
548
+ Description: 'Prefer `render plain:` over `render text:`.'
549
+ StyleGuide: 'https://rails.rubystyle.guide/#plain-text-rendering'
550
+ Enabled: 'pending'
551
+ VersionAdded: '2.7'
552
+ # Convert only when `content_type` is explicitly set to `text/plain`.
553
+ ContentTypeCompatibility: true
554
+
418
555
  Rails/RequestReferer:
419
556
  Description: 'Use consistent syntax for request.referer.'
420
557
  Enabled: true
@@ -434,7 +571,7 @@ Rails/ReversibleMigration:
434
571
  - db/migrate/*.rb
435
572
 
436
573
  Rails/SafeNavigation:
437
- Description: "Use Ruby's safe navigation operator (`&.`) instead of `try!`"
574
+ Description: "Use Ruby's safe navigation operator (`&.`) instead of `try!`."
438
575
  Enabled: true
439
576
  VersionAdded: '0.43'
440
577
  # This will convert usages of `try` to use safe navigation as well as `try!`.
@@ -472,6 +609,16 @@ Rails/ScopeArgs:
472
609
  Include:
473
610
  - app/models/**/*.rb
474
611
 
612
+ Rails/ShortI18n:
613
+ Description: 'Use the short form of the I18n methods: `t` instead of `translate` and `l` instead of `localize`.'
614
+ StyleGuide: 'https://rails.rubystyle.guide/#short-i18n'
615
+ Enabled: 'pending'
616
+ VersionAdded: '2.7'
617
+ EnforcedStyle: conservative
618
+ SupportedStyles:
619
+ - conservative
620
+ - aggressive
621
+
475
622
  Rails/SkipsModelValidations:
476
623
  Description: >-
477
624
  Use methods that skips model validations with caution.
@@ -479,20 +626,33 @@ Rails/SkipsModelValidations:
479
626
  Reference: 'https://guides.rubyonrails.org/active_record_validations.html#skipping-validations'
480
627
  Enabled: true
481
628
  VersionAdded: '0.47'
482
- VersionChanged: '0.60'
483
- Blacklist:
629
+ VersionChanged: '2.7'
630
+ ForbiddenMethods:
484
631
  - decrement!
485
632
  - decrement_counter
486
633
  - increment!
487
634
  - increment_counter
635
+ - insert
636
+ - insert!
637
+ - insert_all
638
+ - insert_all!
488
639
  - toggle!
489
640
  - touch
641
+ - touch_all
490
642
  - update_all
491
643
  - update_attribute
492
644
  - update_column
493
645
  - update_columns
494
646
  - update_counters
495
- Whitelist: []
647
+ - upsert
648
+ - upsert_all
649
+ AllowedMethods: []
650
+
651
+ Rails/SquishedSQLHeredocs:
652
+ Description: 'Checks SQL heredocs to use `.squish`.'
653
+ StyleGuide: 'https://rails.rubystyle.guide/#squished-heredocs'
654
+ Enabled: 'pending'
655
+ VersionAdded: '2.8'
496
656
 
497
657
  Rails/TimeZone:
498
658
  Description: 'Checks the correct usage of time zone aware methods.'
@@ -513,11 +673,12 @@ Rails/UniqBeforePluck:
513
673
  Description: 'Prefer the use of uniq or distinct before pluck.'
514
674
  Enabled: true
515
675
  VersionAdded: '0.40'
516
- VersionChanged: '0.47'
676
+ VersionChanged: '2.8'
517
677
  EnforcedStyle: conservative
518
678
  SupportedStyles:
519
679
  - conservative
520
680
  - aggressive
681
+ SafeAutoCorrect: false
521
682
  AutoCorrect: false
522
683
 
523
684
  Rails/UniqueValidationWithoutIndex:
@@ -543,3 +704,23 @@ Rails/Validation:
543
704
  VersionChanged: '0.41'
544
705
  Include:
545
706
  - app/models/**/*.rb
707
+
708
+ Rails/WhereExists:
709
+ Description: 'Prefer `exists?(...)` over `where(...).exists?`.'
710
+ Enabled: 'pending'
711
+ EnforcedStyle: exists
712
+ SupportedStyles:
713
+ - exists
714
+ - where
715
+ VersionAdded: '2.7'
716
+ VersionChanged: '2.8'
717
+
718
+ Rails/WhereNot:
719
+ Description: 'Use `where.not(...)` instead of manually constructing negated SQL in `where`.'
720
+ StyleGuide: 'https://rails.rubystyle.guide/#where-not'
721
+ Enabled: 'pending'
722
+ VersionAdded: '2.8'
723
+
724
+ # Accept `redirect_to(...) and return` and similar cases.
725
+ Style/AndOr:
726
+ EnforcedStyle: conditionals
@@ -6,6 +6,8 @@ module RuboCop
6
6
  module ActiveRecordHelper
7
7
  extend NodePattern::Macros
8
8
 
9
+ WHERE_METHODS = %i[where rewhere].freeze
10
+
9
11
  def_node_search :find_set_table_name, <<~PATTERN
10
12
  (send self :table_name= {str sym})
11
13
  PATTERN
@@ -14,6 +16,21 @@ module RuboCop
14
16
  (send nil? :belongs_to {str sym} ...)
15
17
  PATTERN
16
18
 
19
+ def external_dependency_checksum
20
+ return @external_dependency_checksum if defined?(@external_dependency_checksum)
21
+
22
+ schema_path = RuboCop::Rails::SchemaLoader.db_schema_path
23
+ return nil if schema_path.nil?
24
+
25
+ schema_code = File.read(schema_path)
26
+
27
+ @external_dependency_checksum ||= Digest::SHA1.hexdigest(schema_code)
28
+ end
29
+
30
+ def schema
31
+ RuboCop::Rails::SchemaLoader.load(target_ruby_version)
32
+ end
33
+
17
34
  def table_name(class_node)
18
35
  table_name = find_set_table_name(class_node).to_a.last&.first_argument
19
36
  return table_name.value.to_s if table_name
@@ -57,6 +74,11 @@ module RuboCop
57
74
  break pair.value.value.to_s
58
75
  end
59
76
  end
77
+
78
+ def in_where?(node)
79
+ send_node = node.each_ancestor(:send).first
80
+ send_node && WHERE_METHODS.include?(send_node.method_name)
81
+ end
60
82
  end
61
83
  end
62
84
  end
@@ -8,6 +8,12 @@ module RuboCop
8
8
  on_bad_each_with_object(node) do |*match|
9
9
  handle_possible_offense(node, match, 'each_with_object')
10
10
  end
11
+
12
+ return if target_ruby_version < 2.6
13
+
14
+ on_bad_to_h(node) do |*match|
15
+ handle_possible_offense(node, match, 'to_h { ... }')
16
+ end
11
17
  end
12
18
 
13
19
  def on_send(node)
@@ -40,6 +46,11 @@ module RuboCop
40
46
  raise NotImplementedError
41
47
  end
42
48
 
49
+ # @abstract Implemented with `def_node_matcher`
50
+ def on_bad_to_h(_node)
51
+ raise NotImplementedError
52
+ end
53
+
43
54
  # @abstract Implemented with `def_node_matcher`
44
55
  def on_bad_map_to_h(_node)
45
56
  raise NotImplementedError
@@ -73,6 +84,8 @@ module RuboCop
73
84
  def prepare_correction(node)
74
85
  if (match = on_bad_each_with_object(node))
75
86
  Autocorrection.from_each_with_object(node, match)
87
+ elsif (match = on_bad_to_h(node))
88
+ Autocorrection.from_to_h(node, match)
76
89
  elsif (match = on_bad_map_to_h(node))
77
90
  Autocorrection.from_map_to_h(node, match)
78
91
  elsif (match = on_bad_hash_brackets_map(node))
@@ -111,8 +124,19 @@ module RuboCop
111
124
  new(match, node, 0, 0)
112
125
  end
113
126
 
127
+ def self.from_to_h(node, match)
128
+ new(match, node, 0, 0)
129
+ end
130
+
114
131
  def self.from_map_to_h(node, match)
115
- strip_trailing_chars = node.parent&.block_type? ? 0 : '.to_h'.length
132
+ strip_trailing_chars = 0
133
+
134
+ unless node.parent&.block_type?
135
+ map_range = node.children.first.source_range
136
+ node_range = node.source_range
137
+ strip_trailing_chars = node_range.end_pos - map_range.end_pos
138
+ end
139
+
116
140
  new(match, node.children.first, 0, strip_trailing_chars)
117
141
  end
118
142