rubocop 1.67.0 → 1.75.7

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 (476) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +266 -47
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +3 -1
  7. data/lib/rubocop/cached_data.rb +12 -4
  8. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  9. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  10. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  11. data/lib/rubocop/cli/command/version.rb +2 -2
  12. data/lib/rubocop/cli.rb +1 -1
  13. data/lib/rubocop/comment_config.rb +2 -2
  14. data/lib/rubocop/config.rb +52 -10
  15. data/lib/rubocop/config_loader.rb +52 -9
  16. data/lib/rubocop/config_loader_resolver.rb +36 -10
  17. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  18. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  19. data/lib/rubocop/config_obsoletion.rb +46 -2
  20. data/lib/rubocop/config_validator.rb +25 -14
  21. data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
  22. data/lib/rubocop/cop/base.rb +7 -1
  23. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  24. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  25. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  26. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  27. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  28. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  29. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  30. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  31. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +49 -5
  32. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  33. data/lib/rubocop/cop/generator.rb +6 -0
  34. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  35. data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
  36. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  37. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  38. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  39. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  40. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  41. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  42. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  43. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +230 -0
  44. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
  45. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  46. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  47. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  48. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  49. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  50. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  51. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  52. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  53. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  54. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  55. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  56. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  57. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  58. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  59. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  60. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  61. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  62. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  63. data/lib/rubocop/cop/layout/class_structure.rb +9 -9
  64. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
  65. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  66. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  67. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  68. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  69. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  70. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +30 -4
  71. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  72. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  73. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  74. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  75. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  76. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  77. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  78. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  79. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  80. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  81. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  82. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  83. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  84. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  85. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  86. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  87. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  88. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  89. data/lib/rubocop/cop/layout/line_length.rb +123 -4
  90. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  91. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  92. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  93. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  94. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  95. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  96. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  97. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
  98. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  99. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  100. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
  101. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  102. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  103. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  104. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  105. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  106. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  107. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  108. data/lib/rubocop/cop/layout/space_around_operators.rb +23 -21
  109. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  110. data/lib/rubocop/cop/layout/space_before_brackets.rb +8 -34
  111. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  112. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  113. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -1
  114. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  115. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  116. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  117. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  118. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  119. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  120. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  121. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  122. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  123. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  124. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  125. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  126. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  127. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  128. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  129. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
  130. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  131. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  132. data/lib/rubocop/cop/lint/duplicate_methods.rb +86 -19
  133. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  134. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  135. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  136. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  137. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  138. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  139. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  140. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  141. data/lib/rubocop/cop/lint/float_comparison.rb +20 -14
  142. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  143. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  144. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  145. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  146. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  147. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  148. data/lib/rubocop/cop/lint/literal_as_condition.rb +118 -9
  149. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  150. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  151. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  152. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  153. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  154. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  155. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  156. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  157. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  158. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  159. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  160. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  161. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  162. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  163. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  164. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  165. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  166. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  167. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  168. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  169. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  170. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  171. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
  172. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  173. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  174. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  175. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  176. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  177. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  178. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  179. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  180. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  181. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  182. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  183. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  184. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  185. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  186. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +8 -1
  187. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  188. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  189. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  190. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  191. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  192. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  193. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  194. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  195. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  196. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  197. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  198. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  199. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  200. data/lib/rubocop/cop/lint/useless_access_modifier.rb +5 -4
  201. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  202. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  203. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  204. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  205. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  206. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  207. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  208. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  209. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  210. data/lib/rubocop/cop/lint/void.rb +16 -12
  211. data/lib/rubocop/cop/message_annotator.rb +7 -3
  212. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  213. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  214. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  215. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  216. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  217. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  218. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  219. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  220. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  221. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  222. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  223. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  224. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  225. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  226. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  227. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  228. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  229. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  230. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  231. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  232. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  233. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  234. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  235. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  236. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +3 -2
  237. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  238. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  239. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  240. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  241. data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
  242. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  243. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  244. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  245. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  246. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  247. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  248. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  249. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  250. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  251. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  252. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  253. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  254. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  255. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  256. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  257. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  258. data/lib/rubocop/cop/naming/method_name.rb +64 -8
  259. data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
  260. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  261. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  262. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  263. data/lib/rubocop/cop/offense.rb +2 -3
  264. data/lib/rubocop/cop/registry.rb +9 -6
  265. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  266. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  267. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  268. data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
  269. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  270. data/lib/rubocop/cop/style/and_or.rb +1 -1
  271. data/lib/rubocop/cop/style/arguments_forwarding.rb +47 -28
  272. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  273. data/lib/rubocop/cop/style/array_intersect.rb +42 -30
  274. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  275. data/lib/rubocop/cop/style/block_delimiters.rb +43 -25
  276. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  277. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  278. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  279. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  280. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  281. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  282. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  283. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  284. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  285. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  286. data/lib/rubocop/cop/style/conditional_assignment.rb +39 -27
  287. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  288. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  289. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  290. data/lib/rubocop/cop/style/documentation.rb +1 -1
  291. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  292. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  293. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  294. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  295. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  296. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  297. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  298. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  299. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  300. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  301. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  302. data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
  303. data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
  304. data/lib/rubocop/cop/style/file_null.rb +89 -0
  305. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  306. data/lib/rubocop/cop/style/float_division.rb +8 -4
  307. data/lib/rubocop/cop/style/for.rb +1 -1
  308. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  309. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  310. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  311. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  312. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  313. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  314. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  315. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  316. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  317. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  318. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  319. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  320. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  321. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  322. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  323. data/lib/rubocop/cop/style/if_unless_modifier.rb +25 -5
  324. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  325. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  326. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  327. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  328. data/lib/rubocop/cop/style/inverse_methods.rb +15 -12
  329. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  330. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  331. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  332. data/lib/rubocop/cop/style/it_block_parameter.rb +100 -0
  333. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  334. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  335. data/lib/rubocop/cop/style/lambda.rb +1 -0
  336. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  337. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  338. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  339. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  340. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  341. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +27 -17
  342. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  343. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  344. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  345. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  346. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  347. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  348. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  349. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  350. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  351. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  352. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  353. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  354. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  355. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  356. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  357. data/lib/rubocop/cop/style/next.rb +44 -0
  358. data/lib/rubocop/cop/style/not.rb +1 -1
  359. data/lib/rubocop/cop/style/object_then.rb +15 -15
  360. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  361. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  362. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  363. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  364. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  365. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  366. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  367. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  368. data/lib/rubocop/cop/style/proc.rb +2 -2
  369. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  370. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  371. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  372. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  373. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  374. data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
  375. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  376. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  377. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  378. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  379. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  380. data/lib/rubocop/cop/style/redundant_format.rb +257 -0
  381. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
  382. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  383. data/lib/rubocop/cop/style/redundant_line_continuation.rb +54 -18
  384. data/lib/rubocop/cop/style/redundant_parentheses.rb +56 -26
  385. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  386. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  387. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  388. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  389. data/lib/rubocop/cop/style/redundant_self.rb +9 -15
  390. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  391. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  392. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  393. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  394. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  395. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  396. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  397. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  398. data/lib/rubocop/cop/style/safe_navigation.rb +32 -5
  399. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  400. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  401. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  402. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  403. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  404. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  405. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  406. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  407. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  408. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  409. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  410. data/lib/rubocop/cop/style/sole_nested_conditional.rb +42 -106
  411. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  412. data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
  413. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  414. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  415. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  416. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  417. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  418. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  419. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  420. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  421. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  422. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  423. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  424. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  425. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  426. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  427. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  428. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  429. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  430. data/lib/rubocop/cop/util.rb +12 -5
  431. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  432. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  433. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  434. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  435. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  436. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  437. data/lib/rubocop/cop/variable_force.rb +5 -11
  438. data/lib/rubocop/cops_documentation_generator.rb +50 -25
  439. data/lib/rubocop/directive_comment.rb +45 -11
  440. data/lib/rubocop/ext/regexp_node.rb +0 -1
  441. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
  442. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  443. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  444. data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
  445. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  446. data/lib/rubocop/lsp/logger.rb +2 -2
  447. data/lib/rubocop/lsp/routes.rb +7 -23
  448. data/lib/rubocop/lsp/runtime.rb +18 -50
  449. data/lib/rubocop/lsp/server.rb +0 -2
  450. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  451. data/lib/rubocop/magic_comment.rb +11 -3
  452. data/lib/rubocop/options.rb +28 -12
  453. data/lib/rubocop/path_util.rb +15 -8
  454. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  455. data/lib/rubocop/plugin/load_error.rb +26 -0
  456. data/lib/rubocop/plugin/loader.rb +100 -0
  457. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  458. data/lib/rubocop/plugin.rb +46 -0
  459. data/lib/rubocop/rake_task.rb +4 -1
  460. data/lib/rubocop/result_cache.rb +13 -13
  461. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  462. data/lib/rubocop/rspec/expect_offense.rb +6 -2
  463. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  464. data/lib/rubocop/rspec/support.rb +4 -2
  465. data/lib/rubocop/runner.rb +26 -15
  466. data/lib/rubocop/server/cache.rb +47 -11
  467. data/lib/rubocop/server/cli.rb +2 -2
  468. data/lib/rubocop/target_finder.rb +7 -2
  469. data/lib/rubocop/target_ruby.rb +17 -2
  470. data/lib/rubocop/version.rb +53 -12
  471. data/lib/rubocop.rb +32 -1
  472. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  473. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  474. metadata +79 -20
  475. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  476. 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)
@@ -7,11 +7,6 @@ module RuboCop
7
7
  #
8
8
  # NOTE: empty `else` branches are handled by `Style/EmptyElse`.
9
9
  #
10
- # @safety
11
- # Autocorrection for this cop is not safe. The conditions for empty branches that
12
- # the autocorrection removes may have side effects, or the logic in subsequent
13
- # branches may change due to the removal of a previous condition.
14
- #
15
10
  # @example
16
11
  # # bad
17
12
  # if condition
@@ -41,6 +36,13 @@ module RuboCop
41
36
  # if condition
42
37
  # do_something
43
38
  # elsif other_condition
39
+ # nil
40
+ # end
41
+ #
42
+ # # good
43
+ # if condition
44
+ # do_something
45
+ # elsif other_condition
44
46
  # do_something_else
45
47
  # end
46
48
  #
@@ -63,11 +65,9 @@ module RuboCop
63
65
  class EmptyConditionalBody < Base
64
66
  extend AutoCorrector
65
67
  include CommentsHelp
66
- include RangeHelp
67
68
 
68
69
  MSG = 'Avoid `%<keyword>s` branches without a body.'
69
70
 
70
- # rubocop:disable Metrics/AbcSize
71
71
  def on_if(node)
72
72
  return if node.body || same_line?(node.loc.begin, node.loc.end)
73
73
  return if cop_config['AllowComments'] && contains_comments?(node)
@@ -75,12 +75,11 @@ module RuboCop
75
75
  range = offense_range(node)
76
76
 
77
77
  add_offense(range, message: format(MSG, keyword: node.keyword)) do |corrector|
78
- next if node.parent&.call_type?
78
+ next unless can_simplify_conditional?(node)
79
79
 
80
- autocorrect(corrector, node)
80
+ flip_orphaned_else(corrector, node)
81
81
  end
82
82
  end
83
- # rubocop:enable Metrics/AbcSize
84
83
 
85
84
  private
86
85
 
@@ -92,53 +91,23 @@ module RuboCop
92
91
  end
93
92
  end
94
93
 
95
- def autocorrect(corrector, node)
96
- remove_comments(corrector, node)
97
- remove_empty_branch(corrector, node)
98
- correct_other_branches(corrector, node)
99
- end
100
-
101
- def remove_comments(corrector, node)
102
- comments_in_range(node).each do |comment|
103
- range = range_by_whole_lines(comment.source_range, include_final_newline: true)
104
- corrector.remove(range)
105
- end
94
+ def can_simplify_conditional?(node)
95
+ node.else_branch && node.loc.else.source == 'else'
106
96
  end
107
97
 
108
- # rubocop:disable Metrics/AbcSize
109
98
  def remove_empty_branch(corrector, node)
110
99
  range = if empty_if_branch?(node) && else_branch?(node)
111
100
  branch_range(node)
112
- elsif same_line?(node, else_kw_loc = node.loc.else)
113
- node.source_range.begin.join(else_kw_loc.begin)
114
- elsif node.parent&.loc.respond_to?(:end) &&
115
- same_line?(node, end_loc = node.parent.loc.end)
116
- node.source_range.begin.join(end_loc.begin)
117
101
  else
118
102
  deletion_range(branch_range(node))
119
103
  end
120
104
 
121
105
  corrector.remove(range)
122
106
  end
123
- # rubocop:enable Metrics/AbcSize
124
-
125
- def correct_other_branches(corrector, node)
126
- return unless require_other_branches_correction?(node)
127
-
128
- if node.else_branch&.if_type? && !node.else_branch.modifier_form?
129
- # Replace an orphaned `elsif` with `if`
130
- corrector.replace(node.else_branch.loc.keyword, 'if')
131
- else
132
- # Flip orphaned `else`
133
- corrector.replace(node.loc.else, "#{node.inverse_keyword} #{node.condition.source}")
134
- end
135
- end
136
-
137
- def require_other_branches_correction?(node)
138
- return false unless node.if_type? && node.else?
139
- return false if !empty_if_branch?(node) && node.elsif?
140
107
 
141
- !empty_elsif_branch?(node)
108
+ def flip_orphaned_else(corrector, node)
109
+ corrector.replace(node.loc.else, "#{node.inverse_keyword} #{node.condition.source}")
110
+ remove_empty_branch(corrector, node)
142
111
  end
143
112
 
144
113
  def empty_if_branch?(node)
@@ -149,36 +118,17 @@ module RuboCop
149
118
  if_branch.if_type? && !if_branch.body
150
119
  end
151
120
 
152
- def empty_elsif_branch?(node)
153
- return false unless (else_branch = node.else_branch)
154
-
155
- else_branch.if_type? && !else_branch.body
156
- end
157
-
158
121
  def else_branch?(node)
159
122
  node.else_branch && !node.else_branch.if_type?
160
123
  end
161
124
 
162
- # rubocop:disable Metrics/AbcSize
163
125
  def branch_range(node)
164
126
  if empty_if_branch?(node) && else_branch?(node)
165
127
  node.source_range.with(end_pos: node.loc.else.begin_pos)
166
128
  elsif node.loc.else
167
129
  node.source_range.with(end_pos: node.condition.source_range.end_pos)
168
- elsif all_branches_body_missing?(node)
169
- if_node = node.ancestors.detect(&:if?)
170
- node.source_range.join(if_node.loc.end.end)
171
- else
172
- node.source_range
173
130
  end
174
131
  end
175
- # rubocop:enable Metrics/AbcSize
176
-
177
- def all_branches_body_missing?(node)
178
- return false unless node.parent&.if_type?
179
-
180
- node.parent.branches.compact.empty?
181
- end
182
132
 
183
133
  def deletion_range(range)
184
134
  # Collect a range between the start of the `if` node and the next relevant node,
@@ -38,7 +38,7 @@ module RuboCop
38
38
  MSG = 'Empty `ensure` block detected.'
39
39
 
40
40
  def on_ensure(node)
41
- return if node.body
41
+ return if node.branch
42
42
 
43
43
  add_offense(node.loc.keyword) { |corrector| corrector.remove(node.loc.keyword) }
44
44
  end
@@ -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)
@@ -21,8 +21,6 @@ module RuboCop
21
21
  # # File consisting only of comments
22
22
  #
23
23
  class EmptyFile < Base
24
- include RangeHelp
25
-
26
24
  MSG = 'Empty file detected.'
27
25
 
28
26
  def on_new_investigation
@@ -43,7 +43,7 @@ module RuboCop
43
43
  MSG = 'Do not return from an `ensure` block.'
44
44
 
45
45
  def on_ensure(node)
46
- node.body&.each_node(:return) { |return_node| add_offense(return_node) }
46
+ node.branch&.each_node(:return) { |return_node| add_offense(return_node) }
47
47
  end
48
48
  end
49
49
  end
@@ -156,12 +156,6 @@ module RuboCop
156
156
 
157
157
  overridden_kwargs
158
158
  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
159
  end
166
160
  end
167
161
  end
@@ -29,11 +29,15 @@ module RuboCop
29
29
  # tolerance = 0.0001
30
30
  # (x - 0.1).abs < tolerance
31
31
  #
32
+ # # good - comparing against nil
33
+ # Float(x, exception: false) == nil
34
+ #
32
35
  # # Or some other epsilon based type of comparison:
33
36
  # # https://www.embeddeduse.com/2019/08/26/qt-compare-two-floats/
34
37
  #
35
38
  class FloatComparison < Base
36
- 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.'
37
41
 
38
42
  EQUALITY_METHODS = %i[== != eql? equal?].freeze
39
43
  FLOAT_RETURNING_METHODS = %i[to_f Float fdiv].freeze
@@ -42,11 +46,17 @@ module RuboCop
42
46
  RESTRICT_ON_SEND = EQUALITY_METHODS
43
47
 
44
48
  def on_send(node)
45
- lhs, _method, rhs = *node
46
- return if literal_zero?(lhs) || literal_zero?(rhs)
49
+ return unless node.arguments.one?
50
+
51
+ lhs = node.receiver
52
+ rhs = node.first_argument
53
+
54
+ return if literal_safe?(lhs) || literal_safe?(rhs)
47
55
 
48
- 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)
49
58
  end
59
+ alias on_csend on_send
50
60
 
51
61
  private
52
62
 
@@ -65,26 +75,22 @@ module RuboCop
65
75
  end
66
76
  end
67
77
 
68
- def literal_zero?(node)
69
- node&.numeric_type? && node.value.zero?
78
+ def literal_safe?(node)
79
+ return false unless node
80
+
81
+ (node.numeric_type? && node.value.zero?) || node.nil_type?
70
82
  end
71
83
 
72
- # rubocop:disable Metrics/PerceivedComplexity
73
84
  def check_send(node)
74
85
  if node.arithmetic_operation?
75
- lhs, _operation, rhs = *node
76
- float?(lhs) || float?(rhs)
86
+ float?(node.receiver) || float?(node.first_argument)
77
87
  elsif FLOAT_RETURNING_METHODS.include?(node.method_name)
78
88
  true
79
89
  elsif node.receiver&.float_type?
80
- if FLOAT_INSTANCE_METHODS.include?(node.method_name)
81
- true
82
- else
90
+ FLOAT_INSTANCE_METHODS.include?(node.method_name) ||
83
91
  check_numeric_returning_method(node)
84
- end
85
92
  end
86
93
  end
87
- # rubocop:enable Metrics/PerceivedComplexity
88
94
 
89
95
  def check_numeric_returning_method(node)
90
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
  #
@@ -18,9 +18,7 @@ module RuboCop
18
18
  MSG = 'Float out of range.'
19
19
 
20
20
  def on_float(node)
21
- value, = *node
22
-
23
- return unless value.infinite? || (value.zero? && /[1-9]/.match?(node.source))
21
+ return unless node.value.infinite? || (node.value.zero? && /[1-9]/.match?(node.source))
24
22
 
25
23
  add_offense(node)
26
24
  end
@@ -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
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Checks for the deprecated use of keyword arguments as a default in `Hash.new`.
7
+ #
8
+ # This usage raises a warning in Ruby 3.3 and results in an error in Ruby 3.4.
9
+ # In Ruby 3.4, keyword arguments will instead be used to change the behavior of a hash.
10
+ # For example, the capacity option can be passed to create a hash with a certain size
11
+ # if you know it in advance, for better performance.
12
+ #
13
+ # NOTE: The following corner case may result in a false negative when upgrading from Ruby 3.3
14
+ # or earlier, but it is intentionally not detected to respect the expected usage in Ruby 3.4.
15
+ #
16
+ # [source,ruby]
17
+ # ----
18
+ # Hash.new(capacity: 42)
19
+ # ----
20
+ #
21
+ # @example
22
+ #
23
+ # # bad
24
+ # Hash.new(key: :value)
25
+ #
26
+ # # good
27
+ # Hash.new({key: :value})
28
+ #
29
+ class HashNewWithKeywordArgumentsAsDefault < Base
30
+ extend AutoCorrector
31
+
32
+ MSG = 'Use a hash literal instead of keyword arguments.'
33
+ RESTRICT_ON_SEND = %i[new].freeze
34
+
35
+ # @!method hash_new(node)
36
+ def_node_matcher :hash_new, <<~PATTERN
37
+ (send (const {nil? (cbase)} :Hash) :new $[hash !braces?])
38
+ PATTERN
39
+
40
+ def on_send(node)
41
+ return unless (first_argument = hash_new(node))
42
+
43
+ if first_argument.pairs.one?
44
+ key = first_argument.pairs.first.key
45
+ return if key.respond_to?(:value) && key.value == :capacity
46
+ end
47
+
48
+ add_offense(first_argument) do |corrector|
49
+ corrector.wrap(first_argument, '{', '}')
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ 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)
@@ -24,14 +24,17 @@ 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
27
28
  def on_str(node)
28
29
  return if node.parent&.regexp_type?
29
30
  return unless /(?<!\\)#\{.*\}/.match?(node.source)
30
31
  return if heredoc?(node)
31
32
  return unless node.loc.begin && node.loc.end
33
+ return unless valid_syntax?(node)
32
34
 
33
35
  add_offense(node) { |corrector| autocorrect(corrector, node) }
34
36
  end
37
+ # rubocop:enable Metrics/CyclomaticComplexity
35
38
 
36
39
  private
37
40
 
@@ -49,6 +52,12 @@ module RuboCop
49
52
  def heredoc?(node)
50
53
  node.loc.is_a?(Parser::Source::Map::Heredoc) || (node.parent && heredoc?(node.parent))
51
54
  end
55
+
56
+ def valid_syntax?(node)
57
+ double_quoted_string = node.source.gsub(/\A'|'\z/, '"')
58
+
59
+ parse(double_quoted_string).valid_syntax?
60
+ end
52
61
  end
53
62
  end
54
63
  end
@@ -26,6 +26,9 @@ module RuboCop
26
26
  #
27
27
  class ItWithoutArgumentsInBlock < Base
28
28
  include NodePattern::Macros
29
+ extend TargetRubyVersion
30
+
31
+ maximum_target_ruby_version 3.3
29
32
 
30
33
  MSG = '`it` calls without arguments will refer to the first block param in Ruby 3.4; ' \
31
34
  'use `it()` or `self.it`.'
@@ -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,26 +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.'
43
+ RESTRICT_ON_SEND = [:!].freeze
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
39
56
 
40
57
  def on_if(node)
41
- check_for_literal(node)
58
+ cond = condition(node)
59
+
60
+ return unless cond.falsey_literal? || cond.truthy_literal?
61
+
62
+ correct_if_node(node, cond)
42
63
  end
43
64
 
44
65
  def on_while(node)
45
- return if condition(node).true_type?
66
+ return if node.condition.source == 'true'
46
67
 
47
- 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
48
77
  end
49
- alias on_while_post on_while
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
92
+ end
93
+ # rubocop:enable Metrics/AbcSize
50
94
 
51
95
  def on_until(node)
52
- return if condition(node).false_type?
96
+ return if node.condition.source == 'false'
53
97
 
54
- 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
55
107
  end
56
- alias on_until_post on_until
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
122
+ end
123
+ # rubocop:enable Metrics/AbcSize
57
124
 
58
125
  def on_case(case_node)
59
126
  if case_node.condition
@@ -129,6 +196,8 @@ module RuboCop
129
196
 
130
197
  def handle_node(node)
131
198
  if node.literal?
199
+ return if node.parent.and_type?
200
+
132
201
  add_offense(node)
133
202
  elsif %i[send and or begin].include?(node.type)
134
203
  check_node(node)
@@ -158,6 +227,46 @@ module RuboCop
158
227
  when_node.conditions.last.source_range.end_pos
159
228
  )
160
229
  end
230
+
231
+ def condition_evaluation(node, cond)
232
+ if node.unless?
233
+ cond.falsey_literal?
234
+ else
235
+ cond.truthy_literal?
236
+ end
237
+ end
238
+
239
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
240
+ def correct_if_node(node, cond)
241
+ result = condition_evaluation(node, cond)
242
+
243
+ if node.elsif? && result
244
+ add_offense(cond) do |corrector|
245
+ corrector.replace(node, "else\n #{node.if_branch.source}")
246
+ end
247
+ elsif node.elsif? && !result
248
+ add_offense(cond) do |corrector|
249
+ corrector.replace(node, "else\n #{node.else_branch.source}")
250
+ end
251
+ elsif node.if_branch && result
252
+ add_offense(cond) do |corrector|
253
+ corrector.replace(node, node.if_branch.source)
254
+ end
255
+ elsif node.elsif_conditional?
256
+ add_offense(cond) do |corrector|
257
+ corrector.replace(node, "#{node.else_branch.source.sub('elsif', 'if')}\nend")
258
+ end
259
+ elsif node.else? || node.ternary?
260
+ add_offense(cond) do |corrector|
261
+ corrector.replace(node, node.else_branch.source)
262
+ end
263
+ else
264
+ add_offense(cond) do |corrector|
265
+ corrector.remove(node)
266
+ end
267
+ end
268
+ end
269
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
161
270
  end
162
271
  end
163
272
  end
@@ -40,7 +40,7 @@ module RuboCop
40
40
  traverse_node(node.condition) do |asgn_node|
41
41
  next unless asgn_node.loc.operator
42
42
 
43
- rhs = asgn_node.to_a.last
43
+ rhs = asgn_node.rhs
44
44
  next if !all_literals?(rhs) || parallel_assignment_with_splat_operator?(rhs)
45
45
 
46
46
  range = offense_range(asgn_node, rhs)