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
@@ -7,21 +7,19 @@ module RuboCop
7
7
  # method calls containing parameters.
8
8
  #
9
9
  # In the default style (require_parentheses), macro methods are allowed.
10
- # Additional methods can be added to the `AllowedMethods`
11
- # or `AllowedPatterns` list. These options are
12
- # valid only in the default style. Macros can be included by
13
- # either setting `IgnoreMacros` to false or adding specific macros to
14
- # the `IncludedMacros` list.
10
+ # Additional methods can be added to the `AllowedMethods` or
11
+ # `AllowedPatterns` list. These options are valid only in the default
12
+ # style. Macros can be included by either setting `IgnoreMacros` to false
13
+ # or adding specific macros to the `IncludedMacros` list.
15
14
  #
16
- # Precedence of options is all follows:
15
+ # Precedence of options is as follows:
17
16
  #
18
17
  # 1. `AllowedMethods`
19
18
  # 2. `AllowedPatterns`
20
19
  # 3. `IncludedMacros`
21
20
  #
22
- # eg. If a method is listed in both
23
- # `IncludedMacros` and `AllowedMethods`, then the latter takes
24
- # precedence (that is, the method is allowed).
21
+ # If a method is listed in both `IncludedMacros` and `AllowedMethods`,
22
+ # then the latter takes precedence (that is, the method is allowed).
25
23
  #
26
24
  # In the alternative style (omit_parentheses), there are three additional
27
25
  # options.
@@ -40,14 +38,29 @@ module RuboCop
40
38
  # to `true` allows the presence of parentheses in such a method call
41
39
  # even with arguments.
42
40
  #
43
- # NOTE: Parentheses are still allowed in cases where omitting them
44
- # results in ambiguous or syntactically incorrect code. For example,
45
- # parentheses are required around a method with arguments when inside an
46
- # endless method definition introduced in Ruby 3.0. Parentheses are also
47
- # allowed when forwarding arguments with the triple-dot syntax introduced
48
- # in Ruby 2.7 as omitting them starts an endless range.
49
- # And Ruby 3.1's hash omission syntax has a case that requires parentheses
50
- # because of the following issue: https://bugs.ruby-lang.org/issues/18396.
41
+ # NOTE: The style of `omit_parentheses` allows parentheses in cases where
42
+ # omitting them results in ambiguous or syntactically incorrect code.
43
+ #
44
+ # Non-exhaustive list of examples:
45
+ #
46
+ # - Parentheses are required allowed in method calls with arguments inside
47
+ # literals, logical operators, setting default values in position and
48
+ # keyword arguments, chaining and more.
49
+ # - Parentheses are allowed in method calls with arguments inside
50
+ # operators to avoid ambiguity.
51
+ # triple-dot syntax introduced in Ruby 2.7 as omitting them starts an
52
+ # endless range.
53
+ # - Parentheses are allowed when forwarding arguments with the
54
+ # triple-dot syntax introduced in Ruby 2.7 as omitting them starts an
55
+ # endless range.
56
+ # - Parentheses are required in calls with arguments when inside an
57
+ # endless method definition introduced in Ruby 3.0.
58
+ # - Ruby 3.1's hash omission syntax allows parentheses if the method call
59
+ # is in conditionals and requires parentheses if the call
60
+ # is not the value-returning expression. See
61
+ # https://bugs.ruby-lang.org/issues/18396.
62
+ # - Parentheses are required in anonymous arguments, keyword arguments
63
+ # and block passing in Ruby 3.2.
51
64
  #
52
65
  # @example EnforcedStyle: require_parentheses (default)
53
66
  #
@@ -80,34 +93,28 @@ module RuboCop
80
93
  # array.delete e
81
94
  #
82
95
  # # bad
83
- # foo.enforce(strict: true)
96
+ # action.enforce(strict: true)
84
97
  #
85
98
  # # good
86
- # foo.enforce strict: true
99
+ # action.enforce strict: true
87
100
  #
88
101
  # # good
89
- # # Allows parens for calls that won't produce valid Ruby or be ambiguous.
90
- # model.validate strict(true)
102
+ # # Parentheses are allowed for code that can be ambiguous without
103
+ # # them.
104
+ # action.enforce(condition) || other_condition
91
105
  #
92
106
  # # good
93
- # # Allows parens for calls that won't produce valid Ruby or be ambiguous.
107
+ # # Parentheses are allowed for calls that won't produce valid Ruby
108
+ # # without them.
94
109
  # yield path, File.basename(path)
95
110
  #
96
111
  # # good
97
- # # Operators methods calls with parens
98
- # array&.[](index)
99
- #
100
- # # good
101
- # # Operators methods without parens, if you prefer
102
- # array.[] index
103
- #
104
- # # good
105
- # # Operators methods calls with parens
106
- # array&.[](index)
107
- #
108
- # # good
109
- # # Operators methods without parens, if you prefer
110
- # array.[] index
112
+ # # Omitting the parentheses in Ruby 3.1 hash omission syntax can lead
113
+ # # to ambiguous code. We allow them in conditionals and non-last
114
+ # # expressions. See https://bugs.ruby-lang.org/issues/18396
115
+ # if meets(criteria:, action:)
116
+ # safe_action(action) || dangerous_action(action)
117
+ # end
111
118
  #
112
119
  # @example IgnoreMacros: true (default)
113
120
  #
@@ -226,7 +233,7 @@ module RuboCop
226
233
  end
227
234
 
228
235
  def args_end(node)
229
- node.loc.expression.end
236
+ node.source_range.end
230
237
  end
231
238
 
232
239
  def args_parenthesized?(node)
@@ -62,6 +62,8 @@ module RuboCop
62
62
  end
63
63
 
64
64
  def same_name_assignment?(node)
65
+ return false if node.receiver
66
+
65
67
  any_assignment?(node) do |asgn_node|
66
68
  next variable_in_mass_assignment?(node.method_name, asgn_node) if asgn_node.masgn_type?
67
69
 
@@ -10,7 +10,9 @@ module RuboCop
10
10
  #
11
11
  # 1. Endless methods
12
12
  # 2. Argument lists containing a `forward-arg` (`...`)
13
- # 3. Argument lists containing an anonymous block forwarding (`&`)
13
+ # 3. Argument lists containing an anonymous rest arguments forwarding (`*`)
14
+ # 4. Argument lists containing an anonymous keyword rest arguments forwarding (`**`)
15
+ # 5. Argument lists containing an anonymous block forwarding (`&`)
14
16
  #
15
17
  # Removing the parens would be a syntax error here.
16
18
  #
@@ -130,9 +132,11 @@ module RuboCop
130
132
  # Regardless of style, parentheses are necessary for:
131
133
  # 1. Endless methods
132
134
  # 2. Argument lists containing a `forward-arg` (`...`)
133
- # 3. Argument lists containing an anonymous block forwarding (`&`)
135
+ # 3. Argument lists containing an anonymous rest arguments forwarding (`*`)
136
+ # 4. Argument lists containing an anonymous keyword rest arguments forwarding (`**`)
137
+ # 5. Argument lists containing an anonymous block forwarding (`&`)
134
138
  # Removing the parens would be a syntax error here.
135
- node.endless? || node.arguments.any?(&:forward_arg_type?) || anonymous_block_arg?(node)
139
+ node.endless? || anonymous_arguments?(node)
136
140
  end
137
141
 
138
142
  def require_parentheses?(args)
@@ -162,7 +166,10 @@ module RuboCop
162
166
  end
163
167
  end
164
168
 
165
- def anonymous_block_arg?(node)
169
+ def anonymous_arguments?(node)
170
+ return true if node.arguments.any? do |arg|
171
+ arg.forward_arg_type? || arg.restarg_type? || arg.kwrestarg_type?
172
+ end
166
173
  return false unless (last_argument = node.arguments.last)
167
174
 
168
175
  last_argument.blockarg_type? && last_argument.name.nil?
@@ -48,13 +48,13 @@ module RuboCop
48
48
  when :return
49
49
  argument_range(node)
50
50
  else
51
- node.loc.expression
51
+ node.source_range
52
52
  end
53
53
  end
54
54
 
55
55
  def argument_range(node)
56
- first_argument_range = node.children.first.loc.expression
57
- last_argument_range = node.children.last.loc.expression
56
+ first_argument_range = node.children.first.source_range
57
+ last_argument_range = node.children.last.source_range
58
58
 
59
59
  first_argument_range.join(last_argument_range)
60
60
  end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Enforces the use of `max` or `min` instead of comparison for greater or less.
7
+ #
8
+ # NOTE: It can be used if you want to present limit or threshold in Ruby 2.7+.
9
+ # That it is slow though. So autocorrection will apply generic `max` or `min`:
10
+ #
11
+ # [source,ruby]
12
+ # ----
13
+ # a.clamp(b..) # Same as `[a, b].max`
14
+ # a.clamp(..b) # Same as `[a, b].min`
15
+ # ----
16
+ #
17
+ # @safety
18
+ # This cop is unsafe because even if a value has `<` or `>` method,
19
+ # it is not necessarily `Comparable`.
20
+ #
21
+ # @example
22
+ #
23
+ # # bad
24
+ # a > b ? a : b
25
+ # a >= b ? a : b
26
+ #
27
+ # # good
28
+ # [a, b].max
29
+ #
30
+ # # bad
31
+ # a < b ? a : b
32
+ # a <= b ? a : b
33
+ #
34
+ # # good
35
+ # [a, b].min
36
+ #
37
+ class MinMaxComparison < Base
38
+ extend AutoCorrector
39
+ include RangeHelp
40
+
41
+ MSG = 'Use `%<prefer>s` instead.'
42
+ GRATER_OPERATORS = %i[> >=].freeze
43
+ LESS_OPERATORS = %i[< <=].freeze
44
+ COMPARISON_OPERATORS = GRATER_OPERATORS + LESS_OPERATORS
45
+
46
+ def on_if(node)
47
+ lhs, operator, rhs = *node.condition
48
+ return unless COMPARISON_OPERATORS.include?(operator)
49
+
50
+ if_branch = node.if_branch
51
+ else_branch = node.else_branch
52
+ preferred_method = preferred_method(operator, lhs, rhs, if_branch, else_branch)
53
+ return unless preferred_method
54
+
55
+ replacement = "[#{lhs.source}, #{rhs.source}].#{preferred_method}"
56
+
57
+ add_offense(node, message: format(MSG, prefer: replacement)) do |corrector|
58
+ autocorrect(corrector, node, replacement)
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def preferred_method(operator, lhs, rhs, if_branch, else_branch)
65
+ if lhs == if_branch && rhs == else_branch
66
+ GRATER_OPERATORS.include?(operator) ? 'max' : 'min'
67
+ elsif lhs == else_branch && rhs == if_branch
68
+ LESS_OPERATORS.include?(operator) ? 'max' : 'min'
69
+ end
70
+ end
71
+
72
+ def autocorrect(corrector, node, replacement)
73
+ if node.elsif?
74
+ corrector.remove(range_between(node.parent.loc.else.begin_pos, node.loc.else.begin_pos))
75
+ corrector.replace(node.else_branch, replacement)
76
+ else
77
+ corrector.replace(node, replacement)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -99,6 +99,7 @@ module RuboCop
99
99
  class MissingElse < Base
100
100
  include OnNormalIfUnless
101
101
  include ConfigurableEnforcedStyle
102
+ extend AutoCorrector
102
103
 
103
104
  MSG = '`%<type>s` condition requires an `else`-clause.'
104
105
  MSG_NIL = '`%<type>s` condition requires an `else`-clause with `nil` in it.'
@@ -126,7 +127,9 @@ module RuboCop
126
127
  def check(node)
127
128
  return if node.else?
128
129
 
129
- add_offense(node, message: format(message_template, type: node.type))
130
+ add_offense(node, message: format(message_template, type: node.type)) do |corrector|
131
+ autocorrect(corrector, node)
132
+ end
130
133
  end
131
134
 
132
135
  def message_template
@@ -140,6 +143,15 @@ module RuboCop
140
143
  end
141
144
  end
142
145
 
146
+ def autocorrect(corrector, node)
147
+ case empty_else_style
148
+ when :empty
149
+ corrector.insert_before(node.loc.end, 'else; nil; ')
150
+ when :nil
151
+ corrector.insert_before(node.loc.end, 'else; ')
152
+ end
153
+ end
154
+
143
155
  def if_style?
144
156
  style == :if
145
157
  end
@@ -40,7 +40,7 @@ module RuboCop
40
40
  def on_class(node)
41
41
  begin_node = node.child_nodes.find(&:begin_type?) || node
42
42
  begin_node.each_child_node(:send).select(&:macro?).each do |macro|
43
- next unless MIXIN_METHODS.include?(macro.method_name)
43
+ next if !MIXIN_METHODS.include?(macro.method_name) || macro.arguments.empty?
44
44
 
45
45
  check(macro)
46
46
  end
@@ -51,9 +51,9 @@ module RuboCop
51
51
  private
52
52
 
53
53
  def range_to_remove_for_subsequent_mixin(mixins, node)
54
- range = node.loc.expression
54
+ range = node.source_range
55
55
  prev_mixin = mixins.each_cons(2) { |m, n| break m if n == node }
56
- between = prev_mixin.loc.expression.end.join(range.begin)
56
+ between = prev_mixin.source_range.end.join(range.begin)
57
57
  # if separated from previous mixin with only whitespace?
58
58
  unless /\S/.match?(between.source)
59
59
  range = range.join(between) # then remove that too
@@ -75,7 +75,7 @@ module RuboCop
75
75
  message = format(MSG, mixin: send_node.method_name, suffix: 'a single statement')
76
76
 
77
77
  add_offense(send_node, message: message) do |corrector|
78
- range = send_node.loc.expression
78
+ range = send_node.source_range
79
79
  mixins = sibling_mixins(send_node)
80
80
  if send_node == mixins.first
81
81
  correction = group_mixins(send_node, mixins)
@@ -94,7 +94,7 @@ module RuboCop
94
94
  message = format(MSG, mixin: send_node.method_name, suffix: 'separate statements')
95
95
 
96
96
  add_offense(send_node, message: message) do |corrector|
97
- range = send_node.loc.expression
97
+ range = send_node.source_range
98
98
  correction = separate_mixins(send_node)
99
99
 
100
100
  corrector.replace(range, correction)
@@ -28,7 +28,7 @@ module RuboCop
28
28
  MSG = 'Avoid multi-line chains of blocks.'
29
29
 
30
30
  def on_block(node)
31
- node.send_node.each_node(:send) do |send_node|
31
+ node.send_node.each_node(:send, :csend) do |send_node|
32
32
  receiver = send_node.receiver
33
33
 
34
34
  next unless (receiver&.block_type? || receiver&.numblock_type?) && receiver&.multiline?
@@ -40,10 +40,6 @@ module RuboCop
40
40
  [condition, indented_body, indented_end].join("\n")
41
41
  end
42
42
 
43
- def configured_indentation_width
44
- super || 2
45
- end
46
-
47
43
  def indented_body(body, node)
48
44
  body_source = "#{offset(node)}#{body.source}"
49
45
  body_source.each_line.map do |line|
@@ -31,6 +31,7 @@ module RuboCop
31
31
  # baz
32
32
  # )
33
33
  class MultilineMemoization < Base
34
+ include Alignment
34
35
  include ConfigurableEnforcedStyle
35
36
  extend AutoCorrector
36
37
 
@@ -75,11 +76,10 @@ module RuboCop
75
76
  end
76
77
 
77
78
  def keyword_begin_str(node, node_buf)
78
- indent = config.for_cop('Layout/IndentationWidth')['Width'] || 2
79
79
  if node_buf.source[node.loc.begin.end_pos] == "\n"
80
80
  'begin'
81
81
  else
82
- "begin\n#{' ' * (node.loc.column + indent)}"
82
+ "begin\n#{' ' * (node.loc.column + configured_indentation_width)}"
83
83
  end
84
84
  end
85
85
 
@@ -28,14 +28,17 @@ module RuboCop
28
28
  return unless node.arguments?
29
29
  return if opening_line(node) == closing_line(node)
30
30
  return if correction_exceeds_max_line_length?(node)
31
+ return unless (begin_of_arguments = node.arguments.loc.begin)
31
32
 
32
- add_offense(node) { |corrector| autocorrect(corrector, node) }
33
+ add_offense(node) do |corrector|
34
+ autocorrect(corrector, node, begin_of_arguments)
35
+ end
33
36
  end
34
37
  alias on_defs on_def
35
38
 
36
39
  private
37
40
 
38
- def autocorrect(corrector, node)
41
+ def autocorrect(corrector, node, begin_of_arguments)
39
42
  arguments = node.arguments
40
43
  joined_arguments = arguments.map(&:source).join(', ')
41
44
  last_line_source_of_arguments = last_line_source_of_arguments(arguments)
@@ -47,7 +50,7 @@ module RuboCop
47
50
  end
48
51
 
49
52
  corrector.remove(arguments_range(node))
50
- corrector.insert_after(arguments.loc.begin, joined_arguments)
53
+ corrector.insert_after(begin_of_arguments, joined_arguments)
51
54
  end
52
55
 
53
56
  def last_line_source_of_arguments(arguments)
@@ -75,7 +78,7 @@ module RuboCop
75
78
  end
76
79
 
77
80
  def indentation_width(node)
78
- processed_source.line_indentation(node.loc.expression.line)
81
+ processed_source.line_indentation(node.source_range.line)
79
82
  end
80
83
 
81
84
  def definition_width(node)
@@ -34,11 +34,12 @@ module RuboCop
34
34
  # return cond ? b : c
35
35
  #
36
36
  class MultilineTernaryOperator < Base
37
+ include CommentsHelp
37
38
  extend AutoCorrector
38
39
 
39
40
  MSG_IF = 'Avoid multi-line ternary operators, use `if` or `unless` instead.'
40
41
  MSG_SINGLE_LINE = 'Avoid multi-line ternary operators, use single-line instead.'
41
- SINGLE_LINE_TYPES = %i[return break next send].freeze
42
+ SINGLE_LINE_TYPES = %i[return break next send csend].freeze
42
43
 
43
44
  def on_if(node)
44
45
  return unless offense?(node)
@@ -46,9 +47,7 @@ module RuboCop
46
47
  message = enforce_single_line_ternary_operator?(node) ? MSG_SINGLE_LINE : MSG_IF
47
48
 
48
49
  add_offense(node, message: message) do |corrector|
49
- next unless offense?(node)
50
-
51
- corrector.replace(node, replacement(node))
50
+ autocorrect(corrector, node)
52
51
  end
53
52
  end
54
53
 
@@ -58,6 +57,16 @@ module RuboCop
58
57
  node.ternary? && node.multiline?
59
58
  end
60
59
 
60
+ def autocorrect(corrector, node)
61
+ return unless offense?(node)
62
+
63
+ corrector.replace(node, replacement(node))
64
+ return unless (parent = node.parent)
65
+ return unless (comments_in_condition = comments_in_condition(node))
66
+
67
+ corrector.insert_before(parent, comments_in_condition)
68
+ end
69
+
61
70
  def replacement(node)
62
71
  if enforce_single_line_ternary_operator?(node)
63
72
  "#{node.condition.source} ? #{node.if_branch.source} : #{node.else_branch.source}"
@@ -72,6 +81,12 @@ module RuboCop
72
81
  end
73
82
  end
74
83
 
84
+ def comments_in_condition(node)
85
+ comments_in_range(node).map do |comment|
86
+ "#{comment.source}\n"
87
+ end.join
88
+ end
89
+
75
90
  def enforce_single_line_ternary_operator?(node)
76
91
  SINGLE_LINE_TYPES.include?(node.parent&.type) && !use_assignment_method?(node.parent)
77
92
  end
@@ -40,6 +40,15 @@ module RuboCop
40
40
  #
41
41
  # # good
42
42
  # foo if [b.lightweight, b.heavyweight].include?(a)
43
+ #
44
+ # @example ComparisonsThreshold: 2 (default)
45
+ # # bad
46
+ # foo if a == 'a' || a == 'b'
47
+ #
48
+ # @example ComparisonsThreshold: 3
49
+ # # good
50
+ # foo if a == 'a' || a == 'b'
51
+ #
43
52
  class MultipleComparison < Base
44
53
  extend AutoCorrector
45
54
 
@@ -58,6 +67,7 @@ module RuboCop
58
67
  return unless node == root_of_or_node
59
68
  return unless nested_variable_comparison?(root_of_or_node)
60
69
  return if @allowed_method_comparison
70
+ return if @compared_elements.size < comparisons_threshold
61
71
 
62
72
  add_offense(node) do |corrector|
63
73
  elements = @compared_elements.join(', ')
@@ -151,6 +161,10 @@ module RuboCop
151
161
  def allow_method_comparison?
152
162
  cop_config.fetch('AllowMethodComparison', true)
153
163
  end
164
+
165
+ def comparisons_threshold
166
+ cop_config.fetch('ComparisonsThreshold', 2)
167
+ end
154
168
  end
155
169
  end
156
170
  end
@@ -48,13 +48,11 @@ module RuboCop
48
48
 
49
49
  def on_if(node)
50
50
  return unless if_else?(node)
51
-
52
- condition = unwrap_begin_nodes(node.condition)
53
-
51
+ return unless (condition = unwrap_begin_nodes(node.condition))
54
52
  return if double_negation?(condition) || !negated_condition?(condition)
55
53
 
56
- type = node.ternary? ? 'ternary' : 'if-else'
57
- add_offense(node, message: format(MSG, type: type)) do |corrector|
54
+ message = message(node)
55
+ add_offense(node, message: message) do |corrector|
58
56
  unless corrected_ancestor?(node)
59
57
  correct_negated_condition(corrector, condition)
60
58
  swap_branches(corrector, node)
@@ -73,7 +71,8 @@ module RuboCop
73
71
  end
74
72
 
75
73
  def unwrap_begin_nodes(node)
76
- node = node.children.first while node.begin_type? || node.kwbegin_type?
74
+ node = node.children.first while node && (node.begin_type? || node.kwbegin_type?)
75
+
77
76
  node
78
77
  end
79
78
 
@@ -82,6 +81,12 @@ module RuboCop
82
81
  (node.negation_method? || NEGATED_EQUALITY_METHODS.include?(node.method_name))
83
82
  end
84
83
 
84
+ def message(node)
85
+ type = node.ternary? ? 'ternary' : 'if-else'
86
+
87
+ format(MSG, type: type)
88
+ end
89
+
85
90
  def corrected_ancestor?(node)
86
91
  node.each_ancestor(:if).any? { |ancestor| @corrected_nodes&.include?(ancestor) }
87
92
  end
@@ -103,11 +108,7 @@ module RuboCop
103
108
  if node.if_branch.nil?
104
109
  corrector.remove(range_by_whole_lines(node.loc.else, include_final_newline: true))
105
110
  else
106
- if_range = if_range(node)
107
- else_range = else_range(node)
108
-
109
- corrector.replace(if_range, else_range.source)
110
- corrector.replace(else_range, if_range.source)
111
+ corrector.swap(if_range(node), else_range(node))
111
112
  end
112
113
  end
113
114
 
@@ -116,7 +117,7 @@ module RuboCop
116
117
  if node.ternary?
117
118
  node.if_branch
118
119
  else
119
- range_between(node.condition.loc.expression.end_pos, node.loc.else.begin_pos)
120
+ range_between(node.condition.source_range.end_pos, node.loc.else.begin_pos)
120
121
  end
121
122
  end
122
123
 
@@ -27,24 +27,16 @@ module RuboCop
27
27
 
28
28
  node.each_descendant(:if).select(&:ternary?).each do |nested_ternary|
29
29
  add_offense(nested_ternary) do |corrector|
30
- if_node = if_node(nested_ternary)
31
- next if part_of_ignored_node?(if_node)
30
+ next if part_of_ignored_node?(node)
32
31
 
33
- autocorrect(corrector, if_node)
34
- ignore_node(if_node)
32
+ autocorrect(corrector, node)
33
+ ignore_node(node)
35
34
  end
36
35
  end
37
36
  end
38
37
 
39
38
  private
40
39
 
41
- def if_node(node)
42
- node = node.parent
43
- return node if node.if_type?
44
-
45
- if_node(node)
46
- end
47
-
48
40
  def autocorrect(corrector, if_node)
49
41
  replace_loc_and_whitespace(corrector, if_node.loc.question, "\n")
50
42
  replace_loc_and_whitespace(corrector, if_node.loc.colon, "\nelse\n")
@@ -57,9 +57,9 @@ module RuboCop
57
57
 
58
58
  def autocorrect(corrector, node)
59
59
  range = if node.single_line?
60
- range_with_surrounding_space(node.body.loc.expression)
60
+ range_with_surrounding_space(node.body.source_range)
61
61
  else
62
- range_by_whole_lines(node.body.loc.expression, include_final_newline: true)
62
+ range_by_whole_lines(node.body.source_range, include_final_newline: true)
63
63
  end
64
64
 
65
65
  corrector.remove(range)
@@ -12,10 +12,11 @@ module RuboCop
12
12
  #
13
13
  # @example Max: 1 (default)
14
14
  # # bad
15
- # foo { _1.call(_2, _3, _4) }
15
+ # use_multiple_numbered_parameters { _1.call(_2, _3, _4) }
16
16
  #
17
17
  # # good
18
- # foo { do_something(_1) }
18
+ # array.each { use_array_element_as_numbered_parameter(_1) }
19
+ # hash.each { use_only_hash_value_as_numbered_parameter(_2) }
19
20
  class NumberedParametersLimit < Base
20
21
  extend TargetRubyVersion
21
22
  extend ExcludeLimit
@@ -26,9 +27,10 @@ module RuboCop
26
27
  exclude_limit 'Max'
27
28
 
28
29
  MSG = 'Avoid using more than %<max>i numbered %<parameter>s; %<count>i detected.'
30
+ NUMBERED_PARAMETER_PATTERN = /\A_[1-9]\z/.freeze
29
31
 
30
32
  def on_numblock(node)
31
- _send_node, param_count, * = *node
33
+ param_count = numbered_parameter_nodes(node).uniq.count
32
34
  return if param_count <= max_count
33
35
 
34
36
  parameter = max_count > 1 ? 'parameters' : 'parameter'
@@ -38,6 +40,12 @@ module RuboCop
38
40
 
39
41
  private
40
42
 
43
+ def numbered_parameter_nodes(node)
44
+ node.each_descendant(:lvar).select do |lvar_node|
45
+ lvar_node.source.match?(NUMBERED_PARAMETER_PATTERN)
46
+ end
47
+ end
48
+
41
49
  def max_count
42
50
  max = cop_config.fetch('Max', DEFAULT_MAX_VALUE)
43
51
 
@@ -121,7 +121,7 @@ module RuboCop
121
121
 
122
122
  def allowed_patterns
123
123
  # Convert the patterns to be anchored
124
- super.map { |regexp| Regexp.new(/\A#{regexp}\z/) }
124
+ super.map { |regexp| /\A#{regexp}\z/ }
125
125
  end
126
126
  end
127
127
  end