rubocop 1.67.0 → 1.75.6

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 (471) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +266 -47
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +3 -1
  7. data/lib/rubocop/cached_data.rb +12 -4
  8. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  9. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  10. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  11. data/lib/rubocop/cli/command/version.rb +2 -2
  12. data/lib/rubocop/cli.rb +1 -1
  13. data/lib/rubocop/comment_config.rb +2 -2
  14. data/lib/rubocop/config.rb +52 -10
  15. data/lib/rubocop/config_loader.rb +52 -9
  16. data/lib/rubocop/config_loader_resolver.rb +36 -10
  17. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  18. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  19. data/lib/rubocop/config_obsoletion.rb +46 -2
  20. data/lib/rubocop/config_validator.rb +25 -14
  21. data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
  22. data/lib/rubocop/cop/base.rb +7 -1
  23. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  24. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  25. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  26. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  27. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  28. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  29. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  30. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  31. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  32. data/lib/rubocop/cop/generator.rb +6 -0
  33. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  34. data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
  35. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  36. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  37. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  38. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  39. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  40. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  41. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  42. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +230 -0
  43. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
  44. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  45. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  46. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  47. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  48. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  49. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  50. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  51. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  52. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  53. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  54. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  55. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  56. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  57. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  58. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  59. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  60. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  61. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  62. data/lib/rubocop/cop/layout/class_structure.rb +9 -9
  63. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
  64. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  65. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  66. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  67. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  68. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  69. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +30 -4
  70. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  71. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  72. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  73. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  74. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  75. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  76. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  77. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  78. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  79. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  80. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  81. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  82. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  83. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  84. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  85. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  86. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  87. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  88. data/lib/rubocop/cop/layout/line_length.rb +123 -4
  89. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  90. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  91. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  92. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  93. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  94. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  95. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  96. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
  97. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  98. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  99. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
  100. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  101. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  102. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  103. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  104. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  105. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  106. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  107. data/lib/rubocop/cop/layout/space_around_operators.rb +23 -21
  108. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  109. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  110. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  111. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  112. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -1
  113. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  114. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  115. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  116. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  117. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  118. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  119. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  120. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  121. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  122. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  123. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  124. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  125. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  126. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  127. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  128. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
  129. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  130. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  131. data/lib/rubocop/cop/lint/duplicate_methods.rb +46 -19
  132. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  133. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  134. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  135. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  136. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  137. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  138. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  139. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  140. data/lib/rubocop/cop/lint/float_comparison.rb +20 -14
  141. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  142. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  143. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  144. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  145. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  146. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  147. data/lib/rubocop/cop/lint/literal_as_condition.rb +118 -9
  148. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  149. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  150. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  151. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  152. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  153. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  154. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  155. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  156. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  157. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  158. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  159. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  160. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  161. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  162. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  163. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  164. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  165. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  166. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  167. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  168. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  169. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  170. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
  171. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  172. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  173. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  174. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  175. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  176. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  177. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  178. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  179. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  180. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  181. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  182. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  183. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  184. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  185. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +8 -1
  186. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  187. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  188. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  189. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  190. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  191. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  192. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  193. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  194. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  195. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  196. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  197. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  198. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  199. data/lib/rubocop/cop/lint/useless_access_modifier.rb +5 -4
  200. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  201. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  202. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  203. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  204. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  205. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  206. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  207. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  208. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  209. data/lib/rubocop/cop/lint/void.rb +16 -12
  210. data/lib/rubocop/cop/message_annotator.rb +7 -3
  211. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  212. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  213. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  214. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  215. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  216. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  217. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  218. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  219. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  220. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  221. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  222. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  223. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  224. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  225. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  226. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  227. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  228. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  229. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  230. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  231. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  232. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  233. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  234. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +3 -2
  235. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  236. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  237. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  238. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  239. data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
  240. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  241. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  242. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  243. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  244. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  245. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  246. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  247. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  248. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  249. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  250. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  251. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  252. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  253. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  254. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  255. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  256. data/lib/rubocop/cop/naming/method_name.rb +64 -8
  257. data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
  258. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  259. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  260. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  261. data/lib/rubocop/cop/offense.rb +2 -3
  262. data/lib/rubocop/cop/registry.rb +9 -6
  263. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  264. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  265. data/lib/rubocop/cop/style/access_modifier_declarations.rb +86 -28
  266. data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
  267. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  268. data/lib/rubocop/cop/style/and_or.rb +1 -1
  269. data/lib/rubocop/cop/style/arguments_forwarding.rb +47 -28
  270. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  271. data/lib/rubocop/cop/style/array_intersect.rb +42 -30
  272. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  273. data/lib/rubocop/cop/style/block_delimiters.rb +43 -25
  274. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  275. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  276. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  277. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  278. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  279. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  280. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  281. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  282. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  283. data/lib/rubocop/cop/style/conditional_assignment.rb +39 -27
  284. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  285. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  286. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  287. data/lib/rubocop/cop/style/documentation.rb +1 -1
  288. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  289. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  290. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  291. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  292. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  293. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  294. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  295. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  296. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  297. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  298. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  299. data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
  300. data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
  301. data/lib/rubocop/cop/style/file_null.rb +89 -0
  302. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  303. data/lib/rubocop/cop/style/float_division.rb +8 -4
  304. data/lib/rubocop/cop/style/for.rb +1 -1
  305. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  306. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  307. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  308. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  309. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  310. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  311. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  312. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  313. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  314. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  315. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  316. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  317. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  318. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  319. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  320. data/lib/rubocop/cop/style/if_unless_modifier.rb +25 -5
  321. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  322. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  323. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  324. data/lib/rubocop/cop/style/inverse_methods.rb +15 -12
  325. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  326. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  327. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  328. data/lib/rubocop/cop/style/it_block_parameter.rb +100 -0
  329. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  330. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  331. data/lib/rubocop/cop/style/lambda.rb +1 -0
  332. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  333. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  334. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  335. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  336. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  337. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +27 -17
  338. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  339. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  340. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  341. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  342. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  343. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  344. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  345. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  346. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  347. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  348. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  349. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  350. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  351. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  352. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  353. data/lib/rubocop/cop/style/next.rb +44 -0
  354. data/lib/rubocop/cop/style/not.rb +1 -1
  355. data/lib/rubocop/cop/style/object_then.rb +15 -15
  356. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  357. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  358. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  359. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  360. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  361. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  362. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  363. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  364. data/lib/rubocop/cop/style/proc.rb +2 -2
  365. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  366. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  367. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  368. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  369. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  370. data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
  371. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  372. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  373. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  374. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  375. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  376. data/lib/rubocop/cop/style/redundant_format.rb +257 -0
  377. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
  378. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  379. data/lib/rubocop/cop/style/redundant_line_continuation.rb +54 -18
  380. data/lib/rubocop/cop/style/redundant_parentheses.rb +56 -26
  381. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  382. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  383. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  384. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  385. data/lib/rubocop/cop/style/redundant_self.rb +9 -15
  386. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  387. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  388. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  389. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  390. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  391. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  392. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  393. data/lib/rubocop/cop/style/safe_navigation.rb +32 -5
  394. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  395. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  396. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  397. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  398. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  399. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  400. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  401. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  402. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  403. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  404. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  405. data/lib/rubocop/cop/style/sole_nested_conditional.rb +42 -106
  406. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  407. data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
  408. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  409. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  410. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  411. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  412. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  413. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  414. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  415. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  416. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  417. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  418. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  419. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  420. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  421. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  422. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  423. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  424. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  425. data/lib/rubocop/cop/util.rb +12 -5
  426. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  427. data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
  428. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  429. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  430. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  431. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  432. data/lib/rubocop/cop/variable_force.rb +5 -11
  433. data/lib/rubocop/cops_documentation_generator.rb +50 -25
  434. data/lib/rubocop/directive_comment.rb +45 -11
  435. data/lib/rubocop/ext/regexp_node.rb +0 -1
  436. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
  437. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  438. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  439. data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
  440. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  441. data/lib/rubocop/lsp/logger.rb +2 -2
  442. data/lib/rubocop/lsp/routes.rb +7 -23
  443. data/lib/rubocop/lsp/runtime.rb +18 -50
  444. data/lib/rubocop/lsp/server.rb +0 -2
  445. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  446. data/lib/rubocop/magic_comment.rb +11 -3
  447. data/lib/rubocop/options.rb +28 -12
  448. data/lib/rubocop/path_util.rb +15 -8
  449. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  450. data/lib/rubocop/plugin/load_error.rb +26 -0
  451. data/lib/rubocop/plugin/loader.rb +100 -0
  452. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  453. data/lib/rubocop/plugin.rb +46 -0
  454. data/lib/rubocop/rake_task.rb +4 -1
  455. data/lib/rubocop/result_cache.rb +13 -13
  456. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  457. data/lib/rubocop/rspec/expect_offense.rb +6 -2
  458. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  459. data/lib/rubocop/rspec/support.rb +4 -2
  460. data/lib/rubocop/runner.rb +26 -15
  461. data/lib/rubocop/server/cache.rb +47 -11
  462. data/lib/rubocop/server/cli.rb +2 -2
  463. data/lib/rubocop/target_finder.rb +7 -2
  464. data/lib/rubocop/target_ruby.rb +17 -2
  465. data/lib/rubocop/version.rb +53 -12
  466. data/lib/rubocop.rb +32 -1
  467. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  468. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  469. metadata +79 -20
  470. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  471. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -13,6 +13,20 @@ module RuboCop
13
13
  # The default variable name is `block`. If the name is already in use, it will not be
14
14
  # autocorrected.
15
15
  #
16
+ # [NOTE]
17
+ # ====
18
+ # Because of a bug in Ruby 3.3.0, when a block is referenced inside of another block,
19
+ # no offense will be registered until Ruby 3.4:
20
+ #
21
+ # [source,ruby]
22
+ # ----
23
+ # def foo(&block)
24
+ # # Using an anonymous block would be a syntax error on Ruby 3.3.0
25
+ # block_method { bar(&block) }
26
+ # end
27
+ # ----
28
+ # ====
29
+ #
16
30
  # @example EnforcedStyle: anonymous (default)
17
31
  #
18
32
  # # bad
@@ -48,7 +62,7 @@ module RuboCop
48
62
  MSG = 'Use %<style>s block forwarding.'
49
63
 
50
64
  def self.autocorrect_incompatible_with
51
- [Lint::AmbiguousOperator, Style::ArgumentsForwarding]
65
+ [Lint::AmbiguousOperator, Style::ArgumentsForwarding, Style::ExplicitBlockArgument]
52
66
  end
53
67
 
54
68
  def on_def(node)
@@ -90,21 +104,11 @@ module RuboCop
90
104
  last_argument.source == block_pass_node.source
91
105
  end
92
106
 
93
- # Prevents the following syntax error:
94
- #
95
- # # foo.rb
96
- # def foo(&)
97
- # block_method do
98
- # bar(&)
99
- # end
100
- # end
101
- #
102
- # $ ruby -vc foo.rb
103
- # ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
104
- # foo.rb: foo.rb:4: anonymous block parameter is also used within block (SyntaxError)
105
- #
107
+ # Ruby 3.3.0 had a bug where accessing an anonymous block argument inside of a block
108
+ # was a syntax error in unambiguous cases: https://bugs.ruby-lang.org/issues/20090
109
+ # We disallow this also for earlier Ruby versions so that code is forwards compatible.
106
110
  def invalidates_syntax?(block_pass_node)
107
- block_pass_node.each_ancestor(:block, :numblock).any?
111
+ target_ruby_version <= 3.3 && block_pass_node.each_ancestor(:any_block).any?
108
112
  end
109
113
 
110
114
  def use_kwarg_in_method_definition?(node)
@@ -138,7 +142,7 @@ module RuboCop
138
142
  def use_block_argument_as_local_variable?(node, last_argument)
139
143
  return false if node.body.nil?
140
144
 
141
- node.body.each_descendant(:lvar, :lvasgn).any? do |lvar|
145
+ node.body.each_node(:lvar, :lvasgn).any? do |lvar|
142
146
  !lvar.parent.block_pass_type? && lvar.node_parts[0].to_s == last_argument
143
147
  end
144
148
  end
@@ -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`.'
@@ -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
  )
@@ -242,7 +242,7 @@ module RuboCop
242
242
  def find_definition(node)
243
243
  # Methods can be defined in a `def` or `defs`,
244
244
  # or dynamically via a `block` node.
245
- node.each_ancestor(:def, :defs, :block).each do |ancestor|
245
+ node.each_ancestor(:any_def, :block).each do |ancestor|
246
246
  method_node, method_name = method_definition?(ancestor)
247
247
  return [method_node, method_name] if method_node
248
248
  end
@@ -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
@@ -6,14 +6,31 @@ module RuboCop
6
6
  # Makes sure that all methods use the configured style,
7
7
  # snake_case or camelCase, for their names.
8
8
  #
9
- # This cop has `AllowedPatterns` configuration option.
9
+ # Method names matching patterns are always allowed.
10
10
  #
11
- # Naming/MethodName:
12
- # AllowedPatterns:
13
- # - '\AonSelectionBulkChange\z'
14
- # - '\AonSelectionCleared\z'
11
+ # The cop can be configured with `AllowedPatterns` to allow certain regexp patterns:
15
12
  #
16
- # Method names matching patterns are always allowed.
13
+ # [source,yaml]
14
+ # ----
15
+ # Naming/MethodName:
16
+ # AllowedPatterns:
17
+ # - '\AonSelectionBulkChange\z'
18
+ # - '\AonSelectionCleared\z'
19
+ # ----
20
+ #
21
+ # As well, you can also forbid specific method names or regexp patterns
22
+ # using `ForbiddenIdentifiers` or `ForbiddenPatterns`:
23
+ #
24
+ # [source,yaml]
25
+ # ----
26
+ # Naming/MethodName:
27
+ # ForbiddenIdentifiers:
28
+ # - 'def'
29
+ # - 'super'
30
+ # ForbiddenPatterns:
31
+ # - '_v1\z'
32
+ # - '_gen1\z'
33
+ # ----
17
34
  #
18
35
  # @example EnforcedStyle: snake_case (default)
19
36
  # # bad
@@ -28,12 +45,26 @@ module RuboCop
28
45
  #
29
46
  # # good
30
47
  # def fooBar; end
48
+ #
49
+ # @example ForbiddenIdentifiers: ['def', 'super']
50
+ # # bad
51
+ # def def; end
52
+ # def super; end
53
+ #
54
+ # @example ForbiddenPatterns: ['_v1\z', '_gen1\z']
55
+ # # bad
56
+ # def release_v1; end
57
+ # def api_gen1; end
58
+ #
31
59
  class MethodName < Base
32
60
  include ConfigurableNaming
33
61
  include AllowedPattern
34
62
  include RangeHelp
63
+ include ForbiddenIdentifiers
64
+ include ForbiddenPattern
35
65
 
36
66
  MSG = 'Use %<style>s for method names.'
67
+ MSG_FORBIDDEN = '`%<identifier>s` is forbidden, use another method name instead.'
37
68
 
38
69
  # @!method sym_name(node)
39
70
  def_node_matcher :sym_name, '(sym $_name)'
@@ -48,19 +79,44 @@ module RuboCop
48
79
  name = attr_name(name_item)
49
80
  next if !name || matches_allowed_pattern?(name)
50
81
 
51
- check_name(node, name, range_position(node))
82
+ if forbidden_name?(name.to_s)
83
+ register_forbidden_name(node)
84
+ else
85
+ check_name(node, name, range_position(node))
86
+ end
52
87
  end
53
88
  end
54
89
 
55
90
  def on_def(node)
56
91
  return if node.operator_method? || matches_allowed_pattern?(node.method_name)
57
92
 
58
- check_name(node, node.method_name, node.loc.name)
93
+ if forbidden_name?(node.method_name.to_s)
94
+ register_forbidden_name(node)
95
+ else
96
+ check_name(node, node.method_name, node.loc.name)
97
+ end
59
98
  end
60
99
  alias on_defs on_def
61
100
 
62
101
  private
63
102
 
103
+ def forbidden_name?(name)
104
+ forbidden_identifier?(name) || forbidden_pattern?(name)
105
+ end
106
+
107
+ def register_forbidden_name(node)
108
+ if node.any_def_type?
109
+ name_node = node.loc.name
110
+ method_name = node.method_name
111
+ else
112
+ attrs = node.attribute_accessor?
113
+ name_node = attrs.last.last
114
+ method_name = attr_name(name_node)
115
+ end
116
+ message = format(MSG_FORBIDDEN, identifier: method_name)
117
+ add_offense(name_node, message: message)
118
+ end
119
+
64
120
  def attr_name(name_item)
65
121
  sym_name(name_item) || str_name(name_item)
66
122
  end
@@ -17,6 +17,10 @@ module RuboCop
17
17
  # they end with a `?`. These methods should be changed to remove the
18
18
  # prefix.
19
19
  #
20
+ # When `UseSorbetSigs` set to true (optional), the cop will only report
21
+ # offenses if the method has a Sorbet `sig` with a return type of
22
+ # `T::Boolean`. Dynamic methods are not supported with this configuration.
23
+ #
20
24
  # @example NamePrefix: ['is_', 'has_', 'have_'] (default)
21
25
  # # bad
22
26
  # def is_even(value)
@@ -58,6 +62,30 @@ module RuboCop
58
62
  # def is_even?(value)
59
63
  # end
60
64
  #
65
+ # @example UseSorbetSigs: false (default)
66
+ # # bad
67
+ # sig { returns(String) }
68
+ # def is_this_thing_on
69
+ # "yes"
70
+ # end
71
+ #
72
+ # # good - Sorbet signature is not evaluated
73
+ # sig { returns(String) }
74
+ # def is_this_thing_on?
75
+ # "yes"
76
+ # end
77
+ #
78
+ # @example UseSorbetSigs: true
79
+ # # bad
80
+ # sig { returns(T::Boolean) }
81
+ # def odd(value)
82
+ # end
83
+ #
84
+ # # good
85
+ # sig { returns(T::Boolean) }
86
+ # def odd?(value)
87
+ # end
88
+ #
61
89
  # @example MethodDefinitionMacros: ['define_method', 'define_singleton_method'] (default)
62
90
  # # bad
63
91
  # define_method(:is_even) { |value| }
@@ -100,6 +128,7 @@ module RuboCop
100
128
  method_name = node.method_name.to_s
101
129
 
102
130
  next if allowed_method_name?(method_name, prefix)
131
+ next if use_sorbet_sigs? && !sorbet_sig?(node, return_type: 'T::Boolean')
103
132
 
104
133
  add_offense(
105
134
  node.loc.name,
@@ -121,6 +150,17 @@ module RuboCop
121
150
 
122
151
  private
123
152
 
153
+ # @!method sorbet_return_type(node)
154
+ def_node_matcher :sorbet_return_type, <<~PATTERN
155
+ (block (send nil? :sig) args (send _ :returns $_type))
156
+ PATTERN
157
+
158
+ def sorbet_sig?(node, return_type: nil)
159
+ return false unless (type = sorbet_return_type(node.left_sibling))
160
+
161
+ type.source == return_type
162
+ end
163
+
124
164
  def allowed_method_name?(method_name, prefix)
125
165
  !(method_name.start_with?(prefix) && # cheap check to avoid allocating Regexp
126
166
  method_name.match?(/^#{prefix}[^0-9]/)) ||
@@ -151,6 +191,10 @@ module RuboCop
151
191
  cop_config['NamePrefix']
152
192
  end
153
193
 
194
+ def use_sorbet_sigs?
195
+ cop_config['UseSorbetSigs']
196
+ end
197
+
154
198
  def method_definition_macros(macro_name)
155
199
  cop_config['MethodDefinitionMacros'].include?(macro_name.to_s)
156
200
  end
@@ -109,11 +109,11 @@ 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
 
116
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
116
+ # rubocop:disable Metrics/MethodLength
117
117
  def correct_node(corrector, node, offending_name, preferred_name)
118
118
  return unless node
119
119
 
@@ -129,24 +129,19 @@ module RuboCop
129
129
  end
130
130
  end
131
131
 
132
- if child_node.masgn_type? || child_node.lvasgn_type?
132
+ if child_node.type?(:masgn, :lvasgn)
133
133
  correct_reassignment(corrector, child_node, offending_name, preferred_name)
134
134
  break
135
135
  end
136
136
  end
137
137
  end
138
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
138
+ # rubocop:enable Metrics/MethodLength
139
139
 
140
140
  # If the exception variable is reassigned, that assignment needs to be corrected.
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 if node.exception_variable.respond_to?(:name)
166
158
  end
167
159
 
168
160
  def message(node)
@@ -3,8 +3,15 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Naming
6
- # Makes sure that all variables use the configured style,
7
- # snake_case or camelCase, for their names.
6
+ # Checks that the configured style (snake_case or camelCase) is used for all variable names.
7
+ # This includes local variables, instance variables, class variables, method arguments
8
+ # (positional, keyword, rest or block), and block arguments.
9
+ #
10
+ # The cop can also be configured to forbid using specific names for variables, using
11
+ # `ForbiddenIdentifiers` or `ForbiddenPatterns`. In addition to the above, this applies
12
+ # to global variables as well.
13
+ #
14
+ # Method definitions and method calls are not affected by this cop.
8
15
  #
9
16
  # @example EnforcedStyle: snake_case (default)
10
17
  # # bad
@@ -26,25 +33,45 @@ module RuboCop
26
33
  #
27
34
  # @example AllowedPatterns: ['_v\d+\z']
28
35
  # # good (with EnforcedStyle: camelCase)
29
- # :release_v1
36
+ # release_v1 = true
37
+ #
38
+ # @example ForbiddenIdentifiers: ['fooBar']
39
+ # # bad (in all cases)
40
+ # fooBar = 1
41
+ # @fooBar = 1
42
+ # @@fooBar = 1
43
+ # $fooBar = 1
44
+ #
45
+ # @example ForbiddenPatterns: ['_v\d+\z']
46
+ # # bad (in all cases)
47
+ # release_v1 = true
48
+ # @release_v1 = true
49
+ # @@release_v1 = true
50
+ # $release_v1 = true
30
51
  #
31
52
  class VariableName < Base
32
53
  include AllowedIdentifiers
33
54
  include ConfigurableNaming
34
55
  include AllowedPattern
56
+ include ForbiddenIdentifiers
57
+ include ForbiddenPattern
35
58
 
36
59
  MSG = 'Use %<style>s for variable names.'
60
+ MSG_FORBIDDEN = '`%<identifier>s` is forbidden, use another name instead.'
37
61
 
38
62
  def valid_name?(node, name, given_style = style)
39
63
  super || matches_allowed_pattern?(name)
40
64
  end
41
65
 
42
66
  def on_lvasgn(node)
43
- name, = *node
44
- return unless name
67
+ return unless (name = node.name)
45
68
  return if allowed_identifier?(name)
46
69
 
47
- check_name(node, name, node.loc.name)
70
+ if forbidden_name?(name)
71
+ register_forbidden_name(node)
72
+ else
73
+ check_name(node, name, node.loc.name)
74
+ end
48
75
  end
49
76
  alias on_ivasgn on_lvasgn
50
77
  alias on_cvasgn on_lvasgn
@@ -57,11 +84,28 @@ module RuboCop
57
84
  alias on_blockarg on_lvasgn
58
85
  alias on_lvar on_lvasgn
59
86
 
87
+ # Only forbidden names are checked for global variable assignment
88
+ def on_gvasgn(node)
89
+ return unless (name = node.name)
90
+ return unless forbidden_name?(name)
91
+
92
+ register_forbidden_name(node)
93
+ end
94
+
60
95
  private
61
96
 
97
+ def forbidden_name?(name)
98
+ forbidden_identifier?(name) || forbidden_pattern?(name)
99
+ end
100
+
62
101
  def message(style)
63
102
  format(MSG, style: style)
64
103
  end
104
+
105
+ def register_forbidden_name(node)
106
+ message = format(MSG_FORBIDDEN, identifier: node.name)
107
+ add_offense(node.loc.name, message: message)
108
+ end
65
109
  end
66
110
  end
67
111
  end
@@ -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
@@ -23,8 +23,8 @@ module RuboCop
23
23
  global.without_department(:Test).cops
24
24
  end
25
25
 
26
- def self.qualified_cop_name(name, origin)
27
- global.qualified_cop_name(name, origin)
26
+ def self.qualified_cop_name(name, origin, warn: true)
27
+ global.qualified_cop_name(name, origin, warn: warn)
28
28
  end
29
29
 
30
30
  # Changes momentarily the global registry
@@ -139,7 +139,7 @@ module RuboCop
139
139
 
140
140
  case potential_badges.size
141
141
  when 0 then name # No namespace found. Deal with it later in caller.
142
- when 1 then resolve_badge(badge, potential_badges.first, path)
142
+ when 1 then resolve_badge(badge, potential_badges.first, path, warn: warn)
143
143
  else raise AmbiguousCopName.new(badge, path, potential_badges)
144
144
  end
145
145
  end
@@ -296,11 +296,14 @@ module RuboCop
296
296
  self.class.new(cops)
297
297
  end
298
298
 
299
- def resolve_badge(given_badge, real_badge, source_path)
299
+ def resolve_badge(given_badge, real_badge, source_path, warn: true)
300
300
  unless given_badge.match?(real_badge)
301
301
  path = PathUtil.smart_path(source_path)
302
- warn "#{path}: #{given_badge} has the wrong namespace - " \
303
- "replace it with #{given_badge.with_department(real_badge.department)}"
302
+
303
+ if warn
304
+ warn("#{path}: #{given_badge} has the wrong namespace - " \
305
+ "replace it with #{given_badge.with_department(real_badge.department)}")
306
+ end
304
307
  end
305
308
 
306
309
  real_badge.to_s
@@ -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
@@ -99,6 +100,7 @@ module RuboCop
99
100
  add_offense(node, message: REDUNDANT_HASH_MSG)
100
101
  end
101
102
  end
103
+ alias on_csend on_send
102
104
  alias on_op_asgn on_send
103
105
  end
104
106
  end
@@ -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')