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
@@ -76,6 +76,9 @@ module RuboCop
76
76
  # # good
77
77
  # {foo:, bar:}
78
78
  #
79
+ # # good - allowed to mix syntaxes
80
+ # {foo:, bar: baz}
81
+ #
79
82
  # @example EnforcedShorthandSyntax: never
80
83
  #
81
84
  # # bad
@@ -137,6 +140,7 @@ module RuboCop
137
140
  MSG_19 = 'Use the new Ruby 1.9 hash syntax.'
138
141
  MSG_NO_MIXED_KEYS = "Don't mix styles in the same hash."
139
142
  MSG_HASH_ROCKETS = 'Use hash rockets syntax.'
143
+ NO_MIXED_KEYS_STYLES = %i[ruby19_no_mixed_keys no_mixed_keys].freeze
140
144
 
141
145
  def on_hash(node)
142
146
  pairs = node.pairs
@@ -196,7 +200,7 @@ module RuboCop
196
200
  def autocorrect(corrector, node)
197
201
  if style == :hash_rockets || force_hash_rockets?(node.parent.pairs)
198
202
  autocorrect_hash_rockets(corrector, node)
199
- elsif style == :ruby19_no_mixed_keys || style == :no_mixed_keys
203
+ elsif NO_MIXED_KEYS_STYLES.include?(style)
200
204
  autocorrect_no_mixed_keys(corrector, node)
201
205
  else
202
206
  autocorrect_ruby19(corrector, node)
@@ -208,7 +212,7 @@ module RuboCop
208
212
  end
209
213
 
210
214
  def word_symbol_pair?(pair)
211
- return false unless pair.key.sym_type? || pair.key.dsym_type?
215
+ return false unless pair.key.type?(:sym, :dsym)
212
216
 
213
217
  acceptable_19_syntax_symbol?(pair.key.source)
214
218
  end
@@ -272,7 +276,9 @@ module RuboCop
272
276
  end
273
277
 
274
278
  def argument_without_space?(node)
275
- node.argument? && node.source_range.begin_pos == node.parent.loc.selector.end_pos
279
+ return false if !node.argument? || !node.parent.loc.selector
280
+
281
+ node.source_range.begin_pos == node.parent.loc.selector.end_pos
276
282
  end
277
283
 
278
284
  def autocorrect_hash_rockets(corrector, pair_node)
@@ -3,8 +3,8 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Looks for uses of `\_.each_with_object({}) {...}`,
7
- # `\_.map {...}.to_h`, and `Hash[\_.map {...}]` that are actually just
6
+ # Looks for uses of `+_.each_with_object({}) {...}+`,
7
+ # `+_.map {...}.to_h+`, and `+Hash[_.map {...}]+` that are actually just
8
8
  # transforming the keys of a hash, and tries to use a simpler & faster
9
9
  # call to `transform_keys` instead.
10
10
  # It should only be enabled on Ruby version 2.5 or newer.
@@ -3,8 +3,8 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Looks for uses of `\_.each_with_object({}) {...}`,
7
- # `\_.map {...}.to_h`, and `Hash[\_.map {...}]` that are actually just
6
+ # Looks for uses of `+_.each_with_object({}) {...}+`,
7
+ # `+_.map {...}.to_h+`, and `+Hash[_.map {...}]+` that are actually just
8
8
  # transforming the values of a hash, and tries to use a simpler & faster
9
9
  # call to `transform_values` instead.
10
10
  #
@@ -189,7 +189,7 @@ module RuboCop
189
189
  end
190
190
  end
191
191
 
192
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
192
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
193
193
  def check_expressions(node, expressions, insert_position)
194
194
  return if expressions.any?(&:nil?)
195
195
 
@@ -197,22 +197,41 @@ module RuboCop
197
197
 
198
198
  expressions.each do |expression|
199
199
  add_offense(expression) do |corrector|
200
- next if node.if_type? && node.ternary?
200
+ next if node.if_type? && (node.ternary? || node.then?)
201
201
 
202
202
  range = range_by_whole_lines(expression.source_range, include_final_newline: true)
203
203
  corrector.remove(range)
204
204
  next if inserted_expression
205
205
 
206
- if insert_position == :after_condition
207
- corrector.insert_after(node, "\n#{expression.source}")
206
+ if node.parent&.assignment?
207
+ correct_assignment(corrector, node, expression, insert_position)
208
208
  else
209
- corrector.insert_before(node, "#{expression.source}\n")
209
+ correct_no_assignment(corrector, node, expression, insert_position)
210
210
  end
211
+
211
212
  inserted_expression = true
212
213
  end
213
214
  end
214
215
  end
215
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
216
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
217
+
218
+ def correct_assignment(corrector, node, expression, insert_position)
219
+ if insert_position == :after_condition
220
+ assignment = node.parent.source_range.with(end_pos: node.source_range.begin_pos)
221
+ corrector.remove(assignment)
222
+ corrector.insert_after(node, "\n#{assignment.source}#{expression.source}")
223
+ else
224
+ corrector.insert_before(node.parent, "#{expression.source}\n")
225
+ end
226
+ end
227
+
228
+ def correct_no_assignment(corrector, node, expression, insert_position)
229
+ if insert_position == :after_condition
230
+ corrector.insert_after(node, "\n#{expression.source}")
231
+ else
232
+ corrector.insert_before(node, "#{expression.source}\n")
233
+ end
234
+ end
216
235
 
217
236
  def last_child_of_parent?(node)
218
237
  return true unless (parent = node.parent)
@@ -59,7 +59,6 @@ module RuboCop
59
59
  # end
60
60
  #
61
61
  class IfInsideElse < Base
62
- include IgnoredNode
63
62
  include RangeHelp
64
63
  extend AutoCorrector
65
64
 
@@ -98,34 +97,31 @@ module RuboCop
98
97
  else
99
98
  correct_to_elsif_from_if_inside_else_form(corrector, node, node.condition)
100
99
  end
101
-
102
- corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
103
- return unless (if_branch = node.if_branch)
104
-
105
- range = range_by_whole_lines(if_branch.source_range, include_final_newline: true)
106
- corrector.remove(range)
107
100
  end
108
101
 
109
102
  def correct_to_elsif_from_modifier_form(corrector, node)
110
- corrector.replace(node.parent.loc.else, <<~RUBY.chop)
111
- elsif #{node.condition.source}
112
- #{indent(node.if_branch)}#{node.if_branch.source}
113
- end
114
- RUBY
103
+ corrector.replace(node.parent.loc.else, "elsif #{node.condition.source}")
104
+
105
+ condition_range = range_between(
106
+ node.if_branch.source_range.end_pos, node.condition.source_range.end_pos
107
+ )
108
+ corrector.remove(condition_range)
115
109
  end
116
110
 
117
- def correct_to_elsif_from_if_inside_else_form(corrector, node, condition)
111
+ def correct_to_elsif_from_if_inside_else_form(corrector, node, condition) # rubocop:disable Metrics/AbcSize
118
112
  corrector.replace(node.parent.loc.else, "elsif #{condition.source}")
119
113
 
120
114
  if_condition_range = if_condition_range(node, condition)
121
115
 
122
116
  if (if_branch = node.if_branch)
123
- corrector.replace(if_condition_range, if_branch.source)
117
+ corrector.replace(if_condition_range, range_with_comments(if_branch).source)
118
+ corrector.remove(range_with_comments_and_lines(if_branch))
124
119
  else
125
120
  corrector.remove(range_by_whole_lines(if_condition_range, include_final_newline: true))
126
121
  end
127
122
 
128
123
  corrector.remove(condition)
124
+ corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
129
125
  end
130
126
 
131
127
  def then?(node)
@@ -23,6 +23,17 @@ module RuboCop
23
23
  # end
24
24
  # ----
25
25
  #
26
+ # The code `def method_name = body if condition` is considered a bad case by
27
+ # `Style/AmbiguousEndlessMethodDefinition` cop. So, to respect the user's intention to use
28
+ # an endless method definition in the `if` body, the following code is allowed:
29
+ #
30
+ # [source,ruby]
31
+ # ----
32
+ # if condition
33
+ # def method_name = body
34
+ # end
35
+ # ----
36
+ #
26
37
  # NOTE: It is allowed when `defined?` argument has an undefined value,
27
38
  # because using the modifier form causes the following incompatibility:
28
39
  #
@@ -77,10 +88,14 @@ module RuboCop
77
88
  [Style::SoleNestedConditional]
78
89
  end
79
90
 
91
+ # rubocop:disable Metrics/AbcSize
80
92
  def on_if(node)
93
+ return if endless_method?(node.body)
94
+
81
95
  condition = node.condition
82
96
  return if defined_nodes(condition).any? { |n| defined_argument_is_undefined?(node, n) } ||
83
97
  pattern_matching_nodes(condition).any?
98
+
84
99
  return unless (msg = message(node))
85
100
 
86
101
  add_offense(node.loc.keyword, message: format(msg, keyword: node.keyword)) do |corrector|
@@ -90,9 +105,14 @@ module RuboCop
90
105
  ignore_node(node)
91
106
  end
92
107
  end
108
+ # rubocop:enable Metrics/AbcSize
93
109
 
94
110
  private
95
111
 
112
+ def endless_method?(body)
113
+ body&.any_def_type? && body.endless?
114
+ end
115
+
96
116
  def defined_nodes(condition)
97
117
  if condition.defined_type?
98
118
  [condition]
@@ -103,7 +123,7 @@ module RuboCop
103
123
 
104
124
  def defined_argument_is_undefined?(if_node, defined_node)
105
125
  defined_argument = defined_node.first_argument
106
- return false unless defined_argument.lvar_type? || defined_argument.send_type?
126
+ return false unless defined_argument.type?(:lvar, :send)
107
127
 
108
128
  if_node.left_siblings.none? do |sibling|
109
129
  sibling.respond_to?(:lvasgn_type?) && sibling.lvasgn_type? &&
@@ -112,11 +132,11 @@ module RuboCop
112
132
  end
113
133
 
114
134
  def pattern_matching_nodes(condition)
115
- if condition.match_pattern_type? || condition.match_pattern_p_type?
135
+ if condition.type?(:match_pattern, :match_pattern_p)
116
136
  [condition]
117
137
  else
118
138
  condition.each_descendant.select do |node|
119
- node.match_pattern_type? || node.match_pattern_p_type?
139
+ node.type?(:match_pattern, :match_pattern_p)
120
140
  end
121
141
  end
122
142
  end
@@ -164,8 +184,8 @@ module RuboCop
164
184
 
165
185
  def too_long_due_to_comment_after_modifier?(node, comment)
166
186
  source_length = processed_source.lines[node.first_line - 1].length
167
- source_length >= max_line_length &&
168
- source_length - comment.source_range.length <= max_line_length
187
+
188
+ max_line_length.between?(source_length - comment.source_range.length, source_length)
169
189
  end
170
190
 
171
191
  def allowed_patterns
@@ -28,19 +28,16 @@ module RuboCop
28
28
 
29
29
  MSG = 'Avoid modifier `%<keyword>s` after another conditional.'
30
30
 
31
+ # rubocop:disable Metrics/AbcSize
31
32
  def on_if(node)
32
33
  return unless node.modifier_form? && node.body.if_type?
33
34
 
34
35
  add_offense(node.loc.keyword, message: format(MSG, keyword: node.keyword)) do |corrector|
35
- keyword = node.if? ? 'if' : 'unless'
36
-
37
- corrector.replace(node, <<~RUBY.chop)
38
- #{keyword} #{node.condition.source}
39
- #{node.if_branch.source}
40
- end
41
- RUBY
36
+ corrector.wrap(node.if_branch, "#{node.keyword} #{node.condition.source}\n", "\nend")
37
+ corrector.remove(node.if_branch.source_range.end.join(node.condition.source_range.end))
42
38
  end
43
39
  end
40
+ # rubocop:enable Metrics/AbcSize
44
41
  end
45
42
  end
46
43
  end
@@ -10,7 +10,7 @@ module RuboCop
10
10
  # `nonzero?` method is allowed by default.
11
11
  # These are customizable with `AllowedMethods` option.
12
12
  #
13
- # This cop targets only `if`s with a single `elsif` or `else` branch. The following
13
+ # This cop targets only ``if``s with a single `elsif` or `else` branch. The following
14
14
  # code will be allowed, because it has two `elsif` branches:
15
15
  #
16
16
  # [source,ruby]
@@ -67,7 +67,7 @@ module RuboCop
67
67
 
68
68
  # @!method if_with_boolean_literal_branches?(node)
69
69
  def_node_matcher :if_with_boolean_literal_branches?, <<~PATTERN
70
- (if #return_boolean_value? {(true) (false) | (false) (true)})
70
+ (if #return_boolean_value? <true false>)
71
71
  PATTERN
72
72
  # @!method double_negative?(node)
73
73
  def_node_matcher :double_negative?, '(send (send _ :!) :!)'
@@ -155,8 +155,7 @@ module RuboCop
155
155
  end
156
156
 
157
157
  def require_parentheses?(condition)
158
- condition.and_type? || condition.or_type? ||
159
- (condition.send_type? && condition.comparison_method?)
158
+ condition.operator_keyword? || (condition.send_type? && condition.comparison_method?)
160
159
  end
161
160
  end
162
161
  end
@@ -23,6 +23,7 @@ module RuboCop
23
23
 
24
24
  def on_normal_if_unless(node)
25
25
  return if node.parent&.if_type?
26
+ return if part_of_ignored_node?(node)
26
27
 
27
28
  beginning = node.loc.begin
28
29
  return unless beginning&.is?(';')
@@ -32,16 +33,17 @@ module RuboCop
32
33
  add_offense(node, message: message) do |corrector|
33
34
  autocorrect(corrector, node)
34
35
  end
36
+
37
+ ignore_node(node)
35
38
  end
36
39
 
37
40
  private
38
41
 
39
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
40
42
  def message(node)
41
- template = if node.if_branch&.begin_type?
43
+ template = if require_newline?(node)
42
44
  MSG_NEWLINE
43
- elsif node.else_branch&.if_type? || node.else_branch&.begin_type? ||
44
- use_block_in_branches?(node)
45
+ elsif node.else_branch&.type?(:if, :begin) ||
46
+ use_masgn_or_block_in_branches?(node)
45
47
  MSG_IF_ELSE
46
48
  else
47
49
  MSG_TERNARY
@@ -49,18 +51,27 @@ module RuboCop
49
51
 
50
52
  format(template, expr: node.condition.source)
51
53
  end
52
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
53
54
 
54
55
  def autocorrect(corrector, node)
55
- if node.branches.compact.any?(&:begin_type?) || use_block_in_branches?(node)
56
+ if require_newline?(node) || use_masgn_or_block_in_branches?(node)
56
57
  corrector.replace(node.loc.begin, "\n")
57
58
  else
58
59
  corrector.replace(node, replacement(node))
59
60
  end
60
61
  end
61
62
 
62
- def use_block_in_branches?(node)
63
- node.branches.compact.any? { |branch| branch.block_type? || branch.numblock_type? }
63
+ def require_newline?(node)
64
+ node.branches.compact.any?(&:begin_type?) || use_return_with_argument?(node)
65
+ end
66
+
67
+ def use_masgn_or_block_in_branches?(node)
68
+ node.branches.compact.any? do |branch|
69
+ branch.type?(:masgn, :any_block)
70
+ end
71
+ end
72
+
73
+ def use_return_with_argument?(node)
74
+ node.if_branch&.return_type? && node.if_branch&.arguments&.any?
64
75
  end
65
76
 
66
77
  def replacement(node)
@@ -111,7 +122,7 @@ module RuboCop
111
122
  end
112
123
 
113
124
  def require_argument_parentheses?(node)
114
- return false unless node.call_type?
125
+ return false if !node.call_type? || node.arithmetic_operation?
115
126
 
116
127
  !node.parenthesized? && node.arguments.any? && !node.method?(:[]) && !node.method?(:[]=)
117
128
  end
@@ -68,7 +68,7 @@ module RuboCop
68
68
  end
69
69
 
70
70
  def autocorrect(corrector, node)
71
- if node.while_post_type? || node.until_post_type?
71
+ if node.type?(:while_post, :until_post)
72
72
  replace_begin_end_with_modifier(corrector, node)
73
73
  elsif node.modifier_form?
74
74
  replace_source(corrector, node.source_range, modifier_replacement(node))
@@ -41,12 +41,12 @@ module RuboCop
41
41
  # f != 1
42
42
  # end
43
43
  class InverseMethods < Base
44
- include IgnoredNode
45
44
  include RangeHelp
46
45
  extend AutoCorrector
47
46
 
48
47
  MSG = 'Use `%<inverse>s` instead of inverting `%<method>s`.'
49
48
  CLASS_COMPARISON_METHODS = %i[<= >= < >].freeze
49
+ SAFE_NAVIGATION_INCOMPATIBLE_METHODS = (CLASS_COMPARISON_METHODS + %i[any? none?]).freeze
50
50
  EQUALITY_METHODS = %i[== != =~ !~ <= >= < >].freeze
51
51
  NEGATED_EQUALITY_METHODS = %i[!= !~].freeze
52
52
  CAMEL_CASE = /[A-Z]+[a-z]+/.freeze
@@ -61,24 +61,24 @@ module RuboCop
61
61
  def_node_matcher :inverse_candidate?, <<~PATTERN
62
62
  {
63
63
  (send $(call $(...) $_ $...) :!)
64
- (send ({block numblock} $(call $(...) $_) $...) :!)
64
+ (send (any_block $(call $(...) $_) $...) :!)
65
65
  (send (begin $(call $(...) $_ $...)) :!)
66
66
  }
67
67
  PATTERN
68
68
 
69
69
  # @!method inverse_block?(node)
70
70
  def_node_matcher :inverse_block?, <<~PATTERN
71
- ({block numblock} $(call (...) $_) ... { $(call ... :!)
72
- $(send (...) {:!= :!~} ...)
73
- (begin ... $(call ... :!))
74
- (begin ... $(send (...) {:!= :!~} ...))
75
- })
71
+ (any_block $(call (...) $_) ... { $(call ... :!)
72
+ $(send (...) {:!= :!~} ...)
73
+ (begin ... $(call ... :!))
74
+ (begin ... $(send (...) {:!= :!~} ...))
75
+ })
76
76
  PATTERN
77
77
 
78
78
  def on_send(node)
79
79
  inverse_candidate?(node) do |method_call, lhs, method, rhs|
80
80
  return unless inverse_methods.key?(method)
81
- return if negated?(node) || relational_comparison_with_safe_navigation?(method_call)
81
+ return if negated?(node) || safe_navigation_incompatible?(method_call)
82
82
  return if part_of_ignored_node?(node)
83
83
  return if possible_class_hierarchy_check?(lhs, rhs, method)
84
84
 
@@ -106,6 +106,7 @@ module RuboCop
106
106
  end
107
107
 
108
108
  alias on_numblock on_block
109
+ alias on_itblock on_block
109
110
 
110
111
  private
111
112
 
@@ -155,10 +156,6 @@ module RuboCop
155
156
  node.parent.respond_to?(:method?) && node.parent.method?(:!)
156
157
  end
157
158
 
158
- def relational_comparison_with_safe_navigation?(node)
159
- node.csend_type? && CLASS_COMPARISON_METHODS.include?(node.method_name)
160
- end
161
-
162
159
  def not_to_receiver(node, method_call)
163
160
  node.loc.selector.begin.join(method_call.source_range.begin)
164
161
  end
@@ -167,6 +164,12 @@ module RuboCop
167
164
  method_call.source_range.end.join(node.source_range.end)
168
165
  end
169
166
 
167
+ def safe_navigation_incompatible?(node)
168
+ return false unless node.csend_type?
169
+
170
+ SAFE_NAVIGATION_INCOMPATIBLE_METHODS.include?(node.method_name)
171
+ end
172
+
170
173
  # When comparing classes, `!(Integer < Numeric)` is not the same as
171
174
  # `Integer > Numeric`.
172
175
  def possible_class_hierarchy_check?(lhs, rhs, method)
@@ -89,8 +89,8 @@ module RuboCop
89
89
 
90
90
  def inheritance_check?(node)
91
91
  argument = node.first_argument
92
- node.method?(:<) &&
93
- (argument.const_type? && argument.short_name.to_s.upcase != argument.short_name.to_s)
92
+ node.method?(:<) && argument.const_type? &&
93
+ argument.short_name.to_s.upcase != argument.short_name.to_s
94
94
  end
95
95
 
96
96
  def preferred_condition(node)
@@ -32,7 +32,7 @@ module RuboCop
32
32
 
33
33
  # To try to avoid doing two regex checks on every string,
34
34
  # shortcut out if the string does not look like an IP address
35
- return false unless could_be_ip?(contents)
35
+ return false unless potential_ip?(contents)
36
36
 
37
37
  ::Resolv::IPv4::Regex.match?(contents) || ::Resolv::IPv6::Regex.match?(contents)
38
38
  end
@@ -52,7 +52,7 @@ module RuboCop
52
52
  Array(allowed_addresses).map(&:downcase)
53
53
  end
54
54
 
55
- def could_be_ip?(str)
55
+ def potential_ip?(str)
56
56
  # If the string is too long, it can't be an IP
57
57
  return false if too_long?(str)
58
58
 
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for assignments to a local `it` variable inside a block
7
+ # where `it` can refer to the first anonymous parameter as of Ruby 3.4.
8
+ #
9
+ # Although Ruby allows reassigning `it` in these cases, it could
10
+ # cause confusion if `it` is used as a block parameter elsewhere.
11
+ # For consistency, this also applies to numblocks and blocks with
12
+ # parameters, even though `it` cannot be used in those cases.
13
+ #
14
+ # @example
15
+ # # bad
16
+ # foo { it = 5 }
17
+ # foo { |bar| it = bar }
18
+ # foo { it = _2 }
19
+ #
20
+ # # good - use a different variable name
21
+ # foo { var = 5 }
22
+ # foo { |bar| var = bar }
23
+ # foo { bar = _2 }
24
+ class ItAssignment < Base
25
+ MSG = '`it` is the default block parameter; consider another name.'
26
+
27
+ def on_lvasgn(node)
28
+ return unless node.name == :it
29
+ return unless node.each_ancestor(:any_block).any?
30
+
31
+ add_offense(node.loc.name)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for blocks with one argument where `it` block parameter can be used.
7
+ #
8
+ # It provides three `EnforcedStyle` options:
9
+ #
10
+ # 1. `only_numbered_parameters` (default) ... Detects only numbered block parameters.
11
+ # 2. `always` ... Always uses the `it` block parameter.
12
+ # 3. `disallow` ... Disallows the `it` block parameter.
13
+ #
14
+ # A single numbered parameter is detected when `only_numbered_parameters` or `always`.
15
+ #
16
+ # @example EnforcedStyle: only_numbered_parameters (default)
17
+ # # bad
18
+ # block { do_something(_1) }
19
+ #
20
+ # # good
21
+ # block { do_something(it) }
22
+ # block { |named_param| do_something(named_param) }
23
+ #
24
+ # @example EnforcedStyle: always
25
+ # # bad
26
+ # block { do_something(_1) }
27
+ # block { |named_param| do_something(named_param) }
28
+ #
29
+ # # good
30
+ # block { do_something(it) }
31
+ #
32
+ # @example EnforcedStyle: disallow
33
+ # # bad
34
+ # block { do_something(it) }
35
+ #
36
+ # # good
37
+ # block { do_something(_1) }
38
+ # block { |named_param| do_something(named_param) }
39
+ #
40
+ class ItBlockParameter < Base
41
+ include ConfigurableEnforcedStyle
42
+ extend TargetRubyVersion
43
+ extend AutoCorrector
44
+
45
+ MSG_USE_IT_BLOCK_PARAMETER = 'Use `it` block parameter.'
46
+ MSG_AVOID_IT_BLOCK_PARAMETER = 'Avoid using `it` block parameter.'
47
+
48
+ minimum_target_ruby_version 3.4
49
+
50
+ def on_block(node)
51
+ return unless style == :always
52
+ return unless node.arguments.one?
53
+
54
+ # `restarg`, `kwrestarg`, `blockarg` nodes can return early.
55
+ return unless node.first_argument.arg_type?
56
+
57
+ variables = find_block_variables(node, node.first_argument.source)
58
+
59
+ variables.each do |variable|
60
+ add_offense(variable, message: MSG_USE_IT_BLOCK_PARAMETER) do |corrector|
61
+ corrector.remove(node.arguments)
62
+ corrector.replace(variable, 'it')
63
+ end
64
+ end
65
+ end
66
+
67
+ def on_numblock(node)
68
+ return if style == :disallow
69
+ return unless node.children[1] == 1
70
+
71
+ variables = find_block_variables(node, '_1')
72
+
73
+ variables.each do |variable|
74
+ add_offense(variable, message: MSG_USE_IT_BLOCK_PARAMETER) do |corrector|
75
+ corrector.replace(variable, 'it')
76
+ end
77
+ end
78
+ end
79
+
80
+ def on_itblock(node)
81
+ return unless style == :disallow
82
+
83
+ variables = find_block_variables(node, 'it')
84
+
85
+ variables.each do |variable|
86
+ add_offense(variable, message: MSG_AVOID_IT_BLOCK_PARAMETER)
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ def find_block_variables(node, block_argument_name)
93
+ node.each_descendant(:lvar).select do |descendant|
94
+ descendant.source == block_argument_name
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end