rubocop 1.50.2 → 1.68.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 (494) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +73 -72
  4. data/assets/output.css.erb +159 -0
  5. data/assets/output.html.erb +1 -160
  6. data/config/default.yml +316 -38
  7. data/config/internal_affairs.yml +11 -0
  8. data/config/obsoletion.yml +5 -0
  9. data/exe/rubocop +4 -3
  10. data/lib/rubocop/cached_data.rb +21 -5
  11. data/lib/rubocop/cli/command/auto_generate_config.rb +28 -15
  12. data/lib/rubocop/cli/command/execute_runner.rb +1 -1
  13. data/lib/rubocop/cli/command/lsp.rb +19 -0
  14. data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
  15. data/lib/rubocop/cli/command/version.rb +2 -2
  16. data/lib/rubocop/cli.rb +14 -2
  17. data/lib/rubocop/comment_config.rb +1 -1
  18. data/lib/rubocop/config.rb +45 -13
  19. data/lib/rubocop/config_finder.rb +14 -4
  20. data/lib/rubocop/config_loader.rb +15 -10
  21. data/lib/rubocop/config_loader_resolver.rb +17 -11
  22. data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
  23. data/lib/rubocop/config_obsoletion.rb +13 -10
  24. data/lib/rubocop/config_validator.rb +17 -9
  25. data/lib/rubocop/cop/autocorrect_logic.rb +30 -3
  26. data/lib/rubocop/cop/base.rb +78 -19
  27. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -0
  28. data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
  29. data/lib/rubocop/cop/bundler/gem_comment.rb +3 -3
  30. data/lib/rubocop/cop/bundler/gem_version.rb +6 -7
  31. data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
  32. data/lib/rubocop/cop/cop.rb +30 -4
  33. data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -13
  34. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
  35. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
  36. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
  37. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
  38. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  39. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  40. data/lib/rubocop/cop/documentation.rb +32 -5
  41. data/lib/rubocop/cop/exclude_limit.rb +1 -1
  42. data/lib/rubocop/cop/force.rb +12 -0
  43. data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
  44. data/lib/rubocop/cop/gemspec/dependency_version.rb +5 -7
  45. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
  46. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  47. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  48. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
  49. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
  50. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
  51. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  52. data/lib/rubocop/cop/internal_affairs/cop_description.rb +32 -12
  53. data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
  54. data/lib/rubocop/cop/internal_affairs/example_description.rb +46 -24
  55. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
  56. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
  57. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
  58. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
  59. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +128 -34
  60. data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
  61. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  62. data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
  63. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +8 -1
  64. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +11 -1
  65. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -5
  66. data/lib/rubocop/cop/internal_affairs.rb +18 -0
  67. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +5 -1
  68. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
  69. data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
  70. data/lib/rubocop/cop/layout/block_alignment.rb +30 -12
  71. data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
  72. data/lib/rubocop/cop/layout/class_structure.rb +7 -0
  73. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
  74. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  75. data/lib/rubocop/cop/layout/condition_position.rb +0 -4
  76. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  77. data/lib/rubocop/cop/layout/dot_position.rb +1 -5
  78. data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
  79. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +43 -10
  80. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
  81. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
  82. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +29 -5
  83. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +10 -3
  84. data/lib/rubocop/cop/layout/end_alignment.rb +15 -3
  85. data/lib/rubocop/cop/layout/extra_spacing.rb +4 -10
  86. data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
  87. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +24 -10
  88. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  89. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
  90. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -4
  91. data/lib/rubocop/cop/layout/heredoc_indentation.rb +5 -2
  92. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  93. data/lib/rubocop/cop/layout/indentation_width.rb +8 -9
  94. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  95. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +17 -9
  96. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
  97. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
  98. data/lib/rubocop/cop/layout/line_length.rb +20 -20
  99. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
  100. data/lib/rubocop/cop/layout/redundant_line_break.rb +30 -7
  101. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -4
  102. data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
  103. data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
  104. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  105. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
  106. data/lib/rubocop/cop/layout/space_around_operators.rb +56 -21
  107. data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
  108. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  109. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +6 -0
  110. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
  111. data/lib/rubocop/cop/layout/space_inside_parens.rb +1 -1
  112. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  113. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
  114. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
  115. data/lib/rubocop/cop/legacy/corrector.rb +12 -2
  116. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -3
  117. data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
  118. data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
  119. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
  120. data/lib/rubocop/cop/lint/assignment_in_condition.rb +6 -6
  121. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  122. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
  123. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -3
  124. data/lib/rubocop/cop/lint/circular_argument_reference.rb +0 -13
  125. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  126. data/lib/rubocop/cop/lint/debugger.rb +45 -10
  127. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  128. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +0 -10
  129. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  130. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
  131. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -5
  132. data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -11
  133. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +46 -19
  134. data/lib/rubocop/cop/lint/duplicate_set_element.rb +74 -0
  135. data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
  136. data/lib/rubocop/cop/lint/else_layout.rb +0 -2
  137. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  138. data/lib/rubocop/cop/lint/empty_conditional_body.rb +29 -8
  139. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -11
  140. data/lib/rubocop/cop/lint/empty_interpolation.rb +0 -4
  141. data/lib/rubocop/cop/lint/empty_when.rb +1 -3
  142. data/lib/rubocop/cop/lint/ensure_return.rb +1 -9
  143. data/lib/rubocop/cop/lint/erb_new_arguments.rb +27 -21
  144. data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
  145. data/lib/rubocop/cop/lint/float_out_of_range.rb +0 -4
  146. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +0 -10
  147. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
  148. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -1
  149. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  150. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +23 -12
  151. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
  152. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +0 -7
  153. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  154. data/lib/rubocop/cop/lint/interpolation_check.rb +0 -4
  155. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +47 -0
  156. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  157. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
  158. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
  159. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +26 -7
  160. data/lib/rubocop/cop/lint/loop.rb +6 -12
  161. data/lib/rubocop/cop/lint/missing_super.rb +34 -5
  162. data/lib/rubocop/cop/lint/mixed_case_range.rb +116 -0
  163. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -7
  164. data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -25
  165. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +0 -5
  166. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +17 -7
  167. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
  168. data/lib/rubocop/cop/lint/number_conversion.rb +14 -4
  169. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  170. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
  171. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -2
  172. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -6
  173. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
  174. data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
  175. data/lib/rubocop/cop/lint/rand_one.rb +0 -4
  176. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +3 -1
  177. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
  178. data/lib/rubocop/cop/lint/redundant_require_statement.rb +12 -3
  179. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +72 -8
  180. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  181. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -5
  182. data/lib/rubocop/cop/lint/redundant_with_index.rb +6 -2
  183. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  184. data/lib/rubocop/cop/lint/require_parentheses.rb +0 -4
  185. data/lib/rubocop/cop/lint/rescue_exception.rb +0 -4
  186. data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
  187. data/lib/rubocop/cop/lint/return_in_void_context.rb +0 -2
  188. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +23 -12
  189. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +107 -41
  190. data/lib/rubocop/cop/lint/script_permission.rb +3 -3
  191. data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
  192. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
  193. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  194. data/lib/rubocop/cop/lint/shadowed_exception.rb +5 -11
  195. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -11
  196. data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
  197. data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
  198. data/lib/rubocop/cop/lint/symbol_conversion.rb +9 -4
  199. data/lib/rubocop/cop/lint/syntax.rb +6 -3
  200. data/lib/rubocop/cop/lint/to_enum_arguments.rb +6 -6
  201. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  202. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
  203. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  204. data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
  205. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +3 -2
  206. data/lib/rubocop/cop/lint/unreachable_code.rb +4 -7
  207. data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
  208. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  209. data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
  210. data/lib/rubocop/cop/lint/useless_assignment.rb +102 -15
  211. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +0 -4
  212. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +77 -0
  213. data/lib/rubocop/cop/lint/useless_setter_call.rb +0 -4
  214. data/lib/rubocop/cop/lint/useless_times.rb +2 -2
  215. data/lib/rubocop/cop/lint/void.rb +128 -15
  216. data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
  217. data/lib/rubocop/cop/metrics/block_length.rb +7 -6
  218. data/lib/rubocop/cop/metrics/block_nesting.rb +19 -7
  219. data/lib/rubocop/cop/metrics/class_length.rb +14 -8
  220. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +4 -1
  221. data/lib/rubocop/cop/metrics/method_length.rb +7 -6
  222. data/lib/rubocop/cop/metrics/module_length.rb +6 -5
  223. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
  224. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +37 -9
  225. data/lib/rubocop/cop/migration/department_name.rb +2 -2
  226. data/lib/rubocop/cop/mixin/alignment.rb +5 -1
  227. data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
  228. data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
  229. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  230. data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
  231. data/lib/rubocop/cop/mixin/check_line_breakable.rb +11 -1
  232. data/lib/rubocop/cop/mixin/code_length.rb +12 -1
  233. data/lib/rubocop/cop/mixin/comments_help.rb +19 -11
  234. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  235. data/lib/rubocop/cop/mixin/configurable_max.rb +5 -1
  236. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  237. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  238. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  239. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +22 -10
  240. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +23 -13
  241. data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
  242. data/lib/rubocop/cop/mixin/line_length_help.rb +7 -2
  243. data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
  244. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -3
  245. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  246. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  247. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
  248. data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
  249. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
  250. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  251. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  252. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -2
  253. data/lib/rubocop/cop/mixin/string_help.rb +4 -2
  254. data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
  255. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  256. data/lib/rubocop/cop/naming/accessor_method_name.rb +5 -0
  257. data/lib/rubocop/cop/naming/block_forwarding.rb +35 -8
  258. data/lib/rubocop/cop/naming/constant_name.rb +2 -3
  259. data/lib/rubocop/cop/naming/file_name.rb +3 -3
  260. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
  261. data/lib/rubocop/cop/naming/inclusive_language.rb +13 -5
  262. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +26 -11
  263. data/lib/rubocop/cop/naming/predicate_name.rb +55 -29
  264. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +21 -4
  265. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  266. data/lib/rubocop/cop/offense.rb +4 -5
  267. data/lib/rubocop/cop/registry.rb +1 -1
  268. data/lib/rubocop/cop/security/compound_hash.rb +2 -2
  269. data/lib/rubocop/cop/security/open.rb +2 -2
  270. data/lib/rubocop/cop/style/access_modifier_declarations.rb +63 -3
  271. data/lib/rubocop/cop/style/accessor_grouping.rb +14 -2
  272. data/lib/rubocop/cop/style/alias.rb +11 -9
  273. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  274. data/lib/rubocop/cop/style/arguments_forwarding.rb +459 -63
  275. data/lib/rubocop/cop/style/array_first_last.rb +64 -0
  276. data/lib/rubocop/cop/style/array_intersect.rb +13 -5
  277. data/lib/rubocop/cop/style/attr.rb +11 -1
  278. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
  279. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  280. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
  281. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  282. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  283. data/lib/rubocop/cop/style/block_delimiters.rb +36 -7
  284. data/lib/rubocop/cop/style/case_like_if.rb +5 -5
  285. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  286. data/lib/rubocop/cop/style/class_check.rb +1 -0
  287. data/lib/rubocop/cop/style/class_equality_comparison.rb +24 -39
  288. data/lib/rubocop/cop/style/class_vars.rb +3 -3
  289. data/lib/rubocop/cop/style/collection_compact.rb +31 -11
  290. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  291. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  292. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  293. data/lib/rubocop/cop/style/combinable_loops.rb +43 -8
  294. data/lib/rubocop/cop/style/commented_keyword.rb +12 -3
  295. data/lib/rubocop/cop/style/concat_array_literals.rb +2 -1
  296. data/lib/rubocop/cop/style/conditional_assignment.rb +13 -12
  297. data/lib/rubocop/cop/style/copyright.rb +36 -23
  298. data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
  299. data/lib/rubocop/cop/style/date_time.rb +5 -4
  300. data/lib/rubocop/cop/style/def_with_parentheses.rb +0 -2
  301. data/lib/rubocop/cop/style/dir.rb +1 -1
  302. data/lib/rubocop/cop/style/dir_empty.rb +8 -14
  303. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
  304. data/lib/rubocop/cop/style/documentation.rb +25 -25
  305. data/lib/rubocop/cop/style/documentation_method.rb +20 -0
  306. data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -8
  307. data/lib/rubocop/cop/style/each_with_object.rb +2 -2
  308. data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
  309. data/lib/rubocop/cop/style/empty_else.rb +6 -5
  310. data/lib/rubocop/cop/style/empty_heredoc.rb +1 -14
  311. data/lib/rubocop/cop/style/empty_literal.rb +32 -23
  312. data/lib/rubocop/cop/style/endless_method.rb +1 -14
  313. data/lib/rubocop/cop/style/eval_with_location.rb +24 -32
  314. data/lib/rubocop/cop/style/exact_regexp_match.rb +70 -0
  315. data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
  316. data/lib/rubocop/cop/style/file_read.rb +4 -7
  317. data/lib/rubocop/cop/style/file_write.rb +2 -5
  318. data/lib/rubocop/cop/style/for.rb +3 -1
  319. data/lib/rubocop/cop/style/format_string.rb +33 -12
  320. data/lib/rubocop/cop/style/format_string_token.rb +2 -2
  321. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -1
  322. data/lib/rubocop/cop/style/global_std_stream.rb +7 -1
  323. data/lib/rubocop/cop/style/guard_clause.rb +45 -2
  324. data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
  325. data/lib/rubocop/cop/style/hash_each_methods.rb +112 -33
  326. data/lib/rubocop/cop/style/hash_except.rb +29 -14
  327. data/lib/rubocop/cop/style/hash_syntax.rb +26 -4
  328. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  329. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  330. data/lib/rubocop/cop/style/identical_conditional_branches.rb +34 -5
  331. data/lib/rubocop/cop/style/if_inside_else.rb +7 -1
  332. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -0
  333. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -4
  334. data/lib/rubocop/cop/style/if_with_semicolon.rb +51 -8
  335. data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
  336. data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
  337. data/lib/rubocop/cop/style/invertible_unless_condition.rb +56 -10
  338. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  339. data/lib/rubocop/cop/style/lambda.rb +4 -4
  340. data/lib/rubocop/cop/style/lambda_call.rb +5 -0
  341. data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
  342. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +82 -50
  343. data/lib/rubocop/cop/style/map_into_array.rb +233 -0
  344. data/lib/rubocop/cop/style/map_to_hash.rb +18 -8
  345. data/lib/rubocop/cop/style/map_to_set.rb +1 -1
  346. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +40 -15
  347. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -5
  348. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +22 -2
  349. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  350. data/lib/rubocop/cop/style/missing_else.rb +0 -4
  351. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
  352. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  353. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  354. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  355. data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
  356. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +6 -4
  357. data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
  358. data/lib/rubocop/cop/style/multiple_comparison.rb +41 -46
  359. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  360. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  361. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
  362. data/lib/rubocop/cop/style/next.rb +1 -1
  363. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  364. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  365. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  366. data/lib/rubocop/cop/style/numeric_predicate.rb +12 -4
  367. data/lib/rubocop/cop/style/object_then.rb +5 -3
  368. data/lib/rubocop/cop/style/one_line_conditional.rb +6 -2
  369. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  370. data/lib/rubocop/cop/style/operator_method_call.rb +32 -7
  371. data/lib/rubocop/cop/style/parallel_assignment.rb +8 -9
  372. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  373. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  374. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  375. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -3
  376. data/lib/rubocop/cop/style/raise_args.rb +4 -1
  377. data/lib/rubocop/cop/style/redundant_argument.rb +33 -4
  378. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  379. data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
  380. data/lib/rubocop/cop/style/redundant_begin.rb +15 -3
  381. data/lib/rubocop/cop/style/redundant_condition.rb +4 -4
  382. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -10
  383. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +39 -0
  384. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +93 -5
  385. data/lib/rubocop/cop/style/redundant_each.rb +7 -4
  386. data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
  387. data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
  388. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
  389. data/lib/rubocop/cop/style/redundant_filter_chain.rb +118 -0
  390. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +46 -0
  391. data/lib/rubocop/cop/style/redundant_line_continuation.rb +48 -9
  392. data/lib/rubocop/cop/style/redundant_parentheses.rb +80 -33
  393. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  394. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +103 -0
  395. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  396. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +9 -24
  397. data/lib/rubocop/cop/style/redundant_return.rb +14 -3
  398. data/lib/rubocop/cop/style/redundant_self.rb +17 -2
  399. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +8 -1
  400. data/lib/rubocop/cop/style/redundant_sort.rb +10 -9
  401. data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
  402. data/lib/rubocop/cop/style/redundant_string_escape.rb +3 -1
  403. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  404. data/lib/rubocop/cop/style/require_order.rb +13 -7
  405. data/lib/rubocop/cop/style/rescue_modifier.rb +14 -4
  406. data/lib/rubocop/cop/style/return_nil.rb +6 -2
  407. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +137 -0
  408. data/lib/rubocop/cop/style/safe_navigation.rb +106 -52
  409. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  410. data/lib/rubocop/cop/style/sample.rb +3 -4
  411. data/lib/rubocop/cop/style/select_by_regexp.rb +29 -15
  412. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  413. data/lib/rubocop/cop/style/semicolon.rb +21 -5
  414. data/lib/rubocop/cop/style/send.rb +4 -4
  415. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +104 -0
  416. data/lib/rubocop/cop/style/signal_exception.rb +1 -1
  417. data/lib/rubocop/cop/style/single_argument_dig.rb +7 -3
  418. data/lib/rubocop/cop/style/single_line_do_end_block.rb +67 -0
  419. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  420. data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
  421. data/lib/rubocop/cop/style/sole_nested_conditional.rb +27 -4
  422. data/lib/rubocop/cop/style/special_global_vars.rb +4 -6
  423. data/lib/rubocop/cop/style/string_chars.rb +1 -0
  424. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
  425. data/lib/rubocop/cop/style/strip.rb +7 -4
  426. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  427. data/lib/rubocop/cop/style/super_arguments.rb +174 -0
  428. data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
  429. data/lib/rubocop/cop/style/symbol_array.rb +35 -15
  430. data/lib/rubocop/cop/style/symbol_proc.rb +75 -5
  431. data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
  432. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  433. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  434. data/lib/rubocop/cop/style/unpack_first.rb +11 -14
  435. data/lib/rubocop/cop/style/while_until_do.rb +0 -2
  436. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  437. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  438. data/lib/rubocop/cop/style/yoda_condition.rb +4 -2
  439. data/lib/rubocop/cop/style/yoda_expression.rb +8 -7
  440. data/lib/rubocop/cop/style/zero_length_predicate.rb +32 -24
  441. data/lib/rubocop/cop/team.rb +27 -3
  442. data/lib/rubocop/cop/util.rb +9 -3
  443. data/lib/rubocop/cop/utils/regexp_ranges.rb +113 -0
  444. data/lib/rubocop/cop/variable_force/assignment.rb +62 -6
  445. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  446. data/lib/rubocop/cop/variable_force/variable.rb +5 -1
  447. data/lib/rubocop/cop/variable_force/variable_table.rb +4 -4
  448. data/lib/rubocop/cop/variable_force.rb +14 -1
  449. data/lib/rubocop/cops_documentation_generator.rb +97 -44
  450. data/lib/rubocop/core_ext/string.rb +2 -6
  451. data/lib/rubocop/directive_comment.rb +10 -8
  452. data/lib/rubocop/ext/regexp_node.rb +18 -35
  453. data/lib/rubocop/ext/regexp_parser.rb +7 -21
  454. data/lib/rubocop/file_finder.rb +11 -9
  455. data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
  456. data/lib/rubocop/formatter/disabled_config_formatter.rb +24 -9
  457. data/lib/rubocop/formatter/formatter_set.rb +7 -1
  458. data/lib/rubocop/formatter/html_formatter.rb +37 -14
  459. data/lib/rubocop/formatter/json_formatter.rb +0 -1
  460. data/lib/rubocop/formatter/junit_formatter.rb +71 -24
  461. data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
  462. data/lib/rubocop/formatter/tap_formatter.rb +3 -7
  463. data/lib/rubocop/formatter.rb +1 -1
  464. data/lib/rubocop/lockfile.rb +58 -7
  465. data/lib/rubocop/lsp/logger.rb +22 -0
  466. data/lib/rubocop/lsp/routes.rb +243 -0
  467. data/lib/rubocop/lsp/runtime.rb +101 -0
  468. data/lib/rubocop/lsp/server.rb +72 -0
  469. data/lib/rubocop/lsp/severity.rb +27 -0
  470. data/lib/rubocop/lsp.rb +36 -0
  471. data/lib/rubocop/magic_comment.rb +13 -11
  472. data/lib/rubocop/options.rb +28 -13
  473. data/lib/rubocop/path_util.rb +6 -2
  474. data/lib/rubocop/rake_task.rb +1 -1
  475. data/lib/rubocop/remote_config.rb +5 -1
  476. data/lib/rubocop/result_cache.rb +7 -10
  477. data/lib/rubocop/rspec/cop_helper.rb +8 -2
  478. data/lib/rubocop/rspec/expect_offense.rb +17 -8
  479. data/lib/rubocop/rspec/shared_contexts.rb +77 -21
  480. data/lib/rubocop/rspec/support.rb +3 -0
  481. data/lib/rubocop/runner.rb +36 -12
  482. data/lib/rubocop/server/cache.rb +16 -1
  483. data/lib/rubocop/server/client_command/exec.rb +5 -5
  484. data/lib/rubocop/server/client_command/start.rb +1 -1
  485. data/lib/rubocop/server/core.rb +5 -0
  486. data/lib/rubocop/server/server_command/exec.rb +0 -1
  487. data/lib/rubocop/string_interpreter.rb +3 -3
  488. data/lib/rubocop/target_finder.rb +91 -81
  489. data/lib/rubocop/target_ruby.rb +90 -79
  490. data/lib/rubocop/version.rb +53 -13
  491. data/lib/rubocop/yaml_duplication_checker.rb +20 -26
  492. data/lib/rubocop.rb +40 -1
  493. metadata +73 -36
  494. /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -81,6 +81,7 @@ module RuboCop
81
81
  cond = node.condition
82
82
 
83
83
  control_op_condition(cond) do |first_child, rest_children|
84
+ return if require_parentheses?(node, first_child)
84
85
  return if semicolon_separated_expressions?(first_child, rest_children)
85
86
  return if modifier_op?(first_child)
86
87
  return if parens_allowed?(cond)
@@ -92,6 +93,13 @@ module RuboCop
92
93
  end
93
94
  end
94
95
 
96
+ def require_parentheses?(node, condition_body)
97
+ return false if !node.while_type? && !node.until_type?
98
+ return false if !condition_body.block_type? && !condition_body.numblock_type?
99
+
100
+ condition_body.send_node.block_literal? && condition_body.keywords?
101
+ end
102
+
95
103
  def semicolon_separated_expressions?(first_exp, rest_exps)
96
104
  return false unless (second_exp = rest_exps.first)
97
105
 
@@ -93,7 +93,7 @@ module RuboCop
93
93
  def contains_delimiter?(node, delimiters)
94
94
  delimiters_regexp = Regexp.union(delimiters)
95
95
 
96
- node.children.map { |n| string_source(n) }.compact.any?(delimiters_regexp)
96
+ node.children.filter_map { |n| string_source(n) }.any?(delimiters_regexp)
97
97
  end
98
98
 
99
99
  def string_source(node)
@@ -61,7 +61,7 @@ module RuboCop
61
61
  if style == :verbose
62
62
  "has_#{method_name}"
63
63
  else
64
- method_name.to_s.sub(/has_/, '')
64
+ method_name.to_s.delete_prefix('has_')
65
65
  end
66
66
  end
67
67
 
@@ -9,7 +9,7 @@ module RuboCop
9
9
  #
10
10
  # String interpolation is always kept in double quotes.
11
11
  #
12
- # Note: `Lint/SymbolConversion` can be used in parallel to ensure that symbols
12
+ # NOTE: `Lint/SymbolConversion` can be used in parallel to ensure that symbols
13
13
  # are not quoted that don't need to be. This cop is for configuring the quoting
14
14
  # style to use for symbols that require quotes.
15
15
  #
@@ -98,8 +98,6 @@ module RuboCop
98
98
 
99
99
  def style
100
100
  return super unless super == :same_as_string_literals
101
-
102
- string_literals_config = config.for_cop('Style/StringLiterals')
103
101
  return :single_quotes unless string_literals_config['Enabled']
104
102
 
105
103
  string_literals_config['EnforcedStyle'].to_sym
@@ -16,6 +16,9 @@ module RuboCop
16
16
  # The exploded style has an `AllowedCompactTypes` configuration
17
17
  # option that takes an Array of exception name Strings.
18
18
  #
19
+ # @safety
20
+ # This cop is unsafe because `raise Foo` calls `Foo.exception`, not `Foo.new`.
21
+ #
19
22
  # @example EnforcedStyle: exploded (default)
20
23
  # # bad
21
24
  # raise StandardError.new('message')
@@ -77,7 +80,7 @@ module RuboCop
77
80
 
78
81
  def correction_exploded_to_compact(node)
79
82
  exception_node, *message_nodes = *node.arguments
80
- return node.source if message_nodes.size > 1
83
+ return if message_nodes.size > 1
81
84
 
82
85
  argument = message_nodes.first.source
83
86
  exception_class = exception_node.receiver&.source || exception_node.source
@@ -35,6 +35,8 @@ module RuboCop
35
35
  # array.join('')
36
36
  # [1, 2, 3].join("")
37
37
  # array.sum(0)
38
+ # exit(true)
39
+ # exit!(false)
38
40
  # string.split(" ")
39
41
  # "first\nsecond".split(" ")
40
42
  # string.chomp("\n")
@@ -45,6 +47,8 @@ module RuboCop
45
47
  # array.join
46
48
  # [1, 2, 3].join
47
49
  # array.sum
50
+ # exit
51
+ # exit!
48
52
  # string.split
49
53
  # "first second".split
50
54
  # string.chomp
@@ -55,19 +59,21 @@ module RuboCop
55
59
  extend AutoCorrector
56
60
 
57
61
  MSG = 'Argument %<arg>s is redundant because it is implied by default.'
62
+ NO_RECEIVER_METHODS = %i[exit exit!].freeze
58
63
 
59
64
  def on_send(node)
60
- return if node.receiver.nil?
65
+ return if !NO_RECEIVER_METHODS.include?(node.method_name) && node.receiver.nil?
61
66
  return if node.arguments.count != 1
62
67
  return unless redundant_argument?(node)
63
68
 
64
69
  offense_range = argument_range(node)
65
- message = format(MSG, arg: node.arguments.first.source)
70
+ message = format(MSG, arg: node.first_argument.source)
66
71
 
67
72
  add_offense(offense_range, message: message) do |corrector|
68
73
  corrector.remove(offense_range)
69
74
  end
70
75
  end
76
+ alias on_csend on_send
71
77
 
72
78
  private
73
79
 
@@ -75,14 +81,20 @@ module RuboCop
75
81
  redundant_argument = redundant_arg_for_method(node.method_name.to_s)
76
82
  return false if redundant_argument.nil?
77
83
 
78
- node.arguments.first == redundant_argument
84
+ target_argument = if node.first_argument.respond_to?(:value)
85
+ node.first_argument.value
86
+ else
87
+ node.first_argument
88
+ end
89
+
90
+ argument_matched?(target_argument, redundant_argument)
79
91
  end
80
92
 
81
93
  def redundant_arg_for_method(method_name)
82
94
  arg = cop_config['Methods'].fetch(method_name) { return }
83
95
 
84
96
  @mem ||= {}
85
- @mem[method_name] ||= parse(arg.inspect).ast
97
+ @mem[method_name] ||= arg.inspect
86
98
  end
87
99
 
88
100
  def argument_range(node)
@@ -92,6 +104,23 @@ module RuboCop
92
104
  range_with_surrounding_space(node.first_argument.source_range, newlines: false)
93
105
  end
94
106
  end
107
+
108
+ def argument_matched?(target_argument, redundant_argument)
109
+ argument = if target_argument.is_a?(AST::Node)
110
+ target_argument.source
111
+ elsif exclude_cntrl_character?(target_argument, redundant_argument)
112
+ target_argument.inspect
113
+ else
114
+ target_argument.to_s
115
+ end
116
+
117
+ argument == redundant_argument
118
+ end
119
+
120
+ def exclude_cntrl_character?(target_argument, redundant_argument)
121
+ !target_argument.to_s.sub(/\A'/, '"').sub(/'\z/, '"').match?(/[[:cntrl:]]/) ||
122
+ !redundant_argument.match?(/[[:cntrl:]]/)
123
+ end
95
124
  end
96
125
  end
97
126
  end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for the instantiation of array using redundant `Array` constructor.
7
+ # Autocorrect replaces to array literal which is the simplest and fastest.
8
+ #
9
+ # @example
10
+ #
11
+ # # bad
12
+ # Array.new([])
13
+ # Array[]
14
+ # Array([])
15
+ # Array.new(['foo', 'foo', 'foo'])
16
+ # Array['foo', 'foo', 'foo']
17
+ # Array(['foo', 'foo', 'foo'])
18
+ #
19
+ # # good
20
+ # []
21
+ # ['foo', 'foo', 'foo']
22
+ # Array.new(3, 'foo')
23
+ # Array.new(3) { 'foo' }
24
+ #
25
+ class RedundantArrayConstructor < Base
26
+ extend AutoCorrector
27
+
28
+ MSG = 'Remove the redundant `Array` constructor.'
29
+
30
+ RESTRICT_ON_SEND = %i[new [] Array].freeze
31
+
32
+ # @!method redundant_array_constructor(node)
33
+ def_node_matcher :redundant_array_constructor, <<~PATTERN
34
+ {
35
+ (send
36
+ (const {nil? cbase} :Array) :new
37
+ $(array ...))
38
+ (send
39
+ (const {nil? cbase} :Array) :[]
40
+ $...)
41
+ (send
42
+ nil? :Array
43
+ $(array ...))
44
+ }
45
+ PATTERN
46
+
47
+ def on_send(node)
48
+ return unless (array_literal = redundant_array_constructor(node))
49
+
50
+ receiver = node.receiver
51
+ selector = node.loc.selector
52
+
53
+ if node.method?(:new)
54
+ range = receiver.source_range.join(selector)
55
+ replacement = array_literal
56
+ elsif node.method?(:Array)
57
+ range = selector
58
+ replacement = array_literal
59
+ else
60
+ range = receiver
61
+ replacement = selector.begin.join(node.source_range.end)
62
+ end
63
+
64
+ register_offense(range, node, replacement)
65
+ end
66
+
67
+ private
68
+
69
+ def register_offense(range, node, replacement)
70
+ add_offense(range) do |corrector|
71
+ corrector.replace(node, replacement.source)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -54,12 +54,14 @@ module RuboCop
54
54
 
55
55
  private
56
56
 
57
+ # rubocop:disable Metrics/CyclomaticComplexity
57
58
  def check_branch(node)
58
59
  return unless node
59
60
 
60
61
  case node.type
61
- when :case then check_case_node(node)
62
- when :if then check_if_node(node)
62
+ when :case then check_case_node(node)
63
+ when :case_match then check_case_match_node(node)
64
+ when :if then check_if_node(node)
63
65
  when :rescue, :resbody
64
66
  check_rescue_node(node)
65
67
  when :ensure then check_ensure_node(node)
@@ -67,12 +69,18 @@ module RuboCop
67
69
  check_begin_node(node)
68
70
  end
69
71
  end
72
+ # rubocop:enable Metrics/CyclomaticComplexity
70
73
 
71
74
  def check_case_node(node)
72
75
  node.when_branches.each { |when_node| check_branch(when_node.body) }
73
76
  check_branch(node.else_branch)
74
77
  end
75
78
 
79
+ def check_case_match_node(node)
80
+ node.in_pattern_branches.each { |in_pattern_node| check_branch(in_pattern_node.body) }
81
+ check_branch(node.else_branch)
82
+ end
83
+
76
84
  def check_if_node(node)
77
85
  return if node.modifier_form? || node.ternary?
78
86
 
@@ -68,6 +68,10 @@ module RuboCop
68
68
 
69
69
  MSG = 'Redundant `begin` block detected.'
70
70
 
71
+ def self.autocorrect_incompatible_with
72
+ [Style::BlockDelimiters]
73
+ end
74
+
71
75
  # @!method offensive_kwbegins(node)
72
76
  def_node_search :offensive_kwbegins, <<~PATTERN
73
77
  [(kwbegin ...) !#allowable_kwbegin?]
@@ -75,7 +79,7 @@ module RuboCop
75
79
 
76
80
  def on_def(node)
77
81
  return unless node.body&.kwbegin_type?
78
- return if node.endless? && !node.body.children.one?
82
+ return if node.endless?
79
83
 
80
84
  register_offense(node.body)
81
85
  end
@@ -114,7 +118,7 @@ module RuboCop
114
118
  if node.parent&.assignment?
115
119
  replace_begin_with_statement(corrector, offense_range, node)
116
120
  else
117
- corrector.remove(offense_range)
121
+ remove_begin(corrector, offense_range, node)
118
122
  end
119
123
 
120
124
  if use_modifier_form_after_multiline_begin_block?(node)
@@ -136,6 +140,14 @@ module RuboCop
136
140
  restore_removed_comments(corrector, offense_range, node, first_child)
137
141
  end
138
142
 
143
+ def remove_begin(corrector, offense_range, node)
144
+ if node.parent.respond_to?(:endless?) && node.parent.endless?
145
+ offense_range = range_with_surrounding_space(offense_range, newlines: true)
146
+ end
147
+
148
+ corrector.remove(offense_range)
149
+ end
150
+
139
151
  # Restore comments that occur between "begin" and "first_child".
140
152
  # These comments will be moved to above the assignment line.
141
153
  def restore_removed_comments(corrector, offense_range, node, first_child)
@@ -146,7 +158,7 @@ module RuboCop
146
158
  end
147
159
 
148
160
  def use_modifier_form_after_multiline_begin_block?(node)
149
- return unless (parent = node.parent)
161
+ return false unless (parent = node.parent)
150
162
 
151
163
  node.multiline? && parent.if_type? && parent.modifier_form?
152
164
  end
@@ -12,7 +12,6 @@ module RuboCop
12
12
  # # good
13
13
  # a = b || c
14
14
  #
15
- # @example
16
15
  # # bad
17
16
  # if b
18
17
  # b
@@ -40,9 +39,9 @@ module RuboCop
40
39
  splat block_pass forwarded_restarg forwarded_kwrestarg forwarded_args
41
40
  ].freeze
42
41
 
42
+ # rubocop:disable Metrics/AbcSize
43
43
  def on_if(node)
44
- return if node.elsif_conditional?
45
- return unless offense?(node)
44
+ return if node.modifier_form? || node.elsif_conditional? || !offense?(node)
46
45
 
47
46
  message = message(node)
48
47
 
@@ -58,6 +57,7 @@ module RuboCop
58
57
  end
59
58
  end
60
59
  end
60
+ # rubocop:enable Metrics/AbcSize
61
61
 
62
62
  private
63
63
 
@@ -94,7 +94,7 @@ module RuboCop
94
94
  end
95
95
 
96
96
  def use_hash_key_assignment?(else_branch)
97
- else_branch&.send_type? && else_branch&.method?(:[]=)
97
+ else_branch&.send_type? && else_branch.method?(:[]=)
98
98
  end
99
99
 
100
100
  def use_hash_key_access?(node)
@@ -63,26 +63,18 @@ module RuboCop
63
63
  RUBY
64
64
 
65
65
  def offense?(node)
66
- return if node.modifier_form?
66
+ return false if node.modifier_form?
67
67
 
68
68
  redundant_condition?(node) || redundant_condition_inverted?(node)
69
69
  end
70
70
 
71
71
  def replacement_condition(node)
72
72
  condition = node.condition.source
73
- expression = invert_expression?(node) ? "!(#{condition})" : condition
73
+ expression = redundant_condition_inverted?(node) ? "!(#{condition})" : condition
74
74
 
75
75
  node.elsif? ? indented_else_node(expression, node) : expression
76
76
  end
77
77
 
78
- def invert_expression?(node)
79
- (
80
- (node.if? || node.elsif? || node.ternary?) && redundant_condition_inverted?(node)
81
- ) || (
82
- node.unless? && redundant_condition?(node)
83
- )
84
- end
85
-
86
78
  def indented_else_node(expression, node)
87
79
  "else\n#{indentation(node)}#{expression}"
88
80
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for uses a redundant current directory in path.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # require_relative './path/to/feature'
12
+ #
13
+ # # good
14
+ # require_relative 'path/to/feature'
15
+ #
16
+ class RedundantCurrentDirectoryInPath < Base
17
+ include RangeHelp
18
+ extend AutoCorrector
19
+
20
+ MSG = 'Remove the redundant current directory path.'
21
+ RESTRICT_ON_SEND = %i[require_relative].freeze
22
+ CURRENT_DIRECTORY_PATH = './'
23
+
24
+ def on_send(node)
25
+ return unless (first_argument = node.first_argument)
26
+ return unless first_argument.str_content&.start_with?(CURRENT_DIRECTORY_PATH)
27
+ return unless (index = first_argument.source.index(CURRENT_DIRECTORY_PATH))
28
+
29
+ begin_pos = first_argument.source_range.begin.begin_pos + index
30
+ range = range_between(begin_pos, begin_pos + 2)
31
+
32
+ add_offense(range) do |corrector|
33
+ corrector.remove(range)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -13,25 +13,71 @@ module RuboCop
13
13
  # # good
14
14
  # do_something(foo: bar, baz: qux)
15
15
  #
16
+ # # bad
17
+ # do_something(**{foo: bar, baz: qux}.merge(options))
18
+ #
19
+ # # good
20
+ # do_something(foo: bar, baz: qux, **options)
21
+ #
16
22
  class RedundantDoubleSplatHashBraces < Base
17
23
  extend AutoCorrector
18
24
 
19
25
  MSG = 'Remove the redundant double splat and braces, use keyword arguments directly.'
26
+ MERGE_METHODS = %i[merge merge!].freeze
20
27
 
28
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
21
29
  def on_hash(node)
22
30
  return if node.pairs.empty? || node.pairs.any?(&:hash_rocket?)
23
31
  return unless (parent = node.parent)
24
- return unless parent.kwsplat_type?
32
+ return unless parent.call_type? || parent.kwsplat_type?
33
+ return unless mergeable?(parent)
34
+ return unless (kwsplat = node.each_ancestor(:kwsplat).first)
35
+ return if !node.braces? || allowed_double_splat_receiver?(kwsplat)
25
36
 
26
- add_offense(parent) do |corrector|
27
- corrector.remove(parent.loc.operator)
28
- corrector.remove(opening_brace(node))
29
- corrector.remove(closing_brace(node))
37
+ add_offense(kwsplat) do |corrector|
38
+ autocorrect(corrector, node, kwsplat)
30
39
  end
31
40
  end
41
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
32
42
 
33
43
  private
34
44
 
45
+ def allowed_double_splat_receiver?(kwsplat)
46
+ first_child = kwsplat.children.first
47
+ return true if first_child.block_type? || first_child.numblock_type?
48
+ return false unless first_child.call_type?
49
+
50
+ root_receiver = root_receiver(first_child)
51
+
52
+ !root_receiver&.hash_type?
53
+ end
54
+
55
+ def autocorrect(corrector, node, kwsplat)
56
+ corrector.remove(kwsplat.loc.operator)
57
+ corrector.remove(opening_brace(node))
58
+ corrector.remove(closing_brace(node))
59
+
60
+ merge_methods = select_merge_method_nodes(kwsplat)
61
+ return if merge_methods.empty?
62
+
63
+ autocorrect_merge_methods(corrector, merge_methods, kwsplat)
64
+ end
65
+
66
+ def root_receiver(node)
67
+ receiver = node.receiver
68
+ if receiver&.receiver
69
+ root_receiver(receiver)
70
+ else
71
+ receiver
72
+ end
73
+ end
74
+
75
+ def select_merge_method_nodes(kwsplat)
76
+ extract_send_methods(kwsplat).select do |node|
77
+ mergeable?(node)
78
+ end
79
+ end
80
+
35
81
  def opening_brace(node)
36
82
  node.loc.begin.join(node.children.first.source_range.begin)
37
83
  end
@@ -39,6 +85,48 @@ module RuboCop
39
85
  def closing_brace(node)
40
86
  node.children.last.source_range.end.join(node.loc.end)
41
87
  end
88
+
89
+ def autocorrect_merge_methods(corrector, merge_methods, kwsplat)
90
+ range = range_of_merge_methods(merge_methods)
91
+
92
+ new_kwsplat_arguments = extract_send_methods(kwsplat).map do |descendant|
93
+ convert_to_new_arguments(descendant)
94
+ end
95
+ new_source = new_kwsplat_arguments.compact.reverse.unshift('').join(', ')
96
+
97
+ corrector.replace(range, new_source)
98
+ end
99
+
100
+ def range_of_merge_methods(merge_methods)
101
+ begin_merge_method = merge_methods.last
102
+ end_merge_method = merge_methods.first
103
+
104
+ begin_merge_method.loc.dot.begin.join(end_merge_method.source_range.end)
105
+ end
106
+
107
+ def extract_send_methods(kwsplat)
108
+ kwsplat.each_descendant(:send, :csend)
109
+ end
110
+
111
+ def convert_to_new_arguments(node)
112
+ return unless mergeable?(node)
113
+
114
+ node.arguments.map do |arg|
115
+ if arg.hash_type?
116
+ arg.source
117
+ else
118
+ "**#{arg.source}"
119
+ end
120
+ end
121
+ end
122
+
123
+ def mergeable?(node)
124
+ return true unless node.call_type?
125
+ return false unless MERGE_METHODS.include?(node.method_name)
126
+ return true unless (parent = node.parent)
127
+
128
+ mergeable?(parent)
129
+ end
42
130
  end
43
131
  end
44
132
  end
@@ -56,6 +56,7 @@ module RuboCop
56
56
  end
57
57
  end
58
58
  end
59
+ alias on_csend on_send
59
60
 
60
61
  private
61
62
 
@@ -64,7 +65,7 @@ module RuboCop
64
65
  return if node.last_argument&.block_pass_type?
65
66
 
66
67
  if node.method?(:each) && !node.parent&.block_type?
67
- ancestor_node = node.each_ancestor(:send).detect do |ancestor|
68
+ ancestor_node = node.each_ancestor(:send, :csend).detect do |ancestor|
68
69
  ancestor.receiver == node &&
69
70
  (RESTRICT_ON_SEND.include?(ancestor.method_name) || ancestor.method?(:reverse_each))
70
71
  end
@@ -83,10 +84,12 @@ module RuboCop
83
84
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
84
85
 
85
86
  def range(node)
86
- if node.method?(:each)
87
- node.loc.dot.join(node.loc.selector)
87
+ return node.selector unless node.method?(:each)
88
+
89
+ if node.parent&.call_type?
90
+ node.selector.join(node.parent.loc.dot)
88
91
  else
89
- node.loc.selector
92
+ node.loc.dot.join(node.selector)
90
93
  end
91
94
  end
92
95
 
@@ -5,17 +5,21 @@ module RuboCop
5
5
  module Style
6
6
  # Checks for RuntimeError as the argument of raise/fail.
7
7
  #
8
- # It checks for code like this:
9
- #
10
8
  # @example
11
- # # Bad
9
+ # # bad
12
10
  # raise RuntimeError, 'message'
13
- #
14
- # # Bad
15
11
  # raise RuntimeError.new('message')
16
12
  #
17
- # # Good
13
+ # # good
18
14
  # raise 'message'
15
+ #
16
+ # # bad - message is not a string
17
+ # raise RuntimeError, Object.new
18
+ # raise RuntimeError.new(Object.new)
19
+ #
20
+ # # good
21
+ # raise Object.new.to_s
22
+ #
19
23
  class RedundantException < Base
20
24
  extend AutoCorrector
21
25
 
@@ -30,26 +34,42 @@ module RuboCop
30
34
  fix_exploded(node) || fix_compact(node)
31
35
  end
32
36
 
37
+ private
38
+
33
39
  def fix_exploded(node)
34
40
  exploded?(node) do |command, message|
35
41
  add_offense(node, message: MSG_1) do |corrector|
36
- if node.parenthesized?
37
- corrector.replace(node, "#{command}(#{message.source})")
38
- else
39
- corrector.replace(node, "#{command} #{message.source}")
40
- end
42
+ corrector.replace(node, replaced_exploded(node, command, message))
41
43
  end
42
44
  end
43
45
  end
44
46
 
47
+ def replaced_exploded(node, command, message)
48
+ arg = string_message?(message) ? message.source : "#{message.source}.to_s"
49
+ arg = node.parenthesized? ? "(#{arg})" : " #{arg}"
50
+ "#{command}#{arg}"
51
+ end
52
+
53
+ def string_message?(message)
54
+ message.str_type? || message.dstr_type? || message.xstr_type?
55
+ end
56
+
45
57
  def fix_compact(node)
46
58
  compact?(node) do |new_call, message|
47
59
  add_offense(node, message: MSG_2) do |corrector|
48
- corrector.replace(new_call, message.source)
60
+ corrector.replace(new_call, replaced_compact(message))
49
61
  end
50
62
  end
51
63
  end
52
64
 
65
+ def replaced_compact(message)
66
+ if string_message?(message)
67
+ message.source
68
+ else
69
+ "#{message.source}.to_s"
70
+ end
71
+ end
72
+
53
73
  # @!method exploded?(node)
54
74
  def_node_matcher :exploded?, <<~PATTERN
55
75
  (send nil? ${:raise :fail} (const {nil? cbase} :RuntimeError) $_)