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
@@ -57,36 +57,58 @@ module RuboCop
57
57
  # end
58
58
  #
59
59
  class CombinableLoops < Base
60
+ extend AutoCorrector
61
+
62
+ include RangeHelp
63
+
60
64
  MSG = 'Combine this loop with the previous loop.'
61
65
 
62
66
  def on_block(node)
63
67
  return unless node.parent&.begin_type?
64
68
  return unless collection_looping_method?(node)
69
+ return unless same_collection_looping_block?(node, node.left_sibling)
65
70
 
66
- add_offense(node) if same_collection_looping?(node, node.left_sibling)
71
+ add_offense(node) do |corrector|
72
+ combine_with_left_sibling(corrector, node)
73
+ end
67
74
  end
68
75
 
76
+ alias on_numblock on_block
77
+
69
78
  def on_for(node)
70
79
  return unless node.parent&.begin_type?
80
+ return unless same_collection_looping_for?(node, node.left_sibling)
71
81
 
72
- sibling = node.left_sibling
73
- add_offense(node) if sibling&.for_type? && node.collection == sibling.collection
82
+ add_offense(node) do |corrector|
83
+ combine_with_left_sibling(corrector, node)
84
+ end
74
85
  end
75
86
 
76
87
  private
77
88
 
78
89
  def collection_looping_method?(node)
79
- # TODO: Remove `Symbol#to_s` after supporting only Ruby >= 2.7.
80
- method_name = node.method_name.to_s
90
+ method_name = node.method_name
81
91
  method_name.start_with?('each') || method_name.end_with?('_each')
82
92
  end
83
93
 
84
- def same_collection_looping?(node, sibling)
85
- sibling&.block_type? &&
94
+ def same_collection_looping_block?(node, sibling)
95
+ (sibling&.block_type? || sibling&.numblock_type?) &&
86
96
  sibling.send_node.method?(node.method_name) &&
87
97
  sibling.receiver == node.receiver &&
88
98
  sibling.send_node.arguments == node.send_node.arguments
89
99
  end
100
+
101
+ def same_collection_looping_for?(node, sibling)
102
+ sibling&.for_type? && node.collection == sibling.collection
103
+ end
104
+
105
+ def combine_with_left_sibling(corrector, node)
106
+ corrector.replace(
107
+ node.left_sibling.body,
108
+ "#{node.left_sibling.body.source}\n#{node.body.source}"
109
+ )
110
+ corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
111
+ end
90
112
  end
91
113
  end
92
114
  end
@@ -148,7 +148,7 @@ module RuboCop
148
148
  end
149
149
 
150
150
  def contains_backtick?(node)
151
- /`/.match?(node_body(node))
151
+ node_body(node).include?('`')
152
152
  end
153
153
 
154
154
  def node_body(node)
@@ -104,7 +104,7 @@ module RuboCop
104
104
  end
105
105
 
106
106
  def inline_comment?(comment)
107
- !comment_line?(comment.loc.expression.source_line)
107
+ !comment_line?(comment.source_range.source_line)
108
108
  end
109
109
 
110
110
  def annotation_range(annotation)
@@ -66,7 +66,7 @@ module RuboCop
66
66
 
67
67
  def register_offense(comment, matched_keyword)
68
68
  add_offense(comment, message: format(MSG, keyword: matched_keyword)) do |corrector|
69
- range = range_with_surrounding_space(comment.loc.expression, newlines: false)
69
+ range = range_with_surrounding_space(comment.source_range, newlines: false)
70
70
  corrector.remove(range)
71
71
 
72
72
  unless matched_keyword == 'end'
@@ -84,7 +84,7 @@ module RuboCop
84
84
  end
85
85
 
86
86
  def source_line(comment)
87
- comment.location.expression.source_line
87
+ comment.source_range.source_line
88
88
  end
89
89
  end
90
90
  end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Enforces the use of `Comparable#clamp` instead of comparison by minimum and maximum.
7
+ #
8
+ # This cop supports autocorrection for `if/elsif/else` bad style only.
9
+ # Because `ArgumentError` occurs if the minimum and maximum of `clamp` arguments are reversed.
10
+ # When these are variables, it is not possible to determine which is the minimum and maximum:
11
+ #
12
+ # [source,ruby]
13
+ # ----
14
+ # [1, [2, 3].max].min # => 1
15
+ # 1.clamp(3, 1) # => min argument must be smaller than max argument (ArgumentError)
16
+ # ----
17
+ #
18
+ # @example
19
+ #
20
+ # # bad
21
+ # [[x, low].max, high].min
22
+ #
23
+ # # bad
24
+ # if x < low
25
+ # low
26
+ # elsif high < x
27
+ # high
28
+ # else
29
+ # x
30
+ # end
31
+ #
32
+ # # good
33
+ # x.clamp(low, high)
34
+ #
35
+ class ComparableClamp < Base
36
+ include Alignment
37
+ extend AutoCorrector
38
+ extend TargetRubyVersion
39
+
40
+ minimum_target_ruby_version 2.4
41
+
42
+ MSG = 'Use `%<prefer>s` instead of `if/elsif/else`.'
43
+ MSG_MIN_MAX = 'Use `Comparable#clamp` instead.'
44
+ RESTRICT_ON_SEND = %i[min max].freeze
45
+
46
+ # @!method if_elsif_else_condition?(node)
47
+ def_node_matcher :if_elsif_else_condition?, <<~PATTERN
48
+ {
49
+ (if (send _x :< _min) _min (if (send _max :< _x) _max _x))
50
+ (if (send _min :> _x) _min (if (send _max :< _x) _max _x))
51
+ (if (send _x :< _min) _min (if (send _x :> _max) _max _x))
52
+ (if (send _min :> _x) _min (if (send _x :> _max) _max _x))
53
+ (if (send _max :< _x) _max (if (send _x :< _min) _min _x))
54
+ (if (send _x :> _max) _max (if (send _x :< _min) _min _x))
55
+ (if (send _max :< _x) _max (if (send _min :> _x) _min _x))
56
+ (if (send _x :> _max) _max (if (send _min :> _x) _min _x))
57
+ }
58
+ PATTERN
59
+
60
+ # @!method array_min_max?(node)
61
+ def_node_matcher :array_min_max?, <<~PATTERN
62
+ {
63
+ (send
64
+ (array
65
+ (send (array _ _) :max) _) :min)
66
+ (send
67
+ (array
68
+ _ (send (array _ _) :max)) :min)
69
+ (send
70
+ (array
71
+ (send (array _ _) :min) _) :max)
72
+ (send
73
+ (array
74
+ _ (send (array _ _) :min)) :max)
75
+ }
76
+ PATTERN
77
+
78
+ def on_if(node)
79
+ return unless if_elsif_else_condition?(node)
80
+
81
+ if_body, elsif_body, else_body = *node.branches
82
+
83
+ else_body_source = else_body.source
84
+
85
+ if min_condition?(node.condition, else_body_source)
86
+ min = if_body.source
87
+ max = elsif_body.source
88
+ else
89
+ min = elsif_body.source
90
+ max = if_body.source
91
+ end
92
+
93
+ prefer = "#{else_body_source}.clamp(#{min}, #{max})"
94
+
95
+ add_offense(node, message: format(MSG, prefer: prefer)) do |corrector|
96
+ autocorrect(corrector, node, prefer)
97
+ end
98
+ end
99
+
100
+ def on_send(node)
101
+ return unless array_min_max?(node)
102
+
103
+ add_offense(node, message: MSG_MIN_MAX)
104
+ end
105
+
106
+ private
107
+
108
+ def autocorrect(corrector, node, prefer)
109
+ if node.elsif?
110
+ corrector.insert_before(node, "else\n")
111
+ corrector.replace(node, "#{indentation(node)}#{prefer}")
112
+ else
113
+ corrector.replace(node, prefer)
114
+ end
115
+ end
116
+
117
+ def min_condition?(if_condition, else_body)
118
+ lhs, op, rhs = *if_condition
119
+
120
+ (lhs.source == else_body && op == :<) || (rhs.source == else_body && op == :>)
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Enforces the use of `Array#push(item)` instead of `Array#concat([item])`
7
+ # to avoid redundant array literals.
8
+ #
9
+ # @safety
10
+ # This cop is unsafe, as it can produce false positives if the receiver
11
+ # is not an `Array` object.
12
+ #
13
+ # @example
14
+ #
15
+ # # bad
16
+ # list.concat([foo])
17
+ # list.concat([bar, baz])
18
+ # list.concat([qux, quux], [corge])
19
+ #
20
+ # # good
21
+ # list.push(foo)
22
+ # list.push(bar, baz)
23
+ # list.push(qux, quux, corge)
24
+ #
25
+ class ConcatArrayLiterals < Base
26
+ extend AutoCorrector
27
+
28
+ MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
29
+ MSG_FOR_PERCENT_LITERALS =
30
+ 'Use `push` with elements as arguments without array brackets instead of `%<current>s`.'
31
+ RESTRICT_ON_SEND = %i[concat].freeze
32
+
33
+ # rubocop:disable Metrics
34
+ def on_send(node)
35
+ return if node.arguments.empty?
36
+ return unless node.arguments.all?(&:array_type?)
37
+
38
+ offense = offense_range(node)
39
+ current = offense.source
40
+
41
+ if (use_percent_literal = node.arguments.any?(&:percent_literal?))
42
+ if percent_literals_includes_only_basic_literals?(node)
43
+ prefer = preferred_method(node)
44
+ message = format(MSG, prefer: prefer, current: current)
45
+ else
46
+ message = format(MSG_FOR_PERCENT_LITERALS, current: current)
47
+ end
48
+ else
49
+ prefer = preferred_method(node)
50
+ message = format(MSG, prefer: prefer, current: current)
51
+ end
52
+
53
+ add_offense(offense, message: message) do |corrector|
54
+ if use_percent_literal
55
+ corrector.replace(offense, prefer)
56
+ else
57
+ corrector.replace(node.loc.selector, 'push')
58
+ node.arguments.each do |argument|
59
+ corrector.remove(argument.loc.begin)
60
+ corrector.remove(argument.loc.end)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ # rubocop:enable Metrics
66
+
67
+ private
68
+
69
+ def offense_range(node)
70
+ node.loc.selector.join(node.source_range.end)
71
+ end
72
+
73
+ def preferred_method(node)
74
+ new_arguments =
75
+ node.arguments.map do |arg|
76
+ if arg.percent_literal?
77
+ arg.children.map(&:value).map(&:inspect)
78
+ else
79
+ arg.children.map(&:source)
80
+ end
81
+ end.join(', ')
82
+
83
+ "push(#{new_arguments})"
84
+ end
85
+
86
+ def percent_literals_includes_only_basic_literals?(node)
87
+ node.arguments.select(&:percent_literal?).all? do |arg|
88
+ arg.children.all? { |child| child.str_type? || child.sym_type? }
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -218,11 +218,9 @@ module RuboCop
218
218
  VARIABLE_ASSIGNMENT_TYPES = %i[casgn cvasgn gvasgn ivasgn lvasgn].freeze
219
219
  ASSIGNMENT_TYPES = VARIABLE_ASSIGNMENT_TYPES + %i[and_asgn or_asgn op_asgn masgn].freeze
220
220
  LINE_LENGTH = 'Layout/LineLength'
221
- INDENTATION_WIDTH = 'Layout/IndentationWidth'
222
221
  ENABLED = 'Enabled'
223
222
  MAX = 'Max'
224
223
  SINGLE_LINE_CONDITIONS_ONLY = 'SingleLineConditionsOnly'
225
- WIDTH = 'Width'
226
224
 
227
225
  # The shovel operator `<<` does not have its own type. It is a `send`
228
226
  # type.
@@ -352,7 +350,7 @@ module RuboCop
352
350
  end
353
351
 
354
352
  def ternary_condition?(node)
355
- [node, node.children.first].any? { |n| n.if_type? && n.ternary? }
353
+ [node, node.children.first].compact.any? { |n| n.if_type? && n.ternary? }
356
354
  end
357
355
 
358
356
  def lhs_all_match?(branches)
@@ -363,7 +361,7 @@ module RuboCop
363
361
  end
364
362
 
365
363
  def assignment_types_match?(*nodes)
366
- return unless assignment_type?(nodes.first)
364
+ return false unless assignment_type?(nodes.first)
367
365
 
368
366
  nodes.map(&:type).uniq.one?
369
367
  end
@@ -388,7 +386,7 @@ module RuboCop
388
386
  def allowed_statements?(branches)
389
387
  return false unless branches.all?
390
388
 
391
- statements = branches.map { |branch| tail(branch) }.compact
389
+ statements = branches.filter_map { |branch| tail(branch) }
392
390
 
393
391
  lhs_all_match?(statements) && statements.none?(&:masgn_type?) &&
394
392
  assignment_types_match?(*statements)
@@ -428,10 +426,6 @@ module RuboCop
428
426
  config.for_cop(LINE_LENGTH)[MAX]
429
427
  end
430
428
 
431
- def indentation_width
432
- config.for_cop(INDENTATION_WIDTH)[WIDTH] || 2
433
- end
434
-
435
429
  def single_line_conditions_only?
436
430
  cop_config[SINGLE_LINE_CONDITIONS_ONLY]
437
431
  end
@@ -446,6 +440,8 @@ module RuboCop
446
440
  module ConditionalCorrectorHelper
447
441
  def remove_whitespace_in_branches(corrector, branch, condition, column)
448
442
  branch.each_node do |child|
443
+ next if child.source_range.nil?
444
+
449
445
  white_space = white_space_range(child, column)
450
446
  corrector.remove(white_space) if white_space.source.strip.empty?
451
447
  end
@@ -456,7 +452,7 @@ module RuboCop
456
452
  end
457
453
 
458
454
  def white_space_range(node, column)
459
- expression = node.loc.expression
455
+ expression = node.source_range
460
456
  begin_pos = expression.begin_pos - (expression.column - column - 2)
461
457
 
462
458
  Parser::Source::Range.new(expression.source_buffer, begin_pos, expression.begin_pos)
@@ -464,9 +460,9 @@ module RuboCop
464
460
 
465
461
  def assignment(node)
466
462
  *_, condition = *node
467
- Parser::Source::Range.new(node.loc.expression.source_buffer,
468
- node.loc.expression.begin_pos,
469
- condition.loc.expression.begin_pos)
463
+ Parser::Source::Range.new(node.source_range.source_buffer,
464
+ node.source_range.begin_pos,
465
+ condition.source_range.begin_pos)
470
466
  end
471
467
 
472
468
  def correct_if_branches(corrector, cop, node)
@@ -571,7 +567,7 @@ module RuboCop
571
567
  end
572
568
 
573
569
  def move_assignment_inside_condition(corrector, node)
574
- column = node.loc.expression.column
570
+ column = node.source_range.column
575
571
  *_var, condition = *node
576
572
  assignment = assignment(node)
577
573
 
@@ -622,7 +618,7 @@ module RuboCop
622
618
  end
623
619
 
624
620
  def move_assignment_inside_condition(corrector, node)
625
- column = node.loc.expression.column
621
+ column = node.source_range.column
626
622
  *_var, condition = *node
627
623
  assignment = assignment(node)
628
624
 
@@ -8,8 +8,11 @@ module RuboCop
8
8
  # The default regexp for an acceptable copyright notice can be found in
9
9
  # config/default.yml. The default can be changed as follows:
10
10
  #
11
- # Style/Copyright:
12
- # Notice: '^Copyright (\(c\) )?2\d{3} Acme Inc'
11
+ # [source,yaml]
12
+ # ----
13
+ # Style/Copyright:
14
+ # Notice: '^Copyright (\(c\) )?2\d{3} Acme Inc'
15
+ # ----
13
16
  #
14
17
  # This regex string is treated as an unanchored regex. For each file
15
18
  # that RuboCop scans, a comment that matches this regex must be found or
@@ -82,7 +85,7 @@ module RuboCop
82
85
  def notice_found?(processed_source)
83
86
  notice_found = false
84
87
  notice_regexp = Regexp.new(notice)
85
- processed_source.each_token do |token|
88
+ processed_source.tokens.each do |token|
86
89
  break unless token.comment?
87
90
 
88
91
  notice_found = notice_regexp.match?(token.text)
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for inheritance from `Data.define` to avoid creating the anonymous parent class.
7
+ #
8
+ # @safety
9
+ # Autocorrection is unsafe because it will change the inheritance
10
+ # tree (e.g. return value of `Module#ancestors`) of the constant.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # class Person < Data.define(:first_name, :last_name)
15
+ # def age
16
+ # 42
17
+ # end
18
+ # end
19
+ #
20
+ # # good
21
+ # Person = Data.define(:first_name, :last_name) do
22
+ # def age
23
+ # 42
24
+ # end
25
+ # end
26
+ class DataInheritance < Base
27
+ include RangeHelp
28
+ extend AutoCorrector
29
+ extend TargetRubyVersion
30
+
31
+ MSG = "Don't extend an instance initialized by `Data.define`. " \
32
+ 'Use a block to customize the class.'
33
+
34
+ minimum_target_ruby_version 3.2
35
+
36
+ def on_class(node)
37
+ return unless data_define?(node.parent_class)
38
+
39
+ add_offense(node.parent_class.source_range) do |corrector|
40
+ corrector.remove(range_with_surrounding_space(node.loc.keyword, newlines: false))
41
+ corrector.replace(node.loc.operator, '=')
42
+
43
+ correct_parent(node.parent_class, corrector)
44
+ end
45
+ end
46
+
47
+ # @!method data_define?(node)
48
+ def_node_matcher :data_define?, <<~PATTERN
49
+ {(send (const {nil? cbase} :Data) :define ...)
50
+ (block (send (const {nil? cbase} :Data) :define ...) ...)}
51
+ PATTERN
52
+
53
+ private
54
+
55
+ def correct_parent(parent, corrector)
56
+ if parent.block_type?
57
+ corrector.remove(range_with_surrounding_space(parent.loc.end, newlines: false))
58
+ elsif (class_node = parent.parent).body.nil?
59
+ corrector.remove(range_for_empty_class_body(class_node, parent))
60
+ else
61
+ corrector.insert_after(parent, ' do')
62
+ end
63
+ end
64
+
65
+ def range_for_empty_class_body(class_node, data_define)
66
+ if class_node.single_line?
67
+ range_between(data_define.source_range.end_pos, class_node.source_range.end_pos)
68
+ else
69
+ range_by_whole_lines(class_node.loc.end, include_final_newline: true)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for places where the `#__dir__` method can replace more
6
+ # Checks for places where the `#\_\_dir\_\_` method can replace more
7
7
  # complex constructs to retrieve a canonicalized absolute path to the
8
8
  # current file.
9
9
  #
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Prefer to use `Dir.empty?('path/to/dir')` when checking if a directory is empty.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # Dir.entries('path/to/dir').size == 2
11
+ # Dir.children('path/to/dir').empty?
12
+ # Dir.children('path/to/dir').size == 0
13
+ # Dir.each_child('path/to/dir').none?
14
+ #
15
+ # # good
16
+ # Dir.empty?('path/to/dir')
17
+ #
18
+ class DirEmpty < Base
19
+ extend AutoCorrector
20
+ extend TargetRubyVersion
21
+
22
+ MSG = 'Use `%<replacement>s` instead.'
23
+ RESTRICT_ON_SEND = %i[== != > empty? none?].freeze
24
+
25
+ minimum_target_ruby_version 2.4
26
+
27
+ # @!method offensive?(node)
28
+ def_node_matcher :offensive?, <<~PATTERN
29
+ {
30
+ (send (send (send $(const {nil? cbase} :Dir) :entries $_) :size) {:== :!= :>} (int 2))
31
+ (send (send (send $(const {nil? cbase} :Dir) :children $_) :size) {:== :!= :>} (int 0))
32
+ (send (send $(const {nil? cbase} :Dir) :children $_) :empty?)
33
+ (send (send $(const {nil? cbase} :Dir) :each_child $_) :none?)
34
+ }
35
+ PATTERN
36
+
37
+ def on_send(node)
38
+ offensive?(node) do |const_node, arg_node|
39
+ replacement = "#{bang(node)}#{const_node.source}.empty?(#{arg_node.source})"
40
+ add_offense(node, message: format(MSG, replacement: replacement)) do |corrector|
41
+ corrector.replace(node, replacement)
42
+ end
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def bang(node)
49
+ '!' if %i[!= >].include? node.method_name
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -34,8 +34,8 @@ module RuboCop
34
34
  extend AutoCorrector
35
35
 
36
36
  # rubocop:enable Lint/RedundantCopDisableDirective
37
- MSG = 'Rubocop disable/enable directives are not permitted.'
38
- MSG_FOR_COPS = 'Rubocop disable/enable directives for %<cops>s are not permitted.'
37
+ MSG = 'RuboCop disable/enable directives are not permitted.'
38
+ MSG_FOR_COPS = 'RuboCop disable/enable directives for %<cops>s are not permitted.'
39
39
 
40
40
  def on_new_investigation
41
41
  processed_source.comments.each do |comment|
@@ -108,15 +108,15 @@ module RuboCop
108
108
  comments = heredoc_comment_blocks(arg_node.loc.heredoc_body.line_span)
109
109
  .concat(preceding_comment_blocks(arg_node.parent))
110
110
 
111
- return if comments.none?
111
+ return false if comments.none?
112
112
 
113
113
  regexp = comment_regexp(arg_node)
114
- comments.any? { |comment| regexp.match?(comment) } || regexp.match?(comments.join)
114
+ comments.any?(regexp) || regexp.match?(comments.join)
115
115
  end
116
116
 
117
117
  def preceding_comment_blocks(node)
118
118
  # Collect comments in the method call, but outside the heredoc
119
- comments = processed_source.each_comment_in_lines(node.loc.expression.line_span)
119
+ comments = processed_source.each_comment_in_lines(node.source_range.line_span)
120
120
 
121
121
  comments.each_with_object({}) do |comment, hash|
122
122
  merge_adjacent_comments(comment.text, comment.loc.line, hash)