rubocop 1.68.0 → 1.69.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +41 -6
  4. data/lib/rubocop/cop/base.rb +1 -1
  5. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  6. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  7. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  8. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  9. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  10. data/lib/rubocop/cop/generator.rb +6 -0
  11. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  12. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  13. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +46 -0
  14. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  15. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  16. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -2
  17. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  18. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  19. data/lib/rubocop/cop/layout/block_alignment.rb +1 -2
  20. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
  21. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -3
  22. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +3 -4
  23. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +3 -1
  24. data/lib/rubocop/cop/layout/indentation_width.rb +7 -7
  25. data/lib/rubocop/cop/layout/leading_comment_space.rb +15 -0
  26. data/lib/rubocop/cop/layout/line_length.rb +118 -4
  27. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
  28. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  29. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
  30. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  31. data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -35
  32. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -2
  33. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  34. data/lib/rubocop/cop/layout/space_around_operators.rb +16 -17
  35. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -0
  36. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
  37. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  38. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  39. data/lib/rubocop/cop/lint/circular_argument_reference.rb +6 -0
  40. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
  41. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  42. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  43. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  44. data/lib/rubocop/cop/lint/float_comparison.rb +14 -6
  45. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -3
  46. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  47. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  48. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  49. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -0
  50. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  51. data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -5
  52. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
  53. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  54. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +1 -1
  55. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  56. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  57. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  58. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +106 -0
  59. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
  60. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -1
  61. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  62. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
  63. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  64. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  65. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  66. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  67. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +2 -0
  68. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  69. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  70. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +3 -0
  71. data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
  72. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  73. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  74. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  75. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
  76. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  77. data/lib/rubocop/cop/lint/void.rb +3 -2
  78. data/lib/rubocop/cop/metrics/class_length.rb +7 -7
  79. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  80. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -3
  81. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  82. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  83. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  84. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
  85. data/lib/rubocop/cop/mixin/range_help.rb +0 -1
  86. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  87. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  88. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  89. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  90. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
  91. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -11
  92. data/lib/rubocop/cop/naming/variable_name.rb +3 -4
  93. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  94. data/lib/rubocop/cop/security/compound_hash.rb +1 -0
  95. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  96. data/lib/rubocop/cop/style/access_modifier_declarations.rb +54 -25
  97. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +1 -1
  98. data/lib/rubocop/cop/style/array_intersect.rb +5 -4
  99. data/lib/rubocop/cop/style/bitwise_predicate.rb +1 -1
  100. data/lib/rubocop/cop/style/block_delimiters.rb +10 -2
  101. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  102. data/lib/rubocop/cop/style/commented_keyword.rb +11 -1
  103. data/lib/rubocop/cop/style/conditional_assignment.rb +19 -21
  104. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  105. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  106. data/lib/rubocop/cop/style/fetch_env_var.rb +1 -0
  107. data/lib/rubocop/cop/style/file_null.rb +73 -0
  108. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  109. data/lib/rubocop/cop/style/for.rb +0 -1
  110. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  111. data/lib/rubocop/cop/style/guard_clause.rb +1 -1
  112. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  113. data/lib/rubocop/cop/style/hash_except.rb +19 -7
  114. data/lib/rubocop/cop/style/if_inside_else.rb +0 -1
  115. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -2
  116. data/lib/rubocop/cop/style/if_with_semicolon.rb +14 -5
  117. data/lib/rubocop/cop/style/inverse_methods.rb +0 -1
  118. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +2 -2
  119. data/lib/rubocop/cop/style/lambda_call.rb +3 -2
  120. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +1 -1
  121. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +7 -11
  122. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  123. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  124. data/lib/rubocop/cop/style/mutable_constant.rb +4 -5
  125. data/lib/rubocop/cop/style/negated_if_else_condition.rb +6 -4
  126. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  127. data/lib/rubocop/cop/style/not.rb +1 -1
  128. data/lib/rubocop/cop/style/object_then.rb +1 -0
  129. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  130. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  131. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  132. data/lib/rubocop/cop/style/parallel_assignment.rb +8 -13
  133. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  134. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  135. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  136. data/lib/rubocop/cop/style/redundant_condition.rb +36 -21
  137. data/lib/rubocop/cop/style/redundant_line_continuation.rb +7 -6
  138. data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -2
  139. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +1 -0
  140. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  141. data/lib/rubocop/cop/style/redundant_self.rb +8 -15
  142. data/lib/rubocop/cop/style/redundant_self_assignment.rb +7 -5
  143. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  144. data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
  145. data/lib/rubocop/cop/style/rescue_modifier.rb +2 -3
  146. data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
  147. data/lib/rubocop/cop/style/select_by_regexp.rb +1 -1
  148. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  149. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  150. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  151. data/lib/rubocop/cop/style/single_line_do_end_block.rb +13 -3
  152. data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -3
  153. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  154. data/lib/rubocop/cop/style/string_concatenation.rb +13 -12
  155. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  156. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  157. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  158. data/lib/rubocop/cop/variable_force.rb +4 -10
  159. data/lib/rubocop/cops_documentation_generator.rb +9 -1
  160. data/lib/rubocop/version.rb +1 -1
  161. data/lib/rubocop.rb +8 -0
  162. metadata +23 -14
@@ -155,6 +155,7 @@ module RuboCop
155
155
  UNDERSCORE_REQUIRED = 'Memoized variable `%<var>s` does not start ' \
156
156
  'with `_`. Use `@%<suggested_var>s` instead.'
157
157
  DYNAMIC_DEFINE_METHODS = %i[define_method define_singleton_method].to_set.freeze
158
+ INITIALIZE_METHODS = %i[initialize initialize_clone initialize_copy initialize_dup].freeze
158
159
 
159
160
  # @!method method_definition?(node)
160
161
  def_node_matcher :method_definition?, <<~PATTERN
@@ -168,7 +169,7 @@ module RuboCop
168
169
  # rubocop:disable Metrics/AbcSize
169
170
  # rubocop:disable Metrics/MethodLength
170
171
  def on_or_asgn(node)
171
- lhs, _value = *node
172
+ lhs = node.lhs
172
173
  return unless lhs.ivasgn_type?
173
174
 
174
175
  method_node, method_name = find_definition(node)
@@ -181,8 +182,8 @@ module RuboCop
181
182
 
182
183
  suggested_var = suggested_var(method_name)
183
184
  msg = format(
184
- message(lhs.children.first.to_s),
185
- var: lhs.children.first.to_s,
185
+ message(lhs.name),
186
+ var: lhs.name,
186
187
  suggested_var: suggested_var,
187
188
  method: method_name
188
189
  )
@@ -209,14 +210,13 @@ module RuboCop
209
210
  method_node, method_name = find_definition(node)
210
211
  return false unless method_node
211
212
 
212
- var_name = arg.children.first
213
- defined_memoized?(method_node.body, var_name) do |defined_ivar, return_ivar, ivar_assign|
213
+ defined_memoized?(method_node.body, arg.name) do |defined_ivar, return_ivar, ivar_assign|
214
214
  return false if matches?(method_name, ivar_assign)
215
215
 
216
216
  suggested_var = suggested_var(method_name)
217
217
  msg = format(
218
- message(var_name.to_s),
219
- var: var_name.to_s,
218
+ message(arg.name),
219
+ var: arg.name,
220
220
  suggested_var: suggested_var,
221
221
  method: method_name
222
222
  )
@@ -251,11 +251,10 @@ module RuboCop
251
251
  end
252
252
 
253
253
  def matches?(method_name, ivar_assign)
254
- return true if ivar_assign.nil? || method_name == :initialize
254
+ return true if ivar_assign.nil? || INITIALIZE_METHODS.include?(method_name)
255
255
 
256
- method_name = method_name.to_s.delete('!?')
257
- variable = ivar_assign.children.first
258
- variable_name = variable.to_s.sub('@', '')
256
+ method_name = method_name.to_s.delete('!?=')
257
+ variable_name = ivar_assign.name.to_s.sub('@', '')
259
258
 
260
259
  variable_name_candidates(method_name).include?(variable_name)
261
260
  end
@@ -269,7 +268,7 @@ module RuboCop
269
268
  end
270
269
 
271
270
  def suggested_var(method_name)
272
- suggestion = method_name.to_s.delete('!?')
271
+ suggestion = method_name.to_s.delete('!?=')
273
272
 
274
273
  style == :required ? "_#{suggestion}" : suggestion
275
274
  end
@@ -109,7 +109,7 @@ module RuboCop
109
109
  variable_name_matches?(lvasgn_node, name)
110
110
  end
111
111
  else
112
- node.children.first == name
112
+ node.name == name
113
113
  end
114
114
  end
115
115
 
@@ -141,12 +141,7 @@ module RuboCop
141
141
  # Further `lvar` nodes will not be corrected though since they now refer to a
142
142
  # different variable.
143
143
  def correct_reassignment(corrector, node, offending_name, preferred_name)
144
- if node.lvasgn_type?
145
- correct_node(corrector, node.child_nodes.first, offending_name, preferred_name)
146
- elsif node.masgn_type?
147
- # With multiple assign, the assignments are in an array as the last child
148
- correct_node(corrector, node.children.last, offending_name, preferred_name)
149
- end
144
+ correct_node(corrector, node.rhs, offending_name, preferred_name)
150
145
  end
151
146
 
152
147
  def preferred_name(variable_name)
@@ -159,10 +154,7 @@ module RuboCop
159
154
  end
160
155
 
161
156
  def variable_name(node)
162
- asgn_node = node.exception_variable
163
- return unless asgn_node
164
-
165
- asgn_node.children.last
157
+ node.exception_variable&.name
166
158
  end
167
159
 
168
160
  def message(node)
@@ -40,11 +40,10 @@ module RuboCop
40
40
  end
41
41
 
42
42
  def on_lvasgn(node)
43
- name, = *node
44
- return unless name
45
- return if allowed_identifier?(name)
43
+ return unless node.name
44
+ return if allowed_identifier?(node.name)
46
45
 
47
- check_name(node, name, node.loc.name)
46
+ check_name(node, node.name, node.loc.name)
48
47
  end
49
48
  alias on_ivasgn on_lvasgn
50
49
  alias on_cvasgn on_lvasgn
@@ -113,10 +113,9 @@ module RuboCop
113
113
 
114
114
  def on_arg(node)
115
115
  @node = node
116
- name, = *node
117
- return if allowed_identifier?(name)
116
+ return if allowed_identifier?(node.name)
118
117
 
119
- check_name(node, name, node.loc.name)
118
+ check_name(node, node.name, node.loc.name)
120
119
  end
121
120
  alias on_lvasgn on_arg
122
121
  alias on_ivasgn on_arg
@@ -32,6 +32,7 @@ module RuboCop
32
32
  MONUPLE_HASH_MSG =
33
33
  'Delegate hash directly without wrapping in an array when only using a single value.'
34
34
  REDUNDANT_HASH_MSG = 'Calling .hash on elements of a hashed array is redundant.'
35
+ RESTRICT_ON_SEND = %i[hash ^ + * |].freeze
35
36
 
36
37
  # @!method hash_method_definition?(node)
37
38
  def_node_matcher :hash_method_definition?, <<~PATTERN
@@ -25,18 +25,19 @@ module RuboCop
25
25
  #
26
26
  class YAMLLoad < Base
27
27
  extend AutoCorrector
28
+ extend TargetRubyVersion
28
29
 
29
30
  MSG = 'Prefer using `YAML.safe_load` over `YAML.load`.'
30
31
  RESTRICT_ON_SEND = %i[load].freeze
31
32
 
33
+ maximum_target_ruby_version 3.0
34
+
32
35
  # @!method yaml_load(node)
33
36
  def_node_matcher :yaml_load, <<~PATTERN
34
37
  (send (const {nil? cbase} :YAML) :load ...)
35
38
  PATTERN
36
39
 
37
40
  def on_send(node)
38
- return if target_ruby_version >= 3.1
39
-
40
41
  yaml_load(node) do
41
42
  add_offense(node.loc.selector) do |corrector|
42
43
  corrector.replace(node.loc.selector, 'safe_load')
@@ -70,6 +70,7 @@ module RuboCop
70
70
  # private :bar, :baz
71
71
  # private *%i[qux quux]
72
72
  # private *METHOD_NAMES
73
+ # private *private_methods
73
74
  #
74
75
  # end
75
76
  #
@@ -80,6 +81,7 @@ module RuboCop
80
81
  # private :bar, :baz
81
82
  # private *%i[qux quux]
82
83
  # private *METHOD_NAMES
84
+ # private *private_methods
83
85
  #
84
86
  # end
85
87
  #
@@ -133,21 +135,18 @@ module RuboCop
133
135
  # @!method access_modifier_with_symbol?(node)
134
136
  def_node_matcher :access_modifier_with_symbol?, <<~PATTERN
135
137
  (send nil? {:private :protected :public :module_function}
136
- {(sym _) (splat {#percent_symbol_array? const})}
138
+ {(sym _)+ (splat {#percent_symbol_array? const send})}
137
139
  )
138
140
  PATTERN
139
141
 
140
142
  # @!method access_modifier_with_attr?(node)
141
143
  def_node_matcher :access_modifier_with_attr?, <<~PATTERN
142
144
  (send nil? {:private :protected :public :module_function}
143
- (send nil? {:attr :attr_reader :attr_writer :attr_accessor} _))
145
+ (send nil? {:attr :attr_reader :attr_writer :attr_accessor} _+))
144
146
  PATTERN
145
147
 
146
148
  def on_send(node)
147
- return unless node.access_modifier?
148
- return if ALLOWED_NODE_TYPES.include?(node.parent&.type)
149
- return if allow_modifiers_on_symbols?(node)
150
- return if allow_modifiers_on_attrs?(node)
149
+ return if allowed?(node)
151
150
 
152
151
  if offense?(node)
153
152
  add_offense(node.loc.selector) do |corrector|
@@ -161,15 +160,22 @@ module RuboCop
161
160
 
162
161
  private
163
162
 
163
+ def allowed?(node)
164
+ !node.access_modifier? ||
165
+ ALLOWED_NODE_TYPES.include?(node.parent&.type) ||
166
+ allow_modifiers_on_symbols?(node) ||
167
+ allow_modifiers_on_attrs?(node)
168
+ end
169
+
164
170
  def autocorrect(corrector, node)
165
171
  case style
166
172
  when :group
167
- def_node = find_corresponding_def_node(node)
168
- return unless def_node
173
+ def_nodes = find_corresponding_def_nodes(node)
174
+ return unless def_nodes.any?
169
175
 
170
- replace_def(corrector, node, def_node)
176
+ replace_defs(corrector, node, def_nodes)
171
177
  when :inline
172
- remove_node(corrector, node)
178
+ remove_nodes(corrector, node)
173
179
  select_grouped_def_nodes(node).each do |grouped_def_node|
174
180
  insert_inline_modifier(corrector, grouped_def_node, node.method_name)
175
181
  end
@@ -190,10 +196,17 @@ module RuboCop
190
196
 
191
197
  def offense?(node)
192
198
  (group_style? && access_modifier_is_inlined?(node) &&
193
- !right_siblings_same_inline_method?(node)) ||
199
+ !node.parent&.if_type? && !right_siblings_same_inline_method?(node)) ||
194
200
  (inline_style? && access_modifier_is_not_inlined?(node))
195
201
  end
196
202
 
203
+ def correctable_group_offense?(node)
204
+ return false unless group_style?
205
+ return false if allowed?(node)
206
+
207
+ access_modifier_is_inlined?(node) && find_corresponding_def_nodes(node).any?
208
+ end
209
+
197
210
  def group_style?
198
211
  style == :group
199
212
  end
@@ -212,7 +225,11 @@ module RuboCop
212
225
 
213
226
  def right_siblings_same_inline_method?(node)
214
227
  node.right_siblings.any? do |sibling|
215
- sibling.send_type? && sibling.method?(node.method_name) && !sibling.arguments.empty?
228
+ sibling.send_type? &&
229
+ correctable_group_offense?(sibling) &&
230
+ sibling.method?(node.method_name) &&
231
+ !sibling.arguments.empty? &&
232
+ find_corresponding_def_nodes(sibling).any?
216
233
  end
217
234
  end
218
235
 
@@ -226,14 +243,22 @@ module RuboCop
226
243
  end
227
244
  end
228
245
 
229
- def find_corresponding_def_node(node)
246
+ def find_corresponding_def_nodes(node)
230
247
  if access_modifier_with_symbol?(node)
231
- method_name = node.first_argument.respond_to?(:value) && node.first_argument.value
232
- node.parent.each_child_node(:def).find do |child|
233
- child.method?(method_name)
248
+ method_names = node.arguments.filter_map do |argument|
249
+ next unless argument.sym_type?
250
+
251
+ argument.respond_to?(:value) && argument.value
252
+ end
253
+
254
+ def_nodes = node.parent.each_child_node(:def).select do |child|
255
+ method_names.include?(child.method_name)
234
256
  end
257
+
258
+ # If there isn't a `def` node for each symbol, we will skip autocorrection.
259
+ def_nodes.size == method_names.size ? def_nodes : []
235
260
  else
236
- node.first_argument
261
+ [node.first_argument]
237
262
  end
238
263
  end
239
264
 
@@ -251,8 +276,8 @@ module RuboCop
251
276
  end.select(&:def_type?)
252
277
  end
253
278
 
254
- def replace_def(corrector, node, def_node)
255
- source = def_source(node, def_node)
279
+ def replace_defs(corrector, node, def_nodes)
280
+ source = def_source(node, def_nodes)
256
281
  argument_less_modifier_node = find_argument_less_modifier_node(node)
257
282
  if argument_less_modifier_node
258
283
  corrector.insert_after(argument_less_modifier_node, "\n\n#{source}")
@@ -264,20 +289,24 @@ module RuboCop
264
289
  return
265
290
  end
266
291
 
267
- remove_node(corrector, def_node)
268
- remove_node(corrector, node)
292
+ remove_nodes(corrector, *def_nodes, node)
269
293
  end
270
294
 
271
295
  def insert_inline_modifier(corrector, node, modifier_name)
272
296
  corrector.insert_before(node, "#{modifier_name} ")
273
297
  end
274
298
 
275
- def remove_node(corrector, node)
276
- corrector.remove(range_with_comments_and_lines(node))
299
+ def remove_nodes(corrector, *nodes)
300
+ nodes.each do |node|
301
+ corrector.remove(range_with_comments_and_lines(node))
302
+ end
277
303
  end
278
304
 
279
- def def_source(node, def_node)
280
- [*processed_source.ast_with_comments[node].map(&:text), def_node.source].join("\n")
305
+ def def_source(node, def_nodes)
306
+ [
307
+ *processed_source.ast_with_comments[node].map(&:text),
308
+ *def_nodes.map(&:source)
309
+ ].join("\n")
281
310
  end
282
311
  end
283
312
  end
@@ -61,7 +61,7 @@ module RuboCop
61
61
  private
62
62
 
63
63
  def modifier_form?(operation)
64
- return true if operation.and_type? || operation.or_type?
64
+ return true if operation.operator_keyword?
65
65
 
66
66
  operation.modifier_form?
67
67
  end
@@ -28,6 +28,7 @@ module RuboCop
28
28
  # # bad
29
29
  # (array1 & array2).any?
30
30
  # (array1 & array2).empty?
31
+ # (array1 & array2).none?
31
32
  #
32
33
  # # good
33
34
  # array1.intersect?(array2)
@@ -57,7 +58,7 @@ module RuboCop
57
58
  (send
58
59
  (begin
59
60
  (send $(...) :& $(...))
60
- ) ${:any? :empty?}
61
+ ) ${:any? :empty? :none?}
61
62
  )
62
63
  PATTERN
63
64
 
@@ -66,18 +67,18 @@ module RuboCop
66
67
  (send
67
68
  (begin
68
69
  (send $(...) :& $(...))
69
- ) ${:present? :any? :blank? :empty?}
70
+ ) ${:present? :any? :blank? :empty? :none?}
70
71
  )
71
72
  PATTERN
72
73
 
73
74
  MSG = 'Use `%<negated>s%<receiver>s.intersect?(%<argument>s)` ' \
74
75
  'instead of `(%<receiver>s & %<argument>s).%<method_name>s`.'
75
76
  STRAIGHT_METHODS = %i[present? any?].freeze
76
- NEGATED_METHODS = %i[blank? empty?].freeze
77
+ NEGATED_METHODS = %i[blank? empty? none?].freeze
77
78
  RESTRICT_ON_SEND = (STRAIGHT_METHODS + NEGATED_METHODS).freeze
78
79
 
79
80
  def on_send(node)
80
- return if (parent = node.parent) && (parent.block_type? || parent.numblock_type?)
81
+ return if node.block_literal?
81
82
  return unless (receiver, argument, method_name = bad_intersection_check?(node))
82
83
 
83
84
  message = message(receiver.source, argument.source, method_name)
@@ -71,7 +71,7 @@ module RuboCop
71
71
  PATTERN
72
72
 
73
73
  def on_send(node)
74
- return unless node.receiver.begin_type?
74
+ return unless node.receiver&.begin_type?
75
75
  return unless (preferred_method = preferred_method(node))
76
76
 
77
77
  bit_operation = node.receiver.children.first
@@ -342,16 +342,23 @@ module RuboCop
342
342
  node.respond_to?(:block_node) && node.block_node
343
343
  end
344
344
 
345
+ # rubocop:disable Metrics/CyclomaticComplexity
345
346
  def get_blocks(node, &block)
346
347
  case node.type
347
348
  when :block, :numblock
348
349
  yield node
349
350
  when :send
351
+ # When a method has an argument which is another method with a block,
352
+ # that block needs braces, otherwise a syntax error will be introduced
353
+ # for subsequent arguments.
354
+ # Additionally, even without additional arguments, changing `{...}` to
355
+ # `do...end` will change the binding of the block to the outer method.
350
356
  get_blocks(node.receiver, &block) if node.receiver
357
+ node.arguments.each { |argument| get_blocks(argument, &block) }
351
358
  when :hash
352
359
  # A hash which is passed as method argument may have no braces
353
360
  # In that case, one of the K/V pairs could contain a block node
354
- # which could change in meaning if do...end replaced {...}
361
+ # which could change in meaning if `do...end` is replaced with `{...}`
355
362
  return if node.braces?
356
363
 
357
364
  node.each_child_node { |child| get_blocks(child, &block) }
@@ -359,6 +366,7 @@ module RuboCop
359
366
  node.each_child_node { |child| get_blocks(child, &block) }
360
367
  end
361
368
  end
369
+ # rubocop:enable Metrics/CyclomaticComplexity
362
370
 
363
371
  # rubocop:disable Metrics/CyclomaticComplexity
364
372
  def proper_block_style?(node)
@@ -481,7 +489,7 @@ module RuboCop
481
489
  end
482
490
 
483
491
  def conditional?(node)
484
- node.if_type? || node.or_type? || node.and_type?
492
+ node.if_type? || node.operator_keyword?
485
493
  end
486
494
 
487
495
  def array_or_range?(node)
@@ -106,7 +106,7 @@ module RuboCop
106
106
  when :or
107
107
  find_target(node.lhs)
108
108
  when :match_with_lvasgn
109
- lhs, rhs = *node
109
+ lhs, rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring
110
110
  if lhs.regexp_type?
111
111
  rhs
112
112
  elsif rhs.regexp_type?
@@ -172,7 +172,7 @@ module RuboCop
172
172
  return collect_conditions(node.lhs, target, conditions) &&
173
173
  collect_conditions(node.rhs, target, conditions)
174
174
  when :match_with_lvasgn
175
- lhs, rhs = *node
175
+ lhs, rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring
176
176
  condition_from_binary_op(lhs, rhs, target)
177
177
  when :send
178
178
  condition_from_send_node(node, target)
@@ -191,8 +191,7 @@ module RuboCop
191
191
  when :=~, :match, :match?
192
192
  condition_from_match_node(node, target)
193
193
  when :===
194
- lhs, _method, rhs = *node
195
- lhs if rhs == target
194
+ node.receiver if node.first_argument == target
196
195
  when :include?, :cover?
197
196
  condition_from_include_or_cover_node(node, target)
198
197
  end
@@ -200,14 +199,12 @@ module RuboCop
200
199
  # rubocop:enable Metrics/CyclomaticComplexity
201
200
 
202
201
  def condition_from_equality_node(node, target)
203
- lhs, _method, rhs = *node
204
- condition = condition_from_binary_op(lhs, rhs, target)
202
+ condition = condition_from_binary_op(node.receiver, node.first_argument, target)
205
203
  condition if condition && !class_reference?(condition)
206
204
  end
207
205
 
208
206
  def condition_from_match_node(node, target)
209
- lhs, _method, rhs = *node
210
- condition_from_binary_op(lhs, rhs, target)
207
+ condition_from_binary_op(node.receiver, node.first_argument, target)
211
208
  end
212
209
 
213
210
  def condition_from_include_or_cover_node(node, target)
@@ -263,11 +260,11 @@ module RuboCop
263
260
  def regexp_with_working_captures?(node)
264
261
  case node.type
265
262
  when :match_with_lvasgn
266
- lhs, _rhs = *node
263
+ lhs, _rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring
267
264
  node.loc.selector.source == '=~' && regexp_with_named_captures?(lhs)
268
265
  when :send
269
- lhs, method, rhs = *node
270
- method == :match && [lhs, rhs].any? { |n| regexp_with_named_captures?(n) }
266
+ node.method?(:match) &&
267
+ [node.receiver, node.first_argument].any? { |n| regexp_with_named_captures?(n) }
271
268
  end
272
269
  end
273
270
 
@@ -57,6 +57,9 @@ module RuboCop
57
57
 
58
58
  REGEXP = /(?<keyword>\S+).*#/.freeze
59
59
 
60
+ SUBCLASS_DEFINITION = /\A\s*class\s+\w+\s*<\s*\w+/.freeze
61
+ METHOD_DEFINITION = /\A\s*def\s/.freeze
62
+
60
63
  def on_new_investigation
61
64
  processed_source.comments.each do |comment|
62
65
  next unless offensive?(comment) && (match = source_line(comment).match(REGEXP))
@@ -93,7 +96,14 @@ module RuboCop
93
96
  end
94
97
 
95
98
  def rbs_inline_annotation?(line, comment)
96
- comment.text.start_with?('#:') && line.start_with?(/\A\s*def\s/)
99
+ case line
100
+ when SUBCLASS_DEFINITION
101
+ comment.text.start_with?(/#\[.+\]/)
102
+ when METHOD_DEFINITION
103
+ comment.text.start_with?('#:')
104
+ else
105
+ false
106
+ end
97
107
  end
98
108
  end
99
109
  end
@@ -33,24 +33,20 @@ module RuboCop
33
33
  branch.begin_type? ? Array(branch).last : branch
34
34
  end
35
35
 
36
- # rubocop:disable Metrics/AbcSize
37
36
  def lhs(node)
38
37
  case node.type
39
38
  when :send
40
39
  lhs_for_send(node)
41
- when :op_asgn
42
- "#{node.children[0].source} #{node.children[1]}= "
43
- when :and_asgn, :or_asgn
44
- "#{node.children[0].source} #{node.loc.operator.source} "
40
+ when :op_asgn, :and_asgn, :or_asgn
41
+ "#{node.assignment_node.source} #{node.operator}= "
45
42
  when :casgn
46
43
  lhs_for_casgn(node)
47
44
  when *ConditionalAssignment::VARIABLE_ASSIGNMENT_TYPES
48
- "#{node.children[0]} = "
45
+ "#{node.name} = "
49
46
  else
50
47
  node.source
51
48
  end
52
49
  end
53
- # rubocop:enable Metrics/AbcSize
54
50
 
55
51
  def indent(cop, source)
56
52
  conf = cop.config.for_cop(END_ALIGNMENT)
@@ -94,11 +90,12 @@ module RuboCop
94
90
  end
95
91
 
96
92
  def lhs_for_casgn(node)
97
- namespace = node.children[0]
98
- if namespace.nil? || namespace.cbase_type?
99
- "#{namespace&.source}#{node.children[1]} = "
93
+ if node.namespace.nil?
94
+ "#{node.name} = "
95
+ elsif node.namespace.cbase_type?
96
+ "::#{node.name} = "
100
97
  else
101
- "#{namespace.source}::#{node.children[1]} = "
98
+ "#{node.namespace.const_name}::#{node.name} = "
102
99
  end
103
100
  end
104
101
 
@@ -210,7 +207,6 @@ module RuboCop
210
207
  class ConditionalAssignment < Base
211
208
  include ConditionalAssignmentHelper
212
209
  include ConfigurableEnforcedStyle
213
- include IgnoredNode
214
210
  extend AutoCorrector
215
211
 
216
212
  MSG = 'Use the return of the conditional for variable assignment and comparison.'
@@ -317,12 +313,14 @@ module RuboCop
317
313
  end
318
314
 
319
315
  def assignment_node(node)
320
- *_variable, assignment = *node
316
+ assignment = node.send_type? ? node.last_argument : node.expression
321
317
 
322
318
  # ignore pseudo-assignments without rhs in for nodes
323
319
  return if node.parent&.for_type?
324
320
 
325
- assignment, = *assignment if assignment.begin_type? && assignment.children.one?
321
+ if assignment.begin_type? && assignment.children.one?
322
+ assignment = assignment.children.first
323
+ end
326
324
 
327
325
  assignment
328
326
  end
@@ -338,7 +336,7 @@ module RuboCop
338
336
  end
339
337
 
340
338
  def move_assignment_inside_condition(corrector, node)
341
- *_assignment, condition = *node
339
+ condition = node.send_type? ? node.last_argument : node.expression
342
340
 
343
341
  if ternary_condition?(condition)
344
342
  TernaryCorrector.move_assignment_inside_condition(corrector, node)
@@ -459,7 +457,7 @@ module RuboCop
459
457
  end
460
458
 
461
459
  def assignment(node)
462
- *_, condition = *node
460
+ condition = node.send_type? ? node.last_argument : node.expression
463
461
 
464
462
  node.source_range.begin.join(condition.source_range.begin)
465
463
  end
@@ -506,7 +504,7 @@ module RuboCop
506
504
  end
507
505
 
508
506
  def move_assignment_inside_condition(corrector, node)
509
- *_var, rhs = *node
507
+ rhs = node.send_type? ? node.last_argument : node.expression
510
508
  if_branch, else_branch = extract_branches(node)
511
509
  assignment = assignment(node)
512
510
 
@@ -537,8 +535,8 @@ module RuboCop
537
535
  end
538
536
 
539
537
  def extract_branches(node)
540
- *_var, rhs = *node
541
- condition, = *rhs if rhs.begin_type? && rhs.children.one?
538
+ rhs = node.send_type? ? node.last_argument : node.expression
539
+ condition = rhs.children.first if rhs.begin_type? && rhs.children.one?
542
540
  _condition, if_branch, else_branch = *(condition || rhs)
543
541
 
544
542
  [if_branch, else_branch]
@@ -567,7 +565,7 @@ module RuboCop
567
565
 
568
566
  def move_assignment_inside_condition(corrector, node)
569
567
  column = node.source_range.column
570
- *_var, condition = *node
568
+ condition = node.send_type? ? node.last_argument : node.expression
571
569
  assignment = assignment(node)
572
570
 
573
571
  corrector.remove(assignment)
@@ -618,7 +616,7 @@ module RuboCop
618
616
 
619
617
  def move_assignment_inside_condition(corrector, node)
620
618
  column = node.source_range.column
621
- *_var, condition = *node
619
+ condition = node.send_type? ? node.last_argument : node.expression
622
620
  assignment = assignment(node)
623
621
 
624
622
  corrector.remove(assignment)