rubocop 1.65.1 → 1.66.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +67 -67
  3. data/config/default.yml +18 -2
  4. data/exe/rubocop +4 -3
  5. data/lib/rubocop/comment_config.rb +1 -1
  6. data/lib/rubocop/config.rb +5 -1
  7. data/lib/rubocop/config_loader.rb +14 -8
  8. data/lib/rubocop/config_loader_resolver.rb +1 -2
  9. data/lib/rubocop/config_validator.rb +1 -1
  10. data/lib/rubocop/cop/base.rb +4 -0
  11. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
  12. data/lib/rubocop/cop/documentation.rb +18 -1
  13. data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
  14. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  15. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +11 -1
  16. data/lib/rubocop/cop/layout/block_alignment.rb +30 -12
  17. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
  18. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +8 -3
  19. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +0 -3
  20. data/lib/rubocop/cop/layout/line_length.rb +14 -14
  21. data/lib/rubocop/cop/lint/empty_conditional_body.rb +27 -6
  22. data/lib/rubocop/cop/lint/float_comparison.rb +1 -3
  23. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +4 -2
  24. data/lib/rubocop/cop/lint/useless_assignment.rb +18 -11
  25. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +77 -0
  26. data/lib/rubocop/cop/lint/void.rb +30 -8
  27. data/lib/rubocop/cop/metrics/block_length.rb +6 -5
  28. data/lib/rubocop/cop/metrics/class_length.rb +6 -5
  29. data/lib/rubocop/cop/metrics/method_length.rb +6 -5
  30. data/lib/rubocop/cop/metrics/module_length.rb +6 -5
  31. data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
  32. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +19 -9
  33. data/lib/rubocop/cop/mixin/line_length_help.rb +7 -2
  34. data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
  35. data/lib/rubocop/cop/naming/accessor_method_name.rb +5 -0
  36. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  37. data/lib/rubocop/cop/style/alias.rb +1 -1
  38. data/lib/rubocop/cop/style/arguments_forwarding.rb +8 -3
  39. data/lib/rubocop/cop/style/empty_else.rb +6 -5
  40. data/lib/rubocop/cop/style/empty_heredoc.rb +1 -14
  41. data/lib/rubocop/cop/style/empty_literal.rb +31 -22
  42. data/lib/rubocop/cop/style/format_string_token.rb +2 -2
  43. data/lib/rubocop/cop/style/guard_clause.rb +2 -0
  44. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  45. data/lib/rubocop/cop/style/if_with_semicolon.rb +45 -6
  46. data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
  47. data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
  48. data/lib/rubocop/cop/style/map_into_array.rb +12 -5
  49. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -2
  50. data/lib/rubocop/cop/style/multiple_comparison.rb +3 -11
  51. data/lib/rubocop/cop/style/numeric_predicate.rb +2 -2
  52. data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
  53. data/lib/rubocop/cop/style/parallel_assignment.rb +5 -4
  54. data/lib/rubocop/cop/style/quoted_symbols.rb +0 -2
  55. data/lib/rubocop/cop/style/redundant_condition.rb +3 -2
  56. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +46 -0
  57. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -1
  58. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  59. data/lib/rubocop/cop/team.rb +6 -2
  60. data/lib/rubocop/formatter/junit_formatter.rb +70 -23
  61. data/lib/rubocop/lockfile.rb +6 -4
  62. data/lib/rubocop/remote_config.rb +5 -1
  63. data/lib/rubocop/result_cache.rb +2 -8
  64. data/lib/rubocop/rspec/shared_contexts.rb +2 -2
  65. data/lib/rubocop/server/cache.rb +1 -1
  66. data/lib/rubocop/target_ruby.rb +7 -3
  67. data/lib/rubocop/version.rb +1 -1
  68. data/lib/rubocop/yaml_duplication_checker.rb +1 -0
  69. data/lib/rubocop.rb +2 -1
  70. metadata +12 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ff6bd1def6f2fc502a83cef45c2031e812de416bf82ee6805ed3c8a4aa4ec08
4
- data.tar.gz: 3fc581f44db6ecb7a31a16b58799151c941184b3d972d11716215165c071d672
3
+ metadata.gz: 8a10568527197e80492a28c5b524fa524dbce965513daff4f47e260e03b49d98
4
+ data.tar.gz: 8ea447437cbd36aa805b3941cf51b07eecc9dc538ed6a4584f09a1335e21cb48
5
5
  SHA512:
6
- metadata.gz: 07e4e645df882074e88da46ca8a69d7b1d12ec0d83bf4dfaaef6d799dcdb49c584b904d9f186e59278e663bbebe3db8e3950a6d4219fa73487978261c72fded6
7
- data.tar.gz: 2d8d8ad60a022ee9df6cb9d164486044787a3a41da8bee073cabb528299d9f62968b8f90fc18a1cba0dbb581968912a478ddda85c1f02c336eb92dbd83092b14
6
+ metadata.gz: 1f292c70ffac1cb186e5be899582c4849a29866722c87ab92a60a723dd16fe86fdf12073c8a7190bba197d246eae3b25ba3cdc6b586b28061cef39ac22b3b438
7
+ data.tar.gz: 2dbfc28779854fae0d28fd266ba269b92cb0e3b5c26200aa250df02ff9810804b7b1fcc289a43bac1913dc04c79f788487f9351444f7242cbcdad6854a821d69
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  ----------
6
6
  [![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop)
7
7
  [![Gem Version](https://badge.fury.io/rb/rubocop.svg)](https://badge.fury.io/rb/rubocop)
8
- [![Actions Status](https://github.com/rubocop/rubocop/workflows/CI/badge.svg?branch=master)](https://github.com/rubocop/rubocop/actions?query=workflow%3ACI)
8
+ [![CI](https://github.com/rubocop/rubocop/actions/workflows/rubocop.yml/badge.svg)](https://github.com/rubocop/rubocop/actions/workflows/rubocop.yml)
9
9
  [![Test Coverage](https://api.codeclimate.com/v1/badges/d2d67f728e88ea84ac69/test_coverage)](https://codeclimate.com/github/rubocop/rubocop/test_coverage)
10
10
  [![Maintainability](https://api.codeclimate.com/v1/badges/d2d67f728e88ea84ac69/maintainability)](https://codeclimate.com/github/rubocop/rubocop/maintainability)
11
11
  [![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://discord.gg/wJjWvGRDmm)
@@ -23,8 +23,8 @@ RuboCop is extremely flexible and most aspects of its behavior can be tweaked vi
23
23
 
24
24
  ----------
25
25
  [![Patreon](https://img.shields.io/badge/patreon-donate-orange.svg)](https://www.patreon.com/bbatsov)
26
- [![OpenCollective](https://opencollective.com/rubocop/backers/badge.svg)](#open-collective-backers)
27
- [![OpenCollective](https://opencollective.com/rubocop/sponsors/badge.svg)](#open-collective-sponsors)
26
+ [![OpenCollective](https://opencollective.com/rubocop/backers/badge.svg)](#open-collective-for-individuals)
27
+ [![OpenCollective](https://opencollective.com/rubocop/sponsors/badge.svg)](#open-collective-for-organizations)
28
28
  [![Tidelift](https://tidelift.com/badges/package/rubygems/rubocop)](https://tidelift.com/subscription/pkg/rubygems-rubocop?utm_source=rubygems-rubocop&utm_medium=referral&utm_campaign=readme)
29
29
 
30
30
  Working on RuboCop is often fun, but it also requires a great deal of time and energy.
@@ -52,7 +52,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
52
52
  in your `Gemfile`:
53
53
 
54
54
  ```rb
55
- gem 'rubocop', '~> 1.65', require: false
55
+ gem 'rubocop', '~> 1.66', require: false
56
56
  ```
57
57
 
58
58
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
@@ -171,75 +171,75 @@ and [Tidelift](https://tidelift.com/subscription/pkg/rubygems-rubocop?utm_source
171
171
  **Note:** If doing a sponsorship in the form of donation is problematic for your company from an accounting standpoint, we'd recommend
172
172
  the use of Tidelift, where you can get a support-like subscription instead.
173
173
 
174
- ### Open Collective Backers
174
+ ### Open Collective for Individuals
175
175
 
176
176
  Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/rubocop#backer)]
177
177
 
178
- <a href="https://opencollective.com/rubocop/backer/0/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/0/avatar.svg"></a>
179
- <a href="https://opencollective.com/rubocop/backer/1/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/1/avatar.svg"></a>
180
- <a href="https://opencollective.com/rubocop/backer/2/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/2/avatar.svg"></a>
181
- <a href="https://opencollective.com/rubocop/backer/3/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/3/avatar.svg"></a>
182
- <a href="https://opencollective.com/rubocop/backer/4/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/4/avatar.svg"></a>
183
- <a href="https://opencollective.com/rubocop/backer/5/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/5/avatar.svg"></a>
184
- <a href="https://opencollective.com/rubocop/backer/6/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/6/avatar.svg"></a>
185
- <a href="https://opencollective.com/rubocop/backer/7/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/7/avatar.svg"></a>
186
- <a href="https://opencollective.com/rubocop/backer/8/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/8/avatar.svg"></a>
187
- <a href="https://opencollective.com/rubocop/backer/9/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/9/avatar.svg"></a>
188
- <a href="https://opencollective.com/rubocop/backer/10/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/10/avatar.svg"></a>
189
- <a href="https://opencollective.com/rubocop/backer/11/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/11/avatar.svg"></a>
190
- <a href="https://opencollective.com/rubocop/backer/12/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/12/avatar.svg"></a>
191
- <a href="https://opencollective.com/rubocop/backer/13/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/13/avatar.svg"></a>
192
- <a href="https://opencollective.com/rubocop/backer/14/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/14/avatar.svg"></a>
193
- <a href="https://opencollective.com/rubocop/backer/15/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/15/avatar.svg"></a>
194
- <a href="https://opencollective.com/rubocop/backer/16/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/16/avatar.svg"></a>
195
- <a href="https://opencollective.com/rubocop/backer/17/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/17/avatar.svg"></a>
196
- <a href="https://opencollective.com/rubocop/backer/18/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/18/avatar.svg"></a>
197
- <a href="https://opencollective.com/rubocop/backer/19/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/19/avatar.svg"></a>
198
- <a href="https://opencollective.com/rubocop/backer/20/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/20/avatar.svg"></a>
199
- <a href="https://opencollective.com/rubocop/backer/21/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/21/avatar.svg"></a>
200
- <a href="https://opencollective.com/rubocop/backer/22/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/22/avatar.svg"></a>
201
- <a href="https://opencollective.com/rubocop/backer/23/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/23/avatar.svg"></a>
202
- <a href="https://opencollective.com/rubocop/backer/24/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/24/avatar.svg"></a>
203
- <a href="https://opencollective.com/rubocop/backer/25/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/25/avatar.svg"></a>
204
- <a href="https://opencollective.com/rubocop/backer/26/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/26/avatar.svg"></a>
205
- <a href="https://opencollective.com/rubocop/backer/27/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/27/avatar.svg"></a>
206
- <a href="https://opencollective.com/rubocop/backer/28/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/28/avatar.svg"></a>
207
- <a href="https://opencollective.com/rubocop/backer/29/website" target="_blank"><img src="https://opencollective.com/rubocop/backer/29/avatar.svg"></a>
208
-
209
- ### Open Collective Sponsors
178
+ <a href="https://opencollective.com/rubocop/individual/0/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/0/avatar.svg"></a>
179
+ <a href="https://opencollective.com/rubocop/individual/1/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/1/avatar.svg"></a>
180
+ <a href="https://opencollective.com/rubocop/individual/2/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/2/avatar.svg"></a>
181
+ <a href="https://opencollective.com/rubocop/individual/3/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/3/avatar.svg"></a>
182
+ <a href="https://opencollective.com/rubocop/individual/4/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/4/avatar.svg"></a>
183
+ <a href="https://opencollective.com/rubocop/individual/5/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/5/avatar.svg"></a>
184
+ <a href="https://opencollective.com/rubocop/individual/6/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/6/avatar.svg"></a>
185
+ <a href="https://opencollective.com/rubocop/individual/7/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/7/avatar.svg"></a>
186
+ <a href="https://opencollective.com/rubocop/individual/8/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/8/avatar.svg"></a>
187
+ <a href="https://opencollective.com/rubocop/individual/9/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/9/avatar.svg"></a>
188
+ <a href="https://opencollective.com/rubocop/individual/10/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/10/avatar.svg"></a>
189
+ <a href="https://opencollective.com/rubocop/individual/11/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/11/avatar.svg"></a>
190
+ <a href="https://opencollective.com/rubocop/individual/12/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/12/avatar.svg"></a>
191
+ <a href="https://opencollective.com/rubocop/individual/13/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/13/avatar.svg"></a>
192
+ <a href="https://opencollective.com/rubocop/individual/14/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/14/avatar.svg"></a>
193
+ <a href="https://opencollective.com/rubocop/individual/15/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/15/avatar.svg"></a>
194
+ <a href="https://opencollective.com/rubocop/individual/16/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/16/avatar.svg"></a>
195
+ <a href="https://opencollective.com/rubocop/individual/17/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/17/avatar.svg"></a>
196
+ <a href="https://opencollective.com/rubocop/individual/18/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/18/avatar.svg"></a>
197
+ <a href="https://opencollective.com/rubocop/individual/19/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/19/avatar.svg"></a>
198
+ <a href="https://opencollective.com/rubocop/individual/20/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/20/avatar.svg"></a>
199
+ <a href="https://opencollective.com/rubocop/individual/21/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/21/avatar.svg"></a>
200
+ <a href="https://opencollective.com/rubocop/individual/22/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/22/avatar.svg"></a>
201
+ <a href="https://opencollective.com/rubocop/individual/23/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/23/avatar.svg"></a>
202
+ <a href="https://opencollective.com/rubocop/individual/24/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/24/avatar.svg"></a>
203
+ <a href="https://opencollective.com/rubocop/individual/25/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/25/avatar.svg"></a>
204
+ <a href="https://opencollective.com/rubocop/individual/26/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/26/avatar.svg"></a>
205
+ <a href="https://opencollective.com/rubocop/individual/27/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/27/avatar.svg"></a>
206
+ <a href="https://opencollective.com/rubocop/individual/28/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/28/avatar.svg"></a>
207
+ <a href="https://opencollective.com/rubocop/individual/29/website" target="_blank"><img src="https://opencollective.com/rubocop/individual/29/avatar.svg"></a>
208
+
209
+ ### Open Collective for Organizations
210
210
 
211
211
  Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor](https://opencollective.com/rubocop#sponsor)]
212
212
 
213
- <a href="https://opencollective.com/rubocop/sponsor/0/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/0/avatar.svg"></a>
214
- <a href="https://opencollective.com/rubocop/sponsor/1/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/1/avatar.svg"></a>
215
- <a href="https://opencollective.com/rubocop/sponsor/2/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/2/avatar.svg"></a>
216
- <a href="https://opencollective.com/rubocop/sponsor/3/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/3/avatar.svg"></a>
217
- <a href="https://opencollective.com/rubocop/sponsor/4/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/4/avatar.svg"></a>
218
- <a href="https://opencollective.com/rubocop/sponsor/5/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/5/avatar.svg"></a>
219
- <a href="https://opencollective.com/rubocop/sponsor/6/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/6/avatar.svg"></a>
220
- <a href="https://opencollective.com/rubocop/sponsor/7/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/7/avatar.svg"></a>
221
- <a href="https://opencollective.com/rubocop/sponsor/8/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/8/avatar.svg"></a>
222
- <a href="https://opencollective.com/rubocop/sponsor/9/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/9/avatar.svg"></a>
223
- <a href="https://opencollective.com/rubocop/sponsor/10/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/10/avatar.svg"></a>
224
- <a href="https://opencollective.com/rubocop/sponsor/11/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/11/avatar.svg"></a>
225
- <a href="https://opencollective.com/rubocop/sponsor/12/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/12/avatar.svg"></a>
226
- <a href="https://opencollective.com/rubocop/sponsor/13/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/13/avatar.svg"></a>
227
- <a href="https://opencollective.com/rubocop/sponsor/14/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/14/avatar.svg"></a>
228
- <a href="https://opencollective.com/rubocop/sponsor/15/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/15/avatar.svg"></a>
229
- <a href="https://opencollective.com/rubocop/sponsor/16/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/16/avatar.svg"></a>
230
- <a href="https://opencollective.com/rubocop/sponsor/17/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/17/avatar.svg"></a>
231
- <a href="https://opencollective.com/rubocop/sponsor/18/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/18/avatar.svg"></a>
232
- <a href="https://opencollective.com/rubocop/sponsor/19/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/19/avatar.svg"></a>
233
- <a href="https://opencollective.com/rubocop/sponsor/20/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/20/avatar.svg"></a>
234
- <a href="https://opencollective.com/rubocop/sponsor/21/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/21/avatar.svg"></a>
235
- <a href="https://opencollective.com/rubocop/sponsor/22/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/22/avatar.svg"></a>
236
- <a href="https://opencollective.com/rubocop/sponsor/23/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/23/avatar.svg"></a>
237
- <a href="https://opencollective.com/rubocop/sponsor/24/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/24/avatar.svg"></a>
238
- <a href="https://opencollective.com/rubocop/sponsor/25/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/25/avatar.svg"></a>
239
- <a href="https://opencollective.com/rubocop/sponsor/26/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/26/avatar.svg"></a>
240
- <a href="https://opencollective.com/rubocop/sponsor/27/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/27/avatar.svg"></a>
241
- <a href="https://opencollective.com/rubocop/sponsor/28/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/28/avatar.svg"></a>
242
- <a href="https://opencollective.com/rubocop/sponsor/29/website" target="_blank"><img src="https://opencollective.com/rubocop/sponsor/29/avatar.svg"></a>
213
+ <a href="https://opencollective.com/rubocop/organization/0/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/0/avatar.svg"></a>
214
+ <a href="https://opencollective.com/rubocop/organization/1/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/1/avatar.svg"></a>
215
+ <a href="https://opencollective.com/rubocop/organization/2/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/2/avatar.svg"></a>
216
+ <a href="https://opencollective.com/rubocop/organization/3/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/3/avatar.svg"></a>
217
+ <a href="https://opencollective.com/rubocop/organization/4/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/4/avatar.svg"></a>
218
+ <a href="https://opencollective.com/rubocop/organization/5/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/5/avatar.svg"></a>
219
+ <a href="https://opencollective.com/rubocop/organization/6/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/6/avatar.svg"></a>
220
+ <a href="https://opencollective.com/rubocop/organization/7/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/7/avatar.svg"></a>
221
+ <a href="https://opencollective.com/rubocop/organization/8/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/8/avatar.svg"></a>
222
+ <a href="https://opencollective.com/rubocop/organization/9/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/9/avatar.svg"></a>
223
+ <a href="https://opencollective.com/rubocop/organization/10/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/10/avatar.svg"></a>
224
+ <a href="https://opencollective.com/rubocop/organization/11/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/11/avatar.svg"></a>
225
+ <a href="https://opencollective.com/rubocop/organization/12/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/12/avatar.svg"></a>
226
+ <a href="https://opencollective.com/rubocop/organization/13/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/13/avatar.svg"></a>
227
+ <a href="https://opencollective.com/rubocop/organization/14/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/14/avatar.svg"></a>
228
+ <a href="https://opencollective.com/rubocop/organization/15/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/15/avatar.svg"></a>
229
+ <a href="https://opencollective.com/rubocop/organization/16/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/16/avatar.svg"></a>
230
+ <a href="https://opencollective.com/rubocop/organization/17/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/17/avatar.svg"></a>
231
+ <a href="https://opencollective.com/rubocop/organization/18/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/18/avatar.svg"></a>
232
+ <a href="https://opencollective.com/rubocop/organization/19/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/19/avatar.svg"></a>
233
+ <a href="https://opencollective.com/rubocop/organization/20/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/20/avatar.svg"></a>
234
+ <a href="https://opencollective.com/rubocop/organization/21/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/21/avatar.svg"></a>
235
+ <a href="https://opencollective.com/rubocop/organization/22/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/22/avatar.svg"></a>
236
+ <a href="https://opencollective.com/rubocop/organization/23/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/23/avatar.svg"></a>
237
+ <a href="https://opencollective.com/rubocop/organization/24/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/24/avatar.svg"></a>
238
+ <a href="https://opencollective.com/rubocop/organization/25/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/25/avatar.svg"></a>
239
+ <a href="https://opencollective.com/rubocop/organization/26/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/26/avatar.svg"></a>
240
+ <a href="https://opencollective.com/rubocop/organization/27/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/27/avatar.svg"></a>
241
+ <a href="https://opencollective.com/rubocop/organization/28/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/28/avatar.svg"></a>
242
+ <a href="https://opencollective.com/rubocop/organization/29/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/29/avatar.svg"></a>
243
243
 
244
244
  ## Changelog
245
245
 
data/config/default.yml CHANGED
@@ -82,6 +82,8 @@ AllCops:
82
82
  StyleGuideBaseURL: https://rubystyle.guide
83
83
  # Documentation URLs will be constructed using the base URL.
84
84
  DocumentationBaseURL: https://docs.rubocop.org/rubocop
85
+ # Documentation URLs will end with this extension.
86
+ DocumentationExtension: .html
85
87
  # Extra details are not displayed in offense messages by default. Change
86
88
  # behavior by overriding ExtraDetails, or by giving the
87
89
  # `-E/--extra-details` option.
@@ -166,6 +168,11 @@ AllCops:
166
168
  rubocop-rspec_rails: [rspec-rails]
167
169
  # Enable/Disable checking the methods extended by Active Support.
168
170
  ActiveSupportExtensionsEnabled: false
171
+ # Future version of Ruby will freeze string literals by default.
172
+ # This allows to opt in early, for example when enabled through RUBYOPT.
173
+ # For now this will behave as if set to false but in future ruby versions
174
+ # (likely 4.0) it will be true by default.
175
+ StringLiteralsFrozenByDefault: ~
169
176
 
170
177
  #################### Bundler ###############################
171
178
 
@@ -2536,8 +2543,7 @@ Lint/UselessAssignment:
2536
2543
  Enabled: true
2537
2544
  AutoCorrect: contextual
2538
2545
  VersionAdded: '0.11'
2539
- VersionChanged: '1.61'
2540
- SafeAutoCorrect: false
2546
+ VersionChanged: '1.66'
2541
2547
 
2542
2548
  Lint/UselessElseWithoutRescue:
2543
2549
  Description: 'Checks for useless `else` in `begin..end` without `rescue`.'
@@ -2553,6 +2559,11 @@ Lint/UselessMethodDefinition:
2553
2559
  VersionChanged: '1.61'
2554
2560
  Safe: false
2555
2561
 
2562
+ Lint/UselessNumericOperation:
2563
+ Description: 'Checks for useless numeric operations.'
2564
+ Enabled: pending
2565
+ VersionAdded: '1.66'
2566
+
2556
2567
  Lint/UselessRescue:
2557
2568
  Description: 'Checks for useless `rescue`s.'
2558
2569
  Enabled: pending
@@ -5051,6 +5062,11 @@ Style/RedundantInterpolation:
5051
5062
  VersionAdded: '0.76'
5052
5063
  VersionChanged: '1.30'
5053
5064
 
5065
+ Style/RedundantInterpolationUnfreeze:
5066
+ Description: 'Checks for redundant unfreezing of interpolated strings.'
5067
+ Enabled: pending
5068
+ VersionAdded: '1.66'
5069
+
5054
5070
  Style/RedundantLineContinuation:
5055
5071
  Description: 'Check for redundant line continuation.'
5056
5072
  Enabled: pending
data/exe/rubocop CHANGED
@@ -11,13 +11,14 @@ exit exit_status if server_cli.exit?
11
11
  if RuboCop::Server.running?
12
12
  exit_status = RuboCop::Server::ClientCommand::Exec.new.run
13
13
  else
14
- require 'benchmark'
15
14
  require 'rubocop'
16
15
 
17
16
  cli = RuboCop::CLI.new
18
17
 
19
- time = Benchmark.realtime { exit_status = cli.run }
18
+ time_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
19
+ exit_status = cli.run
20
+ elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - time_start
20
21
 
21
- puts "Finished in #{time} seconds" if cli.options[:debug] || cli.options[:display_time]
22
+ puts "Finished in #{elapsed_time} seconds" if cli.options[:debug] || cli.options[:display_time]
22
23
  end
23
24
  exit exit_status
@@ -4,7 +4,7 @@ module RuboCop
4
4
  # This class parses the special `rubocop:disable` comments in a source
5
5
  # and provides a way to check if each cop is enabled at arbitrary line.
6
6
  class CommentConfig
7
- extend Forwardable
7
+ extend SimpleForwardable
8
8
 
9
9
  CONFIG_DISABLED_LINE_RANGE_MIN = -Float::INFINITY
10
10
 
@@ -12,7 +12,7 @@ module RuboCop
12
12
  class Config
13
13
  include PathUtil
14
14
  include FileFinder
15
- extend Forwardable
15
+ extend SimpleForwardable
16
16
 
17
17
  CopConfig = Struct.new(:name, :metadata)
18
18
 
@@ -171,6 +171,10 @@ module RuboCop
171
171
  for_all_cops['ActiveSupportExtensionsEnabled']
172
172
  end
173
173
 
174
+ def string_literals_frozen_by_default?
175
+ for_all_cops['StringLiteralsFrozenByDefault']
176
+ end
177
+
174
178
  def file_to_include?(file)
175
179
  relative_file_path = path_relative_to_config(file)
176
180
 
@@ -67,8 +67,8 @@ module RuboCop
67
67
  def load_yaml_configuration(absolute_path)
68
68
  file_contents = read_file(absolute_path)
69
69
  yaml_code = Dir.chdir(File.dirname(absolute_path)) { ERB.new(file_contents).result }
70
- check_duplication(yaml_code, absolute_path)
71
- hash = yaml_safe_load(yaml_code, absolute_path) || {}
70
+ yaml_tree = check_duplication(yaml_code, absolute_path)
71
+ hash = yaml_tree_to_hash(yaml_tree) || {}
72
72
 
73
73
  puts "configuration from #{absolute_path}" if debug?
74
74
 
@@ -235,8 +235,8 @@ module RuboCop
235
235
  raise ConfigNotFoundError, "Configuration file not found: #{absolute_path}"
236
236
  end
237
237
 
238
- def yaml_safe_load(yaml_code, filename)
239
- yaml_safe_load!(yaml_code, filename)
238
+ def yaml_tree_to_hash(yaml_tree)
239
+ yaml_tree_to_hash!(yaml_tree)
240
240
  rescue ::StandardError
241
241
  if defined?(::SafeYAML)
242
242
  raise 'SafeYAML is unmaintained, no longer needed and should be removed'
@@ -245,10 +245,16 @@ module RuboCop
245
245
  raise
246
246
  end
247
247
 
248
- def yaml_safe_load!(yaml_code, filename)
249
- YAML.safe_load(
250
- yaml_code, permitted_classes: [Regexp, Symbol], aliases: true, filename: filename
251
- )
248
+ def yaml_tree_to_hash!(yaml_tree)
249
+ return nil unless yaml_tree
250
+
251
+ # Optimization: Because we checked for duplicate keys, we already have the
252
+ # yaml tree and don't need to parse it again.
253
+ # Also see https://github.com/ruby/psych/blob/v5.1.2/lib/psych.rb#L322-L336
254
+ class_loader = YAML::ClassLoader::Restricted.new(%w[Regexp Symbol], [])
255
+ scanner = YAML::ScalarScanner.new(class_loader)
256
+ visitor = YAML::Visitors::ToRuby.new(scanner, class_loader)
257
+ visitor.accept(yaml_tree)
252
258
  end
253
259
  end
254
260
 
@@ -239,8 +239,7 @@ module RuboCop
239
239
  end
240
240
 
241
241
  def remote_file?(uri)
242
- regex = URI::DEFAULT_PARSER.make_regexp(%w[http https])
243
- /\A#{regex}\z/.match?(uri)
242
+ uri.start_with?('http://', 'https://')
244
243
  end
245
244
 
246
245
  def handle_disabled_by_default(config, new_default_configuration)
@@ -4,7 +4,7 @@ module RuboCop
4
4
  # Handles validation of configuration, for example cop names, parameter
5
5
  # names, and Ruby versions.
6
6
  class ConfigValidator
7
- extend Forwardable
7
+ extend SimpleForwardable
8
8
 
9
9
  # @api private
10
10
  COMMON_PARAMS = %w[Exclude Include Severity inherit_mode AutoCorrect StyleGuide Details].freeze
@@ -273,6 +273,10 @@ module RuboCop
273
273
  @config.active_support_extensions_enabled?
274
274
  end
275
275
 
276
+ def string_literals_frozen_by_default?
277
+ @config.string_literals_frozen_by_default?
278
+ end
279
+
276
280
  def relevant_file?(file)
277
281
  return false unless target_satisfies_all_gem_version_requirements?
278
282
  return true unless @config.clusivity_config_for_badge?(self.class.badge)
@@ -51,6 +51,8 @@ module RuboCop
51
51
  def semicolon(node)
52
52
  @semicolon ||= {}.compare_by_identity
53
53
  @semicolon[node] ||= processed_source.sorted_tokens.select(&:semicolon?).find do |token|
54
+ next if token.pos.end_pos <= node.source_range.begin_pos
55
+
54
56
  same_line?(token, node.body) && trailing_class_definition?(token, node.body)
55
57
  end
56
58
  end
@@ -16,8 +16,9 @@ module RuboCop
16
16
  base = department_to_basename(cop_class.department)
17
17
  fragment = cop_class.cop_name.downcase.gsub(/[^a-z]/, '')
18
18
  base_url = base_url_for(cop_class, config)
19
+ extension = extension_for(cop_class, config)
19
20
 
20
- "#{base_url}/#{base}.html##{fragment}" if base_url
21
+ "#{base_url}/#{base}#{extension}##{fragment}" if base_url
21
22
  end
22
23
 
23
24
  # @api private
@@ -31,11 +32,27 @@ module RuboCop
31
32
  default_base_url if builtin?(cop_class)
32
33
  end
33
34
 
35
+ # @api private
36
+ def extension_for(cop_class, config)
37
+ if config
38
+ department_name = cop_class.department
39
+ extension = config.for_department(department_name)['DocumentationExtension']
40
+ return extension if extension
41
+ end
42
+
43
+ default_extension
44
+ end
45
+
34
46
  # @api private
35
47
  def default_base_url
36
48
  'https://docs.rubocop.org/rubocop'
37
49
  end
38
50
 
51
+ # @api private
52
+ def default_extension
53
+ '.html'
54
+ end
55
+
39
56
  # @api private
40
57
  def builtin?(cop_class)
41
58
  # any custom method will do
@@ -38,7 +38,8 @@ module RuboCop
38
38
  CORRECTION_EXPECTATION_METHODS = %i[expect_correction expect_no_corrections].freeze
39
39
 
40
40
  def on_send(node)
41
- return unless (next_sibling = node.right_sibling) && next_sibling.send_type?
41
+ return unless (next_sibling = node.right_sibling)
42
+ return unless next_sibling.respond_to?(:send_type?) && next_sibling.send_type?
42
43
 
43
44
  method_name = next_sibling.method_name
44
45
  return unless CORRECTION_EXPECTATION_METHODS.include?(method_name)
@@ -45,7 +45,7 @@ module RuboCop
45
45
  PATTERN
46
46
 
47
47
  def on_send(node)
48
- return if node.arguments.none?
48
+ return unless node.arguments.count == 2
49
49
  return unless valid_method_name?(node)
50
50
 
51
51
  actual_name = node.first_argument.value.to_s
@@ -5,12 +5,22 @@ module RuboCop
5
5
  module InternalAffairs
6
6
  # Looks for references to a cop configuration key that isn't defined in config/default.yml.
7
7
  class UndefinedConfig < Base
8
+ # `FileFinder` is a private API not intended to be used by cops,
9
+ # but it's fine for `InternalAffairs`.
10
+ extend FileFinder
11
+
8
12
  ALLOWED_CONFIGURATIONS = %w[
9
13
  Safe SafeAutoCorrect AutoCorrect Severity StyleGuide Details Reference Include Exclude
10
14
  ].freeze
11
15
  RESTRICT_ON_SEND = %i[[] fetch].freeze
12
16
  MSG = '`%<name>s` is not defined in the configuration for `%<cop>s` ' \
13
17
  'in `config/default.yml`.'
18
+ CONFIG_PATH = find_file_upwards('config/default.yml', Dir.pwd)
19
+ CONFIG = if CONFIG_PATH
20
+ ConfigLoader.load_yaml_configuration(CONFIG_PATH)
21
+ else
22
+ {}
23
+ end
14
24
 
15
25
  # @!method cop_class_def(node)
16
26
  def_node_search :cop_class_def, <<~PATTERN
@@ -31,7 +41,7 @@ module RuboCop
31
41
  cop_class = cop_class_def(processed_source.ast).first
32
42
  return unless (@cop_class_name = extract_cop_name(cop_class))
33
43
 
34
- @config_for_cop = RuboCop::ConfigLoader.default_configuration.for_cop(@cop_class_name)
44
+ @config_for_cop = CONFIG[@cop_class_name] || {}
35
45
  end
36
46
 
37
47
  def on_send(node)
@@ -16,7 +16,7 @@ module RuboCop
16
16
  # start of the line where the expression started.
17
17
  #
18
18
  # `either` (which is the default) : the `end` is allowed to be in either
19
- # location. The autofixer will default to `start_of_line`.
19
+ # location. The autocorrect will default to `start_of_line`.
20
20
  #
21
21
  # @example EnforcedStyleAlignWith: either (default)
22
22
  # # bad
@@ -92,16 +92,6 @@ module RuboCop
92
92
 
93
93
  private
94
94
 
95
- def start_for_block_node(block_node)
96
- # Which node should we align the 'end' with?
97
- result = block_end_align_target(block_node)
98
-
99
- # In offense message, we want to show the assignment LHS rather than
100
- # the entire assignment
101
- result, = *result while result.op_asgn_type? || result.masgn_type?
102
- result
103
- end
104
-
105
95
  def block_end_align_target(node)
106
96
  lineage = [node, *node.ancestors]
107
97
 
@@ -153,7 +143,11 @@ module RuboCop
153
143
  end
154
144
 
155
145
  def autocorrect(corrector, node)
156
- ancestor_node = start_for_block_node(node)
146
+ ancestor_node = if style == :start_of_block
147
+ start_for_block_node(node)
148
+ else
149
+ start_for_line_node(node)
150
+ end
157
151
  start_col = compute_start_col(ancestor_node, node)
158
152
  loc_end = node.loc.end
159
153
  delta = start_col - loc_end.column
@@ -175,6 +169,30 @@ module RuboCop
175
169
  )
176
170
  end
177
171
 
172
+ def start_for_block_node(block_node)
173
+ # Which node should we align the 'end' with?
174
+ start_node = block_end_align_target(block_node)
175
+
176
+ find_lhs_node(start_node)
177
+ end
178
+
179
+ def start_for_line_node(block_node)
180
+ start_node = start_for_block_node(block_node)
181
+
182
+ start_node = start_node.each_ancestor.to_a.reverse.find do |node|
183
+ same_line?(start_node, node)
184
+ end || start_node
185
+
186
+ find_lhs_node(start_node)
187
+ end
188
+
189
+ # In offense message, we want to show the assignment LHS rather than
190
+ # the entire assignment.
191
+ def find_lhs_node(node)
192
+ node, = *node while node.op_asgn_type? || node.masgn_type?
193
+ node
194
+ end
195
+
178
196
  def compute_do_source_line_column(node, end_loc)
179
197
  do_loc = node.loc.begin # Actually it's either do or {.
180
198
 
@@ -149,7 +149,8 @@ module RuboCop
149
149
  newline_pos = source_buffer.source.index("\n", end_pos)
150
150
 
151
151
  # Handle the case when multiple one-liners are on the same line.
152
- newline_pos = end_pos + 1 if newline_pos > node.source_range.begin_pos
152
+ begin_pos = node.source_range.begin_pos
153
+ newline_pos = begin_pos - 1 if newline_pos > begin_pos
153
154
 
154
155
  if count > maximum_empty_lines
155
156
  autocorrect_remove_lines(corrector, newline_pos, count)
@@ -83,7 +83,7 @@ module RuboCop
83
83
 
84
84
  locations.each do |loc|
85
85
  line = loc.line
86
- next if line == line_of_def_or_kwbegin || last_rescue_and_end_on_same_line(body)
86
+ next if line == line_of_def_or_kwbegin || last_body_and_end_on_same_line?(body)
87
87
 
88
88
  keyword = loc.source
89
89
  # below the keyword
@@ -93,8 +93,13 @@ module RuboCop
93
93
  end
94
94
  end
95
95
 
96
- def last_rescue_and_end_on_same_line(body)
97
- body.rescue_type? && body.resbody_branches.last.loc.line == body.parent.loc.end.line
96
+ def last_body_and_end_on_same_line?(body)
97
+ end_keyword_line = body.parent.loc.end.line
98
+ return body.loc.last_line == end_keyword_line unless body.rescue_type?
99
+
100
+ last_body_line = body.else? ? body.loc.else.line : body.resbody_branches.last.loc.line
101
+
102
+ last_body_line == end_keyword_line
98
103
  end
99
104
 
100
105
  def message(location, keyword)