rubocop 1.25.1 → 1.27.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +29 -6
  4. data/lib/rubocop/cli.rb +1 -1
  5. data/lib/rubocop/config_obsoletion/extracted_cop.rb +3 -1
  6. data/lib/rubocop/cop/autocorrect_logic.rb +4 -0
  7. data/lib/rubocop/cop/badge.rb +7 -1
  8. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -5
  9. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +1 -5
  10. data/lib/rubocop/cop/gemspec/require_mfa.rb +4 -3
  11. data/lib/rubocop/cop/generator.rb +2 -7
  12. data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +46 -0
  13. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  14. data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
  15. data/lib/rubocop/cop/layout/indentation_width.rb +1 -2
  16. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +7 -8
  17. data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -4
  18. data/lib/rubocop/cop/lint/ambiguous_operator.rb +6 -6
  19. data/lib/rubocop/cop/lint/empty_conditional_body.rb +3 -1
  20. data/lib/rubocop/cop/lint/empty_in_pattern.rb +3 -1
  21. data/lib/rubocop/cop/lint/empty_when.rb +3 -1
  22. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +11 -4
  23. data/lib/rubocop/cop/lint/inherit_exception.rb +19 -28
  24. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +8 -1
  25. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -2
  26. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +5 -0
  27. data/lib/rubocop/cop/lint/refinement_import_methods.rb +51 -0
  28. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +10 -0
  29. data/lib/rubocop/cop/lint/symbol_conversion.rb +3 -2
  30. data/lib/rubocop/cop/lint/syntax.rb +1 -2
  31. data/lib/rubocop/cop/lint/unused_method_argument.rb +1 -1
  32. data/lib/rubocop/cop/lint/useless_times.rb +13 -9
  33. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
  34. data/lib/rubocop/cop/mixin/comments_help.rb +22 -2
  35. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +2 -3
  36. data/lib/rubocop/cop/mixin/line_length_help.rb +17 -6
  37. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -3
  38. data/lib/rubocop/cop/mixin/surrounding_space.rb +4 -2
  39. data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
  40. data/lib/rubocop/cop/security/yaml_load.rb +9 -3
  41. data/lib/rubocop/cop/style/def_with_parentheses.rb +16 -11
  42. data/lib/rubocop/cop/style/double_negation.rb +32 -1
  43. data/lib/rubocop/cop/style/empty_case_condition.rb +1 -2
  44. data/lib/rubocop/cop/style/file_write.rb +12 -0
  45. data/lib/rubocop/cop/style/for.rb +4 -0
  46. data/lib/rubocop/cop/style/lambda_call.rb +12 -20
  47. data/lib/rubocop/cop/style/nested_file_dirname.rb +66 -0
  48. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +3 -2
  49. data/lib/rubocop/cop/style/raise_args.rb +5 -2
  50. data/lib/rubocop/cop/style/redundant_capital_w.rb +1 -2
  51. data/lib/rubocop/cop/style/redundant_initialize.rb +119 -0
  52. data/lib/rubocop/cop/style/safe_navigation.rb +12 -7
  53. data/lib/rubocop/cop/style/select_by_regexp.rb +6 -1
  54. data/lib/rubocop/cop/style/sole_nested_conditional.rb +50 -12
  55. data/lib/rubocop/cop/style/string_concatenation.rb +7 -1
  56. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -2
  57. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +1 -1
  58. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +1 -1
  59. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -4
  60. data/lib/rubocop/cop/style/unless_else.rb +4 -0
  61. data/lib/rubocop/cop/variable_force.rb +1 -5
  62. data/lib/rubocop/cops_documentation_generator.rb +2 -2
  63. data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -2
  64. data/lib/rubocop/formatter/offense_count_formatter.rb +6 -2
  65. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -2
  66. data/lib/rubocop/options.rb +8 -2
  67. data/lib/rubocop/result_cache.rb +9 -1
  68. data/lib/rubocop/rspec/shared_contexts.rb +4 -0
  69. data/lib/rubocop/runner.rb +1 -1
  70. data/lib/rubocop/target_ruby.rb +1 -1
  71. data/lib/rubocop/version.rb +1 -1
  72. data/lib/rubocop.rb +3 -0
  73. metadata +9 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54b88752efa8bb84dc034391460b9071f31179dcb279550a209d31829e7b8c93
4
- data.tar.gz: 31115cff5fdbf562dee62cf7e07033205d150b61ac5fd11476708f21e67000cf
3
+ metadata.gz: d48fd91bc57ba3589a331c3c0141d3e168c7631e5db47238a88cecbd10b12292
4
+ data.tar.gz: 9393d3cab7e09e86a9276ca4614f8f2c4fc2895f2070bd3364096569c2cd5828
5
5
  SHA512:
6
- metadata.gz: acdaf069659a775853b20e05734e85cd65c0c8734b09e568d4360dc9a7440a49ec8e47928b0da78866e1326a588638d18f2564e6e94023bb17b2f39493555027
7
- data.tar.gz: 2765d9c9c10966c485be6cd70190b69a25aa99800c8d483bd67c1fdfe3dc5d13bb97cb1ca7f9f663776869acda5a426bc797f3b40adda17e0241ff8b62a374f1
6
+ metadata.gz: 13d85485214ca48904b07a6da11f89d2e2ef33fceab05912fb4c4f4c1e025da4be79139845d13724a749f97eb837b943eef5515639a5116299b6a164d7517944
7
+ data.tar.gz: 668abbcaedb1f06c43a2e5f61774909d684767659979bc3787c0827ca22adf42be0edf1d30544909a74fc6aac18bcd3758c7c5f77352cb97b51fd96acd24ab18
data/README.md CHANGED
@@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
53
53
  in your `Gemfile`:
54
54
 
55
55
  ```rb
56
- gem 'rubocop', '~> 1.25', require: false
56
+ gem 'rubocop', '~> 1.27', require: false
57
57
  ```
58
58
 
59
59
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
data/config/default.yml CHANGED
@@ -262,7 +262,7 @@ Gemspec/OrderedDependencies:
262
262
  - '**/*.gemspec'
263
263
 
264
264
  Gemspec/RequireMFA:
265
- Description: 'Checks that the gemspec has metadata to require MFA from RubyGems.'
265
+ Description: 'Checks that the gemspec has metadata to require Multi-Factor Authentication from RubyGems.'
266
266
  Enabled: pending
267
267
  VersionAdded: '1.23'
268
268
  Reference:
@@ -1816,12 +1816,14 @@ Lint/IneffectiveAccessModifier:
1816
1816
  Lint/InheritException:
1817
1817
  Description: 'Avoid inheriting from the `Exception` class.'
1818
1818
  Enabled: true
1819
+ SafeAutoCorrect: false
1819
1820
  VersionAdded: '0.41'
1821
+ VersionChanged: '1.26'
1820
1822
  # The default base class in favour of `Exception`.
1821
- EnforcedStyle: runtime_error
1823
+ EnforcedStyle: standard_error
1822
1824
  SupportedStyles:
1823
- - runtime_error
1824
1825
  - standard_error
1826
+ - runtime_error
1825
1827
 
1826
1828
  Lint/InterpolationCheck:
1827
1829
  Description: 'Raise warning for interpolation in single q strs.'
@@ -2011,6 +2013,8 @@ Lint/RedundantDirGlobSort:
2011
2013
  Description: 'Checks for redundant `sort` method to `Dir.glob` and `Dir[]`.'
2012
2014
  Enabled: pending
2013
2015
  VersionAdded: '1.8'
2016
+ VersionChanged: '1.26'
2017
+ SafeAutoCorrect: false
2014
2018
 
2015
2019
  Lint/RedundantRequireStatement:
2016
2020
  Description: 'Checks for unnecessary `require` statement.'
@@ -2054,6 +2058,12 @@ Lint/RedundantWithObject:
2054
2058
  Enabled: true
2055
2059
  VersionAdded: '0.51'
2056
2060
 
2061
+ Lint/RefinementImportMethods:
2062
+ Description: 'Use `Refinement#import_methods` when using `include` or `prepend` in `refine` block.'
2063
+ Enabled: pending
2064
+ SafeAutoCorrect: false
2065
+ VersionAdded: '1.27'
2066
+
2057
2067
  Lint/RegexpAsCondition:
2058
2068
  Description: >-
2059
2069
  Do not use regexp literal as a condition.
@@ -2323,8 +2333,8 @@ Lint/UselessMethodDefinition:
2323
2333
  Description: 'Checks for useless method definitions.'
2324
2334
  Enabled: true
2325
2335
  VersionAdded: '0.90'
2336
+ VersionChanged: '0.91'
2326
2337
  Safe: false
2327
- AllowComments: true
2328
2338
 
2329
2339
  Lint/UselessRuby2Keywords:
2330
2340
  Description: 'Finds unnecessary uses of `ruby2_keywords`.'
@@ -3542,8 +3552,9 @@ Style/For:
3542
3552
  Description: 'Checks use of for or each in multiline loops.'
3543
3553
  StyleGuide: '#no-for-loops'
3544
3554
  Enabled: true
3555
+ SafeAutoCorrect: false
3545
3556
  VersionAdded: '0.13'
3546
- VersionChanged: '0.59'
3557
+ VersionChanged: '1.26'
3547
3558
  EnforcedStyle: each
3548
3559
  SupportedStyles:
3549
3560
  - each
@@ -4122,6 +4133,11 @@ Style/NegatedWhile:
4122
4133
  Enabled: true
4123
4134
  VersionAdded: '0.20'
4124
4135
 
4136
+ Style/NestedFileDirname:
4137
+ Description: 'Checks for nested `File.dirname`.'
4138
+ Enabled: pending
4139
+ VersionAdded: '1.26'
4140
+
4125
4141
  Style/NestedModifier:
4126
4142
  Description: 'Avoid using nested modifiers.'
4127
4143
  StyleGuide: '#no-nested-modifiers'
@@ -4514,6 +4530,11 @@ Style/RedundantFreeze:
4514
4530
  VersionAdded: '0.34'
4515
4531
  VersionChanged: '0.66'
4516
4532
 
4533
+ Style/RedundantInitialize:
4534
+ Description: 'Checks for redundant `initialize` methods.'
4535
+ Enabled: pending
4536
+ VersionAdded: '1.27'
4537
+
4517
4538
  Style/RedundantInterpolation:
4518
4539
  Description: 'Checks for strings that are just an interpolated expression.'
4519
4540
  Enabled: true
@@ -4635,7 +4656,7 @@ Style/SafeNavigation:
4635
4656
  be `nil` or truthy, but never `false`.
4636
4657
  Enabled: true
4637
4658
  VersionAdded: '0.43'
4638
- VersionChanged: '0.77'
4659
+ VersionChanged: '1.27'
4639
4660
  # Safe navigation may cause a statement to start returning `nil` in addition
4640
4661
  # to whatever it used to return.
4641
4662
  ConvertCodeThatCanStartToReturnNil: false
@@ -4646,6 +4667,8 @@ Style/SafeNavigation:
4646
4667
  - try
4647
4668
  - try!
4648
4669
  SafeAutoCorrect: false
4670
+ # Maximum length of method chains for register an offense.
4671
+ MaxChainLength: 2
4649
4672
 
4650
4673
  Style/Sample:
4651
4674
  Description: >-
data/lib/rubocop/cli.rb CHANGED
@@ -14,7 +14,7 @@ module RuboCop
14
14
  ignore_disable_comments lint only only_guide_cops require safe
15
15
  ].freeze
16
16
 
17
- class Finished < RuntimeError; end
17
+ class Finished < StandardError; end
18
18
 
19
19
  attr_reader :options, :config_store
20
20
 
@@ -33,7 +33,9 @@ module RuboCop
33
33
  return old_name unless old_name.end_with?('*')
34
34
 
35
35
  # Handle whole departments (expressed as `Department/*`)
36
- config.keys.grep(Regexp.new("^#{department}"))
36
+ config.keys.select do |key|
37
+ key == department || key.start_with?("#{department}/")
38
+ end
37
39
  end
38
40
 
39
41
  def feature_loaded?
@@ -8,6 +8,10 @@ module RuboCop
8
8
  autocorrect_requested? && correctable? && autocorrect_enabled?
9
9
  end
10
10
 
11
+ def autocorrect_with_disable_uncorrectable?
12
+ autocorrect_requested? && disable_uncorrectable? && autocorrect_enabled?
13
+ end
14
+
11
15
  def autocorrect_requested?
12
16
  @options.fetch(:auto_correct, false)
13
17
  end
@@ -19,7 +19,13 @@ module RuboCop
19
19
  end
20
20
 
21
21
  def self.parse(identifier)
22
- new(identifier.split('/'))
22
+ new(identifier.split('/').map { |i| camel_case(i) })
23
+ end
24
+
25
+ def self.camel_case(name_part)
26
+ return 'RSpec' if name_part == 'rspec'
27
+
28
+ name_part.gsub(/^\w|_\w/) { |match| match[-1, 1].upcase }
23
29
  end
24
30
 
25
31
  def initialize(class_name_parts)
@@ -46,11 +46,7 @@ module RuboCop
46
46
 
47
47
  duplicated_gem_nodes.each do |nodes|
48
48
  nodes[1..-1].each do |node|
49
- register_offense(
50
- node,
51
- node.first_argument.to_a.first,
52
- nodes.first.first_line
53
- )
49
+ register_offense(node, node.first_argument.to_a.first, nodes.first.first_line)
54
50
  end
55
51
  end
56
52
  end
@@ -52,11 +52,7 @@ module RuboCop
52
52
 
53
53
  duplicated_assignment_method_nodes.each do |nodes|
54
54
  nodes[1..-1].each do |node|
55
- register_offense(
56
- node,
57
- node.method_name,
58
- nodes.first.first_line
59
- )
55
+ register_offense(node, node.method_name, nodes.first.first_line)
60
56
  end
61
57
  end
62
58
  end
@@ -5,9 +5,10 @@ module RuboCop
5
5
  module Gemspec
6
6
  # Requires a gemspec to have `rubygems_mfa_required` metadata set.
7
7
  #
8
- # This setting tells RubyGems that MFA is required for accounts to
9
- # be able perform privileged operations, such as (see
10
- # RubyGems' documentation for the full list of privileged operations):
8
+ # This setting tells RubyGems that MFA (Multi-Factor Authentication) is
9
+ # required for accounts to be able perform privileged operations, such as
10
+ # (see RubyGems' documentation for the full list of privileged
11
+ # operations):
11
12
  #
12
13
  # * `gem push`
13
14
  # * `gem yank`
@@ -8,13 +8,7 @@ module RuboCop
8
8
  # and spec file when given a valid qualified cop name.
9
9
  # @api private
10
10
  class Generator
11
- # NOTE: RDoc 5.1.0 or lower has the following issue.
12
- # https://github.com/rubocop/rubocop/issues/7043
13
- #
14
- # The following `String#gsub` can be replaced with
15
- # squiggly heredoc when RuboCop supports Ruby 2.5 or higher
16
- # (RDoc 6.0 or higher).
17
- SOURCE_TEMPLATE = <<-RUBY.gsub(/^ {8}/, '')
11
+ SOURCE_TEMPLATE = <<~RUBY
18
12
  # frozen_string_literal: true
19
13
 
20
14
  module RuboCop
@@ -68,6 +62,7 @@ module RuboCop
68
62
  # For example
69
63
  MSG = 'Use `#good_method` instead of `#bad_method`.'
70
64
 
65
+ # @!method bad_method?(node)
71
66
  def_node_matcher :bad_method?, <<~PATTERN
72
67
  (send nil? :bad_method ...)
73
68
  PATTERN
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # Checks for redundant `:config` parameter in the `context` arguments.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # context 'foo', :config do
12
+ # end
13
+ #
14
+ # # good
15
+ # context 'foo' do
16
+ # end
17
+ #
18
+ class RedundantContextConfigParameter < Base
19
+ include RangeHelp
20
+ extend AutoCorrector
21
+
22
+ MSG = 'Remove the redundant `:config` parameter.'
23
+ RESTRICT_ON_SEND = %i[context].freeze
24
+
25
+ def on_send(node)
26
+ arguments = node.arguments
27
+ config_node = arguments.detect { |argument| argument.source == ':config' }
28
+ return unless config_node
29
+
30
+ add_offense(config_node) do |corrector|
31
+ dup_arguments = arguments.dup
32
+ dup_arguments.delete(config_node)
33
+
34
+ corrector.replace(offense_range(arguments), dup_arguments.map(&:source).join(', '))
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def offense_range(arguments)
41
+ range_between(arguments.first.source_range.begin_pos, arguments.last.source_range.end_pos)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -9,6 +9,7 @@ require_relative 'internal_affairs/node_destructuring'
9
9
  require_relative 'internal_affairs/node_matcher_directive'
10
10
  require_relative 'internal_affairs/node_type_predicate'
11
11
  require_relative 'internal_affairs/offense_location_keyword'
12
+ require_relative 'internal_affairs/redundant_context_config_parameter'
12
13
  require_relative 'internal_affairs/redundant_described_class_as_subject'
13
14
  require_relative 'internal_affairs/redundant_let_rubocop_config_new'
14
15
  require_relative 'internal_affairs/redundant_location_argument'
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cop checks how the `when` and `in`s of a `case` expression
6
+ # This cop checks how the `when` and ``in``s of a `case` expression
7
7
  # are indented in relation to its `case` or `end` keyword.
8
8
  #
9
9
  # It will register a separate offense for each misaligned `when` and `in`.
@@ -185,8 +185,7 @@ module RuboCop
185
185
 
186
186
  def check_members_for_indented_internal_methods_style(members)
187
187
  each_member(members) do |member, previous_modifier|
188
- check_indentation(previous_modifier, member,
189
- indentation_consistency_style)
188
+ check_indentation(previous_modifier, member, indentation_consistency_style)
190
189
  end
191
190
  end
192
191
 
@@ -3,27 +3,26 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cop checks the indentation of the right hand side operand in
7
- # binary operations that span more than one line.
6
+ # This cop checks the indentation of the right hand side operand in binary operations that
7
+ # span more than one line.
8
8
  #
9
- # The `aligned` style checks that operators are aligned if they are part
10
- # of an `if` or `while` condition, a `return` statement, etc. In other
11
- # contexts, the second operand should be indented regardless of enforced
12
- # style.
9
+ # The `aligned` style checks that operators are aligned if they are part of an `if` or `while`
10
+ # condition, an explicit `return` statement, etc. In other contexts, the second operand should
11
+ # be indented regardless of enforced style.
13
12
  #
14
13
  # @example EnforcedStyle: aligned (default)
15
14
  # # bad
16
15
  # if a +
17
16
  # b
18
17
  # something &&
19
- # something_else
18
+ # something_else
20
19
  # end
21
20
  #
22
21
  # # good
23
22
  # if a +
24
23
  # b
25
24
  # something &&
26
- # something_else
25
+ # something_else
27
26
  # end
28
27
  #
29
28
  # @example EnforcedStyle: indented
@@ -105,10 +105,9 @@ module RuboCop
105
105
  end
106
106
 
107
107
  def convertible_block?(node)
108
- return false unless node.parent&.block_type?
109
-
110
- send_node = node.parent&.send_node
111
- send_node.parenthesized? || !send_node.arguments?
108
+ parent = node.parent
109
+ parent&.block_type? && node == parent.send_node &&
110
+ (node.parenthesized? || !node.arguments?)
112
111
  end
113
112
 
114
113
  def comment_within?(node)
@@ -24,11 +24,11 @@ module RuboCop
24
24
  extend AutoCorrector
25
25
 
26
26
  AMBIGUITIES = {
27
- '+' => { actual: 'positive number', possible: 'addition' },
28
- '-' => { actual: 'negative number', possible: 'subtraction' },
29
- '*' => { actual: 'splat', possible: 'multiplication' },
30
- '&' => { actual: 'block', possible: 'binary AND' },
31
- '**' => { actual: 'keyword splat', possible: 'exponent' }
27
+ '+' => { actual: 'positive number', possible: 'an addition' },
28
+ '-' => { actual: 'negative number', possible: 'a subtraction' },
29
+ '*' => { actual: 'splat', possible: 'a multiplication' },
30
+ '&' => { actual: 'block', possible: 'a binary AND' },
31
+ '**' => { actual: 'keyword splat', possible: 'an exponent' }
32
32
  }.each do |key, hash|
33
33
  hash[:operator] = key
34
34
  end
@@ -36,7 +36,7 @@ module RuboCop
36
36
  MSG_FORMAT = 'Ambiguous %<actual>s operator. Parenthesize the method ' \
37
37
  "arguments if it's surely a %<actual>s operator, or add " \
38
38
  'a whitespace to the right of the `%<operator>s` if it ' \
39
- 'should be a %<possible>s.'
39
+ 'should be %<possible>s.'
40
40
 
41
41
  def on_new_investigation
42
42
  processed_source.diagnostics.each do |diagnostic|
@@ -53,11 +53,13 @@ module RuboCop
53
53
  # end
54
54
  #
55
55
  class EmptyConditionalBody < Base
56
+ include CommentsHelp
57
+
56
58
  MSG = 'Avoid `%<keyword>s` branches without a body.'
57
59
 
58
60
  def on_if(node)
59
61
  return if node.body
60
- return if cop_config['AllowComments'] && comment_lines?(node)
62
+ return if cop_config['AllowComments'] && contains_comments?(node)
61
63
 
62
64
  add_offense(node, message: format(MSG, keyword: node.keyword))
63
65
  end
@@ -44,6 +44,7 @@ module RuboCop
44
44
  #
45
45
  class EmptyInPattern < Base
46
46
  extend TargetRubyVersion
47
+ include CommentsHelp
47
48
 
48
49
  MSG = 'Avoid `in` branches without a body.'
49
50
 
@@ -51,7 +52,8 @@ module RuboCop
51
52
 
52
53
  def on_case_match(node)
53
54
  node.in_pattern_branches.each do |branch|
54
- next if branch.body || (cop_config['AllowComments'] && comment_lines?(node))
55
+ next if branch.body
56
+ next if cop_config['AllowComments'] && contains_comments?(branch)
55
57
 
56
58
  add_offense(branch)
57
59
  end
@@ -45,12 +45,14 @@ module RuboCop
45
45
  # end
46
46
  #
47
47
  class EmptyWhen < Base
48
+ include CommentsHelp
49
+
48
50
  MSG = 'Avoid `when` branches without a body.'
49
51
 
50
52
  def on_case(node)
51
53
  node.each_when do |when_node|
52
54
  next if when_node.body
53
- next if cop_config['AllowComments'] && comment_lines?(node)
55
+ next if cop_config['AllowComments'] && contains_comments?(when_node)
54
56
 
55
57
  add_offense(when_node)
56
58
  end
@@ -6,6 +6,15 @@ module RuboCop
6
6
  #
7
7
  # This cop checks for `IO.select` that is incompatible with Fiber Scheduler since Ruby 3.0.
8
8
  #
9
+ # NOTE: When the method is successful the return value of `IO.select` is `[[IO]]`,
10
+ # and the return value of `io.wait_readable` and `io.wait_writable` are `self`.
11
+ # They are not auto-corrected when assigning a return value because these types are different.
12
+ # It's up to user how to handle the return value.
13
+ #
14
+ # @safety
15
+ # This cop's autocorrection is unsafe because `NoMethodError` occurs
16
+ # if `require 'io/wait'` is not called.
17
+ #
9
18
  # @example
10
19
  #
11
20
  # # bad
@@ -20,10 +29,6 @@ module RuboCop
20
29
  # # good
21
30
  # io.wait_writable(timeout)
22
31
  #
23
- # @safety
24
- # This cop's autocorrection is unsafe because `NoMethodError` occurs
25
- # if `require 'io/wait'` is not called.
26
- #
27
32
  class IncompatibleIoSelectWithFiberScheduler < Base
28
33
  extend AutoCorrector
29
34
 
@@ -45,6 +50,8 @@ module RuboCop
45
50
  message = format(MSG, preferred: preferred, current: node.source)
46
51
 
47
52
  add_offense(node, message: message) do |corrector|
53
+ next if node.parent&.assignment?
54
+
48
55
  corrector.replace(node, preferred)
49
56
  end
50
57
  end
@@ -3,12 +3,16 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # This cop looks for error classes inheriting from `Exception`
7
- # and its standard library subclasses, excluding subclasses of
8
- # `StandardError`. It is configurable to suggest using either
9
- # `RuntimeError` (default) or `StandardError` instead.
6
+ # This cop looks for error classes inheriting from `Exception`.
7
+ # It is configurable to suggest using either `StandardError` (default) or
8
+ # `RuntimeError` instead.
10
9
  #
11
- # @example EnforcedStyle: runtime_error (default)
10
+ # @safety
11
+ # This cop's autocorrection is unsafe because `rescue` that omit
12
+ # exception class handle `StandardError` and its subclasses,
13
+ # but not `Exception` and its subclasses.
14
+ #
15
+ # @example EnforcedStyle: standard_error (default)
12
16
  # # bad
13
17
  #
14
18
  # class C < Exception; end
@@ -17,11 +21,11 @@ module RuboCop
17
21
  #
18
22
  # # good
19
23
  #
20
- # class C < RuntimeError; end
24
+ # class C < StandardError; end
21
25
  #
22
- # C = Class.new(RuntimeError)
26
+ # C = Class.new(StandardError)
23
27
  #
24
- # @example EnforcedStyle: standard_error
28
+ # @example EnforcedStyle: runtime_error
25
29
  # # bad
26
30
  #
27
31
  # class C < Exception; end
@@ -30,31 +34,18 @@ module RuboCop
30
34
  #
31
35
  # # good
32
36
  #
33
- # class C < StandardError; end
37
+ # class C < RuntimeError; end
34
38
  #
35
- # C = Class.new(StandardError)
39
+ # C = Class.new(RuntimeError)
36
40
  class InheritException < Base
37
41
  include ConfigurableEnforcedStyle
38
42
  extend AutoCorrector
39
43
 
40
- MSG = 'Inherit from `%<prefer>s` instead of `%<current>s`.'
44
+ MSG = 'Inherit from `%<prefer>s` instead of `Exception`.'
41
45
  PREFERRED_BASE_CLASS = {
42
46
  runtime_error: 'RuntimeError',
43
47
  standard_error: 'StandardError'
44
48
  }.freeze
45
- ILLEGAL_CLASSES = %w[
46
- Exception
47
- SystemStackError
48
- NoMemoryError
49
- SecurityError
50
- NotImplementedError
51
- LoadError
52
- SyntaxError
53
- ScriptError
54
- Interrupt
55
- SignalException
56
- SystemExit
57
- ].freeze
58
49
 
59
50
  RESTRICT_ON_SEND = %i[new].freeze
60
51
 
@@ -66,7 +57,7 @@ module RuboCop
66
57
  PATTERN
67
58
 
68
59
  def on_class(node)
69
- return unless node.parent_class && illegal_class_name?(node.parent_class)
60
+ return unless node.parent_class && exception_class?(node.parent_class)
70
61
 
71
62
  message = message(node.parent_class)
72
63
 
@@ -77,7 +68,7 @@ module RuboCop
77
68
 
78
69
  def on_send(node)
79
70
  constant = class_new_call?(node)
80
- return unless constant && illegal_class_name?(constant)
71
+ return unless constant && exception_class?(constant)
81
72
 
82
73
  message = message(constant)
83
74
 
@@ -92,8 +83,8 @@ module RuboCop
92
83
  format(MSG, prefer: preferred_base_class, current: node.const_name)
93
84
  end
94
85
 
95
- def illegal_class_name?(class_node)
96
- ILLEGAL_CLASSES.include?(class_node.const_name)
86
+ def exception_class?(class_node)
87
+ class_node.const_name == 'Exception'
97
88
  end
98
89
 
99
90
  def preferred_base_class
@@ -31,8 +31,15 @@ module RuboCop
31
31
  MSG = 'lambda without a literal block is deprecated; use the proc without lambda instead.'
32
32
  RESTRICT_ON_SEND = %i[lambda].freeze
33
33
 
34
+ # @!method lambda_with_symbol_proc?(node)
35
+ def_node_matcher :lambda_with_symbol_proc?, <<~PATTERN
36
+ (send nil? :lambda (block_pass (sym _)))
37
+ PATTERN
38
+
34
39
  def on_send(node)
35
- return if node.parent&.block_type? || !node.first_argument
40
+ if node.parent&.block_type? || !node.first_argument || lambda_with_symbol_proc?(node)
41
+ return
42
+ end
36
43
 
37
44
  add_offense(node) do |corrector|
38
45
  corrector.replace(node, node.first_argument.source.delete('&'))
@@ -19,7 +19,7 @@ module RuboCop
19
19
  include RangeHelp
20
20
  extend AutoCorrector
21
21
 
22
- MSG = '`(...)` interpreted as grouped expression.'
22
+ MSG = '`%<argument>s` interpreted as grouped expression.'
23
23
 
24
24
  def on_send(node)
25
25
  return if valid_context?(node)
@@ -28,8 +28,9 @@ module RuboCop
28
28
  return unless space_length.positive?
29
29
 
30
30
  range = space_range(node.first_argument.source_range, space_length)
31
+ message = format(MSG, argument: node.first_argument.source)
31
32
 
32
- add_offense(range) { |corrector| corrector.remove(range) }
33
+ add_offense(range, message: message) { |corrector| corrector.remove(range) }
33
34
  end
34
35
  alias on_csend on_send
35
36
 
@@ -6,6 +6,11 @@ module RuboCop
6
6
  # Sort globbed results by default in Ruby 3.0.
7
7
  # This cop checks for redundant `sort` method to `Dir.glob` and `Dir[]`.
8
8
  #
9
+ # @safety
10
+ # This cop is unsafe, in case of having a file and a directory with
11
+ # identical names, since directory will be loaded before the file, which
12
+ # will break `exe/files.rb` that rely on `exe.rb` file.
13
+ #
9
14
  # @example
10
15
  #
11
16
  # # bad