rubocop 1.73.2 → 1.75.2

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 (141) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +63 -8
  4. data/config/obsoletion.yml +3 -1
  5. data/lib/rubocop/cli.rb +1 -1
  6. data/lib/rubocop/config.rb +35 -6
  7. data/lib/rubocop/config_loader.rb +4 -0
  8. data/lib/rubocop/config_loader_resolver.rb +2 -1
  9. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  10. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  11. data/lib/rubocop/config_obsoletion.rb +46 -2
  12. data/lib/rubocop/config_validator.rb +1 -0
  13. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +2 -1
  14. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  15. data/lib/rubocop/cop/layout/block_alignment.rb +2 -2
  16. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  17. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  18. data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
  19. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +3 -3
  20. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
  21. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  22. data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
  23. data/lib/rubocop/cop/layout/line_length.rb +5 -1
  24. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  25. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  26. data/lib/rubocop/cop/layout/redundant_line_break.rb +9 -5
  27. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -5
  28. data/lib/rubocop/cop/layout/space_around_operators.rb +4 -1
  29. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  30. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
  31. data/lib/rubocop/cop/lint/debugger.rb +2 -2
  32. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  33. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -3
  34. data/lib/rubocop/cop/lint/literal_as_condition.rb +4 -0
  35. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
  36. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  37. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
  38. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  39. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +16 -7
  40. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  41. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  42. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  43. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +8 -1
  44. data/lib/rubocop/cop/lint/shared_mutable_default.rb +12 -1
  45. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  46. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  47. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  48. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
  49. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -0
  50. data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
  51. data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -0
  52. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +2 -11
  53. data/lib/rubocop/cop/lint/void.rb +1 -0
  54. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  55. data/lib/rubocop/cop/metrics/method_length.rb +1 -0
  56. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
  57. data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
  58. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
  59. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  60. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  61. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  62. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  63. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +0 -1
  64. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -0
  65. data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
  66. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  67. data/lib/rubocop/cop/naming/method_name.rb +64 -8
  68. data/lib/rubocop/cop/naming/variable_name.rb +6 -19
  69. data/lib/rubocop/cop/registry.rb +9 -6
  70. data/lib/rubocop/cop/style/array_intersect.rb +39 -28
  71. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  72. data/lib/rubocop/cop/style/class_and_module_children.rb +29 -7
  73. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  74. data/lib/rubocop/cop/style/collection_methods.rb +1 -0
  75. data/lib/rubocop/cop/style/combinable_loops.rb +1 -0
  76. data/lib/rubocop/cop/style/commented_keyword.rb +9 -2
  77. data/lib/rubocop/cop/style/comparable_between.rb +75 -0
  78. data/lib/rubocop/cop/style/conditional_assignment.rb +3 -0
  79. data/lib/rubocop/cop/style/double_negation.rb +2 -2
  80. data/lib/rubocop/cop/style/empty_literal.rb +4 -0
  81. data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
  82. data/lib/rubocop/cop/style/exponential_notation.rb +2 -2
  83. data/lib/rubocop/cop/style/for.rb +1 -0
  84. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  85. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  86. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  87. data/lib/rubocop/cop/style/guard_clause.rb +2 -1
  88. data/lib/rubocop/cop/style/hash_each_methods.rb +3 -2
  89. data/lib/rubocop/cop/style/hash_fetch_chain.rb +105 -0
  90. data/lib/rubocop/cop/style/hash_syntax.rb +3 -0
  91. data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
  92. data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
  93. data/lib/rubocop/cop/style/inverse_methods.rb +1 -0
  94. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  95. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  96. data/lib/rubocop/cop/style/it_block_parameter.rb +100 -0
  97. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
  98. data/lib/rubocop/cop/style/lambda.rb +1 -0
  99. data/lib/rubocop/cop/style/map_into_array.rb +1 -0
  100. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +4 -4
  101. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -0
  102. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -0
  103. data/lib/rubocop/cop/style/next.rb +44 -0
  104. data/lib/rubocop/cop/style/object_then.rb +1 -0
  105. data/lib/rubocop/cop/style/proc.rb +1 -0
  106. data/lib/rubocop/cop/style/raise_args.rb +8 -8
  107. data/lib/rubocop/cop/style/redundant_begin.rb +1 -0
  108. data/lib/rubocop/cop/style/redundant_condition.rb +13 -1
  109. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +14 -4
  110. data/lib/rubocop/cop/style/redundant_format.rb +10 -3
  111. data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -1
  112. data/lib/rubocop/cop/style/redundant_self.rb +1 -0
  113. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  114. data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
  115. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  116. data/lib/rubocop/cop/style/select_by_regexp.rb +4 -1
  117. data/lib/rubocop/cop/style/single_line_do_end_block.rb +3 -1
  118. data/lib/rubocop/cop/style/sole_nested_conditional.rb +41 -100
  119. data/lib/rubocop/cop/style/super_arguments.rb +1 -2
  120. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  121. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -0
  122. data/lib/rubocop/cop/util.rb +1 -1
  123. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  124. data/lib/rubocop/cop/variable_force/variable.rb +2 -7
  125. data/lib/rubocop/cop/variable_force.rb +1 -1
  126. data/lib/rubocop/directive_comment.rb +1 -1
  127. data/lib/rubocop/ext/regexp_node.rb +0 -1
  128. data/lib/rubocop/lsp/runtime.rb +4 -4
  129. data/lib/rubocop/lsp/stdin_runner.rb +3 -1
  130. data/lib/rubocop/magic_comment.rb +8 -0
  131. data/lib/rubocop/rspec/cop_helper.rb +4 -1
  132. data/lib/rubocop/rspec/shared_contexts.rb +20 -0
  133. data/lib/rubocop/rspec/support.rb +2 -0
  134. data/lib/rubocop/runner.rb +5 -1
  135. data/lib/rubocop/server/cache.rb +13 -10
  136. data/lib/rubocop/target_finder.rb +1 -1
  137. data/lib/rubocop/target_ruby.rb +1 -1
  138. data/lib/rubocop/version.rb +14 -7
  139. data/lib/rubocop.rb +5 -0
  140. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +20 -2
  141. metadata +11 -6
@@ -6,25 +6,29 @@ module RuboCop
6
6
  # Checks whether certain expressions, e.g. method calls, that could fit
7
7
  # completely on a single line, are broken up into multiple lines unnecessarily.
8
8
  #
9
- # @example any configuration
9
+ # @example
10
10
  # # bad
11
11
  # foo(
12
12
  # a,
13
13
  # b
14
14
  # )
15
15
  #
16
+ # # good
17
+ # foo(a, b)
18
+ #
19
+ # # bad
16
20
  # puts 'string that fits on ' \
17
21
  # 'a single line'
18
22
  #
23
+ # # good
24
+ # puts 'string that fits on a single line'
25
+ #
26
+ # # bad
19
27
  # things
20
28
  # .select { |thing| thing.cond? }
21
29
  # .join('-')
22
30
  #
23
31
  # # good
24
- # foo(a, b)
25
- #
26
- # puts 'string that fits on a single line'
27
- #
28
32
  # things.select { |thing| thing.cond? }.join('-')
29
33
  #
30
34
  # @example InspectBlocks: false (default)
@@ -29,8 +29,7 @@ module RuboCop
29
29
  MSG = '`%<kw_loc>s` at %<kw_loc_line>d, %<kw_loc_column>d is not ' \
30
30
  'aligned with `%<beginning>s` at ' \
31
31
  '%<begin_loc_line>d, %<begin_loc_column>d.'
32
- ANCESTOR_TYPES = %i[kwbegin def defs class module any_block].freeze
33
- ANCESTOR_TYPES_WITH_ACCESS_MODIFIERS = %i[def defs].freeze
32
+ ANCESTOR_TYPES = %i[kwbegin any_def class module any_block].freeze
34
33
  ALTERNATIVE_ACCESS_MODIFIERS = %i[public_class_method private_class_method].freeze
35
34
 
36
35
  def on_resbody(node)
@@ -96,7 +95,7 @@ module RuboCop
96
95
  def alignment_source(node, starting_loc)
97
96
  ending_loc =
98
97
  case node.type
99
- when :block, :numblock, :kwbegin
98
+ when :block, :numblock, :itblock, :kwbegin
100
99
  node.loc.begin
101
100
  when :def, :defs, :class, :module,
102
101
  :lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
@@ -162,8 +161,7 @@ module RuboCop
162
161
  end
163
162
 
164
163
  def access_modifier_node(node)
165
- return nil unless
166
- ANCESTOR_TYPES_WITH_ACCESS_MODIFIERS.include?(node.type)
164
+ return nil unless node.any_def_type?
167
165
 
168
166
  access_modifier_node = node.ancestors.first
169
167
  return nil unless access_modifier?(access_modifier_node)
@@ -260,7 +260,10 @@ module RuboCop
260
260
  end
261
261
 
262
262
  def hash_table_style?
263
- align_hash_cop_config && align_hash_cop_config['EnforcedHashRocketStyle'] == 'table'
263
+ return false unless align_hash_cop_config
264
+
265
+ enforced_styles = Array(align_hash_cop_config['EnforcedHashRocketStyle'])
266
+ enforced_styles.include?('table')
264
267
  end
265
268
 
266
269
  def space_around_exponent_operator?
@@ -77,6 +77,7 @@ module RuboCop
77
77
  end
78
78
 
79
79
  alias on_numblock on_block
80
+ alias on_itblock on_block
80
81
 
81
82
  private
82
83
 
@@ -103,6 +103,7 @@ module RuboCop
103
103
  end
104
104
 
105
105
  alias on_numblock on_block
106
+ alias on_itblock on_block
106
107
 
107
108
  private
108
109
 
@@ -73,7 +73,7 @@ module RuboCop
73
73
  # require 'my_debugger/start'
74
74
  class Debugger < Base
75
75
  MSG = 'Remove debugger entry point `%<source>s`.'
76
- BLOCK_TYPES = %i[block numblock kwbegin].freeze
76
+ BLOCK_TYPES = %i[block numblock itblock kwbegin].freeze
77
77
 
78
78
  def on_send(node)
79
79
  return if assumed_usage_context?(node)
@@ -120,7 +120,7 @@ module RuboCop
120
120
  return true if assumed_argument?(node)
121
121
 
122
122
  node.each_ancestor.none? do |ancestor|
123
- BLOCK_TYPES.include?(ancestor.type) || ancestor.lambda_or_proc?
123
+ ancestor.type?(:any_block, :kwbegin) || ancestor.lambda_or_proc?
124
124
  end
125
125
  end
126
126
 
@@ -134,7 +134,7 @@ module RuboCop
134
134
  if NO_ARG_ALGORITHM.include?(algorithm_parts.first.upcase) && no_arguments
135
135
  "'#{algorithm_parts.first}'"
136
136
  else
137
- mode = 'cbc' unless size_and_mode == ['cbc']
137
+ mode = 'cbc' if size_and_mode.empty?
138
138
 
139
139
  "'#{(algorithm_parts + size_and_mode + [mode]).compact.take(3).join('-')}'"
140
140
  end
@@ -42,7 +42,6 @@ module RuboCop
42
42
  class DuplicateMethods < Base
43
43
  MSG = 'Method `%<method>s` is defined at both %<defined>s and %<current>s.'
44
44
  RESTRICT_ON_SEND = %i[alias_method attr_reader attr_writer attr_accessor attr].freeze
45
- DEF_TYPES = %i[def defs].freeze
46
45
 
47
46
  def initialize(config = nil, options = nil)
48
47
  super
@@ -162,7 +161,7 @@ module RuboCop
162
161
  end
163
162
 
164
163
  def method_key(node, method_name)
165
- if (ancestor_def = node.each_ancestor(*DEF_TYPES).first)
164
+ if (ancestor_def = node.each_ancestor(:any_def).first)
166
165
  "#{ancestor_def.method_name}.#{method_name}"
167
166
  else
168
167
  method_name
@@ -170,7 +169,7 @@ module RuboCop
170
169
  end
171
170
 
172
171
  def location(node)
173
- if DEF_TYPES.include?(node.type)
172
+ if node.any_def_type?
174
173
  node.loc.keyword.join(node.loc.name)
175
174
  else
176
175
  node.source_range
@@ -46,6 +46,10 @@ module RuboCop
46
46
  return unless node.lhs.truthy_literal?
47
47
 
48
48
  add_offense(node.lhs) do |corrector|
49
+ # Don't autocorrect `'foo' && return` because having `return` as
50
+ # the leftmost node can lead to a void value expression syntax error.
51
+ next if node.rhs.type?(:return, :break, :next)
52
+
49
53
  corrector.replace(node, node.rhs.source)
50
54
  end
51
55
  end
@@ -98,7 +98,7 @@ module RuboCop
98
98
  subject, = *node # rubocop:disable InternalAffairs/NodeDestructuring
99
99
  return if node.defs_type? && allowed_subject_type?(subject)
100
100
 
101
- def_ancestor = node.each_ancestor(:def, :defs).first
101
+ def_ancestor = node.each_ancestor(:any_def).first
102
102
  return unless def_ancestor
103
103
 
104
104
  within_scoping_def =
@@ -46,7 +46,7 @@ module RuboCop
46
46
  def on_return(return_node)
47
47
  return if return_value?(return_node)
48
48
 
49
- return_node.each_ancestor(:block, :def, :defs) do |node|
49
+ return_node.each_ancestor(:any_block, :any_def) do |node|
50
50
  break if scoped_node?(node)
51
51
 
52
52
  # if a proc is passed to `Module#define_method` or
@@ -54,7 +54,7 @@ module RuboCop
54
54
  # non-local exit error
55
55
  break if define_method?(node.send_node)
56
56
 
57
- next unless node.arguments?
57
+ next if node.argument_list.empty?
58
58
 
59
59
  if chained_send?(node.send_node)
60
60
  add_offense(return_node.loc.keyword)
@@ -66,7 +66,7 @@ module RuboCop
66
66
  private
67
67
 
68
68
  def scoped_node?(node)
69
- node.type?(:def, :defs) || node.lambda?
69
+ node.any_def_type? || node.lambda?
70
70
  end
71
71
 
72
72
  def return_value?(return_node)
@@ -30,7 +30,7 @@ module RuboCop
30
30
  return unless node.lhs&.casgn_type?
31
31
 
32
32
  add_offense(node.loc.operator) do |corrector|
33
- next if node.each_ancestor(:def, :defs).any?
33
+ next if node.each_ancestor(:any_def).any?
34
34
 
35
35
  corrector.replace(node.loc.operator, '=')
36
36
  end
@@ -3,15 +3,18 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for `raise` or `fail` statements which are
7
- # raising `Exception` class.
6
+ # Checks for `raise` or `fail` statements which raise `Exception` or
7
+ # `Exception.new`. Use `StandardError` or a specific exception class instead.
8
8
  #
9
- # You can specify a module name that will be an implicit namespace
10
- # using `AllowedImplicitNamespaces` option. The cop cause a false positive
11
- # for namespaced `Exception` when a namespace is omitted. This option can
12
- # prevent the false positive by specifying a namespace to be omitted for
13
- # `Exception`. Alternatively, make `Exception` a fully qualified class
14
- # name with an explicit namespace.
9
+ # If you have defined your own namespaced `Exception` class, it is possible
10
+ # to configure the cop to allow it by setting `AllowedImplicitNamespaces` to
11
+ # an array with the names of the namespaces to allow. By default, this is set to
12
+ # `['Gem']`, which allows `Gem::Exception` to be raised without an explicit namespace.
13
+ # If not allowed, a false positive may be registered if `raise Exception` is called
14
+ # within the namespace.
15
+ #
16
+ # Alternatively, use a fully qualified name with `raise`/`fail`
17
+ # (eg. `raise Namespace::Exception`).
15
18
  #
16
19
  # @safety
17
20
  # This cop is unsafe because it will change the exception class being
@@ -20,15 +23,31 @@ module RuboCop
20
23
  # @example
21
24
  # # bad
22
25
  # raise Exception, 'Error message here'
26
+ # raise Exception.new('Error message here')
23
27
  #
24
28
  # # good
25
29
  # raise StandardError, 'Error message here'
30
+ # raise MyError.new, 'Error message here'
31
+ #
32
+ # @example AllowedImplicitNamespaces: ['Gem'] (default)
33
+ # # bad - `Foo` is not an allowed implicit namespace
34
+ # module Foo
35
+ # def self.foo
36
+ # raise Exception # This is qualified to `Foo::Exception`.
37
+ # end
38
+ # end
26
39
  #
27
- # @example AllowedImplicitNamespaces: ['Gem']
28
40
  # # good
29
41
  # module Gem
30
42
  # def self.foo
31
- # raise Exception # This exception means `Gem::Exception`.
43
+ # raise Exception # This is qualified to `Gem::Exception`.
44
+ # end
45
+ # end
46
+ #
47
+ # # good
48
+ # module Foo
49
+ # def self.foo
50
+ # raise Foo::Exception
32
51
  # end
33
52
  # end
34
53
  class RaiseException < Base
@@ -3,13 +3,13 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for redundant uses of `to_s`, `to_sym`, `to_i`, `to_f`, `to_r`, `to_c`,
6
+ # Checks for redundant uses of `to_s`, `to_sym`, `to_i`, `to_f`, `to_d`, `to_r`, `to_c`,
7
7
  # `to_a`, `to_h`, and `to_set`.
8
8
  #
9
9
  # When one of these methods is called on an object of the same type, that object
10
10
  # is returned, making the call unnecessary. The cop detects conversion methods called
11
11
  # on object literals, class constructors, class `[]` methods, and the `Kernel` methods
12
- # `String()`, `Integer()`, `Float()`, `Rational()`, `Complex()` and `Array()`.
12
+ # `String()`, `Integer()`, `Float()`, BigDecimal(), `Rational()`, `Complex()`, and `Array()`.
13
13
  #
14
14
  # Specifically, these cases are detected for each conversion method:
15
15
  #
@@ -27,7 +27,8 @@ module RuboCop
27
27
  # In all cases, chaining one same `to_*` conversion methods listed above is redundant.
28
28
  #
29
29
  # The cop can also register an offense for chaining conversion methods on methods that are
30
- # expected to return a specific type regardless of receiver (eg. `foo.inspect.to_s`).
30
+ # expected to return a specific type regardless of receiver (eg. `foo.inspect.to_s` and
31
+ # `foo.to_json.to_s`).
31
32
  #
32
33
  # @example
33
34
  # # bad
@@ -69,10 +70,12 @@ module RuboCop
69
70
  # foo.to_s
70
71
  #
71
72
  # # bad - chaining a conversion to a method that is expected to return the same type
72
- # inspect.to_s
73
+ # foo.inspect.to_s
74
+ # foo.to_json.to_s
73
75
  #
74
76
  # # good
75
- # inspect
77
+ # foo.inspect
78
+ # foo.to_json
76
79
  #
77
80
  class RedundantTypeConversion < Base
78
81
  extend AutoCorrector
@@ -98,6 +101,7 @@ module RuboCop
98
101
  to_s: 'string_constructor?',
99
102
  to_i: 'integer_constructor?',
100
103
  to_f: 'float_constructor?',
104
+ to_d: 'bigdecimal_constructor?',
101
105
  to_r: 'rational_constructor?',
102
106
  to_c: 'complex_constructor?',
103
107
  to_a: 'array_constructor?',
@@ -107,10 +111,10 @@ module RuboCop
107
111
 
108
112
  # Methods that already are expected to return a given type, which makes a further
109
113
  # conversion redundant.
110
- TYPED_METHODS = { to_s: %i[inspect] }.freeze
114
+ TYPED_METHODS = { to_s: %i[inspect to_json] }.freeze
111
115
 
112
116
  CONVERSION_METHODS = Set[*LITERAL_NODE_TYPES.keys].freeze
113
- RESTRICT_ON_SEND = CONVERSION_METHODS
117
+ RESTRICT_ON_SEND = CONVERSION_METHODS + [:to_d]
114
118
 
115
119
  private_constant :LITERAL_NODE_TYPES, :CONSTRUCTOR_MAPPING
116
120
 
@@ -137,6 +141,11 @@ module RuboCop
137
141
  #type_constructor?(:Float)
138
142
  PATTERN
139
143
 
144
+ # @!method bigdecimal_constructor?(node)
145
+ def_node_matcher :bigdecimal_constructor?, <<~PATTERN
146
+ #type_constructor?(:BigDecimal)
147
+ PATTERN
148
+
140
149
  # @!method rational_constructor?(node)
141
150
  def_node_matcher :rational_constructor?, <<~PATTERN
142
151
  #type_constructor?(:Rational)
@@ -53,6 +53,7 @@ module RuboCop
53
53
  # rubocop:enable Metrics/AbcSize
54
54
 
55
55
  alias on_numblock on_block
56
+ alias on_itblock on_block
56
57
 
57
58
  private
58
59
 
@@ -64,6 +65,8 @@ module RuboCop
64
65
  (args (arg _)) ...)
65
66
  (numblock
66
67
  $(call _ {:each_with_index :with_index} ...) 1 ...)
68
+ (itblock
69
+ $(call _ {:each_with_index :with_index} ...) _ ...)
67
70
  }
68
71
  PATTERN
69
72
 
@@ -49,6 +49,7 @@ module RuboCop
49
49
  end
50
50
 
51
51
  alias on_numblock on_block
52
+ alias on_itblock on_block
52
53
 
53
54
  private
54
55
 
@@ -59,6 +60,8 @@ module RuboCop
59
60
  $(call _ {:each_with_object :with_object} _) (args (arg _)) ...)
60
61
  (numblock
61
62
  $(call _ {:each_with_object :with_object} _) 1 ...)
63
+ (itblock
64
+ $(call _ {:each_with_object :with_object} _) _ ...)
62
65
  }
63
66
  PATTERN
64
67
 
@@ -32,25 +32,23 @@ module RuboCop
32
32
  class ReturnInVoidContext < Base
33
33
  MSG = 'Do not return a value in `%<method>s`.'
34
34
 
35
+ # Returning out of these methods only exits the block itself.
36
+ SCOPE_CHANGING_METHODS = %i[lambda define_method define_singleton_method].freeze
37
+
35
38
  def on_return(return_node)
36
39
  return unless return_node.descendants.any?
37
40
 
38
- context_node = non_void_context(return_node)
39
-
40
- return unless context_node&.def_type?
41
- return unless context_node&.void_context?
41
+ def_node = return_node.each_ancestor(:any_def).first
42
+ return unless def_node&.void_context?
43
+ return if return_node.each_ancestor(:any_block).any? do |block_node|
44
+ SCOPE_CHANGING_METHODS.include?(block_node.method_name)
45
+ end
42
46
 
43
47
  add_offense(
44
48
  return_node.loc.keyword,
45
- message: format(message, method: context_node.method_name)
49
+ message: format(message, method: def_node.method_name)
46
50
  )
47
51
  end
48
-
49
- private
50
-
51
- def non_void_context(return_node)
52
- return_node.each_ancestor(:block, :def, :defs).first
53
- end
54
52
  end
55
53
  end
56
54
  end
@@ -56,19 +56,26 @@ module RuboCop
56
56
 
57
57
  outer_local_variable = variable_table.find_variable(variable.name)
58
58
  return unless outer_local_variable
59
+ return if variable_used_in_declaration_of_outer?(variable, outer_local_variable)
59
60
  return if same_conditions_node_different_branch?(variable, outer_local_variable)
60
61
 
61
62
  message = format(MSG, variable: variable.name)
62
63
  add_offense(variable.declaration_node, message: message)
63
64
  end
64
65
 
66
+ private
67
+
68
+ def variable_used_in_declaration_of_outer?(variable, outer_local_variable)
69
+ variable.scope.node.each_ancestor.any?(outer_local_variable.declaration_node)
70
+ end
71
+
65
72
  def same_conditions_node_different_branch?(variable, outer_local_variable)
66
73
  variable_node = variable_node(variable)
67
74
  return false unless node_or_its_ascendant_conditional?(variable_node)
68
75
 
69
76
  outer_local_variable_node =
70
77
  find_conditional_node_from_ascendant(outer_local_variable.declaration_node)
71
- return true unless outer_local_variable_node
78
+ return false unless outer_local_variable_node
72
79
  return false unless outer_local_variable_node.conditional?
73
80
  return true if variable_node == outer_local_variable_node
74
81
 
@@ -51,7 +51,18 @@ module RuboCop
51
51
 
52
52
  # @!method hash_initialized_with_mutable_shared_object?(node)
53
53
  def_node_matcher :hash_initialized_with_mutable_shared_object?, <<~PATTERN
54
- (send (const {nil? cbase} :Hash) :new {array hash (send (const {nil? cbase} {:Array :Hash}) :new)})
54
+ {
55
+ (send (const {nil? cbase} :Hash) :new [
56
+ {array hash (send (const {nil? cbase} {:Array :Hash}) :new)}
57
+ !#capacity_keyword_argument?
58
+ ])
59
+ (send (const {nil? cbase} :Hash) :new hash #capacity_keyword_argument?)
60
+ }
61
+ PATTERN
62
+
63
+ # @!method capacity_keyword_argument?(node)
64
+ def_node_matcher :capacity_keyword_argument?, <<~PATTERN
65
+ (hash (pair (sym :capacity) _))
55
66
  PATTERN
56
67
 
57
68
  def on_send(node)
@@ -116,7 +116,7 @@ module RuboCop
116
116
  private
117
117
 
118
118
  def comment_between_rescue_and_end?(node)
119
- ancestor = node.each_ancestor(:kwbegin, :def, :defs, :any_block).first
119
+ ancestor = node.each_ancestor(:kwbegin, :any_def, :any_block).first
120
120
  return false unless ancestor
121
121
 
122
122
  end_line = ancestor.loc.end&.line || ancestor.loc.last_line
@@ -45,7 +45,7 @@ module RuboCop
45
45
  PATTERN
46
46
 
47
47
  def on_send(node)
48
- def_node = node.each_ancestor(:def, :defs).first
48
+ def_node = node.each_ancestor(:any_def).first
49
49
  return unless def_node
50
50
 
51
51
  enum_conversion_call?(node) do |method_node, arguments|
@@ -40,7 +40,7 @@ module RuboCop
40
40
  # top-level return node's ancestors should not be of block, def, or
41
41
  # defs type.
42
42
  def top_level_return?(return_node)
43
- return_node.each_ancestor(:block, :def, :defs).none?
43
+ return_node.each_ancestor(:block, :any_def).none?
44
44
  end
45
45
  end
46
46
  end
@@ -53,6 +53,7 @@ module RuboCop
53
53
  end
54
54
 
55
55
  alias on_numblock on_block
56
+ alias on_itblock on_block
56
57
 
57
58
  private
58
59
 
@@ -74,6 +75,7 @@ module RuboCop
74
75
 
75
76
  def arg_count(node)
76
77
  return node.children[1] if node.numblock_type? # the maximum numbered param for the block
78
+ return 1 if node.itblock_type? # `it` block parameter is always one
77
79
 
78
80
  # Only `arg`, `optarg` and `mlhs` (destructuring) count as arguments that
79
81
  # can be used. Keyword arguments are not used for these methods so are
@@ -43,6 +43,7 @@ module RuboCop
43
43
  end
44
44
 
45
45
  alias on_numblock on_block
46
+ alias on_itblock on_block
46
47
 
47
48
  def after_block(node)
48
49
  @instance_eval_count -= 1 if instance_eval_block?(node)
@@ -101,9 +101,8 @@ module RuboCop
101
101
  check(node) if loop_method?(node)
102
102
  end
103
103
 
104
- def on_numblock(node)
105
- check(node) if loop_method?(node)
106
- end
104
+ alias on_numblock on_block
105
+ alias on_itblock on_block
107
106
 
108
107
  private
109
108
 
@@ -189,8 +188,9 @@ module RuboCop
189
188
 
190
189
  def preceded_by_continue_statement?(break_statement)
191
190
  break_statement.left_siblings.any? do |sibling|
192
- # Numblocks have the arguments count as a number in the AST.
193
- next if sibling.is_a?(Integer)
191
+ # Numblocks have the arguments count as a number or,
192
+ # itblocks have `:it` symbol in the AST.
193
+ next if sibling.is_a?(Integer) || sibling.is_a?(Symbol)
194
194
  next if sibling.loop_keyword? || loop_method?(sibling)
195
195
 
196
196
  sibling.each_descendant(*CONTINUE_KEYWORDS).any?
@@ -143,6 +143,7 @@ module RuboCop
143
143
  end
144
144
 
145
145
  alias on_numblock on_block
146
+ alias on_itblock on_block
146
147
 
147
148
  private
148
149
 
@@ -4,8 +4,8 @@ module RuboCop
4
4
  module Cop
5
5
  module Lint
6
6
  # Checks for useless constant scoping. Private constants must be defined using
7
- # `private_constant` or `class << self`. Even if `private` access modifier is used,
8
- # it is public scope despite its appearance.
7
+ # `private_constant`. Even if `private` access modifier is used, it is public scope despite
8
+ # its appearance.
9
9
  #
10
10
  # It does not support autocorrection due to behavior change and multiple ways to fix it.
11
11
  # Or a public constant may be intended.
@@ -26,14 +26,6 @@ module RuboCop
26
26
  #
27
27
  # # good
28
28
  # class Foo
29
- # class << self
30
- # private
31
- # PRIVATE_CONST = 42
32
- # end
33
- # end
34
- #
35
- # # good
36
- # class Foo
37
29
  # PUBLIC_CONST = 42 # If private scope is not intended.
38
30
  # end
39
31
  #
@@ -46,7 +38,6 @@ module RuboCop
46
38
  PATTERN
47
39
 
48
40
  def on_casgn(node)
49
- return if node.each_ancestor(:sclass).any?
50
41
  return unless after_private_modifier?(node.left_siblings)
51
42
  return if private_constantize?(node.right_siblings, node.name)
52
43
 
@@ -86,6 +86,7 @@ module RuboCop
86
86
  check_expression(node.body)
87
87
  end
88
88
  alias on_numblock on_block
89
+ alias on_itblock on_block
89
90
 
90
91
  def on_begin(node)
91
92
  check_begin(node)
@@ -57,6 +57,7 @@ module RuboCop
57
57
  check_code_length(node)
58
58
  end
59
59
  alias on_numblock on_block
60
+ alias on_itblock on_block
60
61
 
61
62
  private
62
63
 
@@ -63,6 +63,7 @@ module RuboCop
63
63
  check_code_length(node)
64
64
  end
65
65
  alias on_numblock on_block
66
+ alias on_itblock on_block
66
67
 
67
68
  private
68
69
 
@@ -145,7 +145,7 @@ module RuboCop
145
145
 
146
146
  def extract_body(node)
147
147
  case node.type
148
- when :class, :module, :sclass, :block, :numblock, :def, :defs
148
+ when :class, :module, :sclass, :block, :numblock, :itblock, :def, :defs
149
149
  node.body
150
150
  when :casgn
151
151
  extract_body(node.expression)
@@ -48,7 +48,7 @@ module RuboCop
48
48
 
49
49
  args = process_args(node.arguments)
50
50
  return extract_breakable_node_from_elements(node, args, max)
51
- elsif node.def_type?
51
+ elsif node.any_def_type?
52
52
  return extract_breakable_node_from_elements(node, node.arguments, max)
53
53
  elsif node.type?(:array, :hash)
54
54
  return extract_breakable_node_from_elements(node, node.children, max)
@@ -220,7 +220,7 @@ module RuboCop
220
220
 
221
221
  # @api private
222
222
  def already_on_multiple_lines?(node)
223
- return node.first_line != node.last_argument.last_line if node.def_type?
223
+ return node.first_line != node.last_argument.last_line if node.any_def_type?
224
224
 
225
225
  !node.single_line?
226
226
  end