rubocop 1.67.0 → 1.76.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 (488) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +22 -16
  4. data/config/default.yml +315 -53
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +8 -3
  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 +51 -26
  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/bundler/ordered_gems.rb +1 -1
  28. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  29. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  30. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  31. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  32. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +50 -6
  33. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  34. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  35. data/lib/rubocop/cop/generator.rb +6 -0
  36. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  37. data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
  38. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  39. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  40. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  41. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  42. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  43. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  44. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  45. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +231 -0
  46. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
  47. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  48. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  49. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  50. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  51. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  52. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  53. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  54. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  55. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  56. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  57. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  58. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  59. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  60. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  61. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  62. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  63. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  64. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  65. data/lib/rubocop/cop/layout/class_structure.rb +44 -9
  66. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
  67. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  68. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  69. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  70. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  71. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  72. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +36 -6
  73. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  74. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  75. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  76. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  77. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  78. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  79. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  80. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  81. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  82. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  83. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  84. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  85. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  86. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  87. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  88. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  89. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  90. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  91. data/lib/rubocop/cop/layout/line_length.rb +123 -4
  92. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  93. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  94. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  95. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  96. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  97. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  98. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  99. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
  100. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  101. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  102. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
  103. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  104. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  105. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  106. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  107. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  108. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  109. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  110. data/lib/rubocop/cop/layout/space_around_operators.rb +23 -21
  111. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  112. data/lib/rubocop/cop/layout/space_before_brackets.rb +8 -34
  113. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  114. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  115. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -1
  116. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  117. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  118. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  119. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  120. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  121. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  122. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  123. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  124. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  125. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  126. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  127. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  128. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  129. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  130. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  131. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
  132. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  133. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  134. data/lib/rubocop/cop/lint/duplicate_methods.rb +86 -19
  135. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  136. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  137. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  138. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  139. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  140. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  141. data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
  142. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  143. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  144. data/lib/rubocop/cop/lint/float_comparison.rb +47 -14
  145. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  146. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  147. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  148. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  149. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  150. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  151. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  152. data/lib/rubocop/cop/lint/literal_as_condition.rb +110 -9
  153. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  154. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  155. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  156. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  157. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  158. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  159. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  160. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  161. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  162. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  163. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  164. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  165. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  166. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  167. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  168. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  169. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  170. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  171. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  172. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  173. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  174. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  175. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
  176. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  177. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  178. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  179. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  180. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  181. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  182. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  183. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  184. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  185. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  186. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  187. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  188. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  189. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  190. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  191. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  192. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  193. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  194. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  195. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  196. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  197. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  198. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  199. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  200. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  201. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  202. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  203. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  204. data/lib/rubocop/cop/lint/useless_access_modifier.rb +5 -4
  205. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  206. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  207. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +87 -0
  208. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  209. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  210. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  211. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  212. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  213. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  214. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  215. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  216. data/lib/rubocop/cop/lint/void.rb +16 -12
  217. data/lib/rubocop/cop/message_annotator.rb +7 -3
  218. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  219. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  220. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  221. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  222. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  223. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  224. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  225. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  226. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  227. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  228. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  229. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  230. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  231. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  232. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  233. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  234. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  235. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  236. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  237. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  238. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  239. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  240. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  241. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  242. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +3 -2
  243. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  244. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  245. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  246. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  247. data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
  248. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  249. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  250. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  251. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  252. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  253. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  254. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  255. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  256. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  257. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  258. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  259. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  260. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  261. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  262. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  263. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  264. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  265. data/lib/rubocop/cop/naming/method_name.rb +64 -8
  266. data/lib/rubocop/cop/naming/predicate_method.rb +216 -0
  267. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +46 -2
  268. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  269. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  270. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  271. data/lib/rubocop/cop/offense.rb +2 -3
  272. data/lib/rubocop/cop/registry.rb +9 -6
  273. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  274. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  275. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  276. data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
  277. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  278. data/lib/rubocop/cop/style/and_or.rb +1 -1
  279. data/lib/rubocop/cop/style/arguments_forwarding.rb +47 -28
  280. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  281. data/lib/rubocop/cop/style/array_intersect.rb +42 -30
  282. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  283. data/lib/rubocop/cop/style/block_delimiters.rb +43 -25
  284. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  285. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  286. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  287. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  288. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  289. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  290. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  291. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  292. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  293. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  294. data/lib/rubocop/cop/style/conditional_assignment.rb +39 -27
  295. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  296. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  297. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  298. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  299. data/lib/rubocop/cop/style/documentation.rb +1 -1
  300. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  301. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  302. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  303. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  304. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  305. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  306. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  307. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  308. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  309. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  310. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  311. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  312. data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
  313. data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
  314. data/lib/rubocop/cop/style/file_null.rb +89 -0
  315. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  316. data/lib/rubocop/cop/style/float_division.rb +8 -4
  317. data/lib/rubocop/cop/style/for.rb +1 -1
  318. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  319. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  320. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  321. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  322. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  323. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  324. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  325. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  326. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  327. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  328. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  329. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  330. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  331. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  332. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  333. data/lib/rubocop/cop/style/if_unless_modifier.rb +25 -7
  334. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  335. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  336. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  337. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  338. data/lib/rubocop/cop/style/inverse_methods.rb +15 -12
  339. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  340. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  341. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  342. data/lib/rubocop/cop/style/it_block_parameter.rb +119 -0
  343. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  344. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  345. data/lib/rubocop/cop/style/lambda.rb +1 -0
  346. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  347. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  348. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  349. data/lib/rubocop/cop/style/map_to_hash.rb +12 -1
  350. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  351. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +27 -17
  352. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  353. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  354. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  355. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  356. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  357. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  358. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  359. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  360. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  361. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  362. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  363. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  364. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  365. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  366. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  367. data/lib/rubocop/cop/style/next.rb +44 -0
  368. data/lib/rubocop/cop/style/not.rb +1 -1
  369. data/lib/rubocop/cop/style/object_then.rb +15 -15
  370. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  371. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  372. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  373. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  374. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  375. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  376. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  377. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  378. data/lib/rubocop/cop/style/proc.rb +2 -2
  379. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  380. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  381. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  382. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  383. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  384. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  385. data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
  386. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  387. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  388. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  389. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  390. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  391. data/lib/rubocop/cop/style/redundant_format.rb +262 -0
  392. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
  393. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  394. data/lib/rubocop/cop/style/redundant_line_continuation.rb +54 -18
  395. data/lib/rubocop/cop/style/redundant_parentheses.rb +68 -26
  396. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  397. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  398. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  399. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  400. data/lib/rubocop/cop/style/redundant_self.rb +9 -15
  401. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  402. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  403. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  404. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  405. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  406. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  407. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  408. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  409. data/lib/rubocop/cop/style/safe_navigation.rb +56 -16
  410. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  411. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  412. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  413. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  414. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  415. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  416. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  417. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  418. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  419. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  420. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  421. data/lib/rubocop/cop/style/sole_nested_conditional.rb +42 -106
  422. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  423. data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
  424. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  425. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  426. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  427. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  428. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  429. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  430. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  431. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  432. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  433. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  434. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  435. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  436. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  437. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  438. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  439. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  440. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  441. data/lib/rubocop/cop/team.rb +1 -1
  442. data/lib/rubocop/cop/util.rb +12 -5
  443. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  444. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  445. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  446. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  447. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  448. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  449. data/lib/rubocop/cop/variable_force.rb +5 -11
  450. data/lib/rubocop/cops_documentation_generator.rb +50 -25
  451. data/lib/rubocop/directive_comment.rb +45 -11
  452. data/lib/rubocop/ext/regexp_node.rb +0 -1
  453. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
  454. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  455. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  456. data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
  457. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  458. data/lib/rubocop/lsp/logger.rb +2 -2
  459. data/lib/rubocop/lsp/routes.rb +7 -23
  460. data/lib/rubocop/lsp/runtime.rb +18 -50
  461. data/lib/rubocop/lsp/server.rb +0 -2
  462. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  463. data/lib/rubocop/magic_comment.rb +11 -3
  464. data/lib/rubocop/options.rb +28 -12
  465. data/lib/rubocop/path_util.rb +15 -8
  466. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  467. data/lib/rubocop/plugin/load_error.rb +26 -0
  468. data/lib/rubocop/plugin/loader.rb +100 -0
  469. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  470. data/lib/rubocop/plugin.rb +46 -0
  471. data/lib/rubocop/rake_task.rb +4 -1
  472. data/lib/rubocop/result_cache.rb +13 -13
  473. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  474. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  475. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  476. data/lib/rubocop/rspec/support.rb +4 -2
  477. data/lib/rubocop/runner.rb +26 -15
  478. data/lib/rubocop/server/cache.rb +47 -11
  479. data/lib/rubocop/server/cli.rb +2 -2
  480. data/lib/rubocop/target_finder.rb +7 -2
  481. data/lib/rubocop/target_ruby.rb +17 -2
  482. data/lib/rubocop/version.rb +53 -12
  483. data/lib/rubocop.rb +38 -2
  484. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  485. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  486. metadata +85 -21
  487. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  488. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -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
@@ -0,0 +1,216 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Naming
6
+ # Checks that predicate methods end with `?` and non-predicate methods do not.
7
+ #
8
+ # The names of predicate methods (methods that return a boolean value) should end
9
+ # in a question mark. Methods that don’t return a boolean, shouldn’t
10
+ # end in a question mark.
11
+ #
12
+ # The cop assesses a predicate method as one that returns boolean values. Likewise,
13
+ # a method that only returns literal values is assessed as non-predicate. The cop does
14
+ # not make an assessment if the return type is unknown (method calls, variables, etc.).
15
+ #
16
+ # NOTE: Operator methods (`def ==`, etc.) are ignored.
17
+ #
18
+ # By default, the cop runs in `conservative` mode, which allows a method to be named
19
+ # with a question mark as long as at least one return value is boolean. In `aggressive`
20
+ # mode, methods with a question mark will register an offense if any known non-boolean
21
+ # return values are detected.
22
+ #
23
+ # The cop also has `AllowedMethods` configuration in order to prevent the cop from
24
+ # registering an offense from a method name that does not confirm to the naming
25
+ # guidelines. By default, `call` is allowed.
26
+ #
27
+ # @example Mode: conservative (default)
28
+ # # bad
29
+ # def foo
30
+ # bar == baz
31
+ # end
32
+ #
33
+ # # good
34
+ # def foo?
35
+ # bar == baz
36
+ # end
37
+ #
38
+ # # bad
39
+ # def foo?
40
+ # 5
41
+ # end
42
+ #
43
+ # # good
44
+ # def foo
45
+ # 5
46
+ # end
47
+ #
48
+ # # good - operator method
49
+ # def ==(other)
50
+ # hash == other.hash
51
+ # end
52
+ #
53
+ # # good - at least one return value is boolean
54
+ # def foo?
55
+ # return unless bar?
56
+ # true
57
+ # end
58
+ #
59
+ # # ok - return type is not known
60
+ # def foo?
61
+ # bar
62
+ # end
63
+ #
64
+ # # ok - return type is not known
65
+ # def foo
66
+ # bar?
67
+ # end
68
+ #
69
+ # @example Mode: aggressive
70
+ # # bad - the method returns nil in some cases
71
+ # def foo?
72
+ # return unless bar?
73
+ # true
74
+ # end
75
+ #
76
+ class PredicateMethod < Base
77
+ include AllowedMethods
78
+
79
+ MSG_PREDICATE = 'Predicate method names should end with `?`.'
80
+ MSG_NON_PREDICATE = 'Non-predicate method names should not end with `?`.'
81
+
82
+ def on_def(node)
83
+ return if allowed?(node)
84
+
85
+ return_values = return_values(node.body)
86
+ return if acceptable?(return_values)
87
+
88
+ if node.predicate_method? && potential_non_predicate?(return_values)
89
+ add_offense(node.loc.name, message: MSG_NON_PREDICATE)
90
+ elsif !node.predicate_method? && all_return_values_boolean?(return_values)
91
+ add_offense(node.loc.name, message: MSG_PREDICATE)
92
+ end
93
+ end
94
+ alias on_defs on_def
95
+
96
+ private
97
+
98
+ def allowed?(node)
99
+ allowed_method?(node.method_name) ||
100
+ node.operator_method? ||
101
+ node.body.nil?
102
+ end
103
+
104
+ def acceptable?(return_values)
105
+ # In `conservative` mode, if the method returns `super`, `zsuper`, or a
106
+ # non-comparison method call, the method name is acceptable.
107
+ return false unless conservative?
108
+
109
+ return_values.any? do |value|
110
+ value.type?(:super, :zsuper) || non_comparison_call?(value)
111
+ end
112
+ end
113
+
114
+ def non_comparison_call?(value)
115
+ value.call_type? && !value.comparison_method?
116
+ end
117
+
118
+ def return_values(node)
119
+ # Collect all the (implicit and explicit) return values of a node
120
+ return_values = Set.new(node.begin_type? ? [] : [extract_return_value(node)])
121
+
122
+ node.each_descendant(:return) do |return_node|
123
+ return_values << extract_return_value(return_node)
124
+ end
125
+
126
+ last_value = last_value(node)
127
+ return_values << last_value if last_value
128
+
129
+ process_return_values(return_values)
130
+ end
131
+
132
+ def all_return_values_boolean?(return_values)
133
+ values = return_values.reject { |value| value.type?(:super, :zsuper) }
134
+ return false if values.empty?
135
+
136
+ values.all? { |value| boolean_return?(value) }
137
+ end
138
+
139
+ def boolean_return?(value)
140
+ value.boolean_type? || (value.call_type? && value.comparison_method?)
141
+ end
142
+
143
+ def potential_non_predicate?(return_values)
144
+ # Assumes a method to be non-predicate if all return values are non-boolean literals.
145
+ #
146
+ # In `Mode: conservative`, if any of the return values is a boolean,
147
+ # the method name is acceptable.
148
+ # In `Mode: aggressive`, all return values must be booleans for a predicate
149
+ # method, or else an offense will be registered.
150
+ return false if conservative? && return_values.any? { |value| boolean_return?(value) }
151
+
152
+ return_values.any? do |value|
153
+ value.literal? && !value.boolean_type?
154
+ end
155
+ end
156
+
157
+ def extract_return_value(node)
158
+ return node unless node.return_type?
159
+
160
+ # `return` without a value is a `nil` return.
161
+ return s(:nil) if node.arguments.empty?
162
+
163
+ # When there's a multiple return, it cannot be a predicate
164
+ # so just return an `array` sexp for simplicity.
165
+ return s(:array) unless node.arguments.one?
166
+
167
+ node.first_argument
168
+ end
169
+
170
+ def last_value(node)
171
+ value = node.begin_type? ? node.children.last : node
172
+ value&.return_type? ? extract_return_value(value) : value
173
+ end
174
+
175
+ def process_return_values(return_values)
176
+ return_values.flat_map do |value|
177
+ if value.conditional?
178
+ process_return_values(extract_conditional_branches(value))
179
+ elsif and_or?(value)
180
+ process_return_values(extract_and_or_clauses(value))
181
+ else
182
+ value
183
+ end
184
+ end
185
+ end
186
+
187
+ def and_or?(node)
188
+ node.type?(:and, :or)
189
+ end
190
+
191
+ def extract_and_or_clauses(node)
192
+ # Recursively traverse an `and` or `or` node to collect all clauses within
193
+ return node unless and_or?(node)
194
+
195
+ [extract_and_or_clauses(node.lhs), extract_and_or_clauses(node.rhs)].flatten
196
+ end
197
+
198
+ def extract_conditional_branches(node)
199
+ return node unless node.conditional?
200
+
201
+ if node.type?(:while, :until)
202
+ # If there is no body, act as implicit `nil`.
203
+ node.body ? [last_value(node.body)] : [s(:nil)]
204
+ else
205
+ # Branches with no value act as an implicit `nil`.
206
+ node.branches.filter_map { |branch| branch ? last_value(branch) : s(:nil) }
207
+ end
208
+ end
209
+
210
+ def conservative?
211
+ cop_config.fetch('Mode', :conservative).to_sym == :conservative
212
+ end
213
+ end
214
+ end
215
+ end
216
+ 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| }
@@ -72,7 +100,7 @@ module RuboCop
72
100
  # # good
73
101
  # def_node_matcher(:even?) { |value| }
74
102
  #
75
- class PredicateName < Base
103
+ class PredicatePrefix < Base
76
104
  include AllowedMethods
77
105
 
78
106
  # @!method dynamic_method_define(node)
@@ -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,
@@ -114,13 +143,24 @@ module RuboCop
114
143
  next if predicate_prefixes.include?(forbidden_prefix)
115
144
 
116
145
  raise ValidationError, <<~MSG.chomp
117
- The `Naming/PredicateName` cop is misconfigured. Prefix #{forbidden_prefix} must be included in NamePrefix because it is included in ForbiddenPrefixes.
146
+ The `Naming/PredicatePrefix` cop is misconfigured. Prefix #{forbidden_prefix} must be included in NamePrefix because it is included in ForbiddenPrefixes.
118
147
  MSG
119
148
  end
120
149
  end
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')