rubocop 1.52.1 → 1.79.2

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 (658) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +93 -88
  4. data/assets/output.css.erb +159 -0
  5. data/assets/output.html.erb +1 -160
  6. data/config/default.yml +596 -91
  7. data/config/internal_affairs.yml +31 -0
  8. data/config/obsoletion.yml +13 -3
  9. data/exe/rubocop +4 -3
  10. data/lib/rubocop/cached_data.rb +21 -5
  11. data/lib/rubocop/cli/command/auto_generate_config.rb +28 -15
  12. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  13. data/lib/rubocop/cli/command/lsp.rb +19 -0
  14. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  15. data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
  16. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  17. data/lib/rubocop/cli/command/version.rb +2 -2
  18. data/lib/rubocop/cli.rb +26 -3
  19. data/lib/rubocop/comment_config.rb +3 -3
  20. data/lib/rubocop/config.rb +92 -22
  21. data/lib/rubocop/config_finder.rb +14 -4
  22. data/lib/rubocop/config_loader.rb +68 -57
  23. data/lib/rubocop/config_loader_resolver.rb +52 -20
  24. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  25. data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
  26. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  27. data/lib/rubocop/config_obsoletion.rb +56 -9
  28. data/lib/rubocop/config_validator.rb +39 -20
  29. data/lib/rubocop/cop/autocorrect_logic.rb +57 -25
  30. data/lib/rubocop/cop/base.rb +80 -19
  31. data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -2
  32. data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
  33. data/lib/rubocop/cop/bundler/gem_comment.rb +3 -3
  34. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  35. data/lib/rubocop/cop/bundler/gem_version.rb +6 -7
  36. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  37. data/lib/rubocop/cop/bundler/ordered_gems.rb +10 -2
  38. data/lib/rubocop/cop/cop.rb +30 -4
  39. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  40. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
  41. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +6 -14
  42. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
  43. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
  44. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +6 -3
  45. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  46. data/lib/rubocop/cop/documentation.rb +32 -5
  47. data/lib/rubocop/cop/exclude_limit.rb +1 -1
  48. data/lib/rubocop/cop/force.rb +12 -0
  49. data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
  50. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  51. data/lib/rubocop/cop/gemspec/dependency_version.rb +5 -7
  52. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +3 -4
  53. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +39 -17
  54. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +10 -2
  55. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  56. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -3
  57. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
  58. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  59. data/lib/rubocop/cop/generator.rb +6 -0
  60. data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
  61. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  62. data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
  63. data/lib/rubocop/cop/internal_affairs/example_description.rb +51 -25
  64. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  65. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  66. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +6 -5
  67. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
  68. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
  69. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +54 -0
  70. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +127 -33
  71. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  72. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  73. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +231 -0
  74. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  75. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  76. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  77. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  78. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  79. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  80. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  81. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  82. data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
  83. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  84. data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
  85. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +11 -2
  86. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  87. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  88. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +23 -2
  89. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -5
  90. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  91. data/lib/rubocop/cop/internal_affairs.rb +9 -0
  92. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -2
  93. data/lib/rubocop/cop/layout/argument_alignment.rb +3 -10
  94. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  95. data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
  96. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  97. data/lib/rubocop/cop/layout/block_alignment.rb +32 -13
  98. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  99. data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
  100. data/lib/rubocop/cop/layout/class_structure.rb +51 -9
  101. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -1
  102. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  103. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  104. data/lib/rubocop/cop/layout/condition_position.rb +0 -4
  105. data/lib/rubocop/cop/layout/def_end_alignment.rb +2 -2
  106. data/lib/rubocop/cop/layout/dot_position.rb +2 -6
  107. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  108. data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
  109. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +46 -13
  110. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
  111. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
  112. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +33 -13
  113. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  114. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
  115. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  116. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  117. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  118. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
  119. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +14 -8
  120. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  121. data/lib/rubocop/cop/layout/end_alignment.rb +16 -4
  122. data/lib/rubocop/cop/layout/extra_spacing.rb +5 -11
  123. data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -11
  124. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +19 -10
  125. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  126. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  127. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  128. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +3 -3
  129. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  130. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -3
  131. data/lib/rubocop/cop/layout/heredoc_indentation.rb +5 -2
  132. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  133. data/lib/rubocop/cop/layout/indentation_width.rb +16 -16
  134. data/lib/rubocop/cop/layout/leading_comment_space.rb +84 -2
  135. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +28 -11
  136. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +8 -2
  137. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +4 -2
  138. data/lib/rubocop/cop/layout/line_length.rb +168 -28
  139. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  140. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  141. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  142. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  143. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +21 -6
  144. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  145. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  146. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
  147. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  148. data/lib/rubocop/cop/layout/redundant_line_break.rb +40 -44
  149. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +8 -9
  150. data/lib/rubocop/cop/layout/single_line_block_chain.rb +6 -1
  151. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  152. data/lib/rubocop/cop/layout/space_after_comma.rb +10 -2
  153. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  154. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  155. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  156. data/lib/rubocop/cop/layout/space_around_keyword.rb +8 -2
  157. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +3 -3
  158. data/lib/rubocop/cop/layout/space_around_operators.rb +83 -38
  159. data/lib/rubocop/cop/layout/space_before_block_braces.rb +20 -10
  160. data/lib/rubocop/cop/layout/space_before_brackets.rb +7 -40
  161. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  162. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  163. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +18 -3
  164. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  165. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +8 -1
  166. data/lib/rubocop/cop/layout/space_inside_parens.rb +1 -1
  167. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  168. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -5
  169. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
  170. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  171. data/lib/rubocop/cop/legacy/corrector.rb +12 -2
  172. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -3
  173. data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
  174. data/lib/rubocop/cop/lint/ambiguous_range.rb +9 -1
  175. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
  176. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  177. data/lib/rubocop/cop/lint/assignment_in_condition.rb +7 -9
  178. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  179. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +11 -13
  180. data/lib/rubocop/cop/lint/boolean_symbol.rb +2 -4
  181. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -14
  182. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  183. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  184. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  185. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  186. data/lib/rubocop/cop/lint/debugger.rb +45 -10
  187. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +2 -2
  188. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -12
  189. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  190. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
  191. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -5
  192. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  193. data/lib/rubocop/cop/lint/duplicate_methods.rb +110 -32
  194. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +47 -20
  195. data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
  196. data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
  197. data/lib/rubocop/cop/lint/else_layout.rb +0 -2
  198. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  199. data/lib/rubocop/cop/lint/empty_conditional_body.rb +29 -58
  200. data/lib/rubocop/cop/lint/empty_ensure.rb +2 -12
  201. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  202. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  203. data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -5
  204. data/lib/rubocop/cop/lint/empty_when.rb +1 -3
  205. data/lib/rubocop/cop/lint/ensure_return.rb +2 -10
  206. data/lib/rubocop/cop/lint/erb_new_arguments.rb +24 -23
  207. data/lib/rubocop/cop/lint/float_comparison.rb +58 -15
  208. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -8
  209. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -12
  210. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
  211. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  212. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -1
  213. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  214. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +23 -12
  215. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +0 -7
  216. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -4
  217. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +50 -0
  218. data/lib/rubocop/cop/lint/literal_as_condition.rb +126 -11
  219. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
  220. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +50 -13
  221. data/lib/rubocop/cop/lint/loop.rb +6 -12
  222. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  223. data/lib/rubocop/cop/lint/missing_super.rb +33 -7
  224. data/lib/rubocop/cop/lint/mixed_case_range.rb +113 -0
  225. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  226. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -12
  227. data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -25
  228. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -7
  229. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +22 -10
  230. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +6 -8
  231. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  232. data/lib/rubocop/cop/lint/number_conversion.rb +13 -4
  233. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  234. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +94 -0
  235. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  236. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  237. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +6 -11
  238. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
  239. data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
  240. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  241. data/lib/rubocop/cop/lint/rand_one.rb +0 -4
  242. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +4 -2
  243. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
  244. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -12
  245. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +178 -10
  246. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +9 -8
  247. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -6
  248. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  249. data/lib/rubocop/cop/lint/redundant_with_index.rb +9 -2
  250. data/lib/rubocop/cop/lint/redundant_with_object.rb +5 -2
  251. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  252. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  253. data/lib/rubocop/cop/lint/require_parentheses.rb +0 -4
  254. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  255. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -5
  256. data/lib/rubocop/cop/lint/rescue_type.rb +5 -11
  257. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -13
  258. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +31 -13
  259. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +109 -41
  260. data/lib/rubocop/cop/lint/script_permission.rb +3 -3
  261. data/lib/rubocop/cop/lint/self_assignment.rb +71 -10
  262. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  263. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  264. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +26 -12
  265. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  266. data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
  267. data/lib/rubocop/cop/lint/suppressed_exception.rb +3 -3
  268. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  269. data/lib/rubocop/cop/lint/symbol_conversion.rb +9 -4
  270. data/lib/rubocop/cop/lint/syntax.rb +10 -4
  271. data/lib/rubocop/cop/lint/to_enum_arguments.rb +7 -7
  272. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  273. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
  274. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  275. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  276. data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
  277. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +4 -3
  278. data/lib/rubocop/cop/lint/unreachable_code.rb +56 -9
  279. data/lib/rubocop/cop/lint/unreachable_loop.rb +14 -8
  280. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  281. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  282. data/lib/rubocop/cop/lint/useless_access_modifier.rb +36 -10
  283. data/lib/rubocop/cop/lint/useless_assignment.rb +51 -20
  284. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  285. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  286. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  287. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -4
  288. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  289. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +79 -0
  290. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  291. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  292. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
  293. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -29
  294. data/lib/rubocop/cop/lint/useless_times.rb +2 -2
  295. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  296. data/lib/rubocop/cop/lint/void.rb +88 -27
  297. data/lib/rubocop/cop/message_annotator.rb +7 -3
  298. data/lib/rubocop/cop/metrics/abc_size.rb +4 -4
  299. data/lib/rubocop/cop/metrics/block_length.rb +8 -6
  300. data/lib/rubocop/cop/metrics/block_nesting.rb +20 -8
  301. data/lib/rubocop/cop/metrics/class_length.rb +23 -17
  302. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  303. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  304. data/lib/rubocop/cop/metrics/method_length.rb +16 -7
  305. data/lib/rubocop/cop/metrics/module_length.rb +7 -6
  306. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  307. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  308. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +39 -12
  309. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  310. data/lib/rubocop/cop/migration/department_name.rb +2 -2
  311. data/lib/rubocop/cop/mixin/alignment.rb +8 -4
  312. data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
  313. data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
  314. data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
  315. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  316. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  317. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  318. data/lib/rubocop/cop/mixin/code_length.rb +12 -1
  319. data/lib/rubocop/cop/mixin/comments_help.rb +24 -15
  320. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  321. data/lib/rubocop/cop/mixin/configurable_max.rb +5 -1
  322. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  323. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  324. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  325. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  326. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  327. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  328. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  329. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +23 -12
  330. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  331. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  332. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +45 -35
  333. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  334. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  335. data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
  336. data/lib/rubocop/cop/mixin/line_length_help.rb +34 -12
  337. data/lib/rubocop/cop/mixin/method_complexity.rb +17 -7
  338. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +10 -11
  339. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  340. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  341. data/lib/rubocop/cop/mixin/percent_literal.rb +2 -2
  342. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +71 -35
  343. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  344. data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
  345. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
  346. data/lib/rubocop/cop/mixin/statement_modifier.rb +11 -5
  347. data/lib/rubocop/cop/mixin/string_help.rb +5 -3
  348. data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
  349. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  350. data/lib/rubocop/cop/mixin/trailing_comma.rb +22 -6
  351. data/lib/rubocop/cop/naming/accessor_method_name.rb +11 -6
  352. data/lib/rubocop/cop/naming/block_forwarding.rb +40 -9
  353. data/lib/rubocop/cop/naming/constant_name.rb +7 -9
  354. data/lib/rubocop/cop/naming/file_name.rb +5 -7
  355. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
  356. data/lib/rubocop/cop/naming/inclusive_language.rb +13 -5
  357. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +16 -17
  358. data/lib/rubocop/cop/naming/method_name.rb +185 -15
  359. data/lib/rubocop/cop/naming/predicate_method.rb +306 -0
  360. data/lib/rubocop/cop/naming/predicate_prefix.rb +204 -0
  361. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +14 -13
  362. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  363. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  364. data/lib/rubocop/cop/offense.rb +4 -5
  365. data/lib/rubocop/cop/registry.rb +9 -6
  366. data/lib/rubocop/cop/security/compound_hash.rb +4 -2
  367. data/lib/rubocop/cop/security/eval.rb +2 -1
  368. data/lib/rubocop/cop/security/open.rb +3 -2
  369. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  370. data/lib/rubocop/cop/style/access_modifier_declarations.rb +172 -32
  371. data/lib/rubocop/cop/style/accessor_grouping.rb +43 -9
  372. data/lib/rubocop/cop/style/alias.rb +11 -9
  373. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  374. data/lib/rubocop/cop/style/and_or.rb +1 -1
  375. data/lib/rubocop/cop/style/arguments_forwarding.rb +472 -63
  376. data/lib/rubocop/cop/style/array_first_last.rb +80 -0
  377. data/lib/rubocop/cop/style/array_intersect.rb +94 -44
  378. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
  379. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
  380. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  381. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  382. data/lib/rubocop/cop/style/block_delimiters.rb +56 -24
  383. data/lib/rubocop/cop/style/case_like_if.rb +14 -17
  384. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  385. data/lib/rubocop/cop/style/class_check.rb +1 -0
  386. data/lib/rubocop/cop/style/class_equality_comparison.rb +8 -1
  387. data/lib/rubocop/cop/style/class_vars.rb +3 -3
  388. data/lib/rubocop/cop/style/collection_compact.rb +25 -15
  389. data/lib/rubocop/cop/style/collection_methods.rb +4 -1
  390. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  391. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  392. data/lib/rubocop/cop/style/combinable_loops.rb +25 -9
  393. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  394. data/lib/rubocop/cop/style/commented_keyword.rb +30 -4
  395. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  396. data/lib/rubocop/cop/style/concat_array_literals.rb +3 -2
  397. data/lib/rubocop/cop/style/conditional_assignment.rb +53 -38
  398. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  399. data/lib/rubocop/cop/style/copyright.rb +31 -21
  400. data/lib/rubocop/cop/style/data_inheritance.rb +8 -1
  401. data/lib/rubocop/cop/style/date_time.rb +5 -4
  402. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -7
  403. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  404. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
  405. data/lib/rubocop/cop/style/documentation.rb +25 -25
  406. data/lib/rubocop/cop/style/documentation_method.rb +20 -0
  407. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  408. data/lib/rubocop/cop/style/each_for_simple_loop.rb +11 -15
  409. data/lib/rubocop/cop/style/each_with_object.rb +3 -4
  410. data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
  411. data/lib/rubocop/cop/style/empty_else.rb +10 -7
  412. data/lib/rubocop/cop/style/empty_heredoc.rb +1 -14
  413. data/lib/rubocop/cop/style/empty_literal.rb +36 -23
  414. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  415. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  416. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  417. data/lib/rubocop/cop/style/eval_with_location.rb +23 -31
  418. data/lib/rubocop/cop/style/exact_regexp_match.rb +6 -5
  419. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  420. data/lib/rubocop/cop/style/explicit_block_argument.rb +18 -5
  421. data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
  422. data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
  423. data/lib/rubocop/cop/style/file_null.rb +89 -0
  424. data/lib/rubocop/cop/style/file_read.rb +2 -5
  425. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  426. data/lib/rubocop/cop/style/file_write.rb +2 -5
  427. data/lib/rubocop/cop/style/float_division.rb +8 -4
  428. data/lib/rubocop/cop/style/for.rb +4 -2
  429. data/lib/rubocop/cop/style/format_string.rb +33 -12
  430. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  431. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +6 -3
  432. data/lib/rubocop/cop/style/global_std_stream.rb +10 -1
  433. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  434. data/lib/rubocop/cop/style/guard_clause.rb +46 -4
  435. data/lib/rubocop/cop/style/hash_conversion.rb +26 -9
  436. data/lib/rubocop/cop/style/hash_each_methods.rb +110 -12
  437. data/lib/rubocop/cop/style/hash_except.rb +38 -146
  438. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  439. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  440. data/lib/rubocop/cop/style/hash_syntax.rb +35 -7
  441. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  442. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  443. data/lib/rubocop/cop/style/identical_conditional_branches.rb +57 -9
  444. data/lib/rubocop/cop/style/if_inside_else.rb +11 -15
  445. data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
  446. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  447. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +8 -8
  448. data/lib/rubocop/cop/style/if_with_semicolon.rb +62 -8
  449. data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
  450. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  451. data/lib/rubocop/cop/style/inverse_methods.rb +22 -18
  452. data/lib/rubocop/cop/style/invertible_unless_condition.rb +49 -7
  453. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  454. data/lib/rubocop/cop/style/it_assignment.rb +93 -0
  455. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  456. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  457. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  458. data/lib/rubocop/cop/style/lambda.rb +5 -4
  459. data/lib/rubocop/cop/style/lambda_call.rb +14 -3
  460. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  461. data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
  462. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +82 -50
  463. data/lib/rubocop/cop/style/map_into_array.rb +236 -0
  464. data/lib/rubocop/cop/style/map_to_hash.rb +29 -10
  465. data/lib/rubocop/cop/style/map_to_set.rb +4 -5
  466. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +59 -25
  467. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +21 -5
  468. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +30 -13
  469. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  470. data/lib/rubocop/cop/style/method_def_parentheses.rb +2 -2
  471. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  472. data/lib/rubocop/cop/style/missing_else.rb +2 -4
  473. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +35 -5
  474. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  475. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  476. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  477. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  478. data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -9
  479. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +6 -4
  480. data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
  481. data/lib/rubocop/cop/style/multiple_comparison.rb +53 -60
  482. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  483. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  484. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  485. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -2
  486. data/lib/rubocop/cop/style/nested_ternary_operator.rb +8 -15
  487. data/lib/rubocop/cop/style/next.rb +45 -1
  488. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  489. data/lib/rubocop/cop/style/not.rb +1 -1
  490. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  491. data/lib/rubocop/cop/style/numeric_predicate.rb +12 -4
  492. data/lib/rubocop/cop/style/object_then.rb +16 -14
  493. data/lib/rubocop/cop/style/one_line_conditional.rb +31 -6
  494. data/lib/rubocop/cop/style/open_struct_use.rb +6 -6
  495. data/lib/rubocop/cop/style/operator_method_call.rb +32 -8
  496. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  497. data/lib/rubocop/cop/style/parallel_assignment.rb +47 -45
  498. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  499. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  500. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  501. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  502. data/lib/rubocop/cop/style/proc.rb +2 -2
  503. data/lib/rubocop/cop/style/quoted_symbols.rb +2 -4
  504. data/lib/rubocop/cop/style/raise_args.rb +19 -14
  505. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  506. data/lib/rubocop/cop/style/redundant_argument.rb +35 -4
  507. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  508. data/lib/rubocop/cop/style/redundant_assignment.rb +11 -3
  509. data/lib/rubocop/cop/style/redundant_begin.rb +17 -4
  510. data/lib/rubocop/cop/style/redundant_condition.rb +97 -25
  511. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -10
  512. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +50 -0
  513. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +89 -5
  514. data/lib/rubocop/cop/style/redundant_each.rb +7 -4
  515. data/lib/rubocop/cop/style/redundant_exception.rb +33 -13
  516. data/lib/rubocop/cop/style/redundant_fetch_block.rb +4 -12
  517. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
  518. data/lib/rubocop/cop/style/redundant_filter_chain.rb +23 -6
  519. data/lib/rubocop/cop/style/redundant_format.rb +262 -0
  520. data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
  521. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  522. data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
  523. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +46 -0
  524. data/lib/rubocop/cop/style/redundant_line_continuation.rb +73 -20
  525. data/lib/rubocop/cop/style/redundant_parentheses.rb +155 -40
  526. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  527. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +107 -0
  528. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  529. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +10 -25
  530. data/lib/rubocop/cop/style/redundant_return.rb +16 -5
  531. data/lib/rubocop/cop/style/redundant_self.rb +32 -20
  532. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  533. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +12 -5
  534. data/lib/rubocop/cop/style/redundant_sort.rb +11 -10
  535. data/lib/rubocop/cop/style/redundant_sort_by.rb +19 -3
  536. data/lib/rubocop/cop/style/redundant_string_escape.rb +5 -3
  537. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  538. data/lib/rubocop/cop/style/require_order.rb +2 -2
  539. data/lib/rubocop/cop/style/rescue_modifier.rb +18 -4
  540. data/lib/rubocop/cop/style/return_nil.rb +8 -4
  541. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +137 -0
  542. data/lib/rubocop/cop/style/safe_navigation.rb +145 -61
  543. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  544. data/lib/rubocop/cop/style/sample.rb +3 -4
  545. data/lib/rubocop/cop/style/select_by_regexp.rb +20 -13
  546. data/lib/rubocop/cop/style/self_assignment.rb +12 -18
  547. data/lib/rubocop/cop/style/semicolon.rb +10 -5
  548. data/lib/rubocop/cop/style/send.rb +4 -4
  549. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +105 -0
  550. data/lib/rubocop/cop/style/signal_exception.rb +3 -4
  551. data/lib/rubocop/cop/style/single_argument_dig.rb +16 -8
  552. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  553. data/lib/rubocop/cop/style/single_line_do_end_block.rb +78 -0
  554. data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
  555. data/lib/rubocop/cop/style/slicing_with_range.rb +105 -10
  556. data/lib/rubocop/cop/style/sole_nested_conditional.rb +75 -88
  557. data/lib/rubocop/cop/style/special_global_vars.rb +2 -3
  558. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  559. data/lib/rubocop/cop/style/string_chars.rb +1 -0
  560. data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
  561. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  562. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
  563. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  564. data/lib/rubocop/cop/style/strip.rb +7 -4
  565. data/lib/rubocop/cop/style/struct_inheritance.rb +9 -2
  566. data/lib/rubocop/cop/style/super_arguments.rb +221 -0
  567. data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
  568. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  569. data/lib/rubocop/cop/style/symbol_array.rb +35 -15
  570. data/lib/rubocop/cop/style/symbol_proc.rb +78 -6
  571. data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
  572. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  573. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  574. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  575. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  576. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  577. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  578. data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
  579. data/lib/rubocop/cop/style/unpack_first.rb +11 -14
  580. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  581. data/lib/rubocop/cop/style/while_until_do.rb +0 -2
  582. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -2
  583. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  584. data/lib/rubocop/cop/style/yoda_condition.rb +12 -6
  585. data/lib/rubocop/cop/style/yoda_expression.rb +10 -8
  586. data/lib/rubocop/cop/style/zero_length_predicate.rb +32 -24
  587. data/lib/rubocop/cop/team.rb +28 -4
  588. data/lib/rubocop/cop/util.rb +20 -7
  589. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  590. data/lib/rubocop/cop/variable_force/assignment.rb +35 -7
  591. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  592. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  593. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  594. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  595. data/lib/rubocop/cop/variable_force.rb +40 -19
  596. data/lib/rubocop/cops_documentation_generator.rb +133 -56
  597. data/lib/rubocop/core_ext/string.rb +2 -6
  598. data/lib/rubocop/directive_comment.rb +54 -18
  599. data/lib/rubocop/ext/regexp_node.rb +17 -35
  600. data/lib/rubocop/ext/regexp_parser.rb +7 -21
  601. data/lib/rubocop/file_finder.rb +11 -9
  602. data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
  603. data/lib/rubocop/formatter/disabled_config_formatter.rb +26 -10
  604. data/lib/rubocop/formatter/formatter_set.rb +8 -2
  605. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  606. data/lib/rubocop/formatter/html_formatter.rb +38 -15
  607. data/lib/rubocop/formatter/json_formatter.rb +0 -1
  608. data/lib/rubocop/formatter/junit_formatter.rb +71 -24
  609. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  610. data/lib/rubocop/formatter/offense_count_formatter.rb +13 -3
  611. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  612. data/lib/rubocop/formatter/tap_formatter.rb +3 -7
  613. data/lib/rubocop/formatter.rb +1 -1
  614. data/lib/rubocop/lockfile.rb +58 -7
  615. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  616. data/lib/rubocop/lsp/logger.rb +22 -0
  617. data/lib/rubocop/lsp/routes.rb +227 -0
  618. data/lib/rubocop/lsp/runtime.rb +69 -0
  619. data/lib/rubocop/lsp/server.rb +70 -0
  620. data/lib/rubocop/lsp/severity.rb +27 -0
  621. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  622. data/lib/rubocop/lsp.rb +36 -0
  623. data/lib/rubocop/magic_comment.rb +24 -14
  624. data/lib/rubocop/options.rb +54 -23
  625. data/lib/rubocop/path_util.rb +21 -10
  626. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  627. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  628. data/lib/rubocop/plugin/load_error.rb +26 -0
  629. data/lib/rubocop/plugin/loader.rb +100 -0
  630. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  631. data/lib/rubocop/plugin.rb +46 -0
  632. data/lib/rubocop/rake_task.rb +5 -2
  633. data/lib/rubocop/remote_config.rb +5 -1
  634. data/lib/rubocop/result_cache.rb +29 -30
  635. data/lib/rubocop/rspec/cop_helper.rb +20 -2
  636. data/lib/rubocop/rspec/expect_offense.rb +31 -12
  637. data/lib/rubocop/rspec/shared_contexts.rb +114 -21
  638. data/lib/rubocop/rspec/support.rb +7 -2
  639. data/lib/rubocop/runner.rb +40 -13
  640. data/lib/rubocop/server/cache.rb +63 -10
  641. data/lib/rubocop/server/cli.rb +2 -2
  642. data/lib/rubocop/server/client_command/base.rb +10 -0
  643. data/lib/rubocop/server/client_command/exec.rb +4 -4
  644. data/lib/rubocop/server/client_command/start.rb +11 -1
  645. data/lib/rubocop/server/core.rb +5 -0
  646. data/lib/rubocop/server/server_command/exec.rb +0 -1
  647. data/lib/rubocop/string_interpreter.rb +3 -3
  648. data/lib/rubocop/target_finder.rb +97 -82
  649. data/lib/rubocop/target_ruby.rb +102 -77
  650. data/lib/rubocop/version.rb +67 -9
  651. data/lib/rubocop/yaml_duplication_checker.rb +20 -26
  652. data/lib/rubocop.rb +69 -2
  653. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  654. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  655. metadata +136 -42
  656. data/lib/rubocop/cop/naming/predicate_name.rb +0 -134
  657. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
  658. /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -3,14 +3,26 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks the style of children definitions at classes and
7
- # modules. Basically there are two different styles:
6
+ # Checks that namespaced classes and modules are defined with a consistent style.
7
+ #
8
+ # With `nested` style, classes and modules should be defined separately (one constant
9
+ # on each line, without `::`). With `compact` style, classes and modules should be
10
+ # defined with fully qualified names (using `::` for namespaces).
11
+ #
12
+ # NOTE: The style chosen will affect `Module.nesting` for the class or module. Using
13
+ # `nested` style will result in each level being added, whereas `compact` style will
14
+ # only include the fully qualified class or module name.
15
+ #
16
+ # By default, `EnforcedStyle` applies to both classes and modules. If desired, separate
17
+ # styles can be defined for classes and modules by using `EnforcedStyleForClasses` and
18
+ # `EnforcedStyleForModules` respectively. If not set, or set to nil, the `EnforcedStyle`
19
+ # value will be used.
8
20
  #
9
21
  # @safety
10
22
  # Autocorrection is unsafe.
11
23
  #
12
- # Moving from compact to nested children requires knowledge of whether the
13
- # outer parent is a module or a class. Moving from nested to compact requires
24
+ # Moving from `compact` to `nested` children requires knowledge of whether the
25
+ # outer parent is a module or a class. Moving from `nested` to `compact` requires
14
26
  # verification that the outer parent is defined elsewhere. RuboCop does not
15
27
  # have the knowledge to perform either operation safely and thus requires
16
28
  # manual oversight.
@@ -42,16 +54,18 @@ module RuboCop
42
54
  def on_class(node)
43
55
  return if node.parent_class && style != :nested
44
56
 
45
- check_style(node, node.body)
57
+ check_style(node, node.body, style_for_classes)
46
58
  end
47
59
 
48
60
  def on_module(node)
49
- check_style(node, node.body)
61
+ check_style(node, node.body, style_for_modules)
50
62
  end
51
63
 
52
64
  private
53
65
 
54
66
  def nest_or_compact(corrector, node)
67
+ style = node.class_type? ? style_for_classes : style_for_modules
68
+
55
69
  if style == :nested
56
70
  nest_definition(corrector, node)
57
71
  else
@@ -117,18 +131,27 @@ module RuboCop
117
131
  "#{node.body.children.first.const_name}"
118
132
  end
119
133
 
134
+ # rubocop:disable Metrics/AbcSize
120
135
  def remove_end(corrector, body)
121
- remove_begin_pos = body.loc.end.begin_pos - leading_spaces(body).size
136
+ remove_begin_pos = if same_line?(body.loc.name, body.loc.end)
137
+ body.loc.name.end_pos
138
+ else
139
+ body.loc.end.begin_pos - leading_spaces(body).size
140
+ end
122
141
  adjustment = processed_source.raw_source[remove_begin_pos] == ';' ? 0 : 1
123
142
  range = range_between(remove_begin_pos, body.loc.end.end_pos + adjustment)
124
143
 
125
144
  corrector.remove(range)
126
145
  end
146
+ # rubocop:enable Metrics/AbcSize
127
147
 
128
148
  def unindent(corrector, node)
129
- return if node.body.children.last.nil?
149
+ return unless node.body.children.last
130
150
 
131
- column_delta = configured_indentation_width - leading_spaces(node.body.children.last).size
151
+ last_child_leading_spaces = leading_spaces(node.body.children.last)
152
+ return if spaces_size(leading_spaces(node)) == spaces_size(last_child_leading_spaces)
153
+
154
+ column_delta = configured_indentation_width - spaces_size(last_child_leading_spaces)
132
155
  return if column_delta.zero?
133
156
 
134
157
  AlignmentCorrector.correct(corrector, processed_source, node, column_delta)
@@ -138,7 +161,17 @@ module RuboCop
138
161
  node.source_range.source_line[/\A\s*/]
139
162
  end
140
163
 
141
- def check_style(node, body)
164
+ def spaces_size(spaces_string)
165
+ mapping = { "\t" => tab_indentation_width }
166
+ spaces_string.chars.sum { |character| mapping.fetch(character, 1) }
167
+ end
168
+
169
+ def tab_indentation_width
170
+ config.for_cop('Layout/IndentationStyle')['IndentationWidth'] ||
171
+ configured_indentation_width
172
+ end
173
+
174
+ def check_style(node, body, style)
142
175
  return if node.identifier.namespace&.cbase_type?
143
176
 
144
177
  if style == :nested
@@ -158,7 +191,7 @@ module RuboCop
158
191
 
159
192
  def check_compact_style(node, body)
160
193
  parent = node.parent
161
- return if parent&.class_type? || parent&.module_type?
194
+ return if parent&.type?(:class, :module)
162
195
 
163
196
  return unless needs_compacting?(body)
164
197
 
@@ -180,6 +213,14 @@ module RuboCop
180
213
  def compact_node_name?(node)
181
214
  node.identifier.source.include?('::')
182
215
  end
216
+
217
+ def style_for_classes
218
+ cop_config['EnforcedStyleForClasses'] || style
219
+ end
220
+
221
+ def style_for_modules
222
+ cop_config['EnforcedStyleForModules'] || style
223
+ end
183
224
  end
184
225
  end
185
226
  end
@@ -40,6 +40,7 @@ module RuboCop
40
40
  corrector.replace(node.loc.selector, replacement)
41
41
  end
42
42
  end
43
+ alias on_csend on_send
43
44
 
44
45
  def message(node)
45
46
  if node.method?(:is_a?)
@@ -8,6 +8,11 @@ module RuboCop
8
8
  # `==`, `equal?`, and `eql?` custom method definitions are allowed by default.
9
9
  # These are customizable with `AllowedMethods` option.
10
10
  #
11
+ # @safety
12
+ # This cop's autocorrection is unsafe because there is no guarantee that
13
+ # the constant `Foo` exists when autocorrecting `var.class.name == 'Foo'` to
14
+ # `var.instance_of?(Foo)`.
15
+ #
11
16
  # @example
12
17
  # # bad
13
18
  # var.class == Date
@@ -63,12 +68,14 @@ module RuboCop
63
68
  PATTERN
64
69
 
65
70
  def on_send(node)
66
- def_node = node.each_ancestor(:def, :defs).first
71
+ def_node = node.each_ancestor(:any_def).first
67
72
  return if def_node &&
68
73
  (allowed_method?(def_node.method_name) ||
69
74
  matches_allowed_pattern?(def_node.method_name))
70
75
 
71
76
  class_comparison_candidate?(node) do |receiver_node, class_node|
77
+ return if class_node.dstr_type?
78
+
72
79
  range = offense_range(receiver_node, node)
73
80
  class_argument = (class_name = class_name(class_node, node)) ? "(#{class_name})" : ''
74
81
 
@@ -54,9 +54,9 @@ module RuboCop
54
54
  end
55
55
 
56
56
  def on_send(node)
57
- add_offense(
58
- node.first_argument, message: format(MSG, class_var: node.first_argument.source)
59
- )
57
+ return unless (first_argument = node.first_argument)
58
+
59
+ add_offense(first_argument, message: format(MSG, class_var: first_argument.source))
60
60
  end
61
61
  end
62
62
  end
@@ -19,10 +19,11 @@ module RuboCop
19
19
  # @example
20
20
  # # bad
21
21
  # array.reject(&:nil?)
22
- # array.delete_if(&:nil?)
23
22
  # array.reject { |e| e.nil? }
24
- # array.delete_if { |e| e.nil? }
25
23
  # array.select { |e| !e.nil? }
24
+ # array.filter { |e| !e.nil? }
25
+ # array.grep_v(nil)
26
+ # array.grep_v(NilClass)
26
27
  #
27
28
  # # good
28
29
  # array.compact
@@ -31,6 +32,7 @@ module RuboCop
31
32
  # hash.reject!(&:nil?)
32
33
  # hash.reject! { |k, v| v.nil? }
33
34
  # hash.select! { |k, v| !v.nil? }
35
+ # hash.filter! { |k, v| !v.nil? }
34
36
  #
35
37
  # # good
36
38
  # hash.compact!
@@ -46,14 +48,15 @@ module RuboCop
46
48
  extend TargetRubyVersion
47
49
 
48
50
  MSG = 'Use `%<good>s` instead of `%<bad>s`.'
49
- RESTRICT_ON_SEND = %i[reject delete_if reject! select select!].freeze
51
+ RESTRICT_ON_SEND = %i[reject reject! select select! filter filter! grep_v].freeze
50
52
  TO_ENUM_METHODS = %i[to_enum lazy].freeze
53
+ FILTER_METHODS = %i[filter filter!].freeze
51
54
 
52
55
  minimum_target_ruby_version 2.4
53
56
 
54
57
  # @!method reject_method_with_block_pass?(node)
55
58
  def_node_matcher :reject_method_with_block_pass?, <<~PATTERN
56
- (send !nil? {:reject :delete_if :reject!}
59
+ (call !nil? {:reject :reject!}
57
60
  (block_pass
58
61
  (sym :nil?)))
59
62
  PATTERN
@@ -61,41 +64,47 @@ module RuboCop
61
64
  # @!method reject_method?(node)
62
65
  def_node_matcher :reject_method?, <<~PATTERN
63
66
  (block
64
- (send
65
- !nil? {:reject :delete_if :reject!})
67
+ (call
68
+ !nil? {:reject :reject!})
66
69
  $(args ...)
67
- (send
70
+ (call
68
71
  $(lvar _) :nil?))
69
72
  PATTERN
70
73
 
71
74
  # @!method select_method?(node)
72
75
  def_node_matcher :select_method?, <<~PATTERN
73
76
  (block
74
- (send
75
- !nil? {:select :select!})
77
+ (call
78
+ !nil? {:select :select! :filter :filter!})
76
79
  $(args ...)
77
- (send
78
- (send
80
+ (call
81
+ (call
79
82
  $(lvar _) :nil?) :!))
80
83
  PATTERN
81
84
 
85
+ # @!method grep_v_with_nil?(node)
86
+ def_node_matcher :grep_v_with_nil?, <<~PATTERN
87
+ (send _ :grep_v {(nil) (const {nil? cbase} :NilClass)})
88
+ PATTERN
89
+
82
90
  def on_send(node)
91
+ return if target_ruby_version < 2.6 && FILTER_METHODS.include?(node.method_name)
83
92
  return unless (range = offense_range(node))
84
93
  return if allowed_receiver?(node.receiver)
85
- if (target_ruby_version <= 3.0 || node.method?(:delete_if)) && to_enum_method?(node)
86
- return
87
- end
94
+ return if target_ruby_version <= 3.0 && to_enum_method?(node)
88
95
 
89
96
  good = good_method_name(node)
90
97
  message = format(MSG, good: good, bad: range.source)
91
98
 
92
99
  add_offense(range, message: message) { |corrector| corrector.replace(range, good) }
93
100
  end
101
+ alias on_csend on_send
94
102
 
95
103
  private
96
104
 
105
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
97
106
  def offense_range(node)
98
- if reject_method_with_block_pass?(node)
107
+ if reject_method_with_block_pass?(node) || grep_v_with_nil?(node)
99
108
  range(node, node)
100
109
  else
101
110
  block_node = node.parent
@@ -109,6 +118,7 @@ module RuboCop
109
118
  range(node, block_node)
110
119
  end
111
120
  end
121
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
112
122
 
113
123
  def to_enum_method?(node)
114
124
  return false unless node.receiver.send_type?
@@ -25,6 +25,7 @@ module RuboCop
25
25
  # # bad
26
26
  # items.collect
27
27
  # items.collect!
28
+ # items.collect_concat
28
29
  # items.inject
29
30
  # items.detect
30
31
  # items.find_all
@@ -33,6 +34,7 @@ module RuboCop
33
34
  # # good
34
35
  # items.map
35
36
  # items.map!
37
+ # items.flat_map
36
38
  # items.reduce
37
39
  # items.find
38
40
  # items.select
@@ -47,14 +49,15 @@ module RuboCop
47
49
  def on_block(node)
48
50
  check_method_node(node.send_node)
49
51
  end
50
-
51
52
  alias on_numblock on_block
53
+ alias on_itblock on_block
52
54
 
53
55
  def on_send(node)
54
56
  return unless implicit_block?(node)
55
57
 
56
58
  check_method_node(node)
57
59
  end
60
+ alias on_csend on_send
58
61
 
59
62
  private
60
63
 
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Prefer `Enumerable` predicate methods over expressions with `count`.
7
+ #
8
+ # The cop checks calls to `count` without arguments, or with a
9
+ # block. It doesn't register offenses for `count` with a positional
10
+ # argument because its behavior differs from predicate methods (`count`
11
+ # matches the argument using `==`, while `any?`, `none?` and `one?` use
12
+ # `===`).
13
+ #
14
+ # NOTE: This cop doesn't check `length` and `size` methods because they
15
+ # would yield false positives. For example, `String` implements `length`
16
+ # and `size`, but it doesn't include `Enumerable`.
17
+ #
18
+ # @safety
19
+ # The cop is unsafe because receiver might not include `Enumerable`, or
20
+ # it has nonstandard implementation of `count` or any replacement
21
+ # methods.
22
+ #
23
+ # It's also unsafe because for collections with falsey values, expressions
24
+ # with `count` without a block return a different result than methods `any?`,
25
+ # `none?` and `one?`:
26
+ #
27
+ # [source,ruby]
28
+ # ----
29
+ # [nil, false].count.positive?
30
+ # [nil].count == 1
31
+ # # => true
32
+ #
33
+ # [nil, false].any?
34
+ # [nil].one?
35
+ # # => false
36
+ #
37
+ # [nil].count == 0
38
+ # # => false
39
+ #
40
+ # [nil].none?
41
+ # # => true
42
+ # ----
43
+ #
44
+ # Autocorrection is unsafe when replacement methods don't iterate over
45
+ # every element in collection and the given block runs side effects:
46
+ #
47
+ # [source,ruby]
48
+ # ----
49
+ # x.count(&:method_with_side_effects).positive?
50
+ # # calls `method_with_side_effects` on every element
51
+ #
52
+ # x.any?(&:method_with_side_effects)
53
+ # # calls `method_with_side_effects` until first element returns a truthy value
54
+ # ----
55
+ #
56
+ # @example
57
+ #
58
+ # # bad
59
+ # x.count.positive?
60
+ # x.count > 0
61
+ # x.count != 0
62
+ #
63
+ # x.count(&:foo?).positive?
64
+ # x.count { |item| item.foo? }.positive?
65
+ #
66
+ # # good
67
+ # x.any?
68
+ #
69
+ # x.any?(&:foo?)
70
+ # x.any? { |item| item.foo? }
71
+ #
72
+ # # bad
73
+ # x.count.zero?
74
+ # x.count == 0
75
+ #
76
+ # # good
77
+ # x.none?
78
+ #
79
+ # # bad
80
+ # x.count == 1
81
+ # x.one?
82
+ #
83
+ # @example AllCops:ActiveSupportExtensionsEnabled: false (default)
84
+ #
85
+ # # good
86
+ # x.count > 1
87
+ #
88
+ # @example AllCops:ActiveSupportExtensionsEnabled: true
89
+ #
90
+ # # bad
91
+ # x.count > 1
92
+ #
93
+ # # good
94
+ # x.many?
95
+ #
96
+ class CollectionQuerying < Base
97
+ include RangeHelp
98
+ extend AutoCorrector
99
+
100
+ MSG = 'Use `%<prefer>s` instead.'
101
+
102
+ RESTRICT_ON_SEND = %i[positive? > != zero? ==].freeze
103
+
104
+ REPLACEMENTS = {
105
+ [:positive?, nil] => :any?,
106
+ [:>, 0] => :any?,
107
+ [:!=, 0] => :any?,
108
+ [:zero?, nil] => :none?,
109
+ [:==, 0] => :none?,
110
+ [:==, 1] => :one?,
111
+ [:>, 1] => :many?
112
+ }.freeze
113
+
114
+ # @!method count_predicate(node)
115
+ def_node_matcher :count_predicate, <<~PATTERN
116
+ (send
117
+ {
118
+ (any_block $(call !nil? :count) _ _)
119
+ $(call !nil? :count (block-pass _)?)
120
+ }
121
+ {
122
+ :positive? |
123
+ :> (int 0) |
124
+ :!= (int 0) |
125
+ :zero? |
126
+ :== (int 0) |
127
+ :== (int 1) |
128
+ :> (int 1)
129
+ })
130
+ PATTERN
131
+
132
+ def on_send(node)
133
+ return unless (count_node = count_predicate(node))
134
+
135
+ replacement_method = replacement_method(node)
136
+
137
+ return unless replacement_supported?(replacement_method)
138
+
139
+ offense_range = count_node.loc.selector.join(node.source_range.end)
140
+ add_offense(offense_range,
141
+ message: format(MSG, prefer: replacement_method)) do |corrector|
142
+ corrector.replace(count_node.loc.selector, replacement_method)
143
+ corrector.remove(removal_range(node))
144
+ end
145
+ end
146
+
147
+ private
148
+
149
+ def replacement_method(node)
150
+ REPLACEMENTS.fetch([node.method_name, node.first_argument&.value])
151
+ end
152
+
153
+ def replacement_supported?(method_name)
154
+ return true if active_support_extensions_enabled?
155
+
156
+ method_name != :many?
157
+ end
158
+
159
+ def removal_range(node)
160
+ range = (node.loc.dot || node.loc.selector).join(node.source_range.end)
161
+
162
+ range_with_surrounding_space(range, side: :left)
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for multiple `defined?` calls joined by `&&` that can be combined
7
+ # into a single `defined?`.
8
+ #
9
+ # When checking that a nested constant or chained method is defined, it is
10
+ # not necessary to check each ancestor or component of the chain.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # defined?(Foo) && defined?(Foo::Bar) && defined?(Foo::Bar::Baz)
15
+ #
16
+ # # good
17
+ # defined?(Foo::Bar::Baz)
18
+ #
19
+ # # bad
20
+ # defined?(foo) && defined?(foo.bar) && defined?(foo.bar.baz)
21
+ #
22
+ # # good
23
+ # defined?(foo.bar.baz)
24
+ class CombinableDefined < Base
25
+ extend AutoCorrector
26
+ include RangeHelp
27
+
28
+ MSG = 'Combine nested `defined?` calls.'
29
+ OPERATORS = %w[&& and].freeze
30
+
31
+ def on_and(node)
32
+ # Only register an offense if all `&&` terms are `defined?` calls
33
+ return unless (terms = terms(node)).all?(&:defined_type?)
34
+
35
+ calls = defined_calls(terms)
36
+ namespaces = namespaces(calls)
37
+
38
+ calls.each do |call|
39
+ next unless namespaces.any?(call)
40
+
41
+ add_offense(node) do |corrector|
42
+ remove_term(corrector, call)
43
+ end
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def terms(node)
50
+ node.each_descendant.select do |descendant|
51
+ descendant.parent.and_type? && !descendant.and_type?
52
+ end
53
+ end
54
+
55
+ def defined_calls(nodes)
56
+ nodes.filter_map do |defined_node|
57
+ subject = defined_node.first_argument
58
+ subject if subject.type?(:const, :call)
59
+ end
60
+ end
61
+
62
+ def namespaces(nodes)
63
+ nodes.filter_map do |node|
64
+ if node.respond_to?(:namespace)
65
+ node.namespace
66
+ elsif node.respond_to?(:receiver)
67
+ node.receiver
68
+ end
69
+ end
70
+ end
71
+
72
+ def remove_term(corrector, term)
73
+ term = term.parent until term.parent.and_type?
74
+ range = if term == term.parent.children.last
75
+ rhs_range_to_remove(term)
76
+ else
77
+ lhs_range_to_remove(term)
78
+ end
79
+
80
+ corrector.remove(range)
81
+ end
82
+
83
+ # If the redundant `defined?` node is the LHS of an `and` node,
84
+ # the term as well as the subsequent `&&`/`and` operator will be removed.
85
+ def lhs_range_to_remove(term)
86
+ source = @processed_source.buffer.source
87
+
88
+ pos = term.source_range.end_pos
89
+ pos += 1 until source[..pos].end_with?(*OPERATORS)
90
+
91
+ range_with_surrounding_space(
92
+ range: term.source_range.with(end_pos: pos + 1),
93
+ side: :right,
94
+ newlines: false
95
+ )
96
+ end
97
+
98
+ # If the redundant `defined?` node is the RHS of an `and` node,
99
+ # the term as well as the preceding `&&`/`and` operator will be removed.
100
+ def rhs_range_to_remove(term)
101
+ source = @processed_source.buffer.source
102
+
103
+ pos = term.source_range.begin_pos
104
+ pos -= 1 until source[pos, 3].start_with?(*OPERATORS)
105
+
106
+ range_with_surrounding_space(
107
+ range: term.source_range.with(begin_pos: pos - 1),
108
+ side: :right,
109
+ newlines: false
110
+ )
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -7,6 +7,9 @@ module RuboCop
7
7
  # can be combined into a single loop. It is very likely that combining them
8
8
  # will make the code more efficient and more concise.
9
9
  #
10
+ # NOTE: Autocorrection is not applied when the block variable names differ in separate loops,
11
+ # as it is impossible to determine which variable name should be prioritized.
12
+ #
10
13
  # @safety
11
14
  # The cop is unsafe, because the first loop might modify state that the
12
15
  # second loop depends on; these two aren't combinable.
@@ -59,21 +62,25 @@ module RuboCop
59
62
  class CombinableLoops < Base
60
63
  extend AutoCorrector
61
64
 
62
- include RangeHelp
63
-
64
65
  MSG = 'Combine this loop with the previous loop.'
65
66
 
67
+ # rubocop:disable Metrics/CyclomaticComplexity
66
68
  def on_block(node)
67
69
  return unless node.parent&.begin_type?
68
70
  return unless collection_looping_method?(node)
69
71
  return unless same_collection_looping_block?(node, node.left_sibling)
72
+ return unless node.body && node.left_sibling.body
70
73
 
71
74
  add_offense(node) do |corrector|
75
+ next unless node.arguments == node.left_sibling.arguments
76
+
72
77
  combine_with_left_sibling(corrector, node)
73
78
  end
74
79
  end
80
+ # rubocop:enable Metrics/CyclomaticComplexity
75
81
 
76
82
  alias on_numblock on_block
83
+ alias on_itblock on_block
77
84
 
78
85
  def on_for(node)
79
86
  return unless node.parent&.begin_type?
@@ -92,8 +99,9 @@ module RuboCop
92
99
  end
93
100
 
94
101
  def same_collection_looping_block?(node, sibling)
95
- (sibling&.block_type? || sibling&.numblock_type?) &&
96
- sibling.send_node.method?(node.method_name) &&
102
+ return false if sibling.nil? || !sibling.any_block_type?
103
+
104
+ sibling.method?(node.method_name) &&
97
105
  sibling.receiver == node.receiver &&
98
106
  sibling.send_node.arguments == node.send_node.arguments
99
107
  end
@@ -103,11 +111,19 @@ module RuboCop
103
111
  end
104
112
 
105
113
  def combine_with_left_sibling(corrector, node)
106
- corrector.replace(
107
- node.left_sibling.body,
108
- "#{node.left_sibling.body.source}\n#{node.body.source}"
109
- )
110
- corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
114
+ corrector.remove(node.left_sibling.body.source_range.end.join(node.left_sibling.loc.end))
115
+ corrector.remove(node.source_range.begin.join(node.body.source_range.begin))
116
+
117
+ correct_end_of_block(corrector, node)
118
+ end
119
+
120
+ def correct_end_of_block(corrector, node)
121
+ return unless node.left_sibling.respond_to?(:braces?)
122
+ return if node.right_sibling&.any_block_type?
123
+
124
+ end_of_block = node.left_sibling.braces? ? '}' : ' end'
125
+ corrector.remove(node.loc.end)
126
+ corrector.insert_before(node.source_range.end, end_of_block)
111
127
  end
112
128
  end
113
129
  end
@@ -173,7 +173,7 @@ module RuboCop
173
173
  end
174
174
 
175
175
  def preferred_delimiters_config
176
- config.for_cop('Style/PercentLiteralDelimiters') ['PreferredDelimiters']
176
+ config.for_cop('Style/PercentLiteralDelimiters')['PreferredDelimiters']
177
177
  end
178
178
  end
179
179
  end