rubocop 1.69.2 → 1.73.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 (299) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +90 -13
  5. data/config/internal_affairs.yml +16 -0
  6. data/lib/rubocop/cli/command/execute_runner.rb +3 -3
  7. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  8. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  9. data/lib/rubocop/comment_config.rb +2 -2
  10. data/lib/rubocop/config.rb +17 -4
  11. data/lib/rubocop/config_loader.rb +48 -8
  12. data/lib/rubocop/config_loader_resolver.rb +35 -10
  13. data/lib/rubocop/config_validator.rb +19 -9
  14. data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
  15. data/lib/rubocop/cop/base.rb +6 -0
  16. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
  17. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  18. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  19. data/lib/rubocop/cop/internal_affairs/example_description.rb +4 -2
  20. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  21. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  22. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  23. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  24. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  25. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  26. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +229 -0
  27. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  28. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  29. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  30. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  31. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  32. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  33. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
  34. data/lib/rubocop/cop/internal_affairs.rb +5 -16
  35. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  36. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -8
  37. data/lib/rubocop/cop/layout/block_alignment.rb +3 -1
  38. data/lib/rubocop/cop/layout/class_structure.rb +9 -9
  39. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
  40. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  41. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  42. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
  43. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  44. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +27 -1
  45. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
  46. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
  47. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  48. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  49. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  50. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  51. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  52. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  53. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  54. data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
  55. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  56. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  57. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  58. data/lib/rubocop/cop/layout/line_length.rb +4 -3
  59. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  60. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  61. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -0
  62. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  63. data/lib/rubocop/cop/layout/redundant_line_break.rb +7 -6
  64. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
  65. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  66. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  67. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  68. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  69. data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
  70. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -0
  71. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  72. data/lib/rubocop/cop/layout/space_around_operators.rb +3 -3
  73. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  74. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  75. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  76. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  77. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
  78. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  79. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +1 -1
  80. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  81. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  82. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  83. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  84. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  85. data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -14
  86. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  87. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  88. data/lib/rubocop/cop/lint/empty_conditional_body.rb +10 -5
  89. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  90. data/lib/rubocop/cop/lint/float_comparison.rb +6 -8
  91. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
  92. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  93. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  94. data/lib/rubocop/cop/lint/literal_as_condition.rb +99 -9
  95. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  96. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  97. data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -3
  98. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  99. data/lib/rubocop/cop/lint/nested_method_definition.rb +8 -4
  100. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  101. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +4 -3
  102. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  103. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +18 -31
  104. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -1
  105. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  106. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  107. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  108. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  109. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +252 -0
  110. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  111. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -1
  112. data/lib/rubocop/cop/lint/shared_mutable_default.rb +65 -0
  113. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  114. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  115. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  116. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  117. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -4
  118. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
  119. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  120. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  121. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
  122. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
  123. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
  124. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +80 -0
  125. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  126. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  127. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  128. data/lib/rubocop/cop/lint/void.rb +11 -9
  129. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  130. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  131. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
  132. data/lib/rubocop/cop/metrics/method_length.rb +8 -1
  133. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  134. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  135. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  136. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  137. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  138. data/lib/rubocop/cop/mixin/check_line_breakable.rb +11 -11
  139. data/lib/rubocop/cop/mixin/comments_help.rb +4 -2
  140. data/lib/rubocop/cop/mixin/dig_help.rb +1 -1
  141. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  142. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  143. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  144. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  145. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  146. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  147. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +48 -24
  148. data/lib/rubocop/cop/mixin/range_help.rb +3 -3
  149. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  150. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  151. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  152. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  153. data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -3
  154. data/lib/rubocop/cop/naming/block_forwarding.rb +19 -15
  155. data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
  156. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -3
  157. data/lib/rubocop/cop/naming/variable_name.rb +64 -6
  158. data/lib/rubocop/cop/security/compound_hash.rb +1 -0
  159. data/lib/rubocop/cop/style/access_modifier_declarations.rb +34 -5
  160. data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
  161. data/lib/rubocop/cop/style/and_or.rb +1 -1
  162. data/lib/rubocop/cop/style/arguments_forwarding.rb +39 -23
  163. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  164. data/lib/rubocop/cop/style/block_delimiters.rb +7 -20
  165. data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
  166. data/lib/rubocop/cop/style/collection_methods.rb +1 -1
  167. data/lib/rubocop/cop/style/combinable_defined.rb +1 -1
  168. data/lib/rubocop/cop/style/combinable_loops.rb +2 -2
  169. data/lib/rubocop/cop/style/commented_keyword.rb +1 -1
  170. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  171. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -4
  172. data/lib/rubocop/cop/style/documentation.rb +1 -1
  173. data/lib/rubocop/cop/style/double_negation.rb +3 -3
  174. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  175. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  176. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  177. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  178. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  179. data/lib/rubocop/cop/style/endless_method.rb +163 -18
  180. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  181. data/lib/rubocop/cop/style/exact_regexp_match.rb +3 -10
  182. data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
  183. data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
  184. data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
  185. data/lib/rubocop/cop/style/float_division.rb +8 -4
  186. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  187. data/lib/rubocop/cop/style/hash_each_methods.rb +3 -6
  188. data/lib/rubocop/cop/style/hash_except.rb +24 -148
  189. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  190. data/lib/rubocop/cop/style/hash_syntax.rb +6 -3
  191. data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
  192. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
  193. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
  194. data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
  195. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  196. data/lib/rubocop/cop/style/inverse_methods.rb +6 -6
  197. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  198. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
  199. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  200. data/lib/rubocop/cop/style/map_into_array.rb +1 -1
  201. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  202. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  203. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +19 -12
  204. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  205. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -1
  206. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
  207. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  208. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  209. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  210. data/lib/rubocop/cop/style/multiple_comparison.rb +26 -20
  211. data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
  212. data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -1
  213. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  214. data/lib/rubocop/cop/style/object_then.rb +13 -15
  215. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  216. data/lib/rubocop/cop/style/parallel_assignment.rb +1 -5
  217. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  218. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  219. data/lib/rubocop/cop/style/proc.rb +1 -2
  220. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  221. data/lib/rubocop/cop/style/raise_args.rb +6 -4
  222. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  223. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  224. data/lib/rubocop/cop/style/redundant_condition.rb +48 -2
  225. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
  226. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  227. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  228. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  229. data/lib/rubocop/cop/style/redundant_format.rb +250 -0
  230. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
  231. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  232. data/lib/rubocop/cop/style/redundant_line_continuation.rb +34 -13
  233. data/lib/rubocop/cop/style/redundant_parentheses.rb +28 -14
  234. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +3 -0
  235. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  236. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  237. data/lib/rubocop/cop/style/redundant_self_assignment.rb +14 -28
  238. data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
  239. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  240. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  241. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  242. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  243. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  244. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  245. data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -2
  246. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  247. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  248. data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -2
  249. data/lib/rubocop/cop/style/string_concatenation.rb +2 -2
  250. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  251. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  252. data/lib/rubocop/cop/style/super_arguments.rb +65 -17
  253. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  254. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  255. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
  256. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  257. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  258. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  259. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  260. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  261. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  262. data/lib/rubocop/cop/util.rb +12 -5
  263. data/lib/rubocop/cop/utils/format_string.rb +7 -5
  264. data/lib/rubocop/cop/variable_force/variable.rb +14 -2
  265. data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
  266. data/lib/rubocop/cops_documentation_generator.rb +25 -14
  267. data/lib/rubocop/directive_comment.rb +44 -10
  268. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  269. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  270. data/lib/rubocop/lsp/logger.rb +2 -2
  271. data/lib/rubocop/lsp/routes.rb +7 -23
  272. data/lib/rubocop/lsp/runtime.rb +17 -49
  273. data/lib/rubocop/lsp/server.rb +0 -2
  274. data/lib/rubocop/lsp/stdin_runner.rb +83 -0
  275. data/lib/rubocop/options.rb +28 -12
  276. data/lib/rubocop/path_util.rb +15 -8
  277. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  278. data/lib/rubocop/plugin/load_error.rb +26 -0
  279. data/lib/rubocop/plugin/loader.rb +100 -0
  280. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  281. data/lib/rubocop/plugin.rb +46 -0
  282. data/lib/rubocop/rake_task.rb +4 -1
  283. data/lib/rubocop/result_cache.rb +13 -13
  284. data/lib/rubocop/rspec/cop_helper.rb +9 -0
  285. data/lib/rubocop/rspec/expect_offense.rb +6 -2
  286. data/lib/rubocop/rspec/shared_contexts.rb +19 -1
  287. data/lib/rubocop/rspec/support.rb +2 -2
  288. data/lib/rubocop/runner.rb +5 -6
  289. data/lib/rubocop/server/cache.rb +35 -2
  290. data/lib/rubocop/server/cli.rb +2 -2
  291. data/lib/rubocop/target_finder.rb +1 -0
  292. data/lib/rubocop/target_ruby.rb +15 -0
  293. data/lib/rubocop/version.rb +17 -2
  294. data/lib/rubocop.rb +11 -1
  295. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  296. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
  297. metadata +53 -16
  298. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  299. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for duplicate literal, constant, or variable elements in Set.
6
+ # Checks for duplicate literal, constant, or variable elements in `Set` and `SortedSet`.
7
7
  #
8
8
  # @example
9
9
  #
@@ -25,17 +25,28 @@ module RuboCop
25
25
  # # good
26
26
  # [:foo, :bar].to_set
27
27
  #
28
+ # # bad
29
+ # SortedSet[:foo, :bar, :foo]
30
+ #
31
+ # # good
32
+ # SortedSet[:foo, :bar]
33
+ #
34
+ # # bad
35
+ # SortedSet.new([:foo, :bar, :foo])
36
+ #
37
+ # # good
38
+ # SortedSet.new([:foo, :bar])
28
39
  class DuplicateSetElement < Base
29
40
  extend AutoCorrector
30
41
 
31
- MSG = 'Remove the duplicate element in Set.'
42
+ MSG = 'Remove the duplicate element in %<class_name>s.'
32
43
  RESTRICT_ON_SEND = %i[\[\] new to_set].freeze
33
44
 
34
45
  # @!method set_init_elements(node)
35
46
  def_node_matcher :set_init_elements, <<~PATTERN
36
47
  {
37
- (send (const {nil? cbase} :Set) :[] $...)
38
- (send (const {nil? cbase} :Set) :new (array $...))
48
+ (send (const {nil? cbase} {:Set :SortedSet}) :[] $...)
49
+ (send (const {nil? cbase} {:Set :SortedSet}) :new (array $...))
39
50
  (call (array $...) :to_set)
40
51
  }
41
52
  PATTERN
@@ -51,7 +62,7 @@ module RuboCop
51
62
  next if !set_element.literal? && !set_element.const_type? && !set_element.variable?
52
63
 
53
64
  if seen_elements.include?(set_element)
54
- register_offense(set_element, set_elements[index - 1])
65
+ register_offense(set_element, set_elements[index - 1], node)
55
66
  else
56
67
  seen_elements << set_element
57
68
  end
@@ -61,8 +72,10 @@ module RuboCop
61
72
 
62
73
  private
63
74
 
64
- def register_offense(current_element, prev_element)
65
- add_offense(current_element) do |corrector|
75
+ def register_offense(current_element, prev_element, node)
76
+ class_name = node.receiver.const_type? ? node.receiver.const_name : 'Set'
77
+
78
+ add_offense(current_element, message: format(MSG, class_name: class_name)) do |corrector|
66
79
  range = prev_element.source_range.end.join(current_element.source_range.end)
67
80
 
68
81
  corrector.remove(range)
@@ -67,7 +67,6 @@ module RuboCop
67
67
 
68
68
  MSG = 'Avoid `%<keyword>s` branches without a body.'
69
69
 
70
- # rubocop:disable Metrics/AbcSize
71
70
  def on_if(node)
72
71
  return if node.body || same_line?(node.loc.begin, node.loc.end)
73
72
  return if cop_config['AllowComments'] && contains_comments?(node)
@@ -75,15 +74,21 @@ module RuboCop
75
74
  range = offense_range(node)
76
75
 
77
76
  add_offense(range, message: format(MSG, keyword: node.keyword)) do |corrector|
78
- next if node.parent&.call_type?
79
-
80
- autocorrect(corrector, node)
77
+ autocorrect(corrector, node) if do_autocorrect?(node)
81
78
  end
82
79
  end
83
- # rubocop:enable Metrics/AbcSize
84
80
 
85
81
  private
86
82
 
83
+ def do_autocorrect?(node)
84
+ # if condition; end.do_something
85
+ return false if (parent = node.parent)&.call_type?
86
+ # x = if condition; end
87
+ return false if (parent&.assignment? || parent&.operator_keyword?) && node.children.one?
88
+
89
+ true
90
+ end
91
+
87
92
  def offense_range(node)
88
93
  if node.loc.else
89
94
  node.source_range.begin.join(node.loc.else.begin)
@@ -14,8 +14,6 @@ module RuboCop
14
14
  # bar
15
15
  # end
16
16
  #
17
- # @example
18
- #
19
17
  # # good
20
18
  #
21
19
  # foo = (some_expression)
@@ -36,7 +36,8 @@ module RuboCop
36
36
  # # https://www.embeddeduse.com/2019/08/26/qt-compare-two-floats/
37
37
  #
38
38
  class FloatComparison < Base
39
- MSG = 'Avoid (in)equality comparisons of floats as they are unreliable.'
39
+ MSG_EQUALITY = 'Avoid equality comparisons of floats as they are unreliable.'
40
+ MSG_INEQUALITY = 'Avoid inequality comparisons of floats as they are unreliable.'
40
41
 
41
42
  EQUALITY_METHODS = %i[== != eql? equal?].freeze
42
43
  FLOAT_RETURNING_METHODS = %i[to_f Float fdiv].freeze
@@ -52,8 +53,10 @@ module RuboCop
52
53
 
53
54
  return if literal_safe?(lhs) || literal_safe?(rhs)
54
55
 
55
- add_offense(node) if float?(lhs) || float?(rhs)
56
+ message = node.method?(:!=) ? MSG_INEQUALITY : MSG_EQUALITY
57
+ add_offense(node, message: message) if float?(lhs) || float?(rhs)
56
58
  end
59
+ alias on_csend on_send
57
60
 
58
61
  private
59
62
 
@@ -78,21 +81,16 @@ module RuboCop
78
81
  (node.numeric_type? && node.value.zero?) || node.nil_type?
79
82
  end
80
83
 
81
- # rubocop:disable Metrics/PerceivedComplexity
82
84
  def check_send(node)
83
85
  if node.arithmetic_operation?
84
86
  float?(node.receiver) || float?(node.first_argument)
85
87
  elsif FLOAT_RETURNING_METHODS.include?(node.method_name)
86
88
  true
87
89
  elsif node.receiver&.float_type?
88
- if FLOAT_INSTANCE_METHODS.include?(node.method_name)
89
- true
90
- else
90
+ FLOAT_INSTANCE_METHODS.include?(node.method_name) ||
91
91
  check_numeric_returning_method(node)
92
- end
93
92
  end
94
93
  end
95
- # rubocop:enable Metrics/PerceivedComplexity
96
94
 
97
95
  def check_numeric_returning_method(node)
98
96
  return false unless node.receiver
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Identifies Float literals which are, like, really really really
6
+ # Identifies `Float` literals which are, like, really really really
7
7
  # really really really really really big. Too big. No-one needs Floats
8
8
  # that big. If you need a float that big, something is wrong with you.
9
9
  #
@@ -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
  #
@@ -73,7 +73,7 @@ module RuboCop
73
73
 
74
74
  first_arg = node.first_argument
75
75
  return false if num_of_expected_fields.zero? &&
76
- (first_arg.dstr_type? || first_arg.array_type?)
76
+ first_arg.type?(:dstr, :array)
77
77
 
78
78
  matched_arguments_count?(num_of_expected_fields, num_of_format_args)
79
79
  end
@@ -82,7 +82,7 @@ module RuboCop
82
82
  end
83
83
 
84
84
  def string_literal?(node)
85
- node.str_type? || node.dstr_type?
85
+ node.type?(:str, :dstr)
86
86
  end
87
87
 
88
88
  def string_literals?(node1, node2)
@@ -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,27 +37,90 @@ 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
+ corrector.replace(node, node.rhs.source)
50
+ end
51
+ end
52
+
41
53
  def on_if(node)
42
- check_for_literal(node)
54
+ cond = condition(node)
55
+
56
+ if node.unless?
57
+ correct_if_node(node, cond, true) if cond.falsey_literal?
58
+ correct_if_node(node, cond, false) if cond.truthy_literal?
59
+ else
60
+ correct_if_node(node, cond, true) if cond.truthy_literal?
61
+ correct_if_node(node, cond, false) if cond.falsey_literal?
62
+ end
43
63
  end
44
64
 
45
65
  def on_while(node)
46
- return if condition(node).true_type?
66
+ return if node.condition.source == 'true'
47
67
 
48
- check_for_literal(node)
68
+ if node.condition.truthy_literal?
69
+ add_offense(node.condition) do |corrector|
70
+ corrector.replace(node.condition, 'true')
71
+ end
72
+ elsif node.condition.falsey_literal?
73
+ add_offense(node.condition) do |corrector|
74
+ corrector.remove(node)
75
+ end
76
+ end
77
+ end
78
+
79
+ # rubocop:disable Metrics/AbcSize
80
+ def on_while_post(node)
81
+ return if node.condition.source == 'true'
82
+
83
+ if node.condition.truthy_literal?
84
+ add_offense(node.condition) do |corrector|
85
+ corrector.replace(node, node.source.sub(node.condition.source, 'true'))
86
+ end
87
+ elsif node.condition.falsey_literal?
88
+ add_offense(node.condition) do |corrector|
89
+ corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
90
+ end
91
+ end
49
92
  end
50
- alias on_while_post on_while
93
+ # rubocop:enable Metrics/AbcSize
51
94
 
52
95
  def on_until(node)
53
- return if condition(node).false_type?
96
+ return if node.condition.source == 'false'
54
97
 
55
- check_for_literal(node)
98
+ if node.condition.falsey_literal?
99
+ add_offense(node.condition) do |corrector|
100
+ corrector.replace(node.condition, 'false')
101
+ end
102
+ elsif node.condition.truthy_literal?
103
+ add_offense(node.condition) do |corrector|
104
+ corrector.remove(node)
105
+ end
106
+ end
107
+ end
108
+
109
+ # rubocop:disable Metrics/AbcSize
110
+ def on_until_post(node)
111
+ return if node.condition.source == 'false'
112
+
113
+ if node.condition.falsey_literal?
114
+ add_offense(node.condition) do |corrector|
115
+ corrector.replace(node, node.source.sub(node.condition.source, 'false'))
116
+ end
117
+ elsif node.condition.truthy_literal?
118
+ add_offense(node.condition) do |corrector|
119
+ corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
120
+ end
121
+ end
56
122
  end
57
- alias on_until_post on_until
123
+ # rubocop:enable Metrics/AbcSize
58
124
 
59
125
  def on_case(case_node)
60
126
  if case_node.condition
@@ -130,6 +196,8 @@ module RuboCop
130
196
 
131
197
  def handle_node(node)
132
198
  if node.literal?
199
+ return if node.parent.and_type?
200
+
133
201
  add_offense(node)
134
202
  elsif %i[send and or begin].include?(node.type)
135
203
  check_node(node)
@@ -159,6 +227,28 @@ module RuboCop
159
227
  when_node.conditions.last.source_range.end_pos
160
228
  )
161
229
  end
230
+
231
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
232
+ def correct_if_node(node, cond, result)
233
+ if result
234
+ add_offense(cond) do |corrector|
235
+ corrector.replace(node, node.if_branch.source)
236
+ end
237
+ elsif node.elsif_conditional?
238
+ add_offense(cond) do |corrector|
239
+ corrector.replace(node, "#{node.else_branch.source.sub('elsif', 'if')}\nend")
240
+ end
241
+ elsif node.else? || node.ternary?
242
+ add_offense(cond) do |corrector|
243
+ corrector.replace(node, node.else_branch.source)
244
+ end
245
+ else
246
+ add_offense(cond) do |corrector|
247
+ corrector.remove(node)
248
+ end
249
+ end
250
+ end
251
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
162
252
  end
163
253
  end
164
254
  end
@@ -5,6 +5,9 @@ module RuboCop
5
5
  module Lint
6
6
  # Checks for interpolated literals.
7
7
  #
8
+ # NOTE: Array literals interpolated in regexps are not handled by this cop, but
9
+ # by `Lint/ArrayLiteralInRegexp` instead.
10
+ #
8
11
  # @example
9
12
  #
10
13
  # # bad
@@ -21,6 +24,7 @@ module RuboCop
21
24
  MSG = 'Literal interpolation detected.'
22
25
  COMPOSITE = %i[array hash pair irange erange].freeze
23
26
 
27
+ # rubocop:disable Metrics/AbcSize
24
28
  def on_interpolation(begin_node)
25
29
  final_node = begin_node.children.last
26
30
  return unless offending?(final_node)
@@ -35,11 +39,18 @@ module RuboCop
35
39
  return if in_array_percent_literal?(begin_node) && /\s|\A\z/.match?(expanded_value)
36
40
 
37
41
  add_offense(final_node) do |corrector|
38
- return if final_node.dstr_type? # nested, fixed in next iteration
42
+ next if final_node.dstr_type? # nested, fixed in next iteration
43
+
44
+ replacement = if final_node.str_type? && !final_node.value.valid_encoding?
45
+ final_node.source.delete_prefix('"').delete_suffix('"')
46
+ else
47
+ expanded_value
48
+ end
39
49
 
40
- corrector.replace(final_node.parent, expanded_value)
50
+ corrector.replace(final_node.parent, replacement)
41
51
  end
42
52
  end
53
+ # rubocop:enable Metrics/AbcSize
43
54
 
44
55
  private
45
56
 
@@ -47,8 +58,10 @@ module RuboCop
47
58
  node &&
48
59
  !special_keyword?(node) &&
49
60
  prints_as_self?(node) &&
50
- # Special case for Layout/TrailingWhitespace
51
- !(space_literal?(node) && ends_heredoc_line?(node))
61
+ # Special case for `Layout/TrailingWhitespace`
62
+ !(space_literal?(node) && ends_heredoc_line?(node)) &&
63
+ # Handled by `Lint/ArrayLiteralInRegexp`
64
+ !array_in_regexp?(node)
52
65
  end
53
66
 
54
67
  def special_keyword?(node)
@@ -56,6 +69,11 @@ module RuboCop
56
69
  (node.str_type? && !node.loc.respond_to?(:begin)) || node.source_range.is?('__LINE__')
57
70
  end
58
71
 
72
+ def array_in_regexp?(node)
73
+ grandparent = node.parent.parent
74
+ node.array_type? && grandparent.regexp_type?
75
+ end
76
+
59
77
  # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
60
78
  def autocorrected_value(node)
61
79
  case node.type
@@ -168,7 +186,7 @@ module RuboCop
168
186
  end
169
187
 
170
188
  def space_literal?(node)
171
- node.str_type? && node.value.blank?
189
+ node.str_type? && node.value.valid_encoding? && node.value.blank?
172
190
  end
173
191
 
174
192
  def ends_heredoc_line?(node)
@@ -181,7 +199,7 @@ module RuboCop
181
199
 
182
200
  def in_array_percent_literal?(node)
183
201
  parent = node.parent
184
- return false unless parent.dstr_type? || parent.dsym_type?
202
+ return false unless parent.type?(:dstr, :dsym)
185
203
 
186
204
  grandparent = parent.parent
187
205
  grandparent&.array_type? && grandparent.percent_literal?
@@ -97,7 +97,7 @@ module RuboCop
97
97
 
98
98
  # @!method class_new_block(node)
99
99
  def_node_matcher :class_new_block, <<~RUBY
100
- ({block numblock}
100
+ (any_block
101
101
  (send
102
102
  (const {nil? cbase} :Class) :new $_) ...)
103
103
  RUBY
@@ -135,7 +135,7 @@ module RuboCop
135
135
  end
136
136
 
137
137
  def inside_class_with_stateful_parent?(node)
138
- if (block_node = node.each_ancestor(:block, :numblock).first)
138
+ if (block_node = node.each_ancestor(:any_block).first)
139
139
  return false unless (super_class = class_new_block(block_node))
140
140
 
141
141
  !allowed_class?(super_class)
@@ -8,7 +8,7 @@ module RuboCop
8
8
  # Offenses are registered for regexp character classes like `/[A-z]/`
9
9
  # as well as range objects like `('A'..'z')`.
10
10
  #
11
- # NOTE: Range objects cannot be autocorrected.
11
+ # NOTE: `Range` objects cannot be autocorrected.
12
12
  #
13
13
  # @safety
14
14
  # The cop autocorrects regexp character classes
@@ -79,7 +79,7 @@ module RuboCop
79
79
  end
80
80
 
81
81
  def range_pairs(expr)
82
- RuboCop::Cop::Utils::RegexpRanges.new(expr).pairs
82
+ expr.expressions.filter_map { |e| [e.expressions[0], e.expressions[1]] if e.type == :set }
83
83
  end
84
84
 
85
85
  def unsafe_range?(range_start, range_end)
@@ -94,7 +94,7 @@ module RuboCop
94
94
 
95
95
  def skip_range?(range_start, range_end)
96
96
  [range_start, range_end].any? do |bound|
97
- bound.type != :literal
97
+ bound&.type != :literal
98
98
  end
99
99
  end
100
100
 
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Do not mix named captures and numbered captures in a Regexp literal
6
+ # Do not mix named captures and numbered captures in a `Regexp` literal
7
7
  # because numbered capture is ignored if they're mixed.
8
8
  # Replace numbered captures with non-capturing groupings or
9
9
  # named captures.
@@ -96,13 +96,13 @@ module RuboCop
96
96
 
97
97
  def on_def(node)
98
98
  subject, = *node # rubocop:disable InternalAffairs/NodeDestructuring
99
- return if node.defs_type? && subject.variable?
99
+ return if node.defs_type? && allowed_subject_type?(subject)
100
100
 
101
101
  def_ancestor = node.each_ancestor(:def, :defs).first
102
102
  return unless def_ancestor
103
103
 
104
104
  within_scoping_def =
105
- node.each_ancestor(:block, :numblock, :sclass).any? do |ancestor|
105
+ node.each_ancestor(:any_block, :sclass).any? do |ancestor|
106
106
  scoping_method_call?(ancestor)
107
107
  end
108
108
 
@@ -117,6 +117,10 @@ module RuboCop
117
117
  child.class_constructor? || allowed_method_name?(child)
118
118
  end
119
119
 
120
+ def allowed_subject_type?(subject)
121
+ subject.variable? || subject.const_type? || subject.call_type?
122
+ end
123
+
120
124
  def allowed_method_name?(node)
121
125
  name = node.method_name
122
126
 
@@ -125,12 +129,12 @@ module RuboCop
125
129
 
126
130
  # @!method eval_call?(node)
127
131
  def_node_matcher :eval_call?, <<~PATTERN
128
- ({block numblock} (send _ {:instance_eval :class_eval :module_eval} ...) ...)
132
+ (any_block (send _ {:instance_eval :class_eval :module_eval} ...) ...)
129
133
  PATTERN
130
134
 
131
135
  # @!method exec_call?(node)
132
136
  def_node_matcher :exec_call?, <<~PATTERN
133
- ({block numblock} (send _ {:instance_exec :class_exec :module_exec} ...) ...)
137
+ (any_block (send _ {:instance_exec :class_exec :module_exec} ...) ...)
134
138
  PATTERN
135
139
  end
136
140
  end
@@ -43,7 +43,7 @@ module RuboCop
43
43
  PATTERN
44
44
 
45
45
  def parent_block_node(node)
46
- node.each_ancestor(:block, :numblock).first
46
+ node.each_ancestor(:any_block).first
47
47
  end
48
48
  end
49
49
  end
@@ -59,12 +59,12 @@ module RuboCop
59
59
 
60
60
  # @!method send_exist_node(node)
61
61
  def_node_search :send_exist_node, <<~PATTERN
62
- $(send (const nil? {:FileTest :File :Dir :Shell}) {:exist? :exists?} ...)
62
+ $(send (const {cbase nil?} {:FileTest :File :Dir :Shell}) {:exist? :exists?} ...)
63
63
  PATTERN
64
64
 
65
65
  # @!method receiver_and_method_name(node)
66
66
  def_node_matcher :receiver_and_method_name, <<~PATTERN
67
- (send (const nil? $_) $_ ...)
67
+ (send (const {cbase nil?} $_) $_ ...)
68
68
  PATTERN
69
69
 
70
70
  # @!method force?(node)
@@ -78,7 +78,7 @@ module RuboCop
78
78
  PATTERN
79
79
 
80
80
  def on_send(node)
81
- return unless node.receiver
81
+ return unless node.receiver&.const_type?
82
82
  return unless if_node_child?(node)
83
83
  return if explicit_not_force?(node)
84
84
  return unless (exist_node = send_exist_node(node.parent).first)
@@ -116,6 +116,7 @@ module RuboCop
116
116
 
117
117
  def message_remove_file_exist_check(node)
118
118
  receiver, method_name = receiver_and_method_name(node)
119
+
119
120
  format(MSG_REMOVE_FILE_EXIST_CHECK, receiver: receiver, method_name: method_name)
120
121
  end
121
122
 
@@ -66,7 +66,7 @@ module RuboCop
66
66
  private
67
67
 
68
68
  def scoped_node?(node)
69
- node.def_type? || node.defs_type? || node.lambda?
69
+ node.type?(:def, :defs) || node.lambda?
70
70
  end
71
71
 
72
72
  def return_value?(return_node)