rubocop 1.34.1 → 1.54.0

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 (474) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +345 -54
  5. data/exe/rubocop +1 -1
  6. data/lib/rubocop/arguments_env.rb +17 -0
  7. data/lib/rubocop/arguments_file.rb +17 -0
  8. data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +7 -0
  9. data/lib/rubocop/cli/command/execute_runner.rb +14 -9
  10. data/lib/rubocop/cli/command/lsp.rb +19 -0
  11. data/lib/rubocop/cli/command/suggest_extensions.rb +8 -1
  12. data/lib/rubocop/cli.rb +58 -9
  13. data/lib/rubocop/comment_config.rb +60 -1
  14. data/lib/rubocop/config.rb +47 -19
  15. data/lib/rubocop/config_loader.rb +34 -28
  16. data/lib/rubocop/config_loader_resolver.rb +6 -2
  17. data/lib/rubocop/config_obsoletion.rb +2 -2
  18. data/lib/rubocop/config_validator.rb +1 -1
  19. data/lib/rubocop/cop/autocorrect_logic.rb +29 -13
  20. data/lib/rubocop/cop/badge.rb +9 -4
  21. data/lib/rubocop/cop/base.rb +115 -83
  22. data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
  23. data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
  24. data/lib/rubocop/cop/commissioner.rb +19 -6
  25. data/lib/rubocop/cop/cop.rb +53 -33
  26. data/lib/rubocop/cop/corrector.rb +31 -11
  27. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -3
  28. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +3 -3
  29. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +3 -3
  30. data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
  31. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +23 -7
  32. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +2 -7
  33. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +32 -2
  34. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  35. data/lib/rubocop/cop/gemspec/dependency_version.rb +19 -21
  36. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -1
  37. data/lib/rubocop/cop/gemspec/development_dependencies.rb +107 -0
  38. data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
  39. data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
  40. data/lib/rubocop/cop/generator.rb +1 -2
  41. data/lib/rubocop/cop/internal_affairs/cop_description.rb +38 -12
  42. data/lib/rubocop/cop/internal_affairs/create_empty_file.rb +37 -0
  43. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +111 -0
  44. data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
  45. data/lib/rubocop/cop/internal_affairs/lambda_or_proc.rb +46 -0
  46. data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
  47. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +6 -6
  48. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  49. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +69 -0
  50. data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +42 -0
  51. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +11 -3
  52. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  53. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
  54. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +66 -0
  55. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  56. data/lib/rubocop/cop/internal_affairs.rb +7 -0
  57. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  58. data/lib/rubocop/cop/layout/block_alignment.rb +16 -12
  59. data/lib/rubocop/cop/layout/block_end_newline.rb +9 -15
  60. data/lib/rubocop/cop/layout/class_structure.rb +44 -27
  61. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +2 -3
  62. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +2 -6
  63. data/lib/rubocop/cop/layout/comment_indentation.rb +3 -1
  64. data/lib/rubocop/cop/layout/empty_comment.rb +3 -3
  65. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +28 -5
  66. data/lib/rubocop/cop/layout/empty_lines.rb +3 -1
  67. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +7 -2
  68. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -0
  69. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
  70. data/lib/rubocop/cop/layout/end_alignment.rb +9 -1
  71. data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
  72. data/lib/rubocop/cop/layout/extra_spacing.rb +15 -6
  73. data/lib/rubocop/cop/layout/first_argument_indentation.rb +9 -3
  74. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -2
  75. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +35 -8
  76. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -2
  77. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +36 -1
  78. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +57 -8
  79. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +52 -19
  80. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +10 -4
  81. data/lib/rubocop/cop/layout/heredoc_indentation.rb +8 -11
  82. data/lib/rubocop/cop/layout/indentation_style.rb +8 -3
  83. data/lib/rubocop/cop/layout/indentation_width.rb +8 -4
  84. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  85. data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
  86. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +33 -9
  87. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +18 -8
  88. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
  89. data/lib/rubocop/cop/layout/line_length.rb +6 -1
  90. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +31 -1
  91. data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -1
  92. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +29 -1
  93. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +35 -1
  94. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +33 -1
  95. data/lib/rubocop/cop/layout/redundant_line_break.rb +10 -11
  96. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
  97. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  98. data/lib/rubocop/cop/layout/space_around_keyword.rb +3 -3
  99. data/lib/rubocop/cop/layout/space_around_operators.rb +4 -2
  100. data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
  101. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
  102. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
  103. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +22 -20
  104. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +3 -0
  105. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +27 -9
  106. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +30 -3
  107. data/lib/rubocop/cop/layout/space_inside_parens.rb +2 -2
  108. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +34 -0
  109. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  110. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +10 -6
  111. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +5 -4
  112. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +1 -1
  113. data/lib/rubocop/cop/layout/trailing_whitespace.rb +12 -5
  114. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +16 -4
  115. data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -0
  116. data/lib/rubocop/cop/lint/assignment_in_condition.rb +11 -1
  117. data/lib/rubocop/cop/lint/constant_resolution.rb +5 -1
  118. data/lib/rubocop/cop/lint/debugger.rb +16 -26
  119. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +62 -112
  120. data/lib/rubocop/cop/lint/deprecated_constants.rb +8 -1
  121. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  122. data/lib/rubocop/cop/lint/duplicate_branch.rb +0 -2
  123. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
  124. data/lib/rubocop/cop/lint/duplicate_magic_comment.rb +73 -0
  125. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
  126. data/lib/rubocop/cop/lint/duplicate_methods.rb +48 -18
  127. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +55 -11
  128. data/lib/rubocop/cop/lint/duplicate_require.rb +1 -1
  129. data/lib/rubocop/cop/lint/else_layout.rb +3 -7
  130. data/lib/rubocop/cop/lint/empty_block.rb +3 -7
  131. data/lib/rubocop/cop/lint/empty_class.rb +3 -1
  132. data/lib/rubocop/cop/lint/empty_conditional_body.rb +51 -7
  133. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  134. data/lib/rubocop/cop/lint/erb_new_arguments.rb +12 -13
  135. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +14 -7
  136. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +16 -18
  137. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  138. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  139. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
  140. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  141. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  142. data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
  143. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  144. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +48 -2
  145. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +18 -3
  146. data/lib/rubocop/cop/lint/missing_super.rb +63 -5
  147. data/lib/rubocop/cop/lint/mixed_case_range.rb +111 -0
  148. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  149. data/lib/rubocop/cop/lint/nested_method_definition.rb +53 -9
  150. data/lib/rubocop/cop/lint/next_without_accumulator.rb +25 -6
  151. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +15 -10
  152. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +12 -0
  153. data/lib/rubocop/cop/lint/number_conversion.rb +6 -1
  154. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  155. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
  156. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +4 -6
  157. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +17 -2
  158. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -0
  159. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  160. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  161. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +49 -9
  162. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6 -6
  163. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +7 -0
  164. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +120 -0
  165. data/lib/rubocop/cop/lint/redundant_require_statement.rb +53 -10
  166. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +9 -3
  167. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  168. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
  169. data/lib/rubocop/cop/lint/redundant_with_index.rb +14 -11
  170. data/lib/rubocop/cop/lint/redundant_with_object.rb +13 -12
  171. data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
  172. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
  173. data/lib/rubocop/cop/lint/require_parentheses.rb +3 -1
  174. data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
  175. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +13 -14
  176. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
  177. data/lib/rubocop/cop/lint/script_permission.rb +1 -1
  178. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +6 -6
  179. data/lib/rubocop/cop/lint/shadowed_exception.rb +7 -23
  180. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +19 -2
  181. data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
  182. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  183. data/lib/rubocop/cop/lint/syntax.rb +4 -0
  184. data/lib/rubocop/cop/lint/to_enum_arguments.rb +13 -3
  185. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  186. data/lib/rubocop/cop/lint/unreachable_loop.rb +12 -6
  187. data/lib/rubocop/cop/lint/unused_method_argument.rb +6 -1
  188. data/lib/rubocop/cop/lint/useless_access_modifier.rb +17 -12
  189. data/lib/rubocop/cop/lint/useless_assignment.rb +59 -1
  190. data/lib/rubocop/cop/lint/useless_method_definition.rb +12 -4
  191. data/lib/rubocop/cop/lint/useless_rescue.rb +89 -0
  192. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +15 -5
  193. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  194. data/lib/rubocop/cop/lint/void.rb +86 -21
  195. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  196. data/lib/rubocop/cop/metrics/block_length.rb +10 -5
  197. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  198. data/lib/rubocop/cop/metrics/class_length.rb +11 -5
  199. data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
  200. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
  201. data/lib/rubocop/cop/metrics/method_length.rb +9 -4
  202. data/lib/rubocop/cop/metrics/module_length.rb +10 -5
  203. data/lib/rubocop/cop/metrics/parameter_lists.rb +27 -0
  204. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  205. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -8
  206. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +39 -8
  207. data/lib/rubocop/cop/migration/department_name.rb +3 -3
  208. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  209. data/lib/rubocop/cop/mixin/allowed_identifiers.rb +2 -2
  210. data/lib/rubocop/cop/mixin/allowed_methods.rb +13 -6
  211. data/lib/rubocop/cop/mixin/allowed_pattern.rb +13 -5
  212. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  213. data/lib/rubocop/cop/mixin/annotation_comment.rb +14 -7
  214. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  215. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  216. data/lib/rubocop/cop/mixin/comments_help.rb +24 -6
  217. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +21 -9
  218. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  219. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  220. data/lib/rubocop/cop/mixin/first_element_line_break.rb +11 -7
  221. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
  222. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
  223. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +152 -12
  224. data/lib/rubocop/cop/mixin/hash_transform_method.rb +13 -9
  225. data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
  226. data/lib/rubocop/cop/mixin/line_length_help.rb +11 -2
  227. data/lib/rubocop/cop/mixin/method_complexity.rb +9 -7
  228. data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
  229. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
  230. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +5 -6
  231. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  232. data/lib/rubocop/cop/mixin/percent_array.rb +3 -5
  233. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  234. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
  235. data/lib/rubocop/cop/mixin/range_help.rb +20 -3
  236. data/lib/rubocop/cop/mixin/require_library.rb +2 -0
  237. data/lib/rubocop/cop/mixin/rescue_node.rb +5 -3
  238. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  239. data/lib/rubocop/cop/mixin/statement_modifier.rb +18 -3
  240. data/lib/rubocop/cop/mixin/surrounding_space.rb +13 -11
  241. data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -2
  242. data/lib/rubocop/cop/mixin/visibility_help.rb +40 -5
  243. data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
  244. data/lib/rubocop/cop/naming/block_forwarding.rb +6 -2
  245. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  246. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +3 -1
  247. data/lib/rubocop/cop/naming/constant_name.rb +3 -3
  248. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
  249. data/lib/rubocop/cop/naming/inclusive_language.rb +28 -6
  250. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +25 -10
  251. data/lib/rubocop/cop/naming/method_name.rb +3 -3
  252. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  253. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -4
  254. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  255. data/lib/rubocop/cop/registry.rb +73 -45
  256. data/lib/rubocop/cop/security/compound_hash.rb +2 -1
  257. data/lib/rubocop/cop/style/access_modifier_declarations.rb +92 -3
  258. data/lib/rubocop/cop/style/accessor_grouping.rb +50 -20
  259. data/lib/rubocop/cop/style/alias.rb +9 -1
  260. data/lib/rubocop/cop/style/arguments_forwarding.rb +6 -5
  261. data/lib/rubocop/cop/style/array_intersect.rb +111 -0
  262. data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
  263. data/lib/rubocop/cop/style/attr.rb +11 -1
  264. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  265. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
  266. data/lib/rubocop/cop/style/block_comments.rb +3 -3
  267. data/lib/rubocop/cop/style/block_delimiters.rb +22 -7
  268. data/lib/rubocop/cop/style/case_equality.rb +40 -10
  269. data/lib/rubocop/cop/style/case_like_if.rb +20 -3
  270. data/lib/rubocop/cop/style/character_literal.rb +1 -1
  271. data/lib/rubocop/cop/style/class_and_module_children.rb +5 -12
  272. data/lib/rubocop/cop/style/class_equality_comparison.rb +58 -45
  273. data/lib/rubocop/cop/style/class_methods_definitions.rb +2 -1
  274. data/lib/rubocop/cop/style/collection_compact.rb +27 -5
  275. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  276. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  277. data/lib/rubocop/cop/style/combinable_loops.rb +29 -7
  278. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  279. data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
  280. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  281. data/lib/rubocop/cop/style/comparable_clamp.rb +125 -0
  282. data/lib/rubocop/cop/style/concat_array_literals.rb +94 -0
  283. data/lib/rubocop/cop/style/conditional_assignment.rb +11 -15
  284. data/lib/rubocop/cop/style/copyright.rb +6 -3
  285. data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
  286. data/lib/rubocop/cop/style/dir.rb +1 -1
  287. data/lib/rubocop/cop/style/dir_empty.rb +54 -0
  288. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  289. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +3 -3
  290. data/lib/rubocop/cop/style/documentation.rb +22 -10
  291. data/lib/rubocop/cop/style/documentation_method.rb +10 -4
  292. data/lib/rubocop/cop/style/double_negation.rb +2 -2
  293. data/lib/rubocop/cop/style/each_for_simple_loop.rb +41 -6
  294. data/lib/rubocop/cop/style/each_with_object.rb +40 -9
  295. data/lib/rubocop/cop/style/empty_block_parameter.rb +2 -2
  296. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +2 -2
  297. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  298. data/lib/rubocop/cop/style/endless_method.rb +1 -1
  299. data/lib/rubocop/cop/style/eval_with_location.rb +8 -8
  300. data/lib/rubocop/cop/style/exact_regexp_match.rb +68 -0
  301. data/lib/rubocop/cop/style/explicit_block_argument.rb +5 -1
  302. data/lib/rubocop/cop/style/file_empty.rb +71 -0
  303. data/lib/rubocop/cop/style/file_read.rb +3 -3
  304. data/lib/rubocop/cop/style/file_write.rb +1 -1
  305. data/lib/rubocop/cop/style/for.rb +2 -0
  306. data/lib/rubocop/cop/style/format_string_token.rb +1 -1
  307. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  308. data/lib/rubocop/cop/style/guard_clause.rb +127 -38
  309. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +1 -0
  310. data/lib/rubocop/cop/style/hash_each_methods.rb +36 -21
  311. data/lib/rubocop/cop/style/hash_except.rb +27 -12
  312. data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
  313. data/lib/rubocop/cop/style/hash_syntax.rb +26 -2
  314. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  315. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  316. data/lib/rubocop/cop/style/identical_conditional_branches.rb +21 -2
  317. data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
  318. data/lib/rubocop/cop/style/if_unless_modifier.rb +111 -15
  319. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +27 -2
  320. data/lib/rubocop/cop/style/if_with_semicolon.rb +6 -6
  321. data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
  322. data/lib/rubocop/cop/style/inverse_methods.rb +15 -11
  323. data/lib/rubocop/cop/style/invertible_unless_condition.rb +118 -0
  324. data/lib/rubocop/cop/style/lambda.rb +3 -3
  325. data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -1
  326. data/lib/rubocop/cop/style/magic_comment_format.rb +307 -0
  327. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +2 -2
  328. data/lib/rubocop/cop/style/map_to_hash.rb +4 -1
  329. data/lib/rubocop/cop/style/map_to_set.rb +64 -0
  330. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +41 -26
  331. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +44 -37
  332. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -0
  333. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
  334. data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -4
  335. data/lib/rubocop/cop/style/min_max.rb +3 -3
  336. data/lib/rubocop/cop/style/min_max_comparison.rb +83 -0
  337. data/lib/rubocop/cop/style/missing_else.rb +13 -1
  338. data/lib/rubocop/cop/style/mixin_grouping.rb +4 -4
  339. data/lib/rubocop/cop/style/module_function.rb +28 -6
  340. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -1
  341. data/lib/rubocop/cop/style/multiline_if_modifier.rb +0 -4
  342. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
  343. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  344. data/lib/rubocop/cop/style/multiline_method_signature.rb +7 -4
  345. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +18 -3
  346. data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
  347. data/lib/rubocop/cop/style/negated_if_else_condition.rb +17 -10
  348. data/lib/rubocop/cop/style/next.rb +3 -5
  349. data/lib/rubocop/cop/style/nil_lambda.rb +4 -4
  350. data/lib/rubocop/cop/style/numbered_parameters_limit.rb +11 -3
  351. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  352. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
  353. data/lib/rubocop/cop/style/object_then.rb +5 -0
  354. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -6
  355. data/lib/rubocop/cop/style/operator_method_call.rb +67 -0
  356. data/lib/rubocop/cop/style/parallel_assignment.rb +29 -19
  357. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
  358. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  359. data/lib/rubocop/cop/style/perl_backrefs.rb +22 -1
  360. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  361. data/lib/rubocop/cop/style/proc.rb +4 -1
  362. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  363. data/lib/rubocop/cop/style/redundant_argument.rb +3 -0
  364. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  365. data/lib/rubocop/cop/style/redundant_begin.rb +4 -1
  366. data/lib/rubocop/cop/style/redundant_condition.rb +22 -4
  367. data/lib/rubocop/cop/style/redundant_conditional.rb +1 -5
  368. data/lib/rubocop/cop/style/redundant_constant_base.rb +85 -0
  369. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +38 -0
  370. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +45 -0
  371. data/lib/rubocop/cop/style/redundant_each.rb +116 -0
  372. data/lib/rubocop/cop/style/redundant_fetch_block.rb +7 -5
  373. data/lib/rubocop/cop/style/redundant_filter_chain.rb +101 -0
  374. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +58 -0
  375. data/lib/rubocop/cop/style/redundant_initialize.rb +3 -1
  376. data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
  377. data/lib/rubocop/cop/style/redundant_line_continuation.rb +183 -0
  378. data/lib/rubocop/cop/style/redundant_parentheses.rb +7 -3
  379. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  380. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +99 -0
  381. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +9 -3
  382. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  383. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +22 -4
  384. data/lib/rubocop/cop/style/redundant_return.rb +7 -0
  385. data/lib/rubocop/cop/style/redundant_self.rb +2 -0
  386. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +3 -1
  387. data/lib/rubocop/cop/style/redundant_sort.rb +5 -5
  388. data/lib/rubocop/cop/style/redundant_sort_by.rb +24 -8
  389. data/lib/rubocop/cop/style/redundant_string_escape.rb +185 -0
  390. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  391. data/lib/rubocop/cop/style/require_order.rb +139 -0
  392. data/lib/rubocop/cop/style/rescue_modifier.rb +2 -4
  393. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  394. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +81 -0
  395. data/lib/rubocop/cop/style/safe_navigation.rb +41 -10
  396. data/lib/rubocop/cop/style/select_by_regexp.rb +23 -5
  397. data/lib/rubocop/cop/style/self_assignment.rb +2 -2
  398. data/lib/rubocop/cop/style/semicolon.rb +37 -3
  399. data/lib/rubocop/cop/style/signal_exception.rb +9 -7
  400. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  401. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  402. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
  403. data/lib/rubocop/cop/style/sole_nested_conditional.rb +6 -6
  404. data/lib/rubocop/cop/style/special_global_vars.rb +3 -4
  405. data/lib/rubocop/cop/style/static_class.rb +32 -1
  406. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  407. data/lib/rubocop/cop/style/string_hash_keys.rb +4 -1
  408. data/lib/rubocop/cop/style/string_literals.rb +1 -5
  409. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  410. data/lib/rubocop/cop/style/symbol_array.rb +4 -2
  411. data/lib/rubocop/cop/style/symbol_proc.rb +8 -9
  412. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -1
  413. data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
  414. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -4
  415. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  416. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
  417. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  418. data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
  419. data/lib/rubocop/cop/style/unpack_first.rb +3 -3
  420. data/lib/rubocop/cop/style/word_array.rb +57 -2
  421. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  422. data/lib/rubocop/cop/style/yoda_condition.rb +17 -8
  423. data/lib/rubocop/cop/style/yoda_expression.rb +90 -0
  424. data/lib/rubocop/cop/style/zero_length_predicate.rb +40 -19
  425. data/lib/rubocop/cop/team.rb +63 -56
  426. data/lib/rubocop/cop/util.rb +45 -9
  427. data/lib/rubocop/cop/utils/regexp_ranges.rb +100 -0
  428. data/lib/rubocop/cop/variable_force/assignment.rb +34 -2
  429. data/lib/rubocop/cop/variable_force/scope.rb +3 -3
  430. data/lib/rubocop/cop/variable_force/variable.rb +5 -3
  431. data/lib/rubocop/cop/variable_force/variable_table.rb +6 -4
  432. data/lib/rubocop/cop/variable_force.rb +19 -30
  433. data/lib/rubocop/cops_documentation_generator.rb +45 -15
  434. data/lib/rubocop/directive_comment.rb +4 -4
  435. data/lib/rubocop/ext/comment.rb +18 -0
  436. data/lib/rubocop/ext/processed_source.rb +2 -0
  437. data/lib/rubocop/ext/regexp_node.rb +1 -1
  438. data/lib/rubocop/ext/regexp_parser.rb +5 -2
  439. data/lib/rubocop/feature_loader.rb +6 -2
  440. data/lib/rubocop/file_patterns.rb +43 -0
  441. data/lib/rubocop/formatter/disabled_config_formatter.rb +25 -8
  442. data/lib/rubocop/formatter/html_formatter.rb +3 -3
  443. data/lib/rubocop/formatter/junit_formatter.rb +4 -1
  444. data/lib/rubocop/formatter/offense_count_formatter.rb +8 -5
  445. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  446. data/lib/rubocop/formatter/worst_offenders_formatter.rb +6 -3
  447. data/lib/rubocop/formatter.rb +4 -1
  448. data/lib/rubocop/lsp/logger.rb +22 -0
  449. data/lib/rubocop/lsp/routes.rb +231 -0
  450. data/lib/rubocop/lsp/runtime.rb +82 -0
  451. data/lib/rubocop/lsp/server.rb +66 -0
  452. data/lib/rubocop/lsp/severity.rb +27 -0
  453. data/lib/rubocop/options.rb +63 -17
  454. data/lib/rubocop/path_util.rb +50 -22
  455. data/lib/rubocop/result_cache.rb +4 -4
  456. data/lib/rubocop/rspec/cop_helper.rb +26 -3
  457. data/lib/rubocop/rspec/expect_offense.rb +6 -4
  458. data/lib/rubocop/rspec/shared_contexts.rb +18 -1
  459. data/lib/rubocop/rspec/support.rb +3 -2
  460. data/lib/rubocop/runner.rb +69 -18
  461. data/lib/rubocop/server/cache.rb +24 -10
  462. data/lib/rubocop/server/cli.rb +45 -19
  463. data/lib/rubocop/server/client_command/exec.rb +8 -2
  464. data/lib/rubocop/server/client_command/start.rb +6 -1
  465. data/lib/rubocop/server/core.rb +42 -10
  466. data/lib/rubocop/server/helper.rb +1 -1
  467. data/lib/rubocop/server/server_command/exec.rb +1 -1
  468. data/lib/rubocop/server/socket_reader.rb +5 -1
  469. data/lib/rubocop/server.rb +1 -1
  470. data/lib/rubocop/target_finder.rb +1 -1
  471. data/lib/rubocop/target_ruby.rb +5 -5
  472. data/lib/rubocop/version.rb +17 -7
  473. data/lib/rubocop.rb +52 -8
  474. metadata +80 -32
@@ -30,7 +30,7 @@ module RuboCop
30
30
  private
31
31
 
32
32
  def first_offense_range(comment)
33
- expression = comment.loc.expression
33
+ expression = comment.source_range
34
34
  first_offense = first_non_ascii_chars(comment.text)
35
35
 
36
36
  start_position = expression.begin_pos + comment.text.index(first_offense)
@@ -24,7 +24,7 @@ module RuboCop
24
24
  def on_send(node)
25
25
  return unless node.command?(:attr) && node.arguments?
26
26
  # check only for method definitions in class/module body
27
- return if node.parent && !node.parent.class_type? && !class_eval?(node.parent)
27
+ return if allowed_context?(node)
28
28
 
29
29
  message = message(node)
30
30
  add_offense(node.loc.selector, message: message) do |corrector|
@@ -34,6 +34,16 @@ module RuboCop
34
34
 
35
35
  private
36
36
 
37
+ def allowed_context?(node)
38
+ return false unless (class_node = node.each_ancestor(:class, :block).first)
39
+
40
+ (!class_node.class_type? && !class_eval?(class_node)) || define_attr_method?(class_node)
41
+ end
42
+
43
+ def define_attr_method?(node)
44
+ node.each_descendant(:def).any? { |def_node| def_node.method?(:attr) }
45
+ end
46
+
37
47
  def autocorrect(corrector, node)
38
48
  attr_name, setter = *node.arguments
39
49
 
@@ -3,8 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- #
7
- # This cop checks for BEGIN blocks.
6
+ # Checks for BEGIN blocks.
8
7
  #
9
8
  # @example
10
9
  # # bad
@@ -55,7 +55,7 @@ module RuboCop
55
55
  def after_class(class_node)
56
56
  @macros_to_rewrite[class_node].each do |macro|
57
57
  node = macro.node
58
- range = range_by_whole_lines(node.loc.expression, include_final_newline: true)
58
+ range = range_by_whole_lines(node.source_range, include_final_newline: true)
59
59
 
60
60
  correct(range) do |corrector|
61
61
  if macro.writer?
@@ -32,10 +32,10 @@ module RuboCop
32
32
  eq_begin, eq_end, contents = parts(comment)
33
33
 
34
34
  corrector.remove(eq_begin)
35
- unless contents.length.zero?
35
+ unless contents.empty?
36
36
  corrector.replace(
37
37
  contents,
38
- contents.source.gsub(/\A/, '# ').gsub(/\n\n/, "\n#\n").gsub(/\n(?=[^#])/, "\n# ")
38
+ contents.source.gsub(/\A/, '# ').gsub("\n\n", "\n#\n").gsub(/\n(?=[^#])/, "\n# ")
39
39
  )
40
40
  end
41
41
  corrector.remove(eq_end)
@@ -46,7 +46,7 @@ module RuboCop
46
46
  private
47
47
 
48
48
  def parts(comment)
49
- expr = comment.loc.expression
49
+ expr = comment.source_range
50
50
  eq_begin = expr.resize(BEGIN_LENGTH)
51
51
  eq_end = eq_end_part(comment, expr)
52
52
  contents = range_between(eq_begin.end_pos, eq_end.begin_pos)
@@ -157,7 +157,7 @@ module RuboCop
157
157
  # process(something)
158
158
  # }
159
159
  #
160
- # @example AllowedPatterns: [/map/]
160
+ # @example AllowedPatterns: ['map']
161
161
  #
162
162
  # # good
163
163
  # things.map { |thing|
@@ -299,8 +299,8 @@ module RuboCop
299
299
 
300
300
  def move_comment_before_block(corrector, comment, block_node, closing_brace)
301
301
  range = block_node.chained? ? end_of_chain(block_node.parent).source_range : closing_brace
302
- comment_range = range_between(range.end_pos, comment.loc.expression.end_pos)
303
- corrector.remove(range_with_surrounding_space(comment_range, side: :right))
302
+ corrector.remove(range_with_surrounding_space(comment.source_range, side: :right))
303
+ remove_trailing_whitespace(corrector, range, comment)
304
304
  corrector.insert_after(range, "\n")
305
305
 
306
306
  corrector.insert_before(block_node, "#{comment.text}\n")
@@ -313,6 +313,12 @@ module RuboCop
313
313
  end_of_chain(node.parent)
314
314
  end
315
315
 
316
+ def remove_trailing_whitespace(corrector, range, comment)
317
+ range_of_trailing = range.end.join(comment.source_range.begin)
318
+
319
+ corrector.remove(range_of_trailing) if range_of_trailing.source.match?(/\A\s+\z/)
320
+ end
321
+
316
322
  def with_block?(node)
317
323
  node.respond_to?(:block_node) && node.block_node
318
324
  end
@@ -336,6 +342,7 @@ module RuboCop
336
342
  end
337
343
 
338
344
  def proper_block_style?(node)
345
+ return true if require_braces?(node)
339
346
  return special_method_proper_block_style?(node) if special_method?(node.method_name)
340
347
 
341
348
  case style
@@ -346,6 +353,14 @@ module RuboCop
346
353
  end
347
354
  end
348
355
 
356
+ def require_braces?(node)
357
+ return false unless node.braces?
358
+
359
+ node.each_ancestor(:send).any? do |send|
360
+ send.arithmetic_operation? && node.source_range.end_pos < send.loc.selector.begin_pos
361
+ end
362
+ end
363
+
349
364
  def special_method?(method_name)
350
365
  allowed_method?(method_name) ||
351
366
  matches_allowed_pattern?(method_name) ||
@@ -396,7 +411,7 @@ module RuboCop
396
411
  end
397
412
 
398
413
  def correction_would_break_code?(node)
399
- return unless node.keywords?
414
+ return false unless node.keywords?
400
415
 
401
416
  node.send_node.arguments? && !node.send_node.parenthesized?
402
417
  end
@@ -418,19 +433,19 @@ module RuboCop
418
433
  end
419
434
 
420
435
  def return_value_used?(node)
421
- return unless node.parent
436
+ return false unless node.parent
422
437
 
423
438
  # If there are parentheses around the block, check if that
424
439
  # is being used.
425
440
  if node.parent.begin_type?
426
441
  return_value_used?(node.parent)
427
442
  else
428
- node.parent.assignment? || node.parent.send_type?
443
+ node.parent.assignment? || node.parent.call_type?
429
444
  end
430
445
  end
431
446
 
432
447
  def return_value_of_scope?(node)
433
- return unless node.parent
448
+ return false unless node.parent
434
449
 
435
450
  conditional?(node.parent) || array_or_range?(node.parent) ||
436
451
  node.parent.children.last == node
@@ -7,6 +7,9 @@ module RuboCop
7
7
  #
8
8
  # If `AllowOnConstant` option is enabled, the cop will ignore violations when the receiver of
9
9
  # the case equality operator is a constant.
10
+
11
+ # If `AllowOnSelfClass` option is enabled, the cop will ignore violations when the receiver of
12
+ # the case equality operator is `self.class`. Note intermediate variables are not accepted.
10
13
  #
11
14
  # @example
12
15
  # # bad
@@ -26,6 +29,14 @@ module RuboCop
26
29
  # # good
27
30
  # Array === something
28
31
  #
32
+ # @example AllowOnSelfClass: false (default)
33
+ # # bad
34
+ # self.class === something
35
+ #
36
+ # @example AllowOnSelfClass: true
37
+ # # good
38
+ # self.class === something
39
+ #
29
40
  class CaseEquality < Base
30
41
  extend AutoCorrector
31
42
 
@@ -33,7 +44,10 @@ module RuboCop
33
44
  RESTRICT_ON_SEND = %i[===].freeze
34
45
 
35
46
  # @!method case_equality?(node)
36
- def_node_matcher :case_equality?, '(send $#const? :=== $_)'
47
+ def_node_matcher :case_equality?, '(send $#offending_receiver? :=== $_)'
48
+
49
+ # @!method self_class?(node)
50
+ def_node_matcher :self_class?, '(send (self) :class)'
37
51
 
38
52
  def on_send(node)
39
53
  case_equality?(node) do |lhs, rhs|
@@ -48,12 +62,11 @@ module RuboCop
48
62
 
49
63
  private
50
64
 
51
- def const?(node)
52
- if cop_config.fetch('AllowOnConstant', false)
53
- !node&.const_type?
54
- else
55
- true
56
- end
65
+ def offending_receiver?(node)
66
+ return false if node&.const_type? && cop_config.fetch('AllowOnConstant', false)
67
+ return false if self_class?(node) && cop_config.fetch('AllowOnSelfClass', false)
68
+
69
+ true
57
70
  end
58
71
 
59
72
  def replacement(lhs, rhs)
@@ -66,12 +79,29 @@ module RuboCop
66
79
  #
67
80
  # So here is noop.
68
81
  when :begin
69
- child = lhs.children.first
70
- "#{lhs.source}.include?(#{rhs.source})" if child&.range_type?
82
+ begin_replacement(lhs, rhs)
71
83
  when :const
72
- "#{rhs.source}.is_a?(#{lhs.source})"
84
+ const_replacement(lhs, rhs)
85
+ when :send
86
+ send_replacement(lhs, rhs)
73
87
  end
74
88
  end
89
+
90
+ def begin_replacement(lhs, rhs)
91
+ return unless lhs.children.first&.range_type?
92
+
93
+ "#{lhs.source}.include?(#{rhs.source})"
94
+ end
95
+
96
+ def const_replacement(lhs, rhs)
97
+ "#{rhs.source}.is_a?(#{lhs.source})"
98
+ end
99
+
100
+ def send_replacement(lhs, rhs)
101
+ return unless self_class?(lhs)
102
+
103
+ "#{rhs.source}.is_a?(#{lhs.source})"
104
+ end
75
105
  end
76
106
  end
77
107
  end
@@ -11,12 +11,14 @@ module RuboCop
11
11
  # so if the original conditional used a different equality operator, the
12
12
  # behavior may be different.
13
13
  #
14
- # @example
14
+ # @example MinBranchesCount: 3 (default)
15
15
  # # bad
16
16
  # if status == :active
17
17
  # perform_action
18
18
  # elsif status == :inactive || status == :hibernating
19
19
  # check_timeout
20
+ # elsif status == :invalid
21
+ # report_invalid
20
22
  # else
21
23
  # final_action
22
24
  # end
@@ -27,12 +29,27 @@ module RuboCop
27
29
  # perform_action
28
30
  # when :inactive, :hibernating
29
31
  # check_timeout
32
+ # when :invalid
33
+ # report_invalid
34
+ # else
35
+ # final_action
36
+ # end
37
+ #
38
+ # @example MinBranchesCount: 4
39
+ # # good
40
+ # if status == :active
41
+ # perform_action
42
+ # elsif status == :inactive || status == :hibernating
43
+ # check_timeout
44
+ # elsif status == :invalid
45
+ # report_invalid
30
46
  # else
31
47
  # final_action
32
48
  # end
33
49
  #
34
50
  class CaseLikeIf < Base
35
51
  include RangeHelp
52
+ include MinBranchesCount
36
53
  extend AutoCorrector
37
54
 
38
55
  MSG = 'Convert `if-elsif` to `case-when`.'
@@ -78,7 +95,7 @@ module RuboCop
78
95
 
79
96
  def should_check?(node)
80
97
  !node.unless? && !node.elsif? && !node.modifier_form? && !node.ternary? &&
81
- node.elsif_conditional?
98
+ node.elsif_conditional? && min_branches_count?(node)
82
99
  end
83
100
 
84
101
  # rubocop:disable Metrics/MethodLength
@@ -239,7 +256,7 @@ module RuboCop
239
256
  end
240
257
 
241
258
  def correction_range(node)
242
- range_between(node.parent.loc.keyword.begin_pos, node.loc.expression.end_pos)
259
+ range_between(node.parent.loc.keyword.begin_pos, node.source_range.end_pos)
243
260
  end
244
261
 
245
262
  # Named captures work with `=~` (if regexp is on lhs) and with `match` (both sides)
@@ -29,7 +29,7 @@ module RuboCop
29
29
 
30
30
  def offense?(node)
31
31
  # we don't register an offense for things like ?\C-\M-d
32
- node.loc.begin.is?('?') && node.source.size.between?(2, 3)
32
+ node.character_literal? && node.source.size.between?(2, 3)
33
33
  end
34
34
 
35
35
  def autocorrect(corrector, node)
@@ -11,7 +11,7 @@ module RuboCop
11
11
  #
12
12
  # Moving from compact to nested children requires knowledge of whether the
13
13
  # outer parent is a module or a class. Moving from nested to compact requires
14
- # verification that the outer parent is defined elsewhere. Rubocop does not
14
+ # verification that the outer parent is defined elsewhere. RuboCop does not
15
15
  # have the knowledge to perform either operation safely and thus requires
16
16
  # manual oversight.
17
17
  #
@@ -31,6 +31,7 @@ module RuboCop
31
31
  #
32
32
  # The compact style is only forced for classes/modules with one child.
33
33
  class ClassAndModuleChildren < Base
34
+ include Alignment
34
35
  include ConfigurableEnforcedStyle
35
36
  include RangeHelp
36
37
  extend AutoCorrector
@@ -59,7 +60,7 @@ module RuboCop
59
60
  end
60
61
 
61
62
  def nest_definition(corrector, node)
62
- padding = ((' ' * indent_width) + leading_spaces(node)).to_s
63
+ padding = indentation(node) + leading_spaces(node)
63
64
  padding_for_trailing_end = padding.sub(' ' * node.loc.end.column, '')
64
65
 
65
66
  replace_namespace_keyword(corrector, node)
@@ -124,10 +125,6 @@ module RuboCop
124
125
  corrector.remove(range)
125
126
  end
126
127
 
127
- def configured_indentation_width
128
- config.for_badge(Layout::IndentationWidth.badge).fetch('Width', 2)
129
- end
130
-
131
128
  def unindent(corrector, node)
132
129
  return if node.body.children.last.nil?
133
130
 
@@ -141,12 +138,8 @@ module RuboCop
141
138
  node.source_range.source_line[/\A\s*/]
142
139
  end
143
140
 
144
- def indent_width
145
- @config.for_cop('Layout/IndentationWidth')['Width'] || 2
146
- end
147
-
148
141
  def check_style(node, body)
149
- return if node.identifier.children[0]&.cbase_type?
142
+ return if node.identifier.namespace&.cbase_type?
150
143
 
151
144
  if style == :nested
152
145
  check_nested_style(node)
@@ -185,7 +178,7 @@ module RuboCop
185
178
  end
186
179
 
187
180
  def compact_node_name?(node)
188
- /::/.match?(node.identifier.source)
181
+ node.identifier.source.include?('::')
189
182
  end
190
183
  end
191
184
  end
@@ -5,7 +5,7 @@ module RuboCop
5
5
  module Style
6
6
  # Enforces the use of `Object#instance_of?` instead of class comparison
7
7
  # for equality.
8
- # `==`, `equal?`, and `eql?` methods are allowed by default.
8
+ # `==`, `equal?`, and `eql?` custom method definitions are allowed by default.
9
9
  # These are customizable with `AllowedMethods` option.
10
10
  #
11
11
  # @example
@@ -18,45 +18,31 @@ module RuboCop
18
18
  # # good
19
19
  # var.instance_of?(Date)
20
20
  #
21
- # @example AllowedMethods: [] (default)
21
+ # @example AllowedMethods: ['==', 'equal?', 'eql?'] (default)
22
22
  # # good
23
- # var.instance_of?(Date)
23
+ # def ==(other)
24
+ # self.class == other.class && name == other.name
25
+ # end
24
26
  #
25
- # # bad
26
- # var.class == Date
27
- # var.class.equal?(Date)
28
- # var.class.eql?(Date)
29
- # var.class.name == 'Date'
27
+ # def equal?(other)
28
+ # self.class.equal?(other.class) && name.equal?(other.name)
29
+ # end
30
30
  #
31
- # @example AllowedMethods: [`==`]
32
- # # good
33
- # var.instance_of?(Date)
34
- # var.class == Date
35
- # var.class.name == 'Date'
36
- #
37
- # # bad
38
- # var.class.equal?(Date)
39
- # var.class.eql?(Date)
31
+ # def eql?(other)
32
+ # self.class.eql?(other.class) && name.eql?(other.name)
33
+ # end
40
34
  #
41
35
  # @example AllowedPatterns: [] (default)
42
- # # good
43
- # var.instance_of?(Date)
44
- #
45
36
  # # bad
46
- # var.class == Date
47
- # var.class.equal?(Date)
48
- # var.class.eql?(Date)
49
- # var.class.name == 'Date'
37
+ # def eq(other)
38
+ # self.class.eq(other.class) && name.eq(other.name)
39
+ # end
50
40
  #
51
- # @example AllowedPatterns: [`/eq/`]
41
+ # @example AllowedPatterns: ['eq']
52
42
  # # good
53
- # var.instance_of?(Date)
54
- # var.class.equal?(Date)
55
- # var.class.eql?(Date)
56
- #
57
- # # bad
58
- # var.class == Date
59
- # var.class.name == 'Date'
43
+ # def eq(other)
44
+ # self.class.eq(other.class) && name.eq(other.name)
45
+ # end
60
46
  #
61
47
  class ClassEqualityComparison < Base
62
48
  include RangeHelp
@@ -64,14 +50,15 @@ module RuboCop
64
50
  include AllowedPattern
65
51
  extend AutoCorrector
66
52
 
67
- MSG = 'Use `instance_of?(%<class_name>s)` instead of comparing classes.'
53
+ MSG = 'Use `instance_of?%<class_argument>s` instead of comparing classes.'
68
54
 
69
55
  RESTRICT_ON_SEND = %i[== equal? eql?].freeze
56
+ CLASS_NAME_METHODS = %i[name to_s inspect].freeze
70
57
 
71
58
  # @!method class_comparison_candidate?(node)
72
59
  def_node_matcher :class_comparison_candidate?, <<~PATTERN
73
60
  (send
74
- {$(send _ :class) (send $(send _ :class) :name)}
61
+ {$(send _ :class) (send $(send _ :class) #class_name_method?)}
75
62
  {:== :equal? :eql?} $_)
76
63
  PATTERN
77
64
 
@@ -83,10 +70,12 @@ module RuboCop
83
70
 
84
71
  class_comparison_candidate?(node) do |receiver_node, class_node|
85
72
  range = offense_range(receiver_node, node)
86
- class_name = class_name(class_node, node)
73
+ class_argument = (class_name = class_name(class_node, node)) ? "(#{class_name})" : ''
74
+
75
+ add_offense(range, message: format(MSG, class_argument: class_argument)) do |corrector|
76
+ next unless class_name
87
77
 
88
- add_offense(range, message: format(MSG, class_name: class_name)) do |corrector|
89
- corrector.replace(range, "instance_of?(#{class_name})")
78
+ corrector.replace(range, "instance_of?#{class_argument}")
90
79
  end
91
80
  end
92
81
  end
@@ -94,15 +83,39 @@ module RuboCop
94
83
  private
95
84
 
96
85
  def class_name(class_node, node)
97
- if node.children.first.method?(:name)
98
- return class_node.receiver.source if class_node.receiver
99
-
100
- value = class_node.source.delete('"').delete("'")
101
- value.prepend('::') if class_node.each_ancestor(:class, :module).any?
102
- value
103
- else
104
- class_node.source
86
+ if class_name_method?(node.children.first.method_name)
87
+ if (receiver = class_node.receiver) && class_name_method?(class_node.method_name)
88
+ return receiver.source
89
+ end
90
+
91
+ if class_node.str_type?
92
+ value = trim_string_quotes(class_node)
93
+ value.prepend('::') if require_cbase?(class_node)
94
+ return value
95
+ elsif unable_to_determine_type?(class_node)
96
+ # When a variable or return value of a method is used, it returns nil
97
+ # because the type is not known and cannot be suggested.
98
+ return
99
+ end
105
100
  end
101
+
102
+ class_node.source
103
+ end
104
+
105
+ def class_name_method?(method_name)
106
+ CLASS_NAME_METHODS.include?(method_name)
107
+ end
108
+
109
+ def require_cbase?(class_node)
110
+ class_node.each_ancestor(:class, :module).any?
111
+ end
112
+
113
+ def unable_to_determine_type?(class_node)
114
+ class_node.variable? || class_node.call_type?
115
+ end
116
+
117
+ def trim_string_quotes(class_node)
118
+ class_node.source.delete('"').delete("'")
106
119
  end
107
120
 
108
121
  def offense_range(receiver_node, node)
@@ -70,7 +70,7 @@ module RuboCop
70
70
 
71
71
  def on_sclass(node)
72
72
  return unless def_self_style?
73
- return unless node.identifier.source == 'self'
73
+ return unless node.identifier.self_type?
74
74
  return unless all_methods_public?(node)
75
75
 
76
76
  add_offense(node, message: MSG_SCLASS) do |corrector|
@@ -80,6 +80,7 @@ module RuboCop
80
80
 
81
81
  def on_defs(node)
82
82
  return if def_self_style?
83
+ return unless node.receiver.self_type?
83
84
 
84
85
  message = format(MSG, preferred: 'class << self')
85
86
  add_offense(node, message: message)
@@ -8,7 +8,9 @@ module RuboCop
8
8
  #
9
9
  # @safety
10
10
  # It is unsafe by default because false positives may occur in the
11
- # `nil` check of block arguments to the receiver object.
11
+ # `nil` check of block arguments to the receiver object. Additionally,
12
+ # we can't know the type of the receiver object for sure, which may
13
+ # result in false positives as well.
12
14
  #
13
15
  # For example, `[[1, 2], [3, nil]].reject { |first, second| second.nil? }`
14
16
  # and `[[1, 2], [3, nil]].compact` are not compatible. This will work fine
@@ -17,7 +19,9 @@ module RuboCop
17
19
  # @example
18
20
  # # bad
19
21
  # array.reject(&:nil?)
22
+ # array.delete_if(&:nil?)
20
23
  # array.reject { |e| e.nil? }
24
+ # array.delete_if { |e| e.nil? }
21
25
  # array.select { |e| !e.nil? }
22
26
  #
23
27
  # # good
@@ -31,17 +35,25 @@ module RuboCop
31
35
  # # good
32
36
  # hash.compact!
33
37
  #
38
+ # @example AllowedReceivers: ['params']
39
+ # # good
40
+ # params.reject(&:nil?)
41
+ #
34
42
  class CollectionCompact < Base
43
+ include AllowedReceivers
35
44
  include RangeHelp
36
45
  extend AutoCorrector
46
+ extend TargetRubyVersion
37
47
 
38
48
  MSG = 'Use `%<good>s` instead of `%<bad>s`.'
49
+ RESTRICT_ON_SEND = %i[reject delete_if reject! select select!].freeze
50
+ TO_ENUM_METHODS = %i[to_enum lazy].freeze
39
51
 
40
- RESTRICT_ON_SEND = %i[reject reject! select select!].freeze
52
+ minimum_target_ruby_version 2.4
41
53
 
42
54
  # @!method reject_method_with_block_pass?(node)
43
55
  def_node_matcher :reject_method_with_block_pass?, <<~PATTERN
44
- (send !nil? {:reject :reject!}
56
+ (send !nil? {:reject :delete_if :reject!}
45
57
  (block_pass
46
58
  (sym :nil?)))
47
59
  PATTERN
@@ -50,7 +62,7 @@ module RuboCop
50
62
  def_node_matcher :reject_method?, <<~PATTERN
51
63
  (block
52
64
  (send
53
- !nil? {:reject :reject!})
65
+ !nil? {:reject :delete_if :reject!})
54
66
  $(args ...)
55
67
  (send
56
68
  $(lvar _) :nil?))
@@ -69,6 +81,10 @@ module RuboCop
69
81
 
70
82
  def on_send(node)
71
83
  return unless (range = offense_range(node))
84
+ return if allowed_receiver?(node.receiver)
85
+ if (target_ruby_version <= 3.0 || node.method?(:delete_if)) && to_enum_method?(node)
86
+ return
87
+ end
72
88
 
73
89
  good = good_method_name(node)
74
90
  message = format(MSG, good: good, bad: range.source)
@@ -94,6 +110,12 @@ module RuboCop
94
110
  end
95
111
  end
96
112
 
113
+ def to_enum_method?(node)
114
+ return false unless node.receiver.send_type?
115
+
116
+ TO_ENUM_METHODS.include?(node.receiver.method_name)
117
+ end
118
+
97
119
  def good_method_name(node)
98
120
  if node.bang_method?
99
121
  'compact!'
@@ -103,7 +125,7 @@ module RuboCop
103
125
  end
104
126
 
105
127
  def range(begin_pos_node, end_pos_node)
106
- range_between(begin_pos_node.loc.selector.begin_pos, end_pos_node.loc.end.end_pos)
128
+ range_between(begin_pos_node.loc.selector.begin_pos, end_pos_node.source_range.end_pos)
107
129
  end
108
130
  end
109
131
  end
@@ -48,6 +48,8 @@ module RuboCop
48
48
  check_method_node(node.send_node)
49
49
  end
50
50
 
51
+ alias on_numblock on_block
52
+
51
53
  def on_send(node)
52
54
  return unless implicit_block?(node)
53
55
 
@@ -3,8 +3,8 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for methods invoked via the :: operator instead
7
- # of the . operator (like FileUtils::rmdir instead of FileUtils.rmdir).
6
+ # Checks for methods invoked via the `::` operator instead
7
+ # of the `.` operator (like `FileUtils::rmdir` instead of `FileUtils.rmdir`).
8
8
  #
9
9
  # @example
10
10
  # # bad