rubocop 1.71.1 → 1.88.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 (590) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +513 -149
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +38 -4
  7. data/exe/rubocop +1 -8
  8. data/lib/rubocop/cache_config.rb +29 -0
  9. data/lib/rubocop/cli/command/auto_generate_config.rb +36 -4
  10. data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
  11. data/lib/rubocop/cli/command/lsp.rb +1 -1
  12. data/lib/rubocop/cli/command/mcp.rb +19 -0
  13. data/lib/rubocop/cli/command/show_cops.rb +2 -2
  14. data/lib/rubocop/cli/command/show_docs_url.rb +4 -8
  15. data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
  16. data/lib/rubocop/cli.rb +48 -11
  17. data/lib/rubocop/comment_config.rb +60 -18
  18. data/lib/rubocop/config.rb +53 -16
  19. data/lib/rubocop/config_finder.rb +1 -1
  20. data/lib/rubocop/config_loader.rb +65 -49
  21. data/lib/rubocop/config_loader_resolver.rb +44 -19
  22. data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
  23. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  24. data/lib/rubocop/config_obsoletion.rb +46 -2
  25. data/lib/rubocop/config_store.rb +7 -2
  26. data/lib/rubocop/config_validator.rb +7 -6
  27. data/lib/rubocop/cop/autocorrect_logic.rb +27 -14
  28. data/lib/rubocop/cop/base.rb +38 -12
  29. data/lib/rubocop/cop/bundler/gem_comment.rb +5 -3
  30. data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
  31. data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -3
  32. data/lib/rubocop/cop/commissioner.rb +13 -11
  33. data/lib/rubocop/cop/correctors/alignment_corrector.rb +26 -7
  34. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  35. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +1 -1
  36. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
  37. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -1
  38. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
  39. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
  40. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +36 -2
  41. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  42. data/lib/rubocop/cop/correctors.rb +28 -0
  43. data/lib/rubocop/cop/documentation.rb +2 -3
  44. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  45. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  46. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  47. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +49 -17
  48. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -3
  49. data/lib/rubocop/cop/gemspec/require_mfa.rb +22 -5
  50. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
  51. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  52. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
  53. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  54. data/lib/rubocop/cop/internal_affairs/location_exists.rb +142 -0
  55. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  56. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +13 -13
  57. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
  58. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -1
  59. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +6 -2
  60. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  61. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
  62. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  63. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  64. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
  65. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  66. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
  67. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  68. data/lib/rubocop/cop/internal_affairs.rb +3 -16
  69. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -2
  70. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  71. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
  72. data/lib/rubocop/cop/layout/block_alignment.rb +60 -4
  73. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  74. data/lib/rubocop/cop/layout/case_indentation.rb +3 -1
  75. data/lib/rubocop/cop/layout/class_structure.rb +56 -10
  76. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  77. data/lib/rubocop/cop/layout/comment_indentation.rb +9 -2
  78. data/lib/rubocop/cop/layout/condition_position.rb +13 -3
  79. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  80. data/lib/rubocop/cop/layout/dot_position.rb +2 -2
  81. data/lib/rubocop/cop/layout/else_alignment.rb +2 -15
  82. data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
  83. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +28 -9
  84. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +46 -21
  85. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  86. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +34 -4
  87. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  88. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
  89. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +13 -2
  90. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +17 -3
  91. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
  92. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  93. data/lib/rubocop/cop/layout/end_alignment.rb +10 -3
  94. data/lib/rubocop/cop/layout/first_argument_indentation.rb +35 -2
  95. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
  96. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +20 -15
  97. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
  98. data/lib/rubocop/cop/layout/hash_alignment.rb +5 -8
  99. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +3 -3
  100. data/lib/rubocop/cop/layout/heredoc_indentation.rb +33 -3
  101. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  102. data/lib/rubocop/cop/layout/indentation_width.rb +152 -7
  103. data/lib/rubocop/cop/layout/leading_comment_space.rb +13 -1
  104. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
  105. data/lib/rubocop/cop/layout/line_length.rb +62 -15
  106. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
  107. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -2
  108. data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -0
  109. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
  110. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
  111. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +236 -41
  112. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  113. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +9 -5
  114. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  115. data/lib/rubocop/cop/layout/redundant_line_break.rb +12 -6
  116. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +15 -7
  117. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
  118. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  119. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  120. data/lib/rubocop/cop/layout/space_around_keyword.rb +10 -3
  121. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  122. data/lib/rubocop/cop/layout/space_around_operators.rb +18 -3
  123. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  124. data/lib/rubocop/cop/layout/space_before_brackets.rb +6 -39
  125. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
  126. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +12 -3
  127. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
  128. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
  129. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  130. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +1 -11
  131. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  132. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1 -10
  133. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  134. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
  135. data/lib/rubocop/cop/lint/assignment_in_condition.rb +13 -1
  136. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  137. data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -8
  138. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
  139. data/lib/rubocop/cop/lint/constant_reassignment.rb +93 -11
  140. data/lib/rubocop/cop/lint/constant_resolution.rb +6 -6
  141. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +90 -0
  142. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  143. data/lib/rubocop/cop/lint/debugger.rb +13 -4
  144. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  145. data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
  146. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +5 -2
  147. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
  148. data/lib/rubocop/cop/lint/duplicate_methods.rb +219 -32
  149. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
  150. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  151. data/lib/rubocop/cop/lint/empty_block.rb +4 -4
  152. data/lib/rubocop/cop/lint/empty_conditional_body.rb +20 -65
  153. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  154. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  155. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  156. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  157. data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
  158. data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -8
  159. data/lib/rubocop/cop/lint/float_comparison.rb +33 -10
  160. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
  161. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  162. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
  163. data/lib/rubocop/cop/lint/interpolation_check.rb +25 -5
  164. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  165. data/lib/rubocop/cop/lint/literal_as_condition.rb +129 -11
  166. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
  167. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +9 -12
  168. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +19 -10
  169. data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
  170. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  171. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
  172. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  173. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
  174. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
  175. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
  176. data/lib/rubocop/cop/lint/number_conversion.rb +19 -10
  177. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  178. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +11 -0
  179. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
  180. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
  181. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -13
  182. data/lib/rubocop/cop/lint/raise_exception.rb +30 -11
  183. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  184. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +27 -10
  185. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6 -12
  186. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15 -4
  187. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  188. data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -23
  189. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +134 -11
  190. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +12 -2
  191. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +268 -0
  192. data/lib/rubocop/cop/lint/redundant_with_index.rb +4 -1
  193. data/lib/rubocop/cop/lint/redundant_with_object.rb +8 -0
  194. data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
  195. data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
  196. data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
  197. data/lib/rubocop/cop/lint/require_range_parentheses.rb +3 -2
  198. data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
  199. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
  200. data/lib/rubocop/cop/lint/rescue_type.rb +2 -2
  201. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  202. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +22 -4
  203. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +7 -1
  204. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  205. data/lib/rubocop/cop/lint/script_permission.rb +5 -1
  206. data/lib/rubocop/cop/lint/self_assignment.rb +63 -6
  207. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
  208. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  209. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  210. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -1
  211. data/lib/rubocop/cop/lint/shared_mutable_default.rb +14 -1
  212. data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
  213. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  214. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +123 -0
  215. data/lib/rubocop/cop/lint/symbol_conversion.rb +21 -4
  216. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  217. data/lib/rubocop/cop/lint/to_enum_arguments.rb +36 -3
  218. data/lib/rubocop/cop/lint/to_json.rb +20 -17
  219. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  220. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
  221. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +36 -10
  222. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
  223. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -1
  224. data/lib/rubocop/cop/lint/unreachable_code.rb +17 -9
  225. data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
  226. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  227. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  228. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  229. data/lib/rubocop/cop/lint/useless_access_modifier.rb +30 -4
  230. data/lib/rubocop/cop/lint/useless_assignment.rb +55 -25
  231. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  232. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +92 -0
  233. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +11 -10
  234. data/lib/rubocop/cop/lint/useless_or.rb +111 -0
  235. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
  236. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +11 -7
  237. data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -1
  238. data/lib/rubocop/cop/lint/useless_times.rb +22 -1
  239. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +147 -0
  240. data/lib/rubocop/cop/lint/void.rb +50 -21
  241. data/lib/rubocop/cop/message_annotator.rb +7 -3
  242. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  243. data/lib/rubocop/cop/metrics/block_length.rb +2 -1
  244. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  245. data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
  246. data/lib/rubocop/cop/metrics/method_length.rb +3 -2
  247. data/lib/rubocop/cop/metrics/perceived_complexity.rb +38 -7
  248. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
  249. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
  250. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  251. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  252. data/lib/rubocop/cop/migration/department_name.rb +12 -1
  253. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  254. data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
  255. data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -5
  256. data/lib/rubocop/cop/mixin/check_line_breakable.rb +4 -4
  257. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +5 -7
  258. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  259. data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
  260. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  261. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  262. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  263. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  264. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  265. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +20 -0
  266. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -2
  267. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  268. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  269. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  270. data/lib/rubocop/cop/mixin/hash_subset.rb +27 -4
  271. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  272. data/lib/rubocop/cop/mixin/hash_transform_method.rb +32 -78
  273. data/lib/rubocop/cop/mixin/line_length_help.rb +45 -10
  274. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  275. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -1
  276. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  277. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  278. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  279. data/lib/rubocop/cop/mixin/project_index_help.rb +48 -0
  280. data/lib/rubocop/cop/mixin/range_help.rb +15 -3
  281. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  282. data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -7
  283. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  284. data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
  285. data/lib/rubocop/cop/mixin/trailing_comma.rb +25 -6
  286. data/lib/rubocop/cop/mixin.rb +86 -0
  287. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  288. data/lib/rubocop/cop/naming/block_forwarding.rb +3 -3
  289. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  290. data/lib/rubocop/cop/naming/file_name.rb +6 -5
  291. data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
  292. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -2
  293. data/lib/rubocop/cop/naming/method_name.rb +187 -15
  294. data/lib/rubocop/cop/naming/predicate_method.rb +330 -0
  295. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
  296. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -4
  297. data/lib/rubocop/cop/naming/variable_name.rb +51 -6
  298. data/lib/rubocop/cop/offense.rb +17 -1
  299. data/lib/rubocop/cop/registry.rb +66 -39
  300. data/lib/rubocop/cop/security/eval.rb +17 -3
  301. data/lib/rubocop/cop/security/io_methods.rb +2 -2
  302. data/lib/rubocop/cop/security/json_load.rb +33 -11
  303. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  304. data/lib/rubocop/cop/security/open.rb +1 -0
  305. data/lib/rubocop/cop/style/access_modifier_declarations.rb +45 -12
  306. data/lib/rubocop/cop/style/accessor_grouping.rb +46 -8
  307. data/lib/rubocop/cop/style/alias.rb +15 -3
  308. data/lib/rubocop/cop/style/and_or.rb +2 -1
  309. data/lib/rubocop/cop/style/arguments_forwarding.rb +46 -31
  310. data/lib/rubocop/cop/style/array_first_last.rb +12 -1
  311. data/lib/rubocop/cop/style/array_intersect.rb +117 -38
  312. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +50 -0
  313. data/lib/rubocop/cop/style/array_join.rb +4 -2
  314. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  315. data/lib/rubocop/cop/style/attr.rb +5 -2
  316. data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
  317. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  318. data/lib/rubocop/cop/style/bitwise_predicate.rb +8 -1
  319. data/lib/rubocop/cop/style/block_delimiters.rb +42 -34
  320. data/lib/rubocop/cop/style/case_equality.rb +29 -15
  321. data/lib/rubocop/cop/style/case_like_if.rb +1 -1
  322. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  323. data/lib/rubocop/cop/style/class_and_module_children.rb +67 -12
  324. data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -14
  325. data/lib/rubocop/cop/style/class_methods_definitions.rb +11 -5
  326. data/lib/rubocop/cop/style/collection_compact.rb +37 -17
  327. data/lib/rubocop/cop/style/collection_methods.rb +1 -0
  328. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  329. data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
  330. data/lib/rubocop/cop/style/combinable_loops.rb +6 -0
  331. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  332. data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
  333. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  334. data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
  335. data/lib/rubocop/cop/style/concat_array_literals.rb +7 -1
  336. data/lib/rubocop/cop/style/conditional_assignment.rb +33 -24
  337. data/lib/rubocop/cop/style/constant_visibility.rb +20 -12
  338. data/lib/rubocop/cop/style/copyright.rb +22 -11
  339. data/lib/rubocop/cop/style/data_inheritance.rb +11 -0
  340. data/lib/rubocop/cop/style/date_time.rb +4 -4
  341. data/lib/rubocop/cop/style/def_with_parentheses.rb +22 -5
  342. data/lib/rubocop/cop/style/dig_chain.rb +6 -1
  343. data/lib/rubocop/cop/style/dir_empty.rb +4 -0
  344. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
  345. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  346. data/lib/rubocop/cop/style/documentation.rb +6 -6
  347. data/lib/rubocop/cop/style/documentation_method.rb +12 -8
  348. data/lib/rubocop/cop/style/double_negation.rb +3 -3
  349. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  350. data/lib/rubocop/cop/style/each_with_object.rb +4 -3
  351. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  352. data/lib/rubocop/cop/style/empty_case_condition.rb +12 -2
  353. data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
  354. data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
  355. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  356. data/lib/rubocop/cop/style/empty_literal.rb +11 -2
  357. data/lib/rubocop/cop/style/empty_method.rb +0 -6
  358. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +110 -0
  359. data/lib/rubocop/cop/style/encoding.rb +7 -1
  360. data/lib/rubocop/cop/style/end_block.rb +3 -1
  361. data/lib/rubocop/cop/style/endless_method.rb +181 -18
  362. data/lib/rubocop/cop/style/env_home.rb +4 -0
  363. data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
  364. data/lib/rubocop/cop/style/even_odd.rb +11 -1
  365. data/lib/rubocop/cop/style/exact_regexp_match.rb +8 -1
  366. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  367. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  368. data/lib/rubocop/cop/style/exponential_notation.rb +5 -4
  369. data/lib/rubocop/cop/style/fetch_env_var.rb +33 -7
  370. data/lib/rubocop/cop/style/file_null.rb +4 -2
  371. data/lib/rubocop/cop/style/file_open.rb +84 -0
  372. data/lib/rubocop/cop/style/file_write.rb +21 -16
  373. data/lib/rubocop/cop/style/float_division.rb +15 -1
  374. data/lib/rubocop/cop/style/for.rb +4 -0
  375. data/lib/rubocop/cop/style/format_string.rb +17 -4
  376. data/lib/rubocop/cop/style/format_string_token.rb +85 -14
  377. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  378. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  379. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  380. data/lib/rubocop/cop/style/guard_clause.rb +29 -23
  381. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
  382. data/lib/rubocop/cop/style/hash_conversion.rb +28 -12
  383. data/lib/rubocop/cop/style/hash_each_methods.rb +3 -2
  384. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  385. data/lib/rubocop/cop/style/hash_lookup_method.rb +102 -0
  386. data/lib/rubocop/cop/style/hash_slice.rb +16 -0
  387. data/lib/rubocop/cop/style/hash_syntax.rb +6 -1
  388. data/lib/rubocop/cop/style/hash_transform_keys.rb +19 -9
  389. data/lib/rubocop/cop/style/hash_transform_values.rb +19 -9
  390. data/lib/rubocop/cop/style/identical_conditional_branches.rb +18 -7
  391. data/lib/rubocop/cop/style/if_inside_else.rb +26 -20
  392. data/lib/rubocop/cop/style/if_unless_modifier.rb +83 -16
  393. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +16 -19
  394. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -2
  395. data/lib/rubocop/cop/style/if_with_semicolon.rb +16 -6
  396. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  397. data/lib/rubocop/cop/style/inline_comment.rb +5 -2
  398. data/lib/rubocop/cop/style/inverse_methods.rb +10 -6
  399. data/lib/rubocop/cop/style/invertible_unless_condition.rb +27 -7
  400. data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
  401. data/lib/rubocop/cop/style/it_assignment.rb +69 -12
  402. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  403. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
  404. data/lib/rubocop/cop/style/keyword_parameters_order.rb +20 -10
  405. data/lib/rubocop/cop/style/lambda.rb +8 -1
  406. data/lib/rubocop/cop/style/lambda_call.rb +26 -10
  407. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  408. data/lib/rubocop/cop/style/magic_comment_format.rb +3 -3
  409. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
  410. data/lib/rubocop/cop/style/map_into_array.rb +5 -2
  411. data/lib/rubocop/cop/style/map_join.rb +123 -0
  412. data/lib/rubocop/cop/style/map_to_hash.rb +12 -3
  413. data/lib/rubocop/cop/style/map_to_set.rb +1 -3
  414. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +9 -8
  415. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
  416. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +33 -4
  417. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -5
  418. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
  419. data/lib/rubocop/cop/style/method_def_parentheses.rb +7 -5
  420. data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
  421. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +10 -7
  422. data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
  423. data/lib/rubocop/cop/style/module_function.rb +4 -2
  424. data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
  425. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -1
  426. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  427. data/lib/rubocop/cop/style/multiline_if_then.rb +4 -4
  428. data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
  429. data/lib/rubocop/cop/style/multiline_method_signature.rb +13 -16
  430. data/lib/rubocop/cop/style/mutable_constant.rb +106 -12
  431. data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
  432. data/lib/rubocop/cop/style/next.rb +44 -0
  433. data/lib/rubocop/cop/style/nil_comparison.rb +11 -10
  434. data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
  435. data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
  436. data/lib/rubocop/cop/style/not.rb +2 -0
  437. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  438. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
  439. data/lib/rubocop/cop/style/object_then.rb +1 -0
  440. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  441. data/lib/rubocop/cop/style/one_line_conditional.rb +21 -12
  442. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  443. data/lib/rubocop/cop/style/operator_method_call.rb +11 -2
  444. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  445. data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
  446. data/lib/rubocop/cop/style/parallel_assignment.rb +57 -25
  447. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  448. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +4 -0
  449. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  450. data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
  451. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  452. data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
  453. data/lib/rubocop/cop/style/proc.rb +4 -2
  454. data/lib/rubocop/cop/style/raise_args.rb +9 -9
  455. data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
  456. data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
  457. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  458. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  459. data/lib/rubocop/cop/style/redundant_begin.rb +38 -3
  460. data/lib/rubocop/cop/style/redundant_condition.rb +61 -1
  461. data/lib/rubocop/cop/style/redundant_constant_base.rb +5 -5
  462. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +26 -4
  463. data/lib/rubocop/cop/style/redundant_each.rb +3 -3
  464. data/lib/rubocop/cop/style/redundant_exception.rb +7 -1
  465. data/lib/rubocop/cop/style/redundant_fetch_block.rb +2 -10
  466. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  467. data/lib/rubocop/cop/style/redundant_format.rb +312 -0
  468. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
  469. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
  470. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  471. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
  472. data/lib/rubocop/cop/style/redundant_line_continuation.rb +28 -7
  473. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  474. data/lib/rubocop/cop/style/redundant_parentheses.rb +111 -37
  475. data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
  476. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +9 -0
  477. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
  478. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +12 -0
  479. data/lib/rubocop/cop/style/redundant_return.rb +3 -1
  480. data/lib/rubocop/cop/style/redundant_self.rb +20 -7
  481. data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -1
  482. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
  483. data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
  484. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  485. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
  486. data/lib/rubocop/cop/style/regexp_literal.rb +32 -3
  487. data/lib/rubocop/cop/style/rescue_modifier.rb +6 -3
  488. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  489. data/lib/rubocop/cop/style/reverse_find.rb +51 -0
  490. data/lib/rubocop/cop/style/safe_navigation.rb +67 -20
  491. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  492. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  493. data/lib/rubocop/cop/style/select_by_regexp.rb +53 -20
  494. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  495. data/lib/rubocop/cop/style/semicolon.rb +45 -12
  496. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  497. data/lib/rubocop/cop/style/single_line_do_end_block.rb +21 -6
  498. data/lib/rubocop/cop/style/single_line_methods.rb +13 -8
  499. data/lib/rubocop/cop/style/sole_nested_conditional.rb +77 -101
  500. data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
  501. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  502. data/lib/rubocop/cop/style/string_concatenation.rb +18 -15
  503. data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
  504. data/lib/rubocop/cop/style/struct_inheritance.rb +24 -2
  505. data/lib/rubocop/cop/style/super_arguments.rb +3 -4
  506. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  507. data/lib/rubocop/cop/style/symbol_proc.rb +10 -7
  508. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  509. data/lib/rubocop/cop/style/ternary_parentheses.rb +11 -0
  510. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -2
  511. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +52 -1
  512. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  513. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +2 -2
  514. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  515. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  516. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +18 -19
  517. data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
  518. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  519. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  520. data/lib/rubocop/cop/style/while_until_do.rb +7 -0
  521. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -1
  522. data/lib/rubocop/cop/style/word_array.rb +1 -0
  523. data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
  524. data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
  525. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
  526. data/lib/rubocop/cop/team.rb +105 -40
  527. data/lib/rubocop/cop/util.rb +4 -5
  528. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  529. data/lib/rubocop/cop/variable_force/assignment.rb +7 -3
  530. data/lib/rubocop/cop/variable_force/branch.rb +30 -6
  531. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  532. data/lib/rubocop/cop/variable_force/variable.rb +10 -3
  533. data/lib/rubocop/cop/variable_force.rb +26 -9
  534. data/lib/rubocop/cops_documentation_generator.rb +23 -7
  535. data/lib/rubocop/directive_comment.rb +80 -3
  536. data/lib/rubocop/ext/regexp_node.rb +0 -1
  537. data/lib/rubocop/file_patterns.rb +9 -1
  538. data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
  539. data/lib/rubocop/formatter/disabled_config_formatter.rb +38 -13
  540. data/lib/rubocop/formatter/formatter_set.rb +2 -2
  541. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  542. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  543. data/lib/rubocop/formatter/junit_formatter.rb +1 -1
  544. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  545. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  546. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  547. data/lib/rubocop/formatter/simple_text_formatter.rb +0 -2
  548. data/lib/rubocop/formatter/tap_formatter.rb +5 -2
  549. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
  550. data/lib/rubocop/formatter.rb +22 -21
  551. data/lib/rubocop/lsp/diagnostic.rb +22 -37
  552. data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
  553. data/lib/rubocop/lsp/routes.rb +47 -11
  554. data/lib/rubocop/lsp/runtime.rb +19 -8
  555. data/lib/rubocop/lsp/server.rb +0 -2
  556. data/lib/rubocop/lsp/stdin_runner.rb +11 -18
  557. data/lib/rubocop/magic_comment.rb +28 -0
  558. data/lib/rubocop/mcp/server.rb +200 -0
  559. data/lib/rubocop/options.rb +60 -14
  560. data/lib/rubocop/path_util.rb +18 -2
  561. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  562. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  563. data/lib/rubocop/plugin/load_error.rb +26 -0
  564. data/lib/rubocop/plugin/loader.rb +100 -0
  565. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  566. data/lib/rubocop/plugin.rb +46 -0
  567. data/lib/rubocop/project_index_loader.rb +66 -0
  568. data/lib/rubocop/rake_task.rb +5 -2
  569. data/lib/rubocop/remote_config.rb +10 -8
  570. data/lib/rubocop/result_cache.rb +72 -47
  571. data/lib/rubocop/rspec/cop_helper.rb +21 -1
  572. data/lib/rubocop/rspec/expect_offense.rb +9 -3
  573. data/lib/rubocop/rspec/shared_contexts.rb +71 -3
  574. data/lib/rubocop/rspec/support.rb +4 -0
  575. data/lib/rubocop/runner.rb +188 -65
  576. data/lib/rubocop/server/cache.rb +56 -41
  577. data/lib/rubocop/server/cli.rb +2 -2
  578. data/lib/rubocop/server/client_command/base.rb +10 -0
  579. data/lib/rubocop/server/client_command/exec.rb +2 -1
  580. data/lib/rubocop/server/client_command/start.rb +11 -1
  581. data/lib/rubocop/server/core.rb +8 -0
  582. data/lib/rubocop/target_finder.rb +21 -10
  583. data/lib/rubocop/target_ruby.rb +31 -14
  584. data/lib/rubocop/version.rb +50 -10
  585. data/lib/rubocop.rb +47 -96
  586. data/lib/ruby_lsp/rubocop/addon.rb +29 -17
  587. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  588. metadata +86 -16
  589. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  590. data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +0 -50
@@ -19,10 +19,23 @@ module RuboCop
19
19
  MSG = 'Empty interpolation detected.'
20
20
 
21
21
  def on_interpolation(begin_node)
22
- return unless begin_node.children.empty?
22
+ return if in_percent_literal_array?(begin_node)
23
+
24
+ node_children = begin_node.children.dup
25
+ node_children.delete_if { |e| e.nil_type? || (e.basic_literal? && e.str_content&.empty?) }
26
+ return unless node_children.empty?
23
27
 
24
28
  add_offense(begin_node) { |corrector| corrector.remove(begin_node) }
25
29
  end
30
+
31
+ private
32
+
33
+ def in_percent_literal_array?(begin_node)
34
+ array_node = begin_node.each_ancestor(:array).first
35
+ return false unless array_node
36
+
37
+ array_node.percent_literal?
38
+ end
26
39
  end
27
40
  end
28
41
  end
@@ -50,11 +50,18 @@ module RuboCop
50
50
  def on_case(node)
51
51
  node.when_branches.each do |when_node|
52
52
  next if when_node.body
53
- next if cop_config['AllowComments'] && contains_comments?(when_node)
53
+ next if allow_comments?(when_node)
54
54
 
55
55
  add_offense(when_node)
56
56
  end
57
57
  end
58
+
59
+ private
60
+
61
+ def allow_comments?(node)
62
+ cop_config['AllowComments'] && contains_comments?(node) &&
63
+ !comments_contain_disables?(node, name)
64
+ end
58
65
  end
59
66
  end
60
67
  end
@@ -43,7 +43,25 @@ module RuboCop
43
43
  MSG = 'Do not return from an `ensure` block.'
44
44
 
45
45
  def on_ensure(node)
46
- node.branch&.each_node(:return) { |return_node| add_offense(return_node) }
46
+ node.branch&.each_node(:return) do |return_node|
47
+ next if return_from_inner_scope?(return_node, node)
48
+
49
+ add_offense(return_node)
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ # A `return` inside a nested method definition or lambda within the
56
+ # `ensure` returns from that inner scope, not from the method whose
57
+ # `ensure` this is, so it is not an offense. A `return` inside a plain
58
+ # block (or `proc`) does propagate out, so it remains an offense.
59
+ def return_from_inner_scope?(return_node, ensure_node)
60
+ return_node.each_ancestor do |ancestor|
61
+ break if ancestor == ensure_node
62
+ return true if ancestor.any_def_type? || (ancestor.any_block_type? && ancestor.lambda?)
63
+ end
64
+ false
47
65
  end
48
66
  end
49
67
  end
@@ -23,7 +23,7 @@ module RuboCop
23
23
  # `ERB.new` with non-keyword arguments is deprecated since ERB 2.2.0.
24
24
  # Use `:trim_mode` and `:eoutvar` keyword arguments to `ERB.new`.
25
25
  # This cop identifies places where `ERB.new(str, trim_mode, eoutvar)` can
26
- # be replaced by `ERB.new(str, :trim_mode: trim_mode, eoutvar: eoutvar)`.
26
+ # be replaced by `ERB.new(str, trim_mode: trim_mode, eoutvar: eoutvar)`.
27
27
  #
28
28
  # @example
29
29
  # # Target codes supports Ruby 2.6 and higher only
@@ -148,7 +148,9 @@ module RuboCop
148
148
  arguments = node.arguments
149
149
  overridden_kwargs = kwargs.dup
150
150
 
151
- overridden_kwargs[0] = "trim_mode: #{arguments[2].source}" if arguments[2]
151
+ if arguments[2] && !arguments[2].hash_type?
152
+ overridden_kwargs[0] = "trim_mode: #{arguments[2].source}"
153
+ end
152
154
 
153
155
  if arguments[3] && !arguments[3].hash_type?
154
156
  overridden_kwargs[1] = "eoutvar: #{arguments[3].source}"
@@ -156,12 +158,6 @@ module RuboCop
156
158
 
157
159
  overridden_kwargs
158
160
  end
159
-
160
- def arguments_range(node)
161
- arguments = node.arguments
162
-
163
- range_between(arguments.first.source_range.begin_pos, arguments.last.source_range.end_pos)
164
- end
165
161
  end
166
162
  end
167
163
  end
@@ -15,6 +15,14 @@ module RuboCop
15
15
  # x == 0.1
16
16
  # x != 0.1
17
17
  #
18
+ # # bad
19
+ # case value
20
+ # when 1.0
21
+ # foo
22
+ # when 2.0
23
+ # bar
24
+ # end
25
+ #
18
26
  # # good - using BigDecimal
19
27
  # x.to_d == 0.1.to_d
20
28
  #
@@ -32,12 +40,21 @@ module RuboCop
32
40
  # # good - comparing against nil
33
41
  # Float(x, exception: false) == nil
34
42
  #
43
+ # # good - using epsilon comparison in case expression
44
+ # case
45
+ # when (value - 1.0).abs < Float::EPSILON
46
+ # foo
47
+ # when (value - 2.0).abs < Float::EPSILON
48
+ # bar
49
+ # end
50
+ #
35
51
  # # Or some other epsilon based type of comparison:
36
52
  # # https://www.embeddeduse.com/2019/08/26/qt-compare-two-floats/
37
53
  #
38
54
  class FloatComparison < Base
39
55
  MSG_EQUALITY = 'Avoid equality comparisons of floats as they are unreliable.'
40
56
  MSG_INEQUALITY = 'Avoid inequality comparisons of floats as they are unreliable.'
57
+ MSG_CASE = 'Avoid float literal comparisons in case statements as they are unreliable.'
41
58
 
42
59
  EQUALITY_METHODS = %i[== != eql? equal?].freeze
43
60
  FLOAT_RETURNING_METHODS = %i[to_f Float fdiv].freeze
@@ -58,6 +75,16 @@ module RuboCop
58
75
  end
59
76
  alias on_csend on_send
60
77
 
78
+ def on_case(node)
79
+ node.when_branches.each do |when_branch|
80
+ when_branch.conditions.each do |condition|
81
+ next if !float?(condition) || literal_safe?(condition)
82
+
83
+ add_offense(condition, message: MSG_CASE)
84
+ end
85
+ end
86
+ end
87
+
61
88
  private
62
89
 
63
90
  def float?(node)
@@ -67,7 +94,7 @@ module RuboCop
67
94
  when :float
68
95
  true
69
96
  when :send
70
- check_send(node)
97
+ float_send?(node)
71
98
  when :begin
72
99
  float?(node.children.first)
73
100
  else
@@ -77,27 +104,23 @@ module RuboCop
77
104
 
78
105
  def literal_safe?(node)
79
106
  return false unless node
107
+ return literal_safe?(node.children.first) if node.begin_type?
80
108
 
81
109
  (node.numeric_type? && node.value.zero?) || node.nil_type?
82
110
  end
83
111
 
84
- # rubocop:disable Metrics/PerceivedComplexity
85
- def check_send(node)
112
+ def float_send?(node)
86
113
  if node.arithmetic_operation?
87
114
  float?(node.receiver) || float?(node.first_argument)
88
115
  elsif FLOAT_RETURNING_METHODS.include?(node.method_name)
89
116
  true
90
117
  elsif node.receiver&.float_type?
91
- if FLOAT_INSTANCE_METHODS.include?(node.method_name)
92
- true
93
- else
94
- check_numeric_returning_method(node)
95
- end
118
+ FLOAT_INSTANCE_METHODS.include?(node.method_name) ||
119
+ numeric_returning_method?(node)
96
120
  end
97
121
  end
98
- # rubocop:enable Metrics/PerceivedComplexity
99
122
 
100
- def check_numeric_returning_method(node)
123
+ def numeric_returning_method?(node)
101
124
  return false unless node.receiver
102
125
 
103
126
  case node.method_name
@@ -7,7 +7,7 @@ module RuboCop
7
7
  # expected fields for format/sprintf/#% and what is actually
8
8
  # passed as arguments.
9
9
  #
10
- # In addition it checks whether different formats are used in the same
10
+ # In addition, it checks whether different formats are used in the same
11
11
  # format string. Do not mix numbered, unnumbered, and named formats in
12
12
  # the same format string.
13
13
  #
@@ -11,39 +11,43 @@ module RuboCop
11
11
  # @example
12
12
  # # bad
13
13
  # foo.object_id == bar.object_id
14
+ # foo.object_id != baz.object_id
14
15
  #
15
16
  # # good
16
17
  # foo.equal?(bar)
18
+ # !foo.equal?(baz)
17
19
  #
18
20
  class IdentityComparison < Base
19
21
  extend AutoCorrector
20
22
 
21
- MSG = 'Use `equal?` instead `==` when comparing `object_id`.'
22
- RESTRICT_ON_SEND = %i[==].freeze
23
+ MSG = 'Use `%<bang>sequal?` instead of `%<comparison_method>s` when comparing `object_id`.'
24
+ RESTRICT_ON_SEND = %i[== !=].freeze
25
+
26
+ # @!method object_id_comparison(node)
27
+ def_node_matcher :object_id_comparison, <<~PATTERN
28
+ (send
29
+ (send
30
+ _lhs_receiver :object_id) ${:== :!=}
31
+ (send
32
+ _rhs_receiver :object_id))
33
+ PATTERN
23
34
 
24
35
  def on_send(node)
25
- return unless compare_between_object_id_by_double_equal?(node)
36
+ return unless (comparison_method = object_id_comparison(node))
26
37
 
27
- add_offense(node) do |corrector|
38
+ bang = comparison_method == :== ? '' : '!'
39
+ add_offense(node,
40
+ message: format(MSG, comparison_method: comparison_method,
41
+ bang: bang)) do |corrector|
28
42
  receiver = node.receiver.receiver
29
43
  argument = node.first_argument.receiver
30
44
  return unless receiver && argument
31
45
 
32
- replacement = "#{receiver.source}.equal?(#{argument.source})"
46
+ replacement = "#{bang}#{receiver.source}.equal?(#{argument.source})"
33
47
 
34
48
  corrector.replace(node, replacement)
35
49
  end
36
50
  end
37
-
38
- private
39
-
40
- def compare_between_object_id_by_double_equal?(node)
41
- object_id_method?(node.receiver) && object_id_method?(node.first_argument)
42
- end
43
-
44
- def object_id_method?(node)
45
- node.send_type? && node.method?(:object_id)
46
- end
47
51
  end
48
52
  end
49
53
  end
@@ -61,11 +61,15 @@ module RuboCop
61
61
  private
62
62
 
63
63
  def scheduler_compatible?(io1, io2)
64
- return false unless io1&.array_type? && io1.values.size == 1
64
+ return false unless single_io_array?(io1)
65
65
 
66
66
  io2&.array_type? ? io2.values.empty? : (io2.nil? || io2.nil_type?)
67
67
  end
68
68
 
69
+ def single_io_array?(node)
70
+ node&.array_type? && node.values.size == 1 && !node.values.first.splat_type?
71
+ end
72
+
69
73
  def preferred_method(read, write, timeout)
70
74
  timeout_argument = timeout.nil? ? '' : "(#{timeout.source})"
71
75
 
@@ -24,8 +24,25 @@ module RuboCop
24
24
  MSG = 'Interpolation in single quoted string detected. ' \
25
25
  'Use double quoted strings if you need interpolation.'
26
26
 
27
- # rubocop:disable Metrics/CyclomaticComplexity
28
27
  def on_str(node)
28
+ check(node)
29
+ end
30
+
31
+ # A multiline single-quoted string is parsed as a `dstr` of `str` segments, so it
32
+ # is not covered by `on_str`. Inspect single-quoted `dstr`s here; double-quoted
33
+ # interpolation is also a `dstr`, hence the delimiter check.
34
+ def on_dstr(node)
35
+ # A heredoc is also a `dstr`, but its `loc` is a `Parser::Source::Map::Heredoc`
36
+ # with no `begin`, so bail before touching it.
37
+ return if heredoc?(node)
38
+
39
+ check(node) if node.loc.begin&.source == "'"
40
+ end
41
+
42
+ private
43
+
44
+ # rubocop:disable Metrics/CyclomaticComplexity
45
+ def check(node)
29
46
  return if node.parent&.regexp_type?
30
47
  return unless /(?<!\\)#\{.*\}/.match?(node.source)
31
48
  return if heredoc?(node)
@@ -36,8 +53,6 @@ module RuboCop
36
53
  end
37
54
  # rubocop:enable Metrics/CyclomaticComplexity
38
55
 
39
- private
40
-
41
56
  def autocorrect(corrector, node)
42
57
  starting_token, ending_token = if node.source.include?('"')
43
58
  ['%{', '}']
@@ -54,9 +69,14 @@ module RuboCop
54
69
  end
55
70
 
56
71
  def valid_syntax?(node)
57
- double_quoted_string = node.source.gsub(/\A'|'\z/, '"')
72
+ double_quoted_string = if node.source.include?('"')
73
+ node.source.sub(/\A'/, '%{').sub(/'\z/, '}')
74
+ else
75
+ node.source.gsub(/\A'|'\z/, '"')
76
+ end
58
77
 
59
- parse(double_quoted_string).valid_syntax?
78
+ processed_source = parse(double_quoted_string)
79
+ processed_source.valid_syntax? && processed_source.ast.dstr_type?
60
80
  end
61
81
  end
62
82
  end
@@ -42,7 +42,7 @@ module RuboCop
42
42
  end
43
43
 
44
44
  add_offense(node) do |corrector|
45
- corrector.replace(node, node.first_argument.source.delete('&'))
45
+ corrector.replace(node, node.first_argument.source.delete_prefix('&'))
46
46
  end
47
47
  end
48
48
  end
@@ -18,12 +18,15 @@ module RuboCop
18
18
  # end
19
19
  #
20
20
  # # bad
21
- # if some_var && true
21
+ # # We're only interested in the left hand side being a truthy literal,
22
+ # # because it affects the evaluation of the &&, whereas the right hand
23
+ # # side will be conditionally executed/called and can be a literal.
24
+ # if true && some_var
22
25
  # do_something
23
26
  # end
24
27
  #
25
28
  # # good
26
- # if some_var && some_condition
29
+ # if some_var
27
30
  # do_something
28
31
  # end
29
32
  #
@@ -34,30 +37,107 @@ module RuboCop
34
37
  # end
35
38
  class LiteralAsCondition < Base
36
39
  include RangeHelp
40
+ extend AutoCorrector
37
41
 
38
42
  MSG = 'Literal `%<literal>s` appeared as a condition.'
39
43
  RESTRICT_ON_SEND = [:!].freeze
40
44
 
45
+ def on_and(node)
46
+ return unless node.lhs.truthy_literal?
47
+
48
+ add_offense(node.lhs) do |corrector|
49
+ # Don't autocorrect `'foo' && return` because having `return` as
50
+ # the leftmost node can lead to a void value expression syntax error.
51
+ next if node.rhs.type?(:return, :break, :next)
52
+
53
+ corrector.replace(node, node.rhs.source)
54
+ end
55
+ end
56
+
57
+ def on_or(node)
58
+ return unless node.lhs.falsey_literal?
59
+
60
+ add_offense(node.lhs) do |corrector|
61
+ # Don't autocorrect `'foo' && return` because having `return` as
62
+ # the leftmost node can lead to a void value expression syntax error.
63
+ next if node.rhs.type?(:return, :break, :next)
64
+
65
+ corrector.replace(node, node.rhs.source)
66
+ end
67
+ end
68
+
41
69
  def on_if(node)
42
- check_for_literal(node)
70
+ cond = condition(node)
71
+
72
+ return unless cond.falsey_literal? || cond.truthy_literal?
73
+
74
+ correct_if_node(node, cond)
43
75
  end
44
76
 
45
77
  def on_while(node)
46
- return if condition(node).true_type?
78
+ return if node.condition.source == 'true'
47
79
 
48
- check_for_literal(node)
80
+ if node.condition.truthy_literal?
81
+ add_offense(node.condition) do |corrector|
82
+ corrector.replace(node.condition, 'true')
83
+ end
84
+ elsif node.condition.falsey_literal?
85
+ add_offense(node.condition) do |corrector|
86
+ corrector.remove(node)
87
+ end
88
+ end
89
+ end
90
+
91
+ # rubocop:disable Metrics/AbcSize
92
+ def on_while_post(node)
93
+ return if node.condition.source == 'true'
94
+
95
+ if node.condition.truthy_literal?
96
+ add_offense(node.condition) do |corrector|
97
+ corrector.replace(node, node.source.sub(node.condition.source, 'true'))
98
+ end
99
+ elsif node.condition.falsey_literal?
100
+ add_offense(node.condition) do |corrector|
101
+ corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
102
+ end
103
+ end
49
104
  end
50
- alias on_while_post on_while
105
+ # rubocop:enable Metrics/AbcSize
51
106
 
52
107
  def on_until(node)
53
- return if condition(node).false_type?
108
+ return if node.condition.source == 'false'
54
109
 
55
- check_for_literal(node)
110
+ if node.condition.falsey_literal?
111
+ add_offense(node.condition) do |corrector|
112
+ corrector.replace(node.condition, 'false')
113
+ end
114
+ elsif node.condition.truthy_literal?
115
+ add_offense(node.condition) do |corrector|
116
+ corrector.remove(node)
117
+ end
118
+ end
119
+ end
120
+
121
+ # rubocop:disable Metrics/AbcSize
122
+ def on_until_post(node)
123
+ return if node.condition.source == 'false'
124
+
125
+ if node.condition.falsey_literal?
126
+ add_offense(node.condition) do |corrector|
127
+ corrector.replace(node, node.source.sub(node.condition.source, 'false'))
128
+ end
129
+ elsif node.condition.truthy_literal?
130
+ add_offense(node.condition) do |corrector|
131
+ corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
132
+ end
133
+ end
56
134
  end
57
- alias on_until_post on_until
135
+ # rubocop:enable Metrics/AbcSize
58
136
 
59
137
  def on_case(case_node)
60
- if case_node.condition
138
+ if (cond = case_node.condition)
139
+ return if !cond.falsey_literal? && !cond.truthy_literal?
140
+
61
141
  check_case(case_node)
62
142
  else
63
143
  case_node.when_branches.each do |when_node|
@@ -77,7 +157,7 @@ module RuboCop
77
157
 
78
158
  check_case(case_match_node)
79
159
  else
80
- case_match_node.each_in_pattern do |in_pattern_node|
160
+ case_match_node.in_pattern_branches.each do |in_pattern_node|
81
161
  next unless in_pattern_node.condition.literal?
82
162
 
83
163
  add_offense(in_pattern_node)
@@ -130,6 +210,8 @@ module RuboCop
130
210
 
131
211
  def handle_node(node)
132
212
  if node.literal?
213
+ return if node.parent.and_type?
214
+
133
215
  add_offense(node)
134
216
  elsif %i[send and or begin].include?(node.type)
135
217
  check_node(node)
@@ -159,6 +241,42 @@ module RuboCop
159
241
  when_node.conditions.last.source_range.end_pos
160
242
  )
161
243
  end
244
+
245
+ def condition_evaluation?(node, cond)
246
+ if node.unless?
247
+ cond.falsey_literal?
248
+ else
249
+ cond.truthy_literal?
250
+ end
251
+ end
252
+
253
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
254
+ def correct_if_node(node, cond)
255
+ result = condition_evaluation?(node, cond)
256
+
257
+ new_node = if node.elsif? && result
258
+ "else\n #{range_with_comments(node.if_branch).source}"
259
+ elsif node.elsif? && !result
260
+ "else\n #{node.else_branch.source}"
261
+ elsif node.if_branch && result
262
+ node.if_branch.source
263
+ elsif node.elsif_conditional?
264
+ "#{node.else_branch.source.sub('elsif', 'if')}\nend"
265
+ elsif node.else? || node.ternary?
266
+ node.else_branch.source
267
+ else
268
+ '' # Equivalent to removing the node
269
+ end
270
+
271
+ add_offense(cond) do |corrector|
272
+ next if part_of_ignored_node?(node)
273
+
274
+ corrector.replace(node, new_node)
275
+
276
+ ignore_node(node)
277
+ end
278
+ end
279
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
162
280
  end
163
281
  end
164
282
  end
@@ -56,7 +56,17 @@ module RuboCop
56
56
  def traverse_node(node, &block)
57
57
  yield node if node.equals_asgn?
58
58
 
59
- node.each_child_node { |child| traverse_node(child, &block) }
59
+ node.each_child_node do |child|
60
+ next if scope_body?(node, child)
61
+
62
+ traverse_node(child, &block)
63
+ end
64
+ end
65
+
66
+ # An assignment inside a block or method body within the condition belongs to
67
+ # that inner scope rather than the condition itself, so it is not inspected.
68
+ def scope_body?(node, child)
69
+ node.type?(:any_block, :any_def) && child == node.body
60
70
  end
61
71
 
62
72
  def all_literals?(node)
@@ -66,7 +66,7 @@ module RuboCop
66
66
 
67
67
  def special_keyword?(node)
68
68
  # handle strings like __FILE__
69
- (node.str_type? && !node.loc.respond_to?(:begin)) || node.source_range.is?('__LINE__')
69
+ (node.str_type? && !node.loc?(:begin)) || node.source_range.is?('__LINE__')
70
70
  end
71
71
 
72
72
  def array_in_regexp?(node)
@@ -119,11 +119,13 @@ module RuboCop
119
119
  end
120
120
 
121
121
  def autocorrected_value_for_string(node)
122
- if node.source.start_with?("'", '%q')
123
- node.children.last.inspect[1..-2]
124
- else
125
- node.children.last
126
- end
122
+ return node.source.delete_prefix('"').delete_suffix('"') unless node.value.valid_encoding?
123
+
124
+ escape_string_content(node.children.last)
125
+ end
126
+
127
+ def escape_string_content(string)
128
+ string.gsub(/[\\"]|#(?=[@{$])/, '\\\\\&')
127
129
  end
128
130
 
129
131
  def autocorrected_value_for_symbol(node)
@@ -134,12 +136,7 @@ module RuboCop
134
136
  end
135
137
 
136
138
  def autocorrected_value_in_hash_for_symbol(node)
137
- # TODO: We need to detect symbol unacceptable names more correctly
138
- if / |"|'/.match?(node.value.to_s)
139
- ":\\\"#{node.value.to_s.gsub('"') { '\\\\\"' }}\\\""
140
- else
141
- ":#{node.value}"
142
- end
139
+ escape_string_content(node.value.inspect)
143
140
  end
144
141
 
145
142
  def autocorrected_value_for_array(node)
@@ -6,12 +6,24 @@ module RuboCop
6
6
  module Lint
7
7
  # Checks that there is an `# rubocop:enable ...` statement
8
8
  # after a `# rubocop:disable ...` statement. This will prevent leaving
9
- # cop disables on wide ranges of code, that latter contributors to
9
+ # cop disables on wide ranges of code, that later contributors to
10
10
  # a file wouldn't be aware of.
11
11
  #
12
- # @example
13
- # # Lint/MissingCopEnableDirective:
14
- # # MaximumRangeSize: .inf
12
+ # You can set `MaxRangeSize` to define the maximum number of
13
+ # consecutive lines a cop can be disabled for.
14
+ #
15
+ # - `.inf` any size (default)
16
+ # - `0` allows only single-line disables
17
+ # - `1` means the maximum allowed is as follows:
18
+ #
19
+ # [source,ruby]
20
+ # ----
21
+ # # rubocop:disable SomeCop
22
+ # a = 1
23
+ # # rubocop:enable SomeCop
24
+ # ----
25
+ #
26
+ # @example MaxRangeSize: .inf (default)
15
27
  #
16
28
  # # good
17
29
  # # rubocop:disable Layout/SpaceAroundOperators
@@ -25,9 +37,7 @@ module RuboCop
25
37
  # x= 0
26
38
  # # EOF
27
39
  #
28
- # @example
29
- # # Lint/MissingCopEnableDirective:
30
- # # MaximumRangeSize: 2
40
+ # @example MaxRangeSize: 2
31
41
  #
32
42
  # # good
33
43
  # # rubocop:disable Layout/SpaceAroundOperators
@@ -52,10 +62,9 @@ module RuboCop
52
62
  each_missing_enable do |cop, line_range|
53
63
  next if acceptable_range?(cop, line_range)
54
64
 
55
- range = source_range(processed_source.buffer, line_range.min, (0..0))
56
65
  comment = processed_source.comment_at_line(line_range.begin)
57
66
 
58
- add_offense(range, message: message(cop, comment))
67
+ add_offense(comment, message: message(cop, comment))
59
68
  end
60
69
  end
61
70
 
@@ -85,7 +94,7 @@ module RuboCop
85
94
  end
86
95
 
87
96
  def max_range
88
- @max_range ||= cop_config['MaximumRangeSize']
97
+ @max_range ||= cop_config['MaxRangeSize']
89
98
  end
90
99
 
91
100
  def message(cop, comment, type = 'cop')