rubocop 1.41.1 → 1.57.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (423) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +6 -4
  4. data/config/default.yml +243 -48
  5. data/config/obsoletion.yml +5 -0
  6. data/lib/rubocop/cli/command/auto_generate_config.rb +7 -0
  7. data/lib/rubocop/cli/command/execute_runner.rb +7 -2
  8. data/lib/rubocop/cli/command/lsp.rb +19 -0
  9. data/lib/rubocop/cli.rb +59 -10
  10. data/lib/rubocop/comment_config.rb +19 -0
  11. data/lib/rubocop/config.rb +14 -10
  12. data/lib/rubocop/config_finder.rb +2 -2
  13. data/lib/rubocop/config_loader.rb +20 -23
  14. data/lib/rubocop/config_loader_resolver.rb +5 -1
  15. data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
  16. data/lib/rubocop/config_obsoletion.rb +2 -2
  17. data/lib/rubocop/cop/autocorrect_logic.rb +31 -13
  18. data/lib/rubocop/cop/base.rb +96 -73
  19. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -0
  20. data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
  21. data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
  22. data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
  23. data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
  24. data/lib/rubocop/cop/commissioner.rb +8 -2
  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/lambda_literal_to_method_corrector.rb +7 -4
  31. data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
  32. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  33. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +2 -7
  34. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  35. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  36. data/lib/rubocop/cop/gemspec/dependency_version.rb +19 -21
  37. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -1
  38. data/lib/rubocop/cop/gemspec/development_dependencies.rb +107 -0
  39. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
  40. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  41. data/lib/rubocop/cop/internal_affairs/cop_description.rb +37 -13
  42. data/lib/rubocop/cop/internal_affairs/example_description.rb +42 -21
  43. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +3 -3
  44. data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
  45. data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
  46. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
  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/processed_source_buffer_name.rb +42 -0
  50. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +11 -3
  51. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  52. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
  53. data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
  54. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +66 -0
  55. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
  56. data/lib/rubocop/cop/internal_affairs.rb +3 -0
  57. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  58. data/lib/rubocop/cop/layout/block_end_newline.rb +7 -15
  59. data/lib/rubocop/cop/layout/class_structure.rb +44 -26
  60. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +2 -3
  61. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +2 -6
  62. data/lib/rubocop/cop/layout/comment_indentation.rb +3 -1
  63. data/lib/rubocop/cop/layout/dot_position.rb +1 -5
  64. data/lib/rubocop/cop/layout/empty_comment.rb +3 -3
  65. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +42 -9
  66. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +28 -5
  67. data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
  68. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.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/extra_spacing.rb +6 -1
  72. data/lib/rubocop/cop/layout/first_argument_indentation.rb +8 -3
  73. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +25 -34
  74. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +7 -19
  75. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +42 -52
  76. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +38 -55
  77. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +10 -4
  78. data/lib/rubocop/cop/layout/heredoc_indentation.rb +11 -11
  79. data/lib/rubocop/cop/layout/indentation_style.rb +5 -2
  80. data/lib/rubocop/cop/layout/indentation_width.rb +3 -3
  81. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  82. data/lib/rubocop/cop/layout/leading_comment_space.rb +2 -2
  83. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +18 -12
  84. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +17 -13
  85. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
  86. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +8 -27
  87. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
  88. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +7 -26
  89. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -21
  90. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
  91. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +6 -30
  92. data/lib/rubocop/cop/layout/redundant_line_break.rb +20 -11
  93. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
  94. data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
  95. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  96. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
  97. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
  98. data/lib/rubocop/cop/layout/space_around_operators.rb +4 -2
  99. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
  100. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
  101. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -13
  102. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -1
  103. data/lib/rubocop/cop/layout/space_inside_parens.rb +3 -3
  104. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
  105. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  106. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +4 -4
  107. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +5 -4
  108. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
  109. data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -3
  110. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -1
  111. data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -0
  112. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  113. data/lib/rubocop/cop/lint/debugger.rb +22 -25
  114. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +62 -112
  115. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  116. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
  117. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
  118. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
  119. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +47 -22
  120. data/lib/rubocop/cop/lint/else_layout.rb +3 -7
  121. data/lib/rubocop/cop/lint/empty_block.rb +2 -2
  122. data/lib/rubocop/cop/lint/empty_conditional_body.rb +4 -2
  123. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  124. data/lib/rubocop/cop/lint/erb_new_arguments.rb +3 -4
  125. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +14 -7
  126. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +16 -18
  127. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  128. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  129. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
  130. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  131. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  132. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  133. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +47 -5
  134. data/lib/rubocop/cop/lint/missing_super.rb +63 -5
  135. data/lib/rubocop/cop/lint/mixed_case_range.rb +111 -0
  136. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  137. data/lib/rubocop/cop/lint/nested_method_definition.rb +4 -9
  138. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -7
  139. data/lib/rubocop/cop/lint/number_conversion.rb +5 -0
  140. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  141. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
  142. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
  143. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +16 -1
  144. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  145. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  146. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +11 -5
  147. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
  148. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
  149. data/lib/rubocop/cop/lint/redundant_require_statement.rb +21 -2
  150. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +20 -4
  151. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  152. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
  153. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  154. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
  155. data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
  156. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
  157. data/lib/rubocop/cop/lint/require_parentheses.rb +3 -1
  158. data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
  159. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +11 -4
  160. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
  161. data/lib/rubocop/cop/lint/script_permission.rb +1 -1
  162. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
  163. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -12
  164. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +7 -1
  165. data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
  166. data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
  167. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  168. data/lib/rubocop/cop/lint/syntax.rb +4 -0
  169. data/lib/rubocop/cop/lint/to_enum_arguments.rb +18 -6
  170. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  171. data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -3
  172. data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -1
  173. data/lib/rubocop/cop/lint/useless_access_modifier.rb +10 -7
  174. data/lib/rubocop/cop/lint/useless_assignment.rb +94 -10
  175. data/lib/rubocop/cop/lint/useless_method_definition.rb +12 -4
  176. data/lib/rubocop/cop/lint/useless_rescue.rb +89 -0
  177. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +14 -4
  178. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  179. data/lib/rubocop/cop/lint/void.rb +79 -16
  180. data/lib/rubocop/cop/metrics/block_length.rb +2 -2
  181. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  182. data/lib/rubocop/cop/metrics/class_length.rb +3 -2
  183. data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
  184. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
  185. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  186. data/lib/rubocop/cop/metrics/parameter_lists.rb +27 -0
  187. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  188. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -8
  189. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +33 -5
  190. data/lib/rubocop/cop/migration/department_name.rb +3 -3
  191. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  192. data/lib/rubocop/cop/mixin/allowed_methods.rb +3 -1
  193. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  194. data/lib/rubocop/cop/mixin/annotation_comment.rb +2 -2
  195. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  196. data/lib/rubocop/cop/mixin/comments_help.rb +13 -7
  197. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  198. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  199. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  200. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
  201. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +62 -23
  202. data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
  203. data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
  204. data/lib/rubocop/cop/mixin/line_length_help.rb +3 -1
  205. data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
  206. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +0 -3
  207. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -2
  208. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  209. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  210. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
  211. data/lib/rubocop/cop/mixin/range_help.rb +1 -6
  212. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  213. data/lib/rubocop/cop/mixin/statement_modifier.rb +4 -3
  214. data/lib/rubocop/cop/mixin/string_help.rb +4 -2
  215. data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -3
  216. data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
  217. data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
  218. data/lib/rubocop/cop/naming/block_forwarding.rb +5 -1
  219. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
  220. data/lib/rubocop/cop/naming/constant_name.rb +1 -1
  221. data/lib/rubocop/cop/naming/file_name.rb +1 -1
  222. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
  223. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
  224. data/lib/rubocop/cop/naming/inclusive_language.rb +23 -4
  225. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +25 -10
  226. data/lib/rubocop/cop/naming/method_name.rb +3 -3
  227. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  228. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -4
  229. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  230. data/lib/rubocop/cop/registry.rb +37 -30
  231. data/lib/rubocop/cop/security/compound_hash.rb +2 -1
  232. data/lib/rubocop/cop/style/access_modifier_declarations.rb +26 -11
  233. data/lib/rubocop/cop/style/accessor_grouping.rb +43 -17
  234. data/lib/rubocop/cop/style/alias.rb +9 -8
  235. data/lib/rubocop/cop/style/arguments_forwarding.rb +280 -62
  236. data/lib/rubocop/cop/style/array_intersect.rb +14 -6
  237. data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
  238. data/lib/rubocop/cop/style/attr.rb +11 -1
  239. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  240. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
  241. data/lib/rubocop/cop/style/block_comments.rb +3 -3
  242. data/lib/rubocop/cop/style/block_delimiters.rb +22 -6
  243. data/lib/rubocop/cop/style/case_like_if.rb +20 -3
  244. data/lib/rubocop/cop/style/class_and_module_children.rb +5 -12
  245. data/lib/rubocop/cop/style/class_equality_comparison.rb +58 -40
  246. data/lib/rubocop/cop/style/collection_compact.rb +20 -7
  247. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  248. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  249. data/lib/rubocop/cop/style/combinable_loops.rb +30 -8
  250. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  251. data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
  252. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  253. data/lib/rubocop/cop/style/comparable_clamp.rb +125 -0
  254. data/lib/rubocop/cop/style/concat_array_literals.rb +32 -4
  255. data/lib/rubocop/cop/style/conditional_assignment.rb +11 -15
  256. data/lib/rubocop/cop/style/copyright.rb +6 -3
  257. data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
  258. data/lib/rubocop/cop/style/dir.rb +1 -1
  259. data/lib/rubocop/cop/style/dir_empty.rb +54 -0
  260. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  261. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +3 -3
  262. data/lib/rubocop/cop/style/documentation.rb +12 -6
  263. data/lib/rubocop/cop/style/documentation_method.rb +10 -4
  264. data/lib/rubocop/cop/style/double_negation.rb +2 -2
  265. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  266. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  267. data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
  268. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  269. data/lib/rubocop/cop/style/eval_with_location.rb +8 -8
  270. data/lib/rubocop/cop/style/exact_regexp_match.rb +68 -0
  271. data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
  272. data/lib/rubocop/cop/style/file_empty.rb +71 -0
  273. data/lib/rubocop/cop/style/file_read.rb +3 -3
  274. data/lib/rubocop/cop/style/file_write.rb +1 -1
  275. data/lib/rubocop/cop/style/for.rb +1 -1
  276. data/lib/rubocop/cop/style/format_string.rb +24 -3
  277. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +4 -2
  278. data/lib/rubocop/cop/style/guard_clause.rb +40 -8
  279. data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
  280. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -10
  281. data/lib/rubocop/cop/style/hash_except.rb +23 -12
  282. data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
  283. data/lib/rubocop/cop/style/hash_syntax.rb +16 -9
  284. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  285. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  286. data/lib/rubocop/cop/style/identical_conditional_branches.rb +36 -3
  287. data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
  288. data/lib/rubocop/cop/style/if_unless_modifier.rb +111 -15
  289. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
  290. data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
  291. data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
  292. data/lib/rubocop/cop/style/inverse_methods.rb +5 -5
  293. data/lib/rubocop/cop/style/invertible_unless_condition.rb +118 -0
  294. data/lib/rubocop/cop/style/lambda.rb +3 -3
  295. data/lib/rubocop/cop/style/lambda_call.rb +5 -0
  296. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +2 -2
  297. data/lib/rubocop/cop/style/map_to_hash.rb +4 -1
  298. data/lib/rubocop/cop/style/map_to_set.rb +64 -0
  299. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +35 -24
  300. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +44 -37
  301. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -0
  302. data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -4
  303. data/lib/rubocop/cop/style/min_max.rb +3 -3
  304. data/lib/rubocop/cop/style/min_max_comparison.rb +83 -0
  305. data/lib/rubocop/cop/style/missing_else.rb +13 -1
  306. data/lib/rubocop/cop/style/mixin_grouping.rb +5 -5
  307. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  308. data/lib/rubocop/cop/style/multiline_if_modifier.rb +0 -4
  309. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  310. data/lib/rubocop/cop/style/multiline_method_signature.rb +7 -4
  311. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +19 -4
  312. data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
  313. data/lib/rubocop/cop/style/negated_if_else_condition.rb +13 -12
  314. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
  315. data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
  316. data/lib/rubocop/cop/style/numbered_parameters_limit.rb +11 -3
  317. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  318. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -6
  319. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  320. data/lib/rubocop/cop/style/operator_method_call.rb +22 -2
  321. data/lib/rubocop/cop/style/parallel_assignment.rb +29 -19
  322. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
  323. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  324. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  325. data/lib/rubocop/cop/style/redundant_argument.rb +6 -1
  326. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  327. data/lib/rubocop/cop/style/redundant_begin.rb +10 -2
  328. data/lib/rubocop/cop/style/redundant_condition.rb +18 -3
  329. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -14
  330. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +38 -0
  331. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +96 -9
  332. data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
  333. data/lib/rubocop/cop/style/redundant_fetch_block.rb +6 -4
  334. data/lib/rubocop/cop/style/redundant_filter_chain.rb +117 -0
  335. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +58 -0
  336. data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
  337. data/lib/rubocop/cop/style/redundant_line_continuation.rb +183 -0
  338. data/lib/rubocop/cop/style/redundant_parentheses.rb +26 -8
  339. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  340. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +100 -0
  341. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +7 -8
  342. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  343. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +13 -4
  344. data/lib/rubocop/cop/style/redundant_return.rb +7 -2
  345. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +8 -1
  346. data/lib/rubocop/cop/style/redundant_sort.rb +4 -4
  347. data/lib/rubocop/cop/style/redundant_string_escape.rb +9 -6
  348. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  349. data/lib/rubocop/cop/style/require_order.rb +16 -17
  350. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
  351. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  352. data/lib/rubocop/cop/style/return_nil.rb +6 -2
  353. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +95 -0
  354. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  355. data/lib/rubocop/cop/style/select_by_regexp.rb +20 -6
  356. data/lib/rubocop/cop/style/self_assignment.rb +2 -2
  357. data/lib/rubocop/cop/style/semicolon.rb +35 -5
  358. data/lib/rubocop/cop/style/signal_exception.rb +9 -7
  359. data/lib/rubocop/cop/style/single_line_do_end_block.rb +65 -0
  360. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  361. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
  362. data/lib/rubocop/cop/style/sole_nested_conditional.rb +9 -5
  363. data/lib/rubocop/cop/style/special_global_vars.rb +3 -4
  364. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  365. data/lib/rubocop/cop/style/string_hash_keys.rb +4 -1
  366. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
  367. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  368. data/lib/rubocop/cop/style/symbol_array.rb +35 -15
  369. data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
  370. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -4
  371. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
  372. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  373. data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
  374. data/lib/rubocop/cop/style/unpack_first.rb +3 -3
  375. data/lib/rubocop/cop/style/word_array.rb +54 -1
  376. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  377. data/lib/rubocop/cop/style/yoda_condition.rb +17 -8
  378. data/lib/rubocop/cop/style/yoda_expression.rb +91 -0
  379. data/lib/rubocop/cop/style/zero_length_predicate.rb +40 -19
  380. data/lib/rubocop/cop/team.rb +60 -52
  381. data/lib/rubocop/cop/util.rb +14 -5
  382. data/lib/rubocop/cop/utils/regexp_ranges.rb +113 -0
  383. data/lib/rubocop/cop/variable_force/assignment.rb +45 -4
  384. data/lib/rubocop/cop/variable_force/scope.rb +3 -3
  385. data/lib/rubocop/cop/variable_force/variable.rb +5 -3
  386. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -3
  387. data/lib/rubocop/cop/variable_force.rb +2 -4
  388. data/lib/rubocop/cops_documentation_generator.rb +11 -4
  389. data/lib/rubocop/directive_comment.rb +3 -3
  390. data/lib/rubocop/ext/comment.rb +18 -0
  391. data/lib/rubocop/ext/regexp_node.rb +1 -1
  392. data/lib/rubocop/ext/regexp_parser.rb +5 -2
  393. data/lib/rubocop/file_finder.rb +4 -7
  394. data/lib/rubocop/formatter/junit_formatter.rb +4 -1
  395. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  396. data/lib/rubocop/formatter.rb +0 -1
  397. data/lib/rubocop/lsp/logger.rb +22 -0
  398. data/lib/rubocop/lsp/routes.rb +246 -0
  399. data/lib/rubocop/lsp/runtime.rb +99 -0
  400. data/lib/rubocop/lsp/server.rb +68 -0
  401. data/lib/rubocop/lsp/severity.rb +27 -0
  402. data/lib/rubocop/magic_comment.rb +12 -10
  403. data/lib/rubocop/options.rb +37 -3
  404. data/lib/rubocop/path_util.rb +17 -7
  405. data/lib/rubocop/result_cache.rb +7 -3
  406. data/lib/rubocop/rspec/cop_helper.rb +2 -2
  407. data/lib/rubocop/rspec/expect_offense.rb +6 -4
  408. data/lib/rubocop/rspec/shared_contexts.rb +6 -3
  409. data/lib/rubocop/rspec/support.rb +1 -0
  410. data/lib/rubocop/runner.rb +55 -10
  411. data/lib/rubocop/server/cache.rb +12 -4
  412. data/lib/rubocop/server/cli.rb +37 -18
  413. data/lib/rubocop/server/client_command/exec.rb +4 -3
  414. data/lib/rubocop/server/client_command/start.rb +6 -1
  415. data/lib/rubocop/server/core.rb +24 -9
  416. data/lib/rubocop/server/helper.rb +1 -1
  417. data/lib/rubocop/server/server_command/exec.rb +1 -1
  418. data/lib/rubocop/string_interpreter.rb +3 -3
  419. data/lib/rubocop/target_finder.rb +7 -3
  420. data/lib/rubocop/target_ruby.rb +13 -9
  421. data/lib/rubocop/version.rb +10 -6
  422. data/lib/rubocop.rb +31 -0
  423. metadata +84 -37
@@ -31,6 +31,7 @@ module RuboCop
31
31
  # baz
32
32
  # end
33
33
  class OneLineConditional < Base
34
+ include Alignment
34
35
  include ConfigurableEnforcedStyle
35
36
  include OnNormalIfUnless
36
37
  extend AutoCorrector
@@ -57,7 +58,7 @@ module RuboCop
57
58
 
58
59
  def autocorrect(corrector, node)
59
60
  if always_multiline? || cannot_replace_to_ternary?(node)
60
- IfThenCorrector.new(node, indentation: indentation_width).call(corrector)
61
+ IfThenCorrector.new(node, indentation: configured_indentation_width).call(corrector)
61
62
  else
62
63
  corrector.replace(node, ternary_correction(node))
63
64
  end
@@ -67,7 +68,7 @@ module RuboCop
67
68
  replaced_node = ternary_replacement(node)
68
69
 
69
70
  return replaced_node unless node.parent
70
- return "(#{replaced_node})" if %i[and or].include?(node.parent.type)
71
+ return "(#{replaced_node})" if node.parent.operator_keyword?
71
72
  return "(#{replaced_node})" if node.parent.send_type? && node.parent.operator_method?
72
73
 
73
74
  replaced_node
@@ -116,10 +117,6 @@ module RuboCop
116
117
 
117
118
  node.respond_to?(:arguments?) && node.arguments? && !node.parenthesized_call?
118
119
  end
119
-
120
- def indentation_width
121
- @config.for_cop('Layout/IndentationWidth')['Width']
122
- end
123
120
  end
124
121
  end
125
122
  end
@@ -45,7 +45,7 @@ module RuboCop
45
45
  MSG = 'Avoid using `OpenStruct`; use `Struct`, `Hash`, a class or test doubles instead.'
46
46
 
47
47
  # @!method uses_open_struct?(node)
48
- def_node_matcher :uses_open_struct?, <<-PATTERN
48
+ def_node_matcher :uses_open_struct?, <<~PATTERN
49
49
  (const {nil? (cbase)} :OpenStruct)
50
50
  PATTERN
51
51
 
@@ -23,23 +23,43 @@ module RuboCop
23
23
  MSG = 'Redundant dot detected.'
24
24
  RESTRICT_ON_SEND = %i[| ^ & <=> == === =~ > >= < <= << >> + - * / % ** ~ ! != !~].freeze
25
25
 
26
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
26
27
  def on_send(node)
27
28
  return unless (dot = node.loc.dot)
28
- return if node.receiver.const_type?
29
+ return if node.receiver.const_type? || !node.arguments.one?
29
30
 
30
31
  _lhs, _op, rhs = *node
31
- return if rhs.nil? || rhs.children.first
32
+ return if !rhs || method_call_with_parenthesized_arg?(rhs) || anonymous_forwarding?(rhs)
32
33
 
33
34
  add_offense(dot) do |corrector|
34
35
  wrap_in_parentheses_if_chained(corrector, node)
35
36
  corrector.replace(dot, ' ')
37
+
38
+ selector = node.loc.selector
39
+ corrector.insert_after(selector, ' ') if selector.end_pos == rhs.source_range.begin_pos
36
40
  end
37
41
  end
42
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
38
43
 
39
44
  private
40
45
 
46
+ # Checks for an acceptable case of `foo.+(bar).baz`.
47
+ def method_call_with_parenthesized_arg?(argument)
48
+ return false unless argument.parent.parent&.send_type?
49
+
50
+ argument.children.first && argument.parent.parenthesized?
51
+ end
52
+
53
+ def anonymous_forwarding?(argument)
54
+ return true if argument.forwarded_args_type? || argument.forwarded_restarg_type?
55
+ return true if argument.hash_type? && argument.children.first&.forwarded_kwrestarg_type?
56
+
57
+ argument.block_pass_type? && argument.source == '&'
58
+ end
59
+
41
60
  def wrap_in_parentheses_if_chained(corrector, node)
42
61
  return unless node.parent&.call_type?
62
+ return if node.parent.first_argument == node
43
63
 
44
64
  operator = node.loc.selector
45
65
 
@@ -31,22 +31,26 @@ module RuboCop
31
31
  def on_masgn(node)
32
32
  lhs, rhs = *node
33
33
  lhs_elements = *lhs
34
+ rhs = rhs.body if rhs.rescue_type?
34
35
  rhs_elements = Array(rhs).compact # edge case for one constant
35
36
 
36
37
  return if allowed_lhs?(lhs) || allowed_rhs?(rhs) ||
37
38
  allowed_masign?(lhs_elements, rhs_elements)
38
39
 
39
- add_offense(node) { |corrector| autocorrect(corrector, node) }
40
+ range = node.source_range.begin.join(rhs.source_range.end)
41
+
42
+ add_offense(range) do |corrector|
43
+ autocorrect(corrector, node, lhs, rhs)
44
+ end
40
45
  end
41
46
 
42
47
  private
43
48
 
44
- def autocorrect(corrector, node)
45
- left, right = *node
46
- left_elements = *left
47
- right_elements = Array(right).compact
49
+ def autocorrect(corrector, node, lhs, rhs)
50
+ left_elements = *lhs
51
+ right_elements = Array(rhs).compact
48
52
  order = find_valid_order(left_elements, right_elements)
49
- correction = assignment_corrector(node, order)
53
+ correction = assignment_corrector(node, rhs, order)
50
54
 
51
55
  corrector.replace(correction.correction_range, correction.correction)
52
56
  end
@@ -77,14 +81,19 @@ module RuboCop
77
81
  node.block_type? || node.send_type?
78
82
  end
79
83
 
80
- def assignment_corrector(node, order)
81
- _assignment, modifier = *node.parent
84
+ def assignment_corrector(node, rhs, order)
85
+ if node.parent&.rescue_type?
86
+ _assignment, modifier = *node.parent
87
+ else
88
+ _assignment, modifier = *rhs.parent
89
+ end
90
+
82
91
  if modifier_statement?(node.parent)
83
- ModifierCorrector.new(node, config, order)
92
+ ModifierCorrector.new(node, rhs, modifier, config, order)
84
93
  elsif rescue_modifier?(modifier)
85
- RescueCorrector.new(node, config, order)
94
+ RescueCorrector.new(node, rhs, modifier, config, order)
86
95
  else
87
- GenericCorrector.new(node, config, order)
96
+ GenericCorrector.new(node, rhs, modifier, config, order)
88
97
  end
89
98
  end
90
99
 
@@ -172,17 +181,21 @@ module RuboCop
172
181
  end
173
182
 
174
183
  def modifier_statement?(node)
175
- node && %i[if while until].include?(node.type) && node.modifier_form?
184
+ return false unless node
185
+
186
+ node.basic_conditional? && node.modifier_form?
176
187
  end
177
188
 
178
189
  # An internal class for correcting parallel assignment
179
190
  class GenericCorrector
180
191
  include Alignment
181
192
 
182
- attr_reader :config, :node
193
+ attr_reader :node, :rhs, :rescue_result, :config
183
194
 
184
- def initialize(node, config, new_elements)
195
+ def initialize(node, rhs, modifier, config, new_elements)
185
196
  @node = node
197
+ @rhs = rhs
198
+ _, _, @rescue_result = *modifier
186
199
  @config = config
187
200
  @new_elements = new_elements
188
201
  end
@@ -226,13 +239,10 @@ module RuboCop
226
239
  # protected by rescue
227
240
  class RescueCorrector < GenericCorrector
228
241
  def correction
229
- _node, rescue_clause = *node.parent
230
- _, _, rescue_result = *rescue_clause
231
-
232
242
  # If the parallel assignment uses a rescue modifier and it is the
233
243
  # only contents of a method, then we want to make use of the
234
244
  # implicit begin
235
- if node.parent.parent&.def_type?
245
+ if rhs.parent.parent.parent&.def_type?
236
246
  super + def_correction(rescue_result)
237
247
  else
238
248
  begin_correction(rescue_result)
@@ -240,7 +250,7 @@ module RuboCop
240
250
  end
241
251
 
242
252
  def correction_range
243
- node.parent.source_range
253
+ rhs.parent.parent.source_range
244
254
  end
245
255
 
246
256
  private
@@ -92,9 +92,8 @@ module RuboCop
92
92
 
93
93
  def contains_delimiter?(node, delimiters)
94
94
  delimiters_regexp = Regexp.union(delimiters)
95
- node
96
- .children.map { |n| string_source(n) }.compact
97
- .any? { |s| delimiters_regexp.match?(s) }
95
+
96
+ node.children.filter_map { |n| string_source(n) }.any?(delimiters_regexp)
98
97
  end
99
98
 
100
99
  def string_source(node)
@@ -44,7 +44,7 @@ module RuboCop
44
44
 
45
45
  # Report offense only if changing case doesn't change semantics,
46
46
  # i.e., if the string would become dynamic or has special characters.
47
- ast = ProcessedSource.new(corrected(node.source), target_ruby_version).ast
47
+ ast = parse(corrected(node.source)).ast
48
48
  return if node.children != ast.children
49
49
 
50
50
  add_offense(node.loc.begin) do |corrector|
@@ -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
 
@@ -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,9 +59,10 @@ 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
 
@@ -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
@@ -114,7 +114,7 @@ module RuboCop
114
114
  if node.parent&.assignment?
115
115
  replace_begin_with_statement(corrector, offense_range, node)
116
116
  else
117
- corrector.remove(offense_range)
117
+ remove_begin(corrector, offense_range, node)
118
118
  end
119
119
 
120
120
  if use_modifier_form_after_multiline_begin_block?(node)
@@ -136,6 +136,14 @@ module RuboCop
136
136
  restore_removed_comments(corrector, offense_range, node, first_child)
137
137
  end
138
138
 
139
+ def remove_begin(corrector, offense_range, node)
140
+ if node.parent.respond_to?(:endless?) && node.parent.endless?
141
+ offense_range = range_with_surrounding_space(offense_range, newlines: true)
142
+ end
143
+
144
+ corrector.remove(offense_range)
145
+ end
146
+
139
147
  # Restore comments that occur between "begin" and "first_child".
140
148
  # These comments will be moved to above the assignment line.
141
149
  def restore_removed_comments(corrector, offense_range, node, first_child)
@@ -146,7 +154,7 @@ module RuboCop
146
154
  end
147
155
 
148
156
  def use_modifier_form_after_multiline_begin_block?(node)
149
- return unless (parent = node.parent)
157
+ return false unless (parent = node.parent)
150
158
 
151
159
  node.multiline? && parent.if_type? && parent.modifier_form?
152
160
  end
@@ -36,6 +36,9 @@ module RuboCop
36
36
 
37
37
  MSG = 'Use double pipes `||` instead.'
38
38
  REDUNDANT_CONDITION = 'This condition is not needed.'
39
+ ARGUMENT_WITH_OPERATOR_TYPES = %i[
40
+ splat block_pass forwarded_restarg forwarded_kwrestarg forwarded_args
41
+ ].freeze
39
42
 
40
43
  def on_if(node)
41
44
  return if node.elsif_conditional?
@@ -67,8 +70,8 @@ module RuboCop
67
70
  end
68
71
 
69
72
  def range_of_offense(node)
70
- return node.loc.expression unless node.ternary?
71
- return node.loc.expression if node.ternary? && branches_have_method?(node)
73
+ return node.source_range unless node.ternary?
74
+ return node.source_range if node.ternary? && branches_have_method?(node)
72
75
 
73
76
  range_between(node.loc.question.begin_pos, node.loc.colon.end_pos)
74
77
  end
@@ -150,13 +153,25 @@ module RuboCop
150
153
  end
151
154
 
152
155
  def single_argument_method?(node)
153
- node.send_type? && !node.method?(:[]) && node.arguments.one?
156
+ return false if !node.send_type? || node.method?(:[]) || !node.arguments.one?
157
+
158
+ !argument_with_operator?(node.first_argument)
154
159
  end
155
160
 
156
161
  def same_method?(if_branch, else_branch)
157
162
  if_branch.method?(else_branch.method_name) && if_branch.receiver == else_branch.receiver
158
163
  end
159
164
 
165
+ # If the argument is using an operator, it is an invalid syntax.
166
+ # e.g. `foo || *bar`, `foo || **bar`, and `foo || &bar`.
167
+ def argument_with_operator?(argument)
168
+ return true if ARGUMENT_WITH_OPERATOR_TYPES.include?(argument.type)
169
+ return false unless argument.hash_type?
170
+ return false unless (node = argument.children.first)
171
+
172
+ node.kwsplat_type? || node.forwarded_kwrestarg_type?
173
+ end
174
+
160
175
  def if_source(if_branch, arithmetic_operation)
161
176
  if branches_have_method?(if_branch.parent) && if_branch.parenthesized?
162
177
  if_branch.source.delete_suffix(')')
@@ -63,33 +63,21 @@ 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
89
-
90
- def configured_indentation_width
91
- super || 2
92
- end
93
81
  end
94
82
  end
95
83
  end
@@ -0,0 +1,38 @@
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
+ CURRENT_DIRECTORY_PATH = './'
22
+
23
+ def on_send(node)
24
+ return unless node.method?(:require_relative)
25
+ return unless node.first_argument.str_content&.start_with?(CURRENT_DIRECTORY_PATH)
26
+ return unless (index = node.first_argument.source.index(CURRENT_DIRECTORY_PATH))
27
+
28
+ begin_pos = node.first_argument.source_range.begin.begin_pos + index
29
+ range = range_between(begin_pos, begin_pos + 2)
30
+
31
+ add_offense(range) do |corrector|
32
+ corrector.remove(range)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -13,26 +13,113 @@ 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
 
21
- # @!method double_splat_hash_braces?(node)
22
- def_node_matcher :double_splat_hash_braces?, <<~PATTERN
23
- (hash (kwsplat (hash ...)))
24
- PATTERN
25
-
28
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
26
29
  def on_hash(node)
27
30
  return if node.pairs.empty? || node.pairs.any?(&:hash_rocket?)
31
+ return unless (parent = node.parent)
32
+ return if parent.call_type? && !merge_method?(parent)
33
+ return unless (kwsplat = node.each_ancestor(:kwsplat).first)
34
+ return if allowed_double_splat_receiver?(kwsplat)
35
+
36
+ add_offense(kwsplat) do |corrector|
37
+ autocorrect(corrector, node, kwsplat)
38
+ end
39
+ end
40
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
41
+
42
+ private
43
+
44
+ def allowed_double_splat_receiver?(kwsplat)
45
+ return false unless kwsplat.children.first.call_type?
28
46
 
29
- grandparent = node.parent&.parent
30
- return unless double_splat_hash_braces?(grandparent)
47
+ root_receiver = root_receiver(kwsplat.children.first)
31
48
 
32
- add_offense(grandparent) do |corrector|
33
- corrector.replace(grandparent, node.pairs.map(&:source).join(', '))
49
+ !root_receiver&.hash_type?
50
+ end
51
+
52
+ def autocorrect(corrector, node, kwsplat)
53
+ corrector.remove(kwsplat.loc.operator)
54
+ corrector.remove(opening_brace(node))
55
+ corrector.remove(closing_brace(node))
56
+
57
+ merge_methods = select_merge_method_nodes(kwsplat)
58
+ return if merge_methods.empty?
59
+
60
+ autocorrect_merge_methods(corrector, merge_methods, kwsplat)
61
+ end
62
+
63
+ def root_receiver(node)
64
+ receiver = node.receiver
65
+ if receiver&.receiver
66
+ root_receiver(receiver)
67
+ else
68
+ receiver
34
69
  end
35
70
  end
71
+
72
+ def select_merge_method_nodes(kwsplat)
73
+ extract_send_methods(kwsplat).select do |node|
74
+ merge_method?(node)
75
+ end
76
+ end
77
+
78
+ def opening_brace(node)
79
+ node.loc.begin.join(node.children.first.source_range.begin)
80
+ end
81
+
82
+ def closing_brace(node)
83
+ node.children.last.source_range.end.join(node.loc.end)
84
+ end
85
+
86
+ def autocorrect_merge_methods(corrector, merge_methods, kwsplat)
87
+ range = range_of_merge_methods(merge_methods)
88
+
89
+ new_kwsplat_arguments = extract_send_methods(kwsplat).map do |descendant|
90
+ convert_to_new_arguments(descendant)
91
+ end
92
+ new_source = new_kwsplat_arguments.compact.reverse.unshift('').join(', ')
93
+
94
+ corrector.replace(range, new_source)
95
+ end
96
+
97
+ def range_of_merge_methods(merge_methods)
98
+ begin_merge_method = merge_methods.last
99
+ end_merge_method = merge_methods.first
100
+
101
+ begin_merge_method.loc.dot.begin.join(end_merge_method.source_range.end)
102
+ end
103
+
104
+ def extract_send_methods(kwsplat)
105
+ kwsplat.each_descendant(:send, :csend)
106
+ end
107
+
108
+ def convert_to_new_arguments(node)
109
+ return unless merge_method?(node)
110
+
111
+ node.arguments.map do |arg|
112
+ if arg.hash_type?
113
+ arg.source
114
+ else
115
+ "**#{arg.source}"
116
+ end
117
+ end
118
+ end
119
+
120
+ def merge_method?(node)
121
+ MERGE_METHODS.include?(node.method_name)
122
+ end
36
123
  end
37
124
  end
38
125
  end