rubocop 1.65.1 → 1.66.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) 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 +8 -4
  6. data/lib/rubocop/config.rb +20 -4
  7. data/lib/rubocop/config_loader_resolver.rb +1 -2
  8. data/lib/rubocop/config_validator.rb +9 -5
  9. data/lib/rubocop/cop/base.rb +4 -0
  10. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
  11. data/lib/rubocop/cop/documentation.rb +18 -1
  12. data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
  13. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +11 -1
  14. data/lib/rubocop/cop/layout/block_alignment.rb +30 -12
  15. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
  16. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +8 -3
  17. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +0 -3
  18. data/lib/rubocop/cop/layout/line_length.rb +14 -14
  19. data/lib/rubocop/cop/lint/empty_conditional_body.rb +27 -6
  20. data/lib/rubocop/cop/lint/float_comparison.rb +1 -3
  21. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +4 -2
  22. data/lib/rubocop/cop/lint/useless_assignment.rb +18 -11
  23. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +77 -0
  24. data/lib/rubocop/cop/lint/void.rb +30 -8
  25. data/lib/rubocop/cop/metrics/block_length.rb +6 -5
  26. data/lib/rubocop/cop/metrics/class_length.rb +6 -5
  27. data/lib/rubocop/cop/metrics/method_length.rb +6 -5
  28. data/lib/rubocop/cop/metrics/module_length.rb +6 -5
  29. data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
  30. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +19 -9
  31. data/lib/rubocop/cop/mixin/line_length_help.rb +7 -2
  32. data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
  33. data/lib/rubocop/cop/naming/accessor_method_name.rb +5 -0
  34. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  35. data/lib/rubocop/cop/style/alias.rb +1 -1
  36. data/lib/rubocop/cop/style/arguments_forwarding.rb +8 -3
  37. data/lib/rubocop/cop/style/empty_else.rb +5 -5
  38. data/lib/rubocop/cop/style/empty_heredoc.rb +1 -14
  39. data/lib/rubocop/cop/style/empty_literal.rb +32 -23
  40. data/lib/rubocop/cop/style/format_string_token.rb +2 -2
  41. data/lib/rubocop/cop/style/guard_clause.rb +2 -0
  42. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  43. data/lib/rubocop/cop/style/if_with_semicolon.rb +38 -6
  44. data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
  45. data/lib/rubocop/cop/style/magic_comment_format.rb +8 -3
  46. data/lib/rubocop/cop/style/map_into_array.rb +11 -2
  47. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -2
  48. data/lib/rubocop/cop/style/multiple_comparison.rb +3 -11
  49. data/lib/rubocop/cop/style/numeric_predicate.rb +2 -2
  50. data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
  51. data/lib/rubocop/cop/style/parallel_assignment.rb +5 -4
  52. data/lib/rubocop/cop/style/quoted_symbols.rb +0 -2
  53. data/lib/rubocop/cop/style/redundant_condition.rb +3 -2
  54. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +46 -0
  55. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -1
  56. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  57. data/lib/rubocop/cop/team.rb +6 -2
  58. data/lib/rubocop/formatter/junit_formatter.rb +70 -23
  59. data/lib/rubocop/lockfile.rb +6 -4
  60. data/lib/rubocop/remote_config.rb +5 -1
  61. data/lib/rubocop/result_cache.rb +2 -8
  62. data/lib/rubocop/rspec/shared_contexts.rb +2 -2
  63. data/lib/rubocop/server/cache.rb +1 -1
  64. data/lib/rubocop/target_ruby.rb +7 -3
  65. data/lib/rubocop/version.rb +1 -1
  66. data/lib/rubocop.rb +2 -1
  67. 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: 694e2b2b4a391c38f0afd3667beaf252adcf2fe68374a544cf14748cfc97dd80
4
+ data.tar.gz: ad3c46e7dbeaf3c94d16c7427458d2079e28ef58d08463af37ae2a1f6561b345
5
5
  SHA512:
6
- metadata.gz: 07e4e645df882074e88da46ca8a69d7b1d12ec0d83bf4dfaaef6d799dcdb49c584b904d9f186e59278e663bbebe3db8e3950a6d4219fa73487978261c72fded6
7
- data.tar.gz: 2d8d8ad60a022ee9df6cb9d164486044787a3a41da8bee073cabb528299d9f62968b8f90fc18a1cba0dbb581968912a478ddda85c1f02c336eb92dbd83092b14
6
+ metadata.gz: 8df7fd7e62c55adac6725b1d60e071c0021eed0434a84c40b86b9a32b27b3a5e9cd3debe9d3edd21fec732c0065553a7a8299f7810ffffde2d010f5231b657e5
7
+ data.tar.gz: 24192e071f881b02ac9c766b3d0847e8fa77d9e4ff5942c9a2cc72dd0f4d77412c13337a1b76bcd7e250e5a7b737ddf613764c0dccbb49b09fdc0f27b6a8c732
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,8 +4,6 @@ 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
8
-
9
7
  CONFIG_DISABLED_LINE_RANGE_MIN = -Float::INFINITY
10
8
 
11
9
  # This class provides an API compatible with RuboCop::DirectiveComment
@@ -29,13 +27,19 @@ module RuboCop
29
27
 
30
28
  attr_reader :processed_source
31
29
 
32
- def_delegators :@processed_source, :config, :registry
33
-
34
30
  def initialize(processed_source)
35
31
  @processed_source = processed_source
36
32
  @no_directives = !processed_source.raw_source.include?('rubocop')
37
33
  end
38
34
 
35
+ def config
36
+ @processed_source.config
37
+ end
38
+
39
+ def registry
40
+ @processed_source.registry
41
+ end
42
+
39
43
  def cop_enabled_at_line?(cop, line_number)
40
44
  cop = cop.cop_name if cop.respond_to?(:cop_name)
41
45
  disabled_line_ranges = cop_disabled_line_ranges[cop]
@@ -12,7 +12,6 @@ module RuboCop
12
12
  class Config
13
13
  include PathUtil
14
14
  include FileFinder
15
- extend Forwardable
16
15
 
17
16
  CopConfig = Struct.new(:name, :metadata)
18
17
 
@@ -60,9 +59,22 @@ module RuboCop
60
59
  self
61
60
  end
62
61
 
63
- def_delegators :@hash, :[], :[]=, :delete, :dig, :each, :key?, :keys, :each_key,
64
- :fetch, :map, :merge, :replace, :to_h, :to_hash, :transform_values
65
- def_delegators :@validator, :validate, :target_ruby_version
62
+ %i[[] []= delete dig each key? keys each_key fetch map merge replace to_h to_hash
63
+ transform_values].each do |method|
64
+ class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
65
+ def #{method}(...) # def key?(...)
66
+ @hash.#{method}(...) # @hash.key?(...)
67
+ end # end
68
+ RUBY
69
+ end
70
+
71
+ def validate(...)
72
+ @validator.validate(...)
73
+ end
74
+
75
+ def target_ruby_version
76
+ @validator.target_ruby_version
77
+ end
66
78
 
67
79
  def to_s
68
80
  @to_s ||= @hash.to_s
@@ -171,6 +183,10 @@ module RuboCop
171
183
  for_all_cops['ActiveSupportExtensionsEnabled']
172
184
  end
173
185
 
186
+ def string_literals_frozen_by_default?
187
+ for_all_cops['StringLiteralsFrozenByDefault']
188
+ end
189
+
174
190
  def file_to_include?(file)
175
191
  relative_file_path = path_relative_to_config(file)
176
192
 
@@ -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)
@@ -3,9 +3,7 @@
3
3
  module RuboCop
4
4
  # Handles validation of configuration, for example cop names, parameter
5
5
  # names, and Ruby versions.
6
- class ConfigValidator
7
- extend Forwardable
8
-
6
+ class ConfigValidator # rubocop:disable Metrics/ClassLength
9
7
  # @api private
10
8
  COMMON_PARAMS = %w[Exclude Include Severity inherit_mode AutoCorrect StyleGuide Details].freeze
11
9
  # @api private
@@ -21,14 +19,20 @@ module RuboCop
21
19
  CONFIG_CHECK_AUTOCORRECTS = %w[always contextual disabled].freeze
22
20
  private_constant :CONFIG_CHECK_KEYS, :CONFIG_CHECK_DEPARTMENTS
23
21
 
24
- def_delegators :@config, :smart_loaded_path, :for_all_cops
25
-
26
22
  def initialize(config)
27
23
  @config = config
28
24
  @config_obsoletion = ConfigObsoletion.new(config)
29
25
  @target_ruby = TargetRuby.new(config)
30
26
  end
31
27
 
28
+ def smart_loaded_path
29
+ @config.smart_loaded_path
30
+ end
31
+
32
+ def for_all_cops
33
+ @config.for_all_cops
34
+ end
35
+
32
36
  def validate
33
37
  check_cop_config_value(@config)
34
38
  reject_conflicting_safe_settings
@@ -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)
@@ -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)