rubocop 1.71.1 → 1.92.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 (712) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +886 -168
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +47 -4
  7. data/exe/rubocop +2 -9
  8. data/lib/rubocop/cache_config.rb +29 -0
  9. data/lib/rubocop/cached_data.rb +50 -5
  10. data/lib/rubocop/changed_files.rb +134 -0
  11. data/lib/rubocop/cli/command/auto_generate_config.rb +36 -4
  12. data/lib/rubocop/cli/command/cop_names.rb +57 -0
  13. data/lib/rubocop/cli/command/execute_runner.rb +54 -3
  14. data/lib/rubocop/cli/command/explain.rb +34 -0
  15. data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
  16. data/lib/rubocop/cli/command/lsp.rb +1 -1
  17. data/lib/rubocop/cli/command/mcp.rb +19 -0
  18. data/lib/rubocop/cli/command/show_cops.rb +8 -2
  19. data/lib/rubocop/cli/command/show_docs_url.rb +8 -10
  20. data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
  21. data/lib/rubocop/cli.rb +59 -17
  22. data/lib/rubocop/comment_config/directive_range.rb +34 -0
  23. data/lib/rubocop/comment_config/disable_next.rb +143 -0
  24. data/lib/rubocop/comment_config/push_pop.rb +55 -0
  25. data/lib/rubocop/comment_config.rb +98 -45
  26. data/lib/rubocop/config.rb +137 -19
  27. data/lib/rubocop/config_finder.rb +1 -1
  28. data/lib/rubocop/config_loader.rb +75 -49
  29. data/lib/rubocop/config_loader_resolver.rb +124 -33
  30. data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
  31. data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
  32. data/lib/rubocop/config_obsoletion/removed_cop.rb +9 -1
  33. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  34. data/lib/rubocop/config_obsoletion.rb +47 -3
  35. data/lib/rubocop/config_store.rb +7 -2
  36. data/lib/rubocop/config_validator.rb +75 -12
  37. data/lib/rubocop/cop/autocorrect_logic.rb +43 -17
  38. data/lib/rubocop/cop/badge.rb +10 -2
  39. data/lib/rubocop/cop/base.rb +128 -35
  40. data/lib/rubocop/cop/bundler/gem_comment.rb +5 -4
  41. data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
  42. data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -11
  43. data/lib/rubocop/cop/bundler.rb +19 -0
  44. data/lib/rubocop/cop/commissioner.rb +13 -11
  45. data/lib/rubocop/cop/cop_documentation.rb +81 -0
  46. data/lib/rubocop/cop/cop_explanation.rb +140 -0
  47. data/lib/rubocop/cop/corrector.rb +4 -4
  48. data/lib/rubocop/cop/correctors/alignment_corrector.rb +92 -11
  49. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  50. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +37 -7
  51. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
  52. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
  53. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +31 -4
  54. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +35 -5
  55. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
  56. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +73 -2
  57. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  58. data/lib/rubocop/cop/correctors.rb +28 -0
  59. data/lib/rubocop/cop/documentation.rb +3 -4
  60. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  61. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  62. data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
  63. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  64. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +49 -17
  65. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -9
  66. data/lib/rubocop/cop/gemspec/require_mfa.rb +22 -5
  67. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
  68. data/lib/rubocop/cop/gemspec.rb +22 -0
  69. data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
  70. data/lib/rubocop/cop/generator.rb +5 -1
  71. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  72. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
  73. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  74. data/lib/rubocop/cop/internal_affairs/location_exists.rb +142 -0
  75. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  76. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +16 -20
  77. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
  78. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
  79. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +6 -2
  80. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +85 -0
  81. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +2 -2
  82. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  83. data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
  84. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  85. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
  86. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
  87. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  88. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
  89. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  90. data/lib/rubocop/cop/internal_affairs.rb +3 -16
  91. data/lib/rubocop/cop/layout/argument_alignment.rb +9 -3
  92. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  93. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
  94. data/lib/rubocop/cop/layout/block_alignment.rb +86 -4
  95. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  96. data/lib/rubocop/cop/layout/case_indentation.rb +28 -10
  97. data/lib/rubocop/cop/layout/class_structure.rb +191 -41
  98. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  99. data/lib/rubocop/cop/layout/comment_indentation.rb +17 -7
  100. data/lib/rubocop/cop/layout/condition_position.rb +13 -3
  101. data/lib/rubocop/cop/layout/def_end_alignment.rb +5 -1
  102. data/lib/rubocop/cop/layout/dot_position.rb +27 -17
  103. data/lib/rubocop/cop/layout/else_alignment.rb +3 -15
  104. data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
  105. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +27 -9
  106. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
  107. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +21 -8
  108. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +46 -21
  109. data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
  110. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  111. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +34 -4
  112. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  113. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -0
  114. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +22 -5
  115. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +17 -3
  116. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
  117. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
  118. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  119. data/lib/rubocop/cop/layout/end_alignment.rb +23 -15
  120. data/lib/rubocop/cop/layout/extra_spacing.rb +109 -3
  121. data/lib/rubocop/cop/layout/first_argument_indentation.rb +82 -3
  122. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -5
  123. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +41 -0
  124. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +36 -23
  125. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
  126. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
  127. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
  128. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
  129. data/lib/rubocop/cop/layout/hash_alignment.rb +20 -18
  130. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +9 -5
  131. data/lib/rubocop/cop/layout/heredoc_indentation.rb +48 -3
  132. data/lib/rubocop/cop/layout/indentation_consistency.rb +22 -5
  133. data/lib/rubocop/cop/layout/indentation_style.rb +5 -2
  134. data/lib/rubocop/cop/layout/indentation_width.rb +159 -12
  135. data/lib/rubocop/cop/layout/leading_comment_space.rb +40 -1
  136. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +10 -4
  137. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
  138. data/lib/rubocop/cop/layout/line_length.rb +300 -31
  139. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +69 -57
  140. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
  141. data/lib/rubocop/cop/layout/multiline_block_layout.rb +11 -1
  142. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +65 -56
  143. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +7 -1
  144. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +270 -40
  145. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
  146. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  147. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +9 -5
  148. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  149. data/lib/rubocop/cop/layout/redundant_line_break.rb +111 -7
  150. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +29 -9
  151. data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
  152. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
  153. data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
  154. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  155. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +10 -4
  156. data/lib/rubocop/cop/layout/space_around_keyword.rb +20 -3
  157. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  158. data/lib/rubocop/cop/layout/space_around_operators.rb +30 -4
  159. data/lib/rubocop/cop/layout/space_before_block_braces.rb +5 -1
  160. data/lib/rubocop/cop/layout/space_before_brackets.rb +6 -39
  161. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
  162. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +55 -36
  163. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +32 -8
  164. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
  165. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -12
  166. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  167. data/lib/rubocop/cop/layout.rb +114 -0
  168. data/lib/rubocop/cop/lazy_loader.rb +41 -0
  169. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
  170. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +72 -1
  171. data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
  172. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +3 -11
  173. data/lib/rubocop/cop/lint/ambiguous_range.rb +6 -2
  174. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +6 -1
  175. data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
  176. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
  177. data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
  178. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  179. data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -8
  180. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
  181. data/lib/rubocop/cop/lint/constant_reassignment.rb +94 -15
  182. data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
  183. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +240 -0
  184. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  185. data/lib/rubocop/cop/lint/debugger.rb +13 -4
  186. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  187. data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
  188. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +5 -2
  189. data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
  190. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
  191. data/lib/rubocop/cop/lint/duplicate_methods.rb +506 -41
  192. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
  193. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  194. data/lib/rubocop/cop/lint/empty_block.rb +4 -4
  195. data/lib/rubocop/cop/lint/empty_conditional_body.rb +22 -65
  196. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  197. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  198. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  199. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  200. data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
  201. data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -8
  202. data/lib/rubocop/cop/lint/float_comparison.rb +33 -10
  203. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
  204. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +4 -0
  205. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  206. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
  207. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
  208. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
  209. data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
  210. data/lib/rubocop/cop/lint/interpolation_check.rb +25 -6
  211. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  212. data/lib/rubocop/cop/lint/literal_as_condition.rb +152 -11
  213. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
  214. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +75 -37
  215. data/lib/rubocop/cop/lint/loop.rb +24 -2
  216. data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +245 -0
  217. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +60 -23
  218. data/lib/rubocop/cop/lint/missing_super.rb +31 -1
  219. data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
  220. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  221. data/lib/rubocop/cop/lint/name_typo.rb +270 -0
  222. data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
  223. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  224. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
  225. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
  226. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
  227. data/lib/rubocop/cop/lint/number_conversion.rb +22 -11
  228. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  229. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +11 -0
  230. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
  231. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
  232. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
  233. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +20 -14
  234. data/lib/rubocop/cop/lint/raise_exception.rb +30 -11
  235. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  236. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +160 -39
  237. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +53 -19
  238. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +28 -6
  239. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  240. data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -25
  241. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +134 -12
  242. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -4
  243. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +267 -0
  244. data/lib/rubocop/cop/lint/redundant_with_index.rb +5 -3
  245. data/lib/rubocop/cop/lint/redundant_with_object.rb +8 -0
  246. data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
  247. data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
  248. data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
  249. data/lib/rubocop/cop/lint/require_range_parentheses.rb +3 -2
  250. data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
  251. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
  252. data/lib/rubocop/cop/lint/rescue_type.rb +2 -2
  253. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  254. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +28 -4
  255. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +56 -6
  256. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  257. data/lib/rubocop/cop/lint/script_permission.rb +5 -1
  258. data/lib/rubocop/cop/lint/self_assignment.rb +63 -6
  259. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
  260. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  261. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  262. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -1
  263. data/lib/rubocop/cop/lint/shared_mutable_default.rb +14 -1
  264. data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
  265. data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
  266. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  267. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +122 -0
  268. data/lib/rubocop/cop/lint/symbol_conversion.rb +22 -4
  269. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  270. data/lib/rubocop/cop/lint/to_enum_arguments.rb +73 -5
  271. data/lib/rubocop/cop/lint/to_json.rb +20 -17
  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 +5 -1
  274. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +54 -11
  275. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
  276. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -1
  277. data/lib/rubocop/cop/lint/unreachable_code.rb +16 -9
  278. data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
  279. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  280. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  281. data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
  282. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  283. data/lib/rubocop/cop/lint/useless_access_modifier.rb +31 -6
  284. data/lib/rubocop/cop/lint/useless_assignment.rb +63 -27
  285. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +107 -0
  286. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +92 -0
  287. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  288. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +11 -10
  289. data/lib/rubocop/cop/lint/useless_or.rb +111 -0
  290. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -3
  291. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +13 -7
  292. data/lib/rubocop/cop/lint/useless_setter_call.rb +11 -5
  293. data/lib/rubocop/cop/lint/useless_times.rb +22 -1
  294. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +201 -0
  295. data/lib/rubocop/cop/lint/void.rb +68 -22
  296. data/lib/rubocop/cop/lint.rb +179 -0
  297. data/lib/rubocop/cop/message_annotator.rb +7 -3
  298. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  299. data/lib/rubocop/cop/metrics/block_length.rb +2 -1
  300. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  301. data/lib/rubocop/cop/metrics/class_length.rb +4 -2
  302. data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
  303. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
  304. data/lib/rubocop/cop/metrics/method_length.rb +3 -2
  305. data/lib/rubocop/cop/metrics/module_length.rb +4 -2
  306. data/lib/rubocop/cop/metrics/perceived_complexity.rb +37 -7
  307. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
  308. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
  309. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  310. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  311. data/lib/rubocop/cop/metrics.rb +31 -0
  312. data/lib/rubocop/cop/migration/department_name.rb +11 -5
  313. data/lib/rubocop/cop/migration.rb +13 -0
  314. data/lib/rubocop/cop/mixin/alignment.rb +7 -3
  315. data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
  316. data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -5
  317. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  318. data/lib/rubocop/cop/mixin/check_line_breakable.rb +50 -28
  319. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +13 -9
  320. data/lib/rubocop/cop/mixin/code_length.rb +10 -2
  321. data/lib/rubocop/cop/mixin/comments_help.rb +2 -3
  322. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
  323. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  324. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  325. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +13 -2
  326. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  327. data/lib/rubocop/cop/mixin/endless_method_body_help.rb +105 -0
  328. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
  329. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  330. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +20 -0
  331. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -2
  332. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  333. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +68 -21
  334. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +52 -25
  335. data/lib/rubocop/cop/mixin/hash_subset.rb +28 -6
  336. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  337. data/lib/rubocop/cop/mixin/hash_transform_method.rb +32 -78
  338. data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
  339. data/lib/rubocop/cop/mixin/line_length_help.rb +52 -11
  340. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  341. data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
  342. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
  343. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -1
  344. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +10 -1
  345. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +2 -2
  346. data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
  347. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  348. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +79 -8
  349. data/lib/rubocop/cop/mixin/project_index_help.rb +203 -0
  350. data/lib/rubocop/cop/mixin/range_help.rb +16 -5
  351. data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +181 -0
  352. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  353. data/lib/rubocop/cop/mixin/statement_modifier.rb +69 -12
  354. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  355. data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
  356. data/lib/rubocop/cop/mixin/trailing_comma.rb +23 -6
  357. data/lib/rubocop/cop/mixin/visibility_help.rb +2 -1
  358. data/lib/rubocop/cop/mixin.rb +93 -0
  359. data/lib/rubocop/cop/naming/accessor_method_name.rb +8 -0
  360. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
  361. data/lib/rubocop/cop/naming/block_forwarding.rb +7 -4
  362. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  363. data/lib/rubocop/cop/naming/file_name.rb +6 -5
  364. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
  365. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
  366. data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
  367. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +13 -6
  368. data/lib/rubocop/cop/naming/method_name.rb +190 -15
  369. data/lib/rubocop/cop/naming/predicate_method.rb +330 -0
  370. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +65 -8
  371. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -7
  372. data/lib/rubocop/cop/naming/variable_name.rb +51 -6
  373. data/lib/rubocop/cop/naming/variable_number.rb +3 -1
  374. data/lib/rubocop/cop/naming.rb +31 -0
  375. data/lib/rubocop/cop/offense.rb +108 -9
  376. data/lib/rubocop/cop/registry.rb +234 -65
  377. data/lib/rubocop/cop/security/eval.rb +17 -3
  378. data/lib/rubocop/cop/security/io_methods.rb +2 -2
  379. data/lib/rubocop/cop/security/json_load.rb +45 -11
  380. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  381. data/lib/rubocop/cop/security/open.rb +1 -0
  382. data/lib/rubocop/cop/security.rb +19 -0
  383. data/lib/rubocop/cop/severity.rb +12 -0
  384. data/lib/rubocop/cop/style/access_modifier_declarations.rb +83 -14
  385. data/lib/rubocop/cop/style/accessor_grouping.rb +47 -10
  386. data/lib/rubocop/cop/style/alias.rb +33 -8
  387. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
  388. data/lib/rubocop/cop/style/and_or.rb +8 -3
  389. data/lib/rubocop/cop/style/arguments_forwarding.rb +80 -39
  390. data/lib/rubocop/cop/style/array_first_last.rb +13 -3
  391. data/lib/rubocop/cop/style/array_intersect.rb +136 -38
  392. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +50 -0
  393. data/lib/rubocop/cop/style/array_join.rb +4 -2
  394. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  395. data/lib/rubocop/cop/style/attr.rb +8 -6
  396. data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
  397. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  398. data/lib/rubocop/cop/style/bitwise_predicate.rb +13 -5
  399. data/lib/rubocop/cop/style/block_delimiters.rb +77 -40
  400. data/lib/rubocop/cop/style/case_equality.rb +29 -15
  401. data/lib/rubocop/cop/style/case_like_if.rb +12 -11
  402. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  403. data/lib/rubocop/cop/style/class_and_module_children.rb +181 -27
  404. data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -14
  405. data/lib/rubocop/cop/style/class_methods_definitions.rb +26 -5
  406. data/lib/rubocop/cop/style/collection_compact.rb +37 -17
  407. data/lib/rubocop/cop/style/collection_methods.rb +1 -0
  408. data/lib/rubocop/cop/style/collection_querying.rb +200 -0
  409. data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
  410. data/lib/rubocop/cop/style/combinable_loops.rb +92 -9
  411. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  412. data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
  413. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  414. data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
  415. data/lib/rubocop/cop/style/concat_array_literals.rb +65 -9
  416. data/lib/rubocop/cop/style/conditional_assignment.rb +58 -24
  417. data/lib/rubocop/cop/style/constant_visibility.rb +23 -12
  418. data/lib/rubocop/cop/style/copyright.rb +27 -12
  419. data/lib/rubocop/cop/style/data_inheritance.rb +25 -0
  420. data/lib/rubocop/cop/style/date_time.rb +4 -4
  421. data/lib/rubocop/cop/style/def_with_parentheses.rb +22 -5
  422. data/lib/rubocop/cop/style/dig_chain.rb +6 -1
  423. data/lib/rubocop/cop/style/dir_empty.rb +4 -0
  424. data/lib/rubocop/cop/style/directive_scope.rb +304 -0
  425. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +184 -20
  426. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  427. data/lib/rubocop/cop/style/documentation.rb +53 -6
  428. data/lib/rubocop/cop/style/documentation_method.rb +8 -12
  429. data/lib/rubocop/cop/style/double_negation.rb +14 -3
  430. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  431. data/lib/rubocop/cop/style/each_with_object.rb +4 -3
  432. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  433. data/lib/rubocop/cop/style/empty_case_condition.rb +13 -4
  434. data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
  435. data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
  436. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  437. data/lib/rubocop/cop/style/empty_literal.rb +12 -3
  438. data/lib/rubocop/cop/style/empty_method.rb +15 -9
  439. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +152 -0
  440. data/lib/rubocop/cop/style/encoding.rb +7 -1
  441. data/lib/rubocop/cop/style/end_block.rb +3 -1
  442. data/lib/rubocop/cop/style/endless_method.rb +256 -19
  443. data/lib/rubocop/cop/style/env_home.rb +4 -0
  444. data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
  445. data/lib/rubocop/cop/style/even_odd.rb +11 -1
  446. data/lib/rubocop/cop/style/exact_regexp_match.rb +52 -8
  447. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  448. data/lib/rubocop/cop/style/explicit_block_argument.rb +62 -9
  449. data/lib/rubocop/cop/style/exponential_notation.rb +5 -4
  450. data/lib/rubocop/cop/style/fetch_env_var.rb +33 -7
  451. data/lib/rubocop/cop/style/file_null.rb +6 -4
  452. data/lib/rubocop/cop/style/file_open.rb +84 -0
  453. data/lib/rubocop/cop/style/file_write.rb +21 -16
  454. data/lib/rubocop/cop/style/float_division.rb +43 -15
  455. data/lib/rubocop/cop/style/for.rb +61 -1
  456. data/lib/rubocop/cop/style/format_string.rb +44 -9
  457. data/lib/rubocop/cop/style/format_string_token.rb +86 -16
  458. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +5 -3
  459. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  460. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  461. data/lib/rubocop/cop/style/guard_clause.rb +58 -40
  462. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +31 -9
  463. data/lib/rubocop/cop/style/hash_conversion.rb +52 -16
  464. data/lib/rubocop/cop/style/hash_each_methods.rb +4 -4
  465. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  466. data/lib/rubocop/cop/style/hash_lookup_method.rb +128 -0
  467. data/lib/rubocop/cop/style/hash_slice.rb +16 -0
  468. data/lib/rubocop/cop/style/hash_syntax.rb +23 -6
  469. data/lib/rubocop/cop/style/hash_transform_keys.rb +19 -9
  470. data/lib/rubocop/cop/style/hash_transform_values.rb +19 -9
  471. data/lib/rubocop/cop/style/identical_conditional_branches.rb +39 -11
  472. data/lib/rubocop/cop/style/if_inside_else.rb +46 -21
  473. data/lib/rubocop/cop/style/if_unless_modifier.rb +101 -70
  474. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +19 -19
  475. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -2
  476. data/lib/rubocop/cop/style/if_with_semicolon.rb +61 -8
  477. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  478. data/lib/rubocop/cop/style/inline_comment.rb +5 -2
  479. data/lib/rubocop/cop/style/inverse_methods.rb +34 -8
  480. data/lib/rubocop/cop/style/invertible_unless_condition.rb +27 -7
  481. data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
  482. data/lib/rubocop/cop/style/it_assignment.rb +69 -12
  483. data/lib/rubocop/cop/style/it_block_parameter.rb +211 -0
  484. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
  485. data/lib/rubocop/cop/style/keyword_parameters_order.rb +23 -11
  486. data/lib/rubocop/cop/style/lambda.rb +46 -2
  487. data/lib/rubocop/cop/style/lambda_call.rb +31 -10
  488. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  489. data/lib/rubocop/cop/style/magic_comment_format.rb +4 -4
  490. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
  491. data/lib/rubocop/cop/style/map_into_array.rb +6 -4
  492. data/lib/rubocop/cop/style/map_join.rb +123 -0
  493. data/lib/rubocop/cop/style/map_to_hash.rb +13 -5
  494. data/lib/rubocop/cop/style/map_to_set.rb +1 -3
  495. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +110 -27
  496. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
  497. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +58 -6
  498. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +36 -8
  499. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
  500. data/lib/rubocop/cop/style/method_def_parentheses.rb +36 -8
  501. data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
  502. data/lib/rubocop/cop/style/missing_else.rb +7 -1
  503. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +40 -7
  504. data/lib/rubocop/cop/style/mixin_grouping.rb +12 -3
  505. data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
  506. data/lib/rubocop/cop/style/module_function.rb +4 -2
  507. data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
  508. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -1
  509. data/lib/rubocop/cop/style/multiline_if_modifier.rb +47 -5
  510. data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
  511. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
  512. data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
  513. data/lib/rubocop/cop/style/multiline_method_signature.rb +15 -22
  514. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
  515. data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
  516. data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
  517. data/lib/rubocop/cop/style/mutable_constant.rb +158 -14
  518. data/lib/rubocop/cop/style/negated_if_else_condition.rb +3 -3
  519. data/lib/rubocop/cop/style/negative_array_index.rb +228 -0
  520. data/lib/rubocop/cop/style/nested_modifier.rb +36 -12
  521. data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
  522. data/lib/rubocop/cop/style/next.rb +68 -10
  523. data/lib/rubocop/cop/style/nil_comparison.rb +53 -13
  524. data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
  525. data/lib/rubocop/cop/style/non_nil_check.rb +21 -11
  526. data/lib/rubocop/cop/style/not.rb +12 -3
  527. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
  528. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  529. data/lib/rubocop/cop/style/numeric_predicate.rb +22 -6
  530. data/lib/rubocop/cop/style/object_then.rb +1 -0
  531. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  532. data/lib/rubocop/cop/style/one_line_conditional.rb +35 -15
  533. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  534. data/lib/rubocop/cop/style/operator_method_call.rb +10 -2
  535. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  536. data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
  537. data/lib/rubocop/cop/style/parallel_assignment.rb +58 -27
  538. data/lib/rubocop/cop/style/parentheses_around_condition.rb +7 -2
  539. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  540. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +18 -3
  541. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  542. data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
  543. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  544. data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
  545. data/lib/rubocop/cop/style/proc.rb +4 -2
  546. data/lib/rubocop/cop/style/raise_args.rb +28 -18
  547. data/lib/rubocop/cop/style/reduce_to_hash.rb +216 -0
  548. data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
  549. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  550. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  551. data/lib/rubocop/cop/style/redundant_assignment.rb +12 -2
  552. data/lib/rubocop/cop/style/redundant_begin.rb +60 -7
  553. data/lib/rubocop/cop/style/redundant_condition.rb +93 -18
  554. data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
  555. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +26 -4
  556. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +17 -3
  557. data/lib/rubocop/cop/style/redundant_each.rb +4 -5
  558. data/lib/rubocop/cop/style/redundant_exception.rb +22 -4
  559. data/lib/rubocop/cop/style/redundant_fetch_block.rb +11 -11
  560. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
  561. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  562. data/lib/rubocop/cop/style/redundant_format.rb +319 -0
  563. data/lib/rubocop/cop/style/redundant_freeze.rb +13 -5
  564. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
  565. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  566. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +49 -10
  567. data/lib/rubocop/cop/style/redundant_line_continuation.rb +83 -119
  568. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  569. data/lib/rubocop/cop/style/redundant_parentheses.rb +176 -83
  570. data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
  571. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +15 -0
  572. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
  573. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +27 -7
  574. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +16 -0
  575. data/lib/rubocop/cop/style/redundant_return.rb +4 -3
  576. data/lib/rubocop/cop/style/redundant_self.rb +20 -7
  577. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -3
  578. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +27 -4
  579. data/lib/rubocop/cop/style/redundant_sort.rb +45 -11
  580. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  581. data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
  582. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
  583. data/lib/rubocop/cop/style/regexp_literal.rb +107 -29
  584. data/lib/rubocop/cop/style/require_order.rb +25 -8
  585. data/lib/rubocop/cop/style/rescue_modifier.rb +16 -12
  586. data/lib/rubocop/cop/style/return_nil.rb +19 -4
  587. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
  588. data/lib/rubocop/cop/style/reverse_find.rb +51 -0
  589. data/lib/rubocop/cop/style/safe_navigation.rb +76 -20
  590. data/lib/rubocop/cop/style/sample.rb +19 -13
  591. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  592. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  593. data/lib/rubocop/cop/style/select_by_regexp.rb +54 -22
  594. data/lib/rubocop/cop/style/self_assignment.rb +13 -16
  595. data/lib/rubocop/cop/style/semicolon.rb +56 -14
  596. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +4 -0
  597. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  598. data/lib/rubocop/cop/style/single_line_do_end_block.rb +22 -8
  599. data/lib/rubocop/cop/style/single_line_methods.rb +33 -11
  600. data/lib/rubocop/cop/style/sole_nested_conditional.rb +96 -104
  601. data/lib/rubocop/cop/style/special_global_vars.rb +7 -2
  602. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +32 -6
  603. data/lib/rubocop/cop/style/static_class.rb +21 -0
  604. data/lib/rubocop/cop/style/string_concatenation.rb +38 -16
  605. data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
  606. data/lib/rubocop/cop/style/struct_inheritance.rb +44 -2
  607. data/lib/rubocop/cop/style/super_arguments.rb +7 -6
  608. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  609. data/lib/rubocop/cop/style/symbol_proc.rb +35 -15
  610. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  611. data/lib/rubocop/cop/style/ternary_parentheses.rb +34 -1
  612. data/lib/rubocop/cop/style/time_now.rb +41 -0
  613. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -2
  614. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +52 -1
  615. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  616. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +2 -2
  617. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  618. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  619. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +35 -32
  620. data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
  621. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  622. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  623. data/lib/rubocop/cop/style/while_until_do.rb +7 -0
  624. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -1
  625. data/lib/rubocop/cop/style/word_array.rb +1 -0
  626. data/lib/rubocop/cop/style/yoda_condition.rb +26 -12
  627. data/lib/rubocop/cop/style/yoda_expression.rb +11 -2
  628. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
  629. data/lib/rubocop/cop/style.rb +311 -0
  630. data/lib/rubocop/cop/team.rb +172 -49
  631. data/lib/rubocop/cop/util.rb +7 -10
  632. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  633. data/lib/rubocop/cop/variable_force/assignment.rb +8 -4
  634. data/lib/rubocop/cop/variable_force/branch.rb +30 -6
  635. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  636. data/lib/rubocop/cop/variable_force/variable.rb +42 -11
  637. data/lib/rubocop/cop/variable_force.rb +26 -9
  638. data/lib/rubocop/cops_documentation_generator.rb +49 -15
  639. data/lib/rubocop/directive_comment.rb +147 -5
  640. data/lib/rubocop/ext/regexp_node.rb +0 -1
  641. data/lib/rubocop/feature_loader.rb +0 -6
  642. data/lib/rubocop/file_patterns.rb +9 -1
  643. data/lib/rubocop/formatter/base_formatter.rb +22 -0
  644. data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
  645. data/lib/rubocop/formatter/disabled_config_formatter.rb +57 -14
  646. data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
  647. data/lib/rubocop/formatter/formatter_set.rb +7 -2
  648. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  649. data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
  650. data/lib/rubocop/formatter/html_formatter.rb +3 -5
  651. data/lib/rubocop/formatter/json_formatter.rb +82 -7
  652. data/lib/rubocop/formatter/junit_formatter.rb +27 -10
  653. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  654. data/lib/rubocop/formatter/offense_count_formatter.rb +5 -4
  655. data/lib/rubocop/formatter/pacman_formatter.rb +5 -2
  656. data/lib/rubocop/formatter/sarif_formatter.rb +186 -0
  657. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
  658. data/lib/rubocop/formatter/tap_formatter.rb +8 -3
  659. data/lib/rubocop/formatter/worst_offenders_formatter.rb +5 -4
  660. data/lib/rubocop/formatter.rb +23 -21
  661. data/lib/rubocop/lockfile.rb +18 -0
  662. data/lib/rubocop/lsp/diagnostic.rb +22 -41
  663. data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
  664. data/lib/rubocop/lsp/routes.rb +158 -55
  665. data/lib/rubocop/lsp/runtime.rb +66 -15
  666. data/lib/rubocop/lsp/server.rb +4 -2
  667. data/lib/rubocop/lsp/stdin_runner.rb +38 -19
  668. data/lib/rubocop/lsp.rb +5 -2
  669. data/lib/rubocop/magic_comment.rb +55 -0
  670. data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
  671. data/lib/rubocop/mcp/explain_tool.rb +68 -0
  672. data/lib/rubocop/mcp/scope.rb +65 -0
  673. data/lib/rubocop/mcp/server.rb +307 -0
  674. data/lib/rubocop/mcp/source_files.rb +35 -0
  675. data/lib/rubocop/offense_limit.rb +30 -0
  676. data/lib/rubocop/options.rb +166 -23
  677. data/lib/rubocop/path_util.rb +20 -5
  678. data/lib/rubocop/pending_cops_reporter.rb +51 -0
  679. data/lib/rubocop/plugin/configuration_integrator.rb +153 -0
  680. data/lib/rubocop/plugin/load_error.rb +26 -0
  681. data/lib/rubocop/plugin/loader.rb +100 -0
  682. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  683. data/lib/rubocop/plugin.rb +46 -0
  684. data/lib/rubocop/project_index_loader.rb +82 -0
  685. data/lib/rubocop/rake_task.rb +6 -4
  686. data/lib/rubocop/remote_config.rb +18 -13
  687. data/lib/rubocop/result_cache.rb +110 -65
  688. data/lib/rubocop/rspec/cop_helper.rb +21 -1
  689. data/lib/rubocop/rspec/expect_offense.rb +11 -7
  690. data/lib/rubocop/rspec/shared_contexts.rb +85 -3
  691. data/lib/rubocop/rspec/support.rb +4 -0
  692. data/lib/rubocop/runner.rb +368 -106
  693. data/lib/rubocop/server/cache.rb +67 -48
  694. data/lib/rubocop/server/cli.rb +2 -4
  695. data/lib/rubocop/server/client_command/base.rb +10 -0
  696. data/lib/rubocop/server/client_command/exec.rb +2 -1
  697. data/lib/rubocop/server/client_command/start.rb +11 -1
  698. data/lib/rubocop/server/core.rb +8 -0
  699. data/lib/rubocop/server.rb +14 -0
  700. data/lib/rubocop/target_finder.rb +25 -11
  701. data/lib/rubocop/target_ruby.rb +52 -23
  702. data/lib/rubocop/todo_audit.rb +111 -0
  703. data/lib/rubocop/unified_diff.rb +257 -0
  704. data/lib/rubocop/util.rb +69 -0
  705. data/lib/rubocop/version.rb +48 -10
  706. data/lib/rubocop.rb +35 -682
  707. data/lib/ruby_lsp/rubocop/addon.rb +28 -17
  708. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  709. metadata +129 -21
  710. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
  711. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  712. data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +0 -50
@@ -4,13 +4,15 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # Checks for single-line method definitions that contain a body.
7
- # It will accept single-line methods with no body.
7
+ # Single-line methods with a body are harder to read and debug
8
+ # than their multi-line equivalents. It will accept single-line
9
+ # methods with no body.
8
10
  #
9
11
  # Endless methods added in Ruby 3.0 are also accepted by this cop.
10
12
  #
11
- # If `Style/EndlessMethod` is enabled with `EnforcedStyle: allow_single_line` or
12
- # `allow_always`, single-line methods will be autocorrected to endless
13
- # methods if there is only one statement in the body.
13
+ # If `Style/EndlessMethod` is enabled with `EnforcedStyle: allow_single_line`, `allow_always`,
14
+ # `require_single_line`, or `require_always`, single-line methods will be autocorrected
15
+ # to endless methods if there is only one statement in the body.
14
16
  #
15
17
  # @example
16
18
  # # bad
@@ -33,6 +35,7 @@ module RuboCop
33
35
  #
34
36
  class SingleLineMethods < Base
35
37
  include Alignment
38
+ include EndlessMethodBodyHelp
36
39
  extend AutoCorrector
37
40
 
38
41
  MSG = 'Avoid single-line method definitions.'
@@ -65,10 +68,19 @@ module RuboCop
65
68
  return false if target_ruby_version < 3.0
66
69
  return false if disallow_endless_method_style?
67
70
  return false unless body_node
68
- return false if body_node.parent.assignment_method? ||
69
- NOT_SUPPORTED_ENDLESS_METHOD_BODY_TYPES.include?(body_node.type)
71
+ return false if body_node.parent.assignment_method?
70
72
 
71
- !body_node.type?(:begin, :kwbegin)
73
+ !unsupported_endless_method_body?(body_node) && endless_method_body?(body_node)
74
+ end
75
+
76
+ def unsupported_endless_method_body?(body_node)
77
+ body_node.basic_conditional? ||
78
+ NOT_SUPPORTED_ENDLESS_METHOD_BODY_TYPES.include?(body_node.type)
79
+ end
80
+
81
+ # The body gets parenthesized when it becomes endless, so it is no longer a command.
82
+ def command_body_in_argument?(body)
83
+ !require_parentheses?(body) && super
72
84
  end
73
85
 
74
86
  def correct_to_multiline(corrector, node)
@@ -86,10 +98,10 @@ module RuboCop
86
98
  end
87
99
 
88
100
  def correct_to_endless(corrector, node)
89
- self_receiver = node.self_receiver? ? 'self.' : ''
90
- arguments = node.arguments.any? ? node.arguments.source : '()'
101
+ receiver = "#{node.receiver.source}." if node.receiver
91
102
  body_source = method_body_source(node.body)
92
- replacement = "def #{self_receiver}#{node.method_name}#{arguments} = #{body_source}"
103
+ arguments = endless_arguments(node)
104
+ replacement = "def #{receiver}#{node.method_name}#{arguments} = #{body_source}"
93
105
 
94
106
  corrector.replace(node, replacement)
95
107
  end
@@ -130,7 +142,17 @@ module RuboCop
130
142
  end
131
143
 
132
144
  def require_parentheses?(method_body)
133
- method_body.send_type? && !method_body.arguments.empty? && !method_body.comparison_method?
145
+ return false unless method_body.send_type?
146
+ return false if method_body.arithmetic_operation?
147
+
148
+ !method_body.arguments.empty? && !method_body.comparison_method?
149
+ end
150
+
151
+ def endless_arguments(node)
152
+ arguments = node.arguments
153
+ return '()' if arguments.none?
154
+
155
+ arguments.loc.begin ? arguments.source : "(#{arguments.source})"
134
156
  end
135
157
 
136
158
  def disallow_endless_method_style?
@@ -48,6 +48,7 @@ module RuboCop
48
48
  # end if condition_a
49
49
  class SoleNestedConditional < Base
50
50
  include RangeHelp
51
+ include ReparsedEquivalence
51
52
  extend AutoCorrector
52
53
 
53
54
  MSG = 'Consider merging nested conditions into outer `%<conditional_type>s` conditions.'
@@ -57,20 +58,39 @@ module RuboCop
57
58
  end
58
59
 
59
60
  def on_if(node)
60
- return if node.ternary? || node.else? || node.elsif?
61
+ return unless offending_conditional?(node)
61
62
 
62
63
  if_branch = node.if_branch
63
- return if use_variable_assignment_in_condition?(node.condition, if_branch)
64
- return unless offending_branch?(node, if_branch)
64
+ return unless correction_parses?(node)
65
65
 
66
66
  message = format(MSG, conditional_type: node.keyword)
67
67
  add_offense(if_branch.loc.keyword, message: message) do |corrector|
68
+ next if ignored_node?(node)
69
+
68
70
  autocorrect(corrector, node, if_branch)
71
+ ignore_node(if_branch)
69
72
  end
70
73
  end
71
74
 
72
75
  private
73
76
 
77
+ def offending_conditional?(node)
78
+ return false if node.ternary? || node.else? || node.elsif?
79
+
80
+ if_branch = node.if_branch
81
+ return false if use_variable_assignment_in_condition?(node.condition, if_branch)
82
+
83
+ offending_branch?(node, if_branch)
84
+ end
85
+
86
+ # Merging the conditionals intentionally produces a different AST, so
87
+ # full equivalence cannot be checked, but the corrected source must at
88
+ # least remain parseable (see `ReparsedEquivalence#correction_parses?`),
89
+ # which suppresses the entire produces-invalid-code bug class.
90
+ def apply_reparse_correction(corrector, node)
91
+ autocorrect(corrector, node, node.if_branch)
92
+ end
93
+
74
94
  def use_variable_assignment_in_condition?(condition, if_branch)
75
95
  assigned_variables = assigned_variables(condition)
76
96
 
@@ -96,11 +116,7 @@ module RuboCop
96
116
  end
97
117
 
98
118
  def autocorrect(corrector, node, if_branch)
99
- if node.condition.or_type? || node.condition.assignment?
100
- corrector.wrap(node.condition, '(', ')')
101
- end
102
-
103
- if outer_condition_modify_form?(node, if_branch)
119
+ if node.modifier_form?
104
120
  autocorrect_outer_condition_modify_form(corrector, node, if_branch)
105
121
  else
106
122
  autocorrect_outer_condition_basic(corrector, node, if_branch)
@@ -108,74 +124,54 @@ module RuboCop
108
124
  end
109
125
 
110
126
  def autocorrect_outer_condition_basic(corrector, node, if_branch)
111
- correct_from_unless_to_if(corrector, node) if node.unless?
112
-
113
- outer_condition = node.condition
114
- correct_outer_condition(corrector, outer_condition)
127
+ correct_node(corrector, node)
115
128
 
116
- and_operator = if_branch.unless? ? ' && !' : ' && '
117
129
  if if_branch.modifier_form?
118
- correct_for_guard_condition_style(corrector, outer_condition, if_branch, and_operator)
130
+ correct_for_guard_condition_style(corrector, node, if_branch)
119
131
  else
120
- correct_for_basic_condition_style(corrector, node, if_branch, and_operator)
132
+ correct_for_basic_condition_style(corrector, node, if_branch)
121
133
  correct_for_comment(corrector, node, if_branch)
122
134
  end
123
135
  end
124
136
 
125
- def autocorrect_outer_condition_modify_form(corrector, node, if_branch)
126
- correct_from_unless_to_if(corrector, if_branch, is_modify_form: true) if if_branch.unless?
127
- correct_for_outer_condition_modify_form_style(corrector, node, if_branch)
128
- end
129
-
130
- def correct_from_unless_to_if(corrector, node, is_modify_form: false)
131
- corrector.replace(node.loc.keyword, 'if')
132
-
133
- insert_bang(corrector, node, is_modify_form)
137
+ def correct_node(corrector, node)
138
+ corrector.replace(node.loc.keyword, 'if') if node.unless?
139
+ corrector.replace(node.condition, chainable_condition(node))
134
140
  end
135
141
 
136
- def correct_for_guard_condition_style(corrector, outer_condition, if_branch, and_operator)
137
- condition = if_branch.condition
138
- corrector.insert_after(outer_condition, "#{and_operator}#{replace_condition(condition)}")
142
+ def correct_for_guard_condition_style(corrector, node, if_branch)
143
+ corrector.insert_after(node.condition, " && #{chainable_condition(if_branch)}")
139
144
 
140
- range = range_between(if_branch.loc.keyword.begin_pos, condition.source_range.end_pos)
145
+ range = range_between(
146
+ if_branch.loc.keyword.begin_pos, if_branch.condition.source_range.end_pos
147
+ )
141
148
  corrector.remove(range_with_surrounding_space(range, newlines: false))
142
- corrector.remove(if_branch.loc.keyword)
143
149
  end
144
150
 
145
- def correct_for_basic_condition_style(corrector, node, if_branch, and_operator)
151
+ # rubocop:disable-next Metrics/AbcSize
152
+ def correct_for_basic_condition_style(corrector, node, if_branch)
146
153
  range = range_between(
147
154
  node.condition.source_range.end_pos, if_branch.condition.source_range.begin_pos
148
155
  )
149
- corrector.replace(range, and_operator)
150
- corrector.remove(range_by_whole_lines(node.loc.end, include_final_newline: true))
151
-
152
- wrap_condition(corrector, if_branch.condition)
153
- end
154
-
155
- def wrap_condition(corrector, condition)
156
- # Handle `send` and `block` nodes that need to be wrapped in parens
157
- # FIXME: autocorrection prevents syntax errors by wrapping the entire node in parens,
158
- # but wrapping the argument list would be a more ergonomic correction.
159
- node_to_check = condition&.any_block_type? ? condition.send_node : condition
160
- return unless wrap_condition?(node_to_check)
156
+ corrector.replace(range, ' && ')
161
157
 
162
- if condition.call_type?
163
- source = parenthesized_method_arguments(condition)
158
+ corrector.replace(if_branch.condition, chainable_condition(if_branch))
164
159
 
165
- corrector.replace(condition, source)
166
- else
167
- corrector.wrap(condition, '(', ')')
168
- end
160
+ end_range = if same_line?(node.loc.end, node.if_branch.loc.end)
161
+ node.loc.end
162
+ else
163
+ range_by_whole_lines(node.loc.end, include_final_newline: true)
164
+ end
165
+ corrector.remove(end_range)
169
166
  end
170
167
 
171
- def correct_for_outer_condition_modify_form_style(corrector, node, if_branch)
172
- condition = if_branch.condition
173
- corrector.insert_before(condition,
174
- "#{'!' if node.unless?}#{replace_condition(node.condition)} && ")
168
+ def autocorrect_outer_condition_modify_form(corrector, node, if_branch)
169
+ correct_node(corrector, if_branch)
170
+
171
+ corrector.insert_before(if_branch.condition, "#{chainable_condition(node)} && ")
175
172
 
176
- corrector.remove(node.condition)
177
- corrector.remove(range_with_surrounding_space(node.loc.keyword, newlines: false))
178
- corrector.replace(if_branch.loc.keyword, 'if')
173
+ range = range_between(node.loc.keyword.begin_pos, node.condition.source_range.end_pos)
174
+ corrector.remove(range_with_surrounding_space(range, newlines: false))
179
175
  end
180
176
 
181
177
  def correct_for_comment(corrector, node, if_branch)
@@ -187,67 +183,47 @@ module RuboCop
187
183
  corrector.insert_before(node.loc.keyword, comment_text) unless comments.empty?
188
184
  end
189
185
 
190
- def correct_outer_condition(corrector, condition)
191
- return unless require_parentheses?(condition)
186
+ def chainable_condition(node)
187
+ wrapped_condition = add_parentheses_if_needed(node.condition)
192
188
 
193
- end_pos = condition.loc.selector.end_pos
194
- begin_pos = condition.first_argument.source_range.begin_pos
195
- return if end_pos > begin_pos
189
+ return wrapped_condition if node.if?
196
190
 
197
- range = range_between(end_pos, begin_pos)
198
- corrector.remove(range)
199
- corrector.insert_after(range, '(')
200
- corrector.insert_after(condition.last_argument, ')')
191
+ node.condition.and_type? ? "!(#{wrapped_condition})" : "!#{wrapped_condition}"
201
192
  end
202
193
 
203
- def insert_bang(corrector, node, is_modify_form)
204
- condition = node.condition
194
+ def add_parentheses_if_needed(condition)
195
+ # Handle `send` and `block` nodes that need to be wrapped in parens
196
+ # FIXME: autocorrection prevents syntax errors by wrapping the entire node in parens,
197
+ # but wrapping the argument list would be a more ergonomic correction.
198
+ node_to_check = condition&.any_block_type? ? condition.send_node : condition
199
+ return condition.source unless add_parentheses?(node_to_check)
205
200
 
206
- if (condition.send_type? && condition.comparison_method? && !condition.parenthesized?) ||
207
- (is_modify_form && wrap_condition?(condition))
208
- corrector.wrap(node.condition, '!(', ')')
201
+ if parenthesize_method?(condition)
202
+ parenthesized_method_arguments(condition)
209
203
  elsif condition.and_type?
210
- insert_bang_for_and(corrector, node)
211
- else
212
- corrector.insert_before(condition, '!')
213
- end
214
- end
215
-
216
- def insert_bang_for_and(corrector, node)
217
- lhs, rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring
218
-
219
- if lhs.and_type?
220
- insert_bang_for_and(corrector, lhs)
221
- corrector.insert_before(rhs, '!') if rhs
204
+ parenthesized_and(condition)
222
205
  else
223
- corrector.insert_before(lhs, '!')
224
- corrector.insert_before(rhs, '!')
206
+ "(#{condition.source})"
225
207
  end
226
208
  end
227
209
 
228
- def require_parentheses?(condition)
229
- condition.call_type? && !condition.arguments.empty? && !condition.parenthesized? &&
230
- !condition.comparison_method?
210
+ def parenthesize_method?(node)
211
+ node.call_type? && node.arguments.any? && !node.parenthesized? &&
212
+ !node.comparison_method? && !node.operator_method?
231
213
  end
232
214
 
233
- def arguments_range(node)
234
- range_between(
235
- node.first_argument.source_range.begin_pos, node.last_argument.source_range.end_pos
236
- )
237
- end
215
+ def add_parentheses?(node)
216
+ return true if node.assignment? || node.or_type?
217
+ return true if assignment_in_and?(node)
218
+ return false unless node.call_type?
238
219
 
239
- def wrap_condition?(node)
240
- node.operator_keyword? || (node.call_type? && node.arguments.any? && !node.parenthesized?)
220
+ (node.arguments.any? && !node.parenthesized?) || node.prefix_not?
241
221
  end
242
222
 
243
- def replace_condition(condition)
244
- return condition.source unless wrap_condition?(condition)
223
+ def assignment_in_and?(node)
224
+ return false unless node.and_type?
245
225
 
246
- if condition.call_type? && !condition.comparison_method?
247
- parenthesized_method_arguments(condition)
248
- else
249
- "(#{condition.source})"
250
- end
226
+ node.each_descendant.any?(&:assignment?)
251
227
  end
252
228
 
253
229
  def parenthesized_method_arguments(node)
@@ -257,12 +233,28 @@ module RuboCop
257
233
  "#{method_call}(#{arguments})"
258
234
  end
259
235
 
260
- def allow_modifier?
261
- cop_config['AllowModifier']
236
+ def parenthesized_and(node)
237
+ # We only need to add parentheses around the last clause if it's an assignment,
238
+ # because other clauses will be unchanged by merging conditionals.
239
+ lhs = node.lhs.source
240
+ rhs = parenthesized_and_clause(node.rhs)
241
+ operator = range_with_surrounding_space(node.loc.operator, whitespace: true).source
242
+
243
+ "#{lhs}#{operator}#{rhs}"
262
244
  end
263
245
 
264
- def outer_condition_modify_form?(node, if_branch)
265
- node.condition.source_range.begin_pos > if_branch.condition.source_range.begin_pos
246
+ def parenthesized_and_clause(node)
247
+ if node.and_type?
248
+ parenthesized_and(node)
249
+ elsif node.assignment?
250
+ "(#{node.source})"
251
+ else
252
+ node.source
253
+ end
254
+ end
255
+
256
+ def allow_modifier?
257
+ cop_config['AllowModifier']
266
258
  end
267
259
  end
268
260
  end
@@ -4,7 +4,12 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # Looks for uses of Perl-style global variables.
7
- # Correcting to global variables in the 'English' library
7
+ # Perl-style global variables like `$;` or `$/` are cryptic
8
+ # and hard to understand without consulting documentation.
9
+ # The `English` library provides descriptive aliases like
10
+ # `$FIELD_SEPARATOR` and `$INPUT_RECORD_SEPARATOR`.
11
+ #
12
+ # Correcting to global variables in the `English` library
8
13
  # will add a require statement to the top of the file if
9
14
  # enabled by RequireEnglish config.
10
15
  #
@@ -96,7 +101,7 @@ module RuboCop
96
101
  'module (don\'t forget to require it) over `%<global>s`.'
97
102
  MSG_REGULAR = 'Prefer `%<prefer>s` over `%<global>s`.'
98
103
 
99
- ENGLISH_VARS = { # rubocop:disable Style/MutableConstant
104
+ ENGLISH_VARS = { # rubocop:disable Style/MutableConstant -- merged into below, then frozen
100
105
  :$: => [:$LOAD_PATH],
101
106
  :$" => [:$LOADED_FEATURES],
102
107
  :$0 => [:$PROGRAM_NAME],
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Check for parentheses around stabby lambda arguments.
6
+ # Checks for parentheses around stabby lambda arguments.
7
7
  # There are two different styles. Defaults to `require_parentheses`.
8
8
  #
9
9
  # @example EnforcedStyle: require_parentheses (default)
@@ -25,6 +25,8 @@ module RuboCop
25
25
 
26
26
  MSG_REQUIRE = 'Wrap stabby lambda arguments with parentheses.'
27
27
  MSG_NO_REQUIRE = 'Do not wrap stabby lambda arguments with parentheses.'
28
+ RESTRICT_ON_SEND = %i[lambda].freeze
29
+
28
30
  def on_send(node)
29
31
  return unless stabby_lambda_with_args?(node)
30
32
  return unless redundant_parentheses?(node) || missing_parentheses?(node)
@@ -48,7 +50,33 @@ module RuboCop
48
50
  end
49
51
 
50
52
  def redundant_parentheses?(node)
51
- style == :require_no_parentheses && parentheses?(node)
53
+ return false unless style == :require_no_parentheses && parentheses?(node)
54
+
55
+ arguments = node.block_node.arguments
56
+ !arguments_require_parentheses?(arguments) && !comment_inside_parentheses?(arguments)
57
+ end
58
+
59
+ def arguments_require_parentheses?(arguments)
60
+ arguments.each_descendant(:any_block, :hash).any? do |node|
61
+ !node.hash_type? || node.braces?
62
+ end
63
+ end
64
+
65
+ def comment_inside_parentheses?(arguments)
66
+ !leading_padding(arguments).source.strip.empty? ||
67
+ !trailing_padding(arguments).source.strip.empty?
68
+ end
69
+
70
+ def leading_padding(arguments)
71
+ first_argument = arguments.children.first
72
+
73
+ arguments.loc.begin.end.join(first_argument.source_range.begin)
74
+ end
75
+
76
+ def trailing_padding(arguments)
77
+ last_argument = arguments.children.last
78
+
79
+ last_argument.source_range.end.join(arguments.loc.end.begin)
52
80
  end
53
81
 
54
82
  def message(_node)
@@ -60,10 +88,8 @@ module RuboCop
60
88
  end
61
89
 
62
90
  def unwanted_parentheses_corrector(corrector, node)
63
- args_loc = node.loc
64
-
65
- corrector.replace(args_loc.begin, '')
66
- corrector.remove(args_loc.end)
91
+ corrector.remove(node.loc.begin.join(leading_padding(node)))
92
+ corrector.remove(trailing_padding(node).join(node.loc.end))
67
93
  end
68
94
 
69
95
  def stabby_lambda_with_args?(node)
@@ -12,6 +12,11 @@ module RuboCop
12
12
  # for some other subclass, monkey-patched with instance methods or
13
13
  # a dummy instance is instantiated from it somewhere.
14
14
  #
15
+ # When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is
16
+ # installed, classes that are subclassed anywhere in the project are
17
+ # not reported, since converting them to modules would break their
18
+ # subclasses.
19
+ #
15
20
  # @example
16
21
  # # bad
17
22
  # class SomeClass
@@ -44,6 +49,7 @@ module RuboCop
44
49
  # end
45
50
  #
46
51
  class StaticClass < Base
52
+ include ProjectIndexHelp
47
53
  include RangeHelp
48
54
  include VisibilityHelp
49
55
  extend AutoCorrector
@@ -53,6 +59,7 @@ module RuboCop
53
59
  def on_class(class_node)
54
60
  return if class_node.parent_class
55
61
  return unless class_convertible_to_module?(class_node)
62
+ return if subclassed_in_project?(class_node)
56
63
 
57
64
  add_offense(class_node) do |corrector|
58
65
  autocorrect(corrector, class_node)
@@ -61,6 +68,20 @@ module RuboCop
61
68
 
62
69
  private
63
70
 
71
+ # When `AllCops/UseProjectIndex` is enabled, a class with descendants
72
+ # anywhere in the project is not reported: converting it to a module
73
+ # would break its subclasses.
74
+ def subclassed_in_project?(class_node)
75
+ return false unless project_index
76
+
77
+ declaration = resolve_constant_in_index(class_node.identifier)
78
+ return false unless declaration.is_a?(Rubydex::Class)
79
+
80
+ declaration.descendants.any? { |descendant| descendant.name != declaration.name }
81
+ rescue StandardError
82
+ false
83
+ end
84
+
64
85
  def autocorrect(corrector, class_node)
65
86
  corrector.replace(class_node.loc.keyword, 'module')
66
87
  corrector.insert_after(class_node.loc.name, "\nmodule_function\n")
@@ -51,7 +51,6 @@ module RuboCop
51
51
  # Pathname.new('/') + 'test'
52
52
  #
53
53
  class StringConcatenation < Base
54
- include RangeHelp
55
54
  extend AutoCorrector
56
55
 
57
56
  MSG = 'Prefer string interpolation to string concatenation.'
@@ -101,7 +100,7 @@ module RuboCop
101
100
  node.receiver.str_type? &&
102
101
  node.first_argument.str_type? &&
103
102
  node.multiline? &&
104
- node.source =~ /\+\s*\n/
103
+ node.source.match?(/\+\s*\n/)
105
104
  end
106
105
 
107
106
  def find_topmost_plus_node(node)
@@ -128,7 +127,7 @@ module RuboCop
128
127
  end
129
128
 
130
129
  def uncorrectable?(part)
131
- part.multiline? || heredoc?(part) || part.each_descendant(:block).any?
130
+ part.multiline? || heredoc?(part) || part.each_descendant(:any_block).any?
132
131
  end
133
132
 
134
133
  def heredoc?(node)
@@ -142,22 +141,37 @@ module RuboCop
142
141
  end
143
142
 
144
143
  def replacement(parts)
145
- interpolated_parts = parts.map do |part|
146
- case part.type
147
- when :str
148
- adjust_str(part)
149
- when :dstr
150
- part.children.all?(&:str_type?) ? adjust_str(part) : contents_range(part).source
151
- else
152
- "\#{#{part.source}}"
153
- end
154
- end
144
+ interpolated_parts = parts.map { |part| adjust_str(part) }
155
145
 
156
146
  "\"#{handle_quotes(interpolated_parts).join}\""
157
147
  end
158
148
 
159
- def adjust_str(node)
160
- single_quoted?(node) ? node.value.gsub(/(\\|")/, '\\\\\&') : node.value.inspect[1..-2]
149
+ def adjust_str(part)
150
+ case part.type
151
+ when :str
152
+ adjust_str_literal(part)
153
+ when :dstr, :begin
154
+ part.children.map do |child|
155
+ adjust_str(child)
156
+ end.join
157
+ else
158
+ "\#{#{part.source}}"
159
+ end
160
+ end
161
+
162
+ def adjust_str_literal(part)
163
+ if file_keyword?(part)
164
+ "\#{#{part.source}}"
165
+ elsif single_quoted?(part)
166
+ part.value.gsub(/(\\|"|#\{|#@|#\$)/, '\\\\\&')
167
+ elsif double_quoted?(part)
168
+ # Reuse the source as written - rebuilding it from the value via
169
+ # `inspect` would rewrite the author's escape notation
170
+ # (e.g. `\x0a` into `\n`).
171
+ part.source[1..-2]
172
+ else
173
+ part.value.inspect[1..-2]
174
+ end
161
175
  end
162
176
 
163
177
  def handle_quotes(parts)
@@ -166,8 +180,16 @@ module RuboCop
166
180
  end
167
181
  end
168
182
 
183
+ def file_keyword?(str_node)
184
+ str_node.source == '__FILE__' && !str_node.parent.dstr_type?
185
+ end
186
+
169
187
  def single_quoted?(str_node)
170
- str_node.source.start_with?("'")
188
+ str_node.loc.begin && str_node.source.start_with?("'")
189
+ end
190
+
191
+ def double_quoted?(str_node)
192
+ str_node.loc.begin && str_node.source.start_with?('"')
171
193
  end
172
194
 
173
195
  def mode
@@ -41,6 +41,7 @@ module RuboCop
41
41
 
42
42
  def on_pair(node)
43
43
  return unless string_hash_key?(node)
44
+ return if node.key.heredoc?
44
45
 
45
46
  key_content = node.key.str_content
46
47
  return unless key_content.valid_encoding?