rubocop 1.66.1 → 1.69.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (246) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +96 -12
  4. data/config/internal_affairs.yml +11 -0
  5. data/lib/rubocop/cached_data.rb +12 -4
  6. data/lib/rubocop/cli/command/auto_generate_config.rb +6 -7
  7. data/lib/rubocop/cli/command/execute_runner.rb +1 -1
  8. data/lib/rubocop/cli/command/lsp.rb +2 -2
  9. data/lib/rubocop/cli/command/version.rb +2 -2
  10. data/lib/rubocop/config_loader_resolver.rb +3 -3
  11. data/lib/rubocop/config_validator.rb +2 -1
  12. data/lib/rubocop/cop/autocorrect_logic.rb +22 -2
  13. data/lib/rubocop/cop/base.rb +7 -3
  14. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  15. data/lib/rubocop/cop/bundler/gem_version.rb +1 -0
  16. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  17. data/lib/rubocop/cop/cop.rb +8 -0
  18. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  19. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  20. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  21. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  22. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  23. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  24. data/lib/rubocop/cop/generator.rb +6 -0
  25. data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
  26. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  27. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  28. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +46 -0
  29. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  30. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +8 -1
  31. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  32. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
  33. data/lib/rubocop/cop/internal_affairs.rb +17 -0
  34. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +5 -1
  35. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -2
  36. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  37. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  38. data/lib/rubocop/cop/layout/block_alignment.rb +1 -2
  39. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  40. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
  41. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -3
  42. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +3 -4
  43. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +3 -1
  44. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  45. data/lib/rubocop/cop/layout/indentation_width.rb +11 -12
  46. data/lib/rubocop/cop/layout/leading_comment_space.rb +71 -1
  47. data/lib/rubocop/cop/layout/line_length.rb +118 -4
  48. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
  49. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  50. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
  51. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  52. data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -35
  53. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -2
  54. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  55. data/lib/rubocop/cop/layout/space_around_operators.rb +16 -17
  56. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  57. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -0
  58. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
  59. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
  60. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  61. data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
  62. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  63. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  64. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  65. data/lib/rubocop/cop/lint/circular_argument_reference.rb +6 -0
  66. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
  67. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  68. data/lib/rubocop/cop/lint/duplicate_set_element.rb +74 -0
  69. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  70. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  71. data/lib/rubocop/cop/lint/ensure_return.rb +1 -4
  72. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  73. data/lib/rubocop/cop/lint/float_comparison.rb +15 -7
  74. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -3
  75. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  76. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +10 -4
  77. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  78. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +8 -14
  79. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -0
  80. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  81. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +25 -2
  82. data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -5
  83. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
  84. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  85. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +8 -1
  86. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  87. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  88. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  89. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +106 -0
  90. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
  91. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -1
  92. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -6
  93. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  94. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +13 -8
  95. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  96. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  97. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  98. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  99. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +9 -0
  100. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +109 -41
  101. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  102. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  103. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  104. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +91 -0
  105. data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
  106. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  107. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  108. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  109. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  110. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
  111. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  112. data/lib/rubocop/cop/lint/void.rb +3 -2
  113. data/lib/rubocop/cop/metrics/class_length.rb +7 -7
  114. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +4 -1
  115. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  116. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -3
  117. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  118. data/lib/rubocop/cop/mixin/check_line_breakable.rb +10 -0
  119. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  120. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  121. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  122. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +3 -1
  123. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
  124. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  125. data/lib/rubocop/cop/mixin/range_help.rb +0 -1
  126. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -2
  127. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  128. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  129. data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
  130. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  131. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  132. data/lib/rubocop/cop/naming/inclusive_language.rb +12 -3
  133. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
  134. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  135. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -11
  136. data/lib/rubocop/cop/naming/variable_name.rb +3 -4
  137. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  138. data/lib/rubocop/cop/offense.rb +4 -5
  139. data/lib/rubocop/cop/security/compound_hash.rb +1 -0
  140. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  141. data/lib/rubocop/cop/style/access_modifier_declarations.rb +64 -25
  142. data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
  143. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  144. data/lib/rubocop/cop/style/arguments_forwarding.rb +46 -6
  145. data/lib/rubocop/cop/style/array_intersect.rb +5 -4
  146. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  147. data/lib/rubocop/cop/style/block_delimiters.rb +41 -5
  148. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  149. data/lib/rubocop/cop/style/collection_compact.rb +10 -10
  150. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  151. data/lib/rubocop/cop/style/combinable_loops.rb +7 -0
  152. data/lib/rubocop/cop/style/commented_keyword.rb +17 -1
  153. data/lib/rubocop/cop/style/conditional_assignment.rb +20 -22
  154. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  155. data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
  156. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  157. data/lib/rubocop/cop/style/endless_method.rb +1 -14
  158. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  159. data/lib/rubocop/cop/style/fetch_env_var.rb +1 -0
  160. data/lib/rubocop/cop/style/file_null.rb +73 -0
  161. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  162. data/lib/rubocop/cop/style/for.rb +0 -1
  163. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  164. data/lib/rubocop/cop/style/guard_clause.rb +16 -3
  165. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  166. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -0
  167. data/lib/rubocop/cop/style/hash_except.rb +19 -7
  168. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  169. data/lib/rubocop/cop/style/if_inside_else.rb +1 -2
  170. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -2
  171. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -7
  172. data/lib/rubocop/cop/style/inverse_methods.rb +0 -1
  173. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  174. data/lib/rubocop/cop/style/lambda.rb +1 -1
  175. data/lib/rubocop/cop/style/lambda_call.rb +3 -2
  176. data/lib/rubocop/cop/style/map_into_array.rb +59 -8
  177. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +13 -8
  178. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +7 -11
  179. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  180. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  181. data/lib/rubocop/cop/style/multiple_comparison.rb +28 -39
  182. data/lib/rubocop/cop/style/mutable_constant.rb +4 -5
  183. data/lib/rubocop/cop/style/negated_if_else_condition.rb +6 -4
  184. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  185. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  186. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  187. data/lib/rubocop/cop/style/not.rb +1 -1
  188. data/lib/rubocop/cop/style/object_then.rb +1 -0
  189. data/lib/rubocop/cop/style/one_line_conditional.rb +29 -4
  190. data/lib/rubocop/cop/style/operator_method_call.rb +25 -7
  191. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  192. data/lib/rubocop/cop/style/parallel_assignment.rb +8 -13
  193. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  194. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  195. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  196. data/lib/rubocop/cop/style/redundant_begin.rb +4 -0
  197. data/lib/rubocop/cop/style/redundant_condition.rb +37 -22
  198. data/lib/rubocop/cop/style/redundant_line_continuation.rb +24 -5
  199. data/lib/rubocop/cop/style/redundant_parentheses.rb +11 -13
  200. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +1 -0
  201. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  202. data/lib/rubocop/cop/style/redundant_self.rb +8 -15
  203. data/lib/rubocop/cop/style/redundant_self_assignment.rb +7 -5
  204. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  205. data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
  206. data/lib/rubocop/cop/style/require_order.rb +1 -1
  207. data/lib/rubocop/cop/style/rescue_modifier.rb +15 -4
  208. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
  209. data/lib/rubocop/cop/style/safe_navigation.rb +104 -50
  210. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  211. data/lib/rubocop/cop/style/select_by_regexp.rb +10 -7
  212. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  213. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  214. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  215. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  216. data/lib/rubocop/cop/style/single_line_do_end_block.rb +13 -3
  217. data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -3
  218. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  219. data/lib/rubocop/cop/style/string_concatenation.rb +13 -12
  220. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  221. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  222. data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
  223. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  224. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  225. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  226. data/lib/rubocop/cop/team.rb +8 -1
  227. data/lib/rubocop/cop/util.rb +1 -1
  228. data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
  229. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  230. data/lib/rubocop/cop/variable_force/variable.rb +5 -1
  231. data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
  232. data/lib/rubocop/cop/variable_force.rb +4 -10
  233. data/lib/rubocop/cops_documentation_generator.rb +90 -41
  234. data/lib/rubocop/file_finder.rb +9 -4
  235. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  236. data/lib/rubocop/lsp/runtime.rb +2 -0
  237. data/lib/rubocop/lsp/server.rb +0 -1
  238. data/lib/rubocop/rspec/expect_offense.rb +1 -0
  239. data/lib/rubocop/runner.rb +17 -6
  240. data/lib/rubocop/server/cache.rb +6 -1
  241. data/lib/rubocop/server/core.rb +1 -0
  242. data/lib/rubocop/target_ruby.rb +13 -13
  243. data/lib/rubocop/version.rb +28 -7
  244. data/lib/rubocop/yaml_duplication_checker.rb +20 -27
  245. data/lib/rubocop.rb +18 -0
  246. metadata +32 -14
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Common functionality for rewriting endless methods to normal method definitions
6
+ module EndlessMethodRewriter
7
+ def correct_to_multiline(corrector, node)
8
+ replacement = <<~RUBY.strip
9
+ def #{node.method_name}#{arguments(node)}
10
+ #{node.body.source}
11
+ end
12
+ RUBY
13
+
14
+ corrector.replace(node, replacement)
15
+ end
16
+
17
+ private
18
+
19
+ def arguments(node, missing = '')
20
+ node.arguments.any? ? node.arguments.source : missing
21
+ end
22
+ end
23
+ end
24
+ end
@@ -29,7 +29,9 @@ module RuboCop
29
29
  end
30
30
 
31
31
  def uninterpolated_string?(node)
32
- node.str_type? || (node.dstr_type? && node.each_descendant(:begin).none?)
32
+ node.str_type? || (
33
+ node.dstr_type? && node.each_descendant(:begin, :ivar, :cvar, :gvar).none?
34
+ )
33
35
  end
34
36
 
35
37
  def uninterpolated_heredoc?(node)
@@ -121,12 +121,10 @@ module RuboCop
121
121
 
122
122
  def indented_keyword_expression(node)
123
123
  if node.for_type?
124
- expression = node.collection
124
+ node.collection
125
125
  else
126
- expression, = *node
126
+ node.children.first
127
127
  end
128
-
129
- expression
130
128
  end
131
129
 
132
130
  def argument_in_method_call(node, kind) # rubocop:todo Metrics/CyclomaticComplexity
@@ -187,12 +185,10 @@ module RuboCop
187
185
 
188
186
  def assignment_rhs(node)
189
187
  case node.type
190
- when :casgn then _scope, _lhs, rhs = *node
191
- when :op_asgn then _lhs, _op, rhs = *node
192
- when :send, :csend then rhs = node.last_argument
193
- else _lhs, rhs = *node
188
+ when :casgn, :op_asgn then node.rhs
189
+ when :send, :csend then node.last_argument
190
+ else node.children.last
194
191
  end
195
- rhs
196
192
  end
197
193
 
198
194
  def not_for_this_cop?(node)
@@ -15,7 +15,7 @@ module RuboCop
15
15
  parent = node.parent
16
16
 
17
17
  parent&.send_type? && parent.arguments.include?(node) &&
18
- !parent.parenthesized? && parent&.block_literal?
18
+ !parent.parenthesized? && parent.block_literal?
19
19
  end
20
20
 
21
21
  # Override to determine values that are invalid in a percent array
@@ -56,7 +56,6 @@ module RuboCop
56
56
  range: NOT_GIVEN, side: :both, newlines: true,
57
57
  whitespace: false, continuations: false,
58
58
  buffer: @processed_source.buffer)
59
-
60
59
  range = range_positional unless range_positional == NOT_GIVEN
61
60
 
62
61
  src = buffer.source
@@ -5,7 +5,6 @@ module RuboCop
5
5
  # Common functionality for modifier cops.
6
6
  module StatementModifier
7
7
  include LineLengthHelp
8
- include RangeHelp
9
8
 
10
9
  private
11
10
 
@@ -65,7 +64,9 @@ module RuboCop
65
64
  end
66
65
 
67
66
  def method_source(if_body)
68
- range_between(if_body.source_range.begin_pos, if_body.loc.selector.end_pos).source
67
+ end_range = if_body.implicit_call? ? if_body.loc.dot.end : if_body.loc.selector
68
+
69
+ if_body.source_range.begin.join(end_range).source
69
70
  end
70
71
 
71
72
  def first_line_comment(node)
@@ -8,12 +8,28 @@ module RuboCop
8
8
  @minimum_target_ruby_version
9
9
  end
10
10
 
11
+ def required_maximum_ruby_version
12
+ @maximum_target_ruby_version
13
+ end
14
+
11
15
  def minimum_target_ruby_version(version)
12
16
  @minimum_target_ruby_version = version
13
17
  end
14
18
 
19
+ def maximum_target_ruby_version(version)
20
+ @maximum_target_ruby_version = version
21
+ end
22
+
15
23
  def support_target_ruby_version?(version)
16
- required_minimum_ruby_version <= version
24
+ # By default, no minimum or maximum versions of ruby are required
25
+ # to run any cop. In order to do a simple numerical comparison of
26
+ # the requested version against any requirements, we use 0 and
27
+ # Infinity as the default values to indicate no minimum (0) and no
28
+ # maximum (Infinity).
29
+ min = required_minimum_ruby_version || 0
30
+ max = required_maximum_ruby_version || Float::INFINITY
31
+
32
+ min <= version && max >= version
17
33
  end
18
34
  end
19
35
  end
@@ -3,13 +3,13 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Naming
6
- # Makes sure that accessor methods are named properly. Applies
7
- # to both instance and class methods.
6
+ # Avoid prefixing accessor method names with `get_` or `set_`.
7
+ # Applies to both instance and class methods.
8
8
  #
9
- # NOTE: Offenses are only registered for methods with the expected
10
- # arity. Getters (`get_attribute`) must have no arguments to be
11
- # registered, and setters (`set_attribute(value)`) must have exactly
12
- # one.
9
+ # NOTE: Method names starting with `get_` or `set_` only register an offense
10
+ # when the methods match the expected arity for getters and setters respectively.
11
+ # Getters (`get_attribute`) must have no arguments to be registered,
12
+ # and setters (`set_attribute(value)`) must have exactly one.
13
13
  #
14
14
  # @example
15
15
  # # bad
@@ -48,7 +48,7 @@ module RuboCop
48
48
  MSG = 'Use %<style>s block forwarding.'
49
49
 
50
50
  def self.autocorrect_incompatible_with
51
- [Lint::AmbiguousOperator, Style::ArgumentsForwarding]
51
+ [Lint::AmbiguousOperator, Style::ArgumentsForwarding, Style::ExplicitBlockArgument]
52
52
  end
53
53
 
54
54
  def on_def(node)
@@ -31,12 +31,11 @@ module RuboCop
31
31
  PATTERN
32
32
 
33
33
  def on_casgn(node)
34
- if node.parent&.or_asgn_type?
35
- lhs, value = *node.parent
36
- _scope, const_name = *lhs
37
- else
38
- _scope, const_name, value = *node
39
- end
34
+ value = if node.parent&.or_asgn_type?
35
+ node.parent.expression
36
+ else
37
+ node.expression
38
+ end
40
39
 
41
40
  # We cannot know the result of method calls like
42
41
  # NewClass = something_that_returns_a_class
@@ -46,7 +45,7 @@ module RuboCop
46
45
  # SomeClass = Class.new(...)
47
46
  # SomeClass = Struct.new(...)
48
47
  return if allowed_assignment?(value)
49
- return if SNAKE_CASE.match?(const_name)
48
+ return if SNAKE_CASE.match?(node.name)
50
49
 
51
50
  add_offense(node.loc.name)
52
51
  end
@@ -37,8 +37,6 @@ module RuboCop
37
37
  #
38
38
  # anything/using_snake_case.rake
39
39
  class FileName < Base
40
- include RangeHelp
41
-
42
40
  MSG_SNAKE_CASE = 'The name of this source file (`%<basename>s`) should use snake_case.'
43
41
  MSG_NO_DEFINITION = '`%<basename>s` should define a class or module called `%<namespace>s`.'
44
42
  MSG_REGEX = '`%<basename>s` should match `%<regex>s`.'
@@ -116,9 +116,9 @@ module RuboCop
116
116
  add_offense(range, message: create_message(word)) do |corrector|
117
117
  suggestions = find_flagged_term(word)['Suggestions']
118
118
 
119
- next unless suggestions.is_a?(String)
120
-
121
- corrector.replace(range, suggestions)
119
+ if (preferred_term = preferred_sole_term(suggestions))
120
+ corrector.replace(range, preferred_term)
121
+ end
122
122
  end
123
123
  end
124
124
  end
@@ -157,6 +157,15 @@ module RuboCop
157
157
  set_regexes(flagged_term_strings, allowed_strings)
158
158
  end
159
159
 
160
+ def preferred_sole_term(suggestions)
161
+ case suggestions
162
+ when Array
163
+ suggestions.one? && preferred_sole_term(suggestions.first)
164
+ when String
165
+ suggestions
166
+ end
167
+ end
168
+
160
169
  def extract_regexp(term, term_definition)
161
170
  return term_definition['Regex'] if term_definition['Regex']
162
171
  return /(?:\b|(?<=[\W_]))#{term}(?:\b|(?=[\W_]))/ if term_definition['WholeWord']
@@ -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
@@ -88,7 +88,7 @@ module RuboCop
88
88
  next if allowed_method_name?(method_name.to_s, prefix)
89
89
 
90
90
  add_offense(
91
- node.first_argument.source_range,
91
+ node.first_argument,
92
92
  message: message(method_name, expected_name(method_name.to_s, prefix))
93
93
  )
94
94
  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
@@ -43,11 +43,10 @@ module RuboCop
43
43
  # @!attribute [r] cop_name
44
44
  #
45
45
  # @return [String]
46
- # a cop class name without department.
47
- # i.e. type of the violation.
46
+ # the cop name as a String for which this offense is for.
48
47
  #
49
48
  # @example
50
- # 'LineLength'
49
+ # 'Layout/LineLength'
51
50
  attr_reader :cop_name
52
51
 
53
52
  # @api private
@@ -97,8 +96,8 @@ module RuboCop
97
96
  # @!attribute [r] correctable?
98
97
  #
99
98
  # @return [Boolean]
100
- # whether this offense can be automatically corrected via
101
- # autocorrect or a todo.
99
+ # whether this offense can be automatically corrected via autocorrect.
100
+ # This includes todo comments, for example when requested with `--disable-uncorrectable`.
102
101
  def correctable?
103
102
  @status != :unsupported
104
103
  end
@@ -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')
@@ -68,6 +68,9 @@ module RuboCop
68
68
  # class Foo
69
69
  #
70
70
  # private :bar, :baz
71
+ # private *%i[qux quux]
72
+ # private *METHOD_NAMES
73
+ # private *private_methods
71
74
  #
72
75
  # end
73
76
  #
@@ -76,6 +79,9 @@ module RuboCop
76
79
  # class Foo
77
80
  #
78
81
  # private :bar, :baz
82
+ # private *%i[qux quux]
83
+ # private *METHOD_NAMES
84
+ # private *private_methods
79
85
  #
80
86
  # end
81
87
  #
@@ -128,20 +134,19 @@ module RuboCop
128
134
 
129
135
  # @!method access_modifier_with_symbol?(node)
130
136
  def_node_matcher :access_modifier_with_symbol?, <<~PATTERN
131
- (send nil? {:private :protected :public :module_function} (sym _))
137
+ (send nil? {:private :protected :public :module_function}
138
+ {(sym _)+ (splat {#percent_symbol_array? const send})}
139
+ )
132
140
  PATTERN
133
141
 
134
142
  # @!method access_modifier_with_attr?(node)
135
143
  def_node_matcher :access_modifier_with_attr?, <<~PATTERN
136
144
  (send nil? {:private :protected :public :module_function}
137
- (send nil? {:attr :attr_reader :attr_writer :attr_accessor} _))
145
+ (send nil? {:attr :attr_reader :attr_writer :attr_accessor} _+))
138
146
  PATTERN
139
147
 
140
148
  def on_send(node)
141
- return unless node.access_modifier?
142
- return if ALLOWED_NODE_TYPES.include?(node.parent&.type)
143
- return if allow_modifiers_on_symbols?(node)
144
- return if allow_modifiers_on_attrs?(node)
149
+ return if allowed?(node)
145
150
 
146
151
  if offense?(node)
147
152
  add_offense(node.loc.selector) do |corrector|
@@ -155,21 +160,32 @@ module RuboCop
155
160
 
156
161
  private
157
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
+
158
170
  def autocorrect(corrector, node)
159
171
  case style
160
172
  when :group
161
- def_node = find_corresponding_def_node(node)
162
- return unless def_node
173
+ def_nodes = find_corresponding_def_nodes(node)
174
+ return unless def_nodes.any?
163
175
 
164
- replace_def(corrector, node, def_node)
176
+ replace_defs(corrector, node, def_nodes)
165
177
  when :inline
166
- remove_node(corrector, node)
178
+ remove_nodes(corrector, node)
167
179
  select_grouped_def_nodes(node).each do |grouped_def_node|
168
180
  insert_inline_modifier(corrector, grouped_def_node, node.method_name)
169
181
  end
170
182
  end
171
183
  end
172
184
 
185
+ def percent_symbol_array?(node)
186
+ node.array_type? && node.percent_literal?(:symbol)
187
+ end
188
+
173
189
  def allow_modifiers_on_symbols?(node)
174
190
  cop_config['AllowModifiersOnSymbols'] && access_modifier_with_symbol?(node)
175
191
  end
@@ -180,10 +196,17 @@ module RuboCop
180
196
 
181
197
  def offense?(node)
182
198
  (group_style? && access_modifier_is_inlined?(node) &&
183
- !right_siblings_same_inline_method?(node)) ||
199
+ !node.parent&.if_type? && !right_siblings_same_inline_method?(node)) ||
184
200
  (inline_style? && access_modifier_is_not_inlined?(node))
185
201
  end
186
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
+
187
210
  def group_style?
188
211
  style == :group
189
212
  end
@@ -202,7 +225,11 @@ module RuboCop
202
225
 
203
226
  def right_siblings_same_inline_method?(node)
204
227
  node.right_siblings.any? do |sibling|
205
- 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?
206
233
  end
207
234
  end
208
235
 
@@ -216,14 +243,22 @@ module RuboCop
216
243
  end
217
244
  end
218
245
 
219
- def find_corresponding_def_node(node)
246
+ def find_corresponding_def_nodes(node)
220
247
  if access_modifier_with_symbol?(node)
221
- method_name = node.first_argument.value
222
- node.parent.each_child_node(:def).find do |child|
223
- 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)
224
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 : []
225
260
  else
226
- node.first_argument
261
+ [node.first_argument]
227
262
  end
228
263
  end
229
264
 
@@ -241,8 +276,8 @@ module RuboCop
241
276
  end.select(&:def_type?)
242
277
  end
243
278
 
244
- def replace_def(corrector, node, def_node)
245
- source = def_source(node, def_node)
279
+ def replace_defs(corrector, node, def_nodes)
280
+ source = def_source(node, def_nodes)
246
281
  argument_less_modifier_node = find_argument_less_modifier_node(node)
247
282
  if argument_less_modifier_node
248
283
  corrector.insert_after(argument_less_modifier_node, "\n\n#{source}")
@@ -254,20 +289,24 @@ module RuboCop
254
289
  return
255
290
  end
256
291
 
257
- remove_node(corrector, def_node)
258
- remove_node(corrector, node)
292
+ remove_nodes(corrector, *def_nodes, node)
259
293
  end
260
294
 
261
295
  def insert_inline_modifier(corrector, node, modifier_name)
262
296
  corrector.insert_before(node, "#{modifier_name} ")
263
297
  end
264
298
 
265
- def remove_node(corrector, node)
266
- 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
267
303
  end
268
304
 
269
- def def_source(node, def_node)
270
- [*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")
271
310
  end
272
311
  end
273
312
  end
@@ -10,6 +10,9 @@ module RuboCop
10
10
  # NOTE: If there is a method call before the accessor method it is always allowed
11
11
  # as it might be intended like Sorbet.
12
12
  #
13
+ # NOTE: If there is a RBS::Inline annotation comment just after the accessor method
14
+ # it is always allowed.
15
+ #
13
16
  # @example EnforcedStyle: grouped (default)
14
17
  # # bad
15
18
  # class Foo
@@ -92,7 +95,7 @@ module RuboCop
92
95
  comment_line?(processed_source[node.first_line - 2])
93
96
  end
94
97
 
95
- # rubocop:disable Metrics/CyclomaticComplexity
98
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
96
99
  def groupable_accessor?(node)
97
100
  return true unless (previous_expression = node.left_siblings.last)
98
101
 
@@ -105,11 +108,16 @@ module RuboCop
105
108
 
106
109
  return true unless previous_expression.send_type?
107
110
 
111
+ # Accessors with RBS::Inline annotations shouldn't be groupable.
112
+ return false if processed_source.comments.any? do |c|
113
+ same_line?(c, previous_expression) && c.text.start_with?('#:')
114
+ end
115
+
108
116
  previous_expression.attribute_accessor? ||
109
117
  previous_expression.access_modifier? ||
110
118
  node.first_line - previous_expression.last_line > 1 # there is a space between nodes
111
119
  end
112
- # rubocop:enable Metrics/CyclomaticComplexity
120
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
113
121
 
114
122
  def class_send_elements(class_node)
115
123
  class_def = class_node.body