rubocop 1.69.0 → 1.79.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +290 -65
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +8 -3
  7. data/lib/rubocop/cli/command/execute_runner.rb +3 -3
  8. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  9. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  10. data/lib/rubocop/cli.rb +13 -2
  11. data/lib/rubocop/comment_config.rb +2 -2
  12. data/lib/rubocop/config.rb +52 -10
  13. data/lib/rubocop/config_loader.rb +53 -47
  14. data/lib/rubocop/config_loader_resolver.rb +36 -10
  15. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  16. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  17. data/lib/rubocop/config_obsoletion.rb +46 -2
  18. data/lib/rubocop/config_validator.rb +25 -14
  19. data/lib/rubocop/cop/autocorrect_logic.rb +44 -39
  20. data/lib/rubocop/cop/base.rb +6 -0
  21. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  22. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  23. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  24. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  25. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  26. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
  27. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  28. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  29. data/lib/rubocop/cop/generator.rb +6 -0
  30. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  31. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  32. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  33. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  34. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  35. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  36. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
  37. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  38. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  39. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +231 -0
  40. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  41. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  42. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  43. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  44. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +4 -2
  45. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  46. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  47. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  48. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  49. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  50. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  51. data/lib/rubocop/cop/internal_affairs.rb +6 -16
  52. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  53. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -8
  54. data/lib/rubocop/cop/layout/block_alignment.rb +3 -1
  55. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  56. data/lib/rubocop/cop/layout/class_structure.rb +44 -9
  57. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  58. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  59. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  60. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  61. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
  62. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  63. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  64. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +35 -4
  65. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  66. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  67. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  68. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
  69. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
  70. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
  71. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  72. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  73. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  74. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  75. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  76. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  77. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  78. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  79. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  80. data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
  81. data/lib/rubocop/cop/layout/leading_comment_space.rb +13 -1
  82. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  83. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  84. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  85. data/lib/rubocop/cop/layout/line_length.rb +35 -9
  86. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  87. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  88. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  89. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -0
  90. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  91. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  92. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +1 -1
  93. data/lib/rubocop/cop/layout/redundant_line_break.rb +16 -11
  94. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -5
  95. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  96. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  97. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  98. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  99. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  100. data/lib/rubocop/cop/layout/space_around_keyword.rb +7 -1
  101. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  102. data/lib/rubocop/cop/layout/space_around_operators.rb +15 -4
  103. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  104. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -38
  105. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  106. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  107. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +12 -3
  108. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
  109. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
  110. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  111. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  112. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  113. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  114. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  115. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -3
  116. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  117. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -3
  118. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  119. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  120. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  121. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  122. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  123. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
  124. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  125. data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
  126. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  127. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  128. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  129. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  130. data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
  131. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  132. data/lib/rubocop/cop/lint/float_comparison.rb +37 -12
  133. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
  134. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  135. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  136. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  137. data/lib/rubocop/cop/lint/literal_as_condition.rb +125 -10
  138. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  139. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  140. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  141. data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -3
  142. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  143. data/lib/rubocop/cop/lint/nested_method_definition.rb +9 -5
  144. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  145. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +4 -2
  146. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  147. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  148. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +19 -31
  149. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
  150. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -1
  151. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  152. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  153. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
  154. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  155. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +101 -2
  156. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  157. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  158. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  159. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  160. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  161. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  162. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  163. data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
  164. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  165. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -1
  166. data/lib/rubocop/cop/lint/self_assignment.rb +25 -0
  167. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  168. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  169. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  170. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  171. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  172. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  173. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  174. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  175. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -1
  176. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  177. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  178. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  179. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  180. data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
  181. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  182. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  183. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  184. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  185. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  186. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +3 -1
  187. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  188. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
  189. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
  190. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  191. data/lib/rubocop/cop/lint/void.rb +14 -11
  192. data/lib/rubocop/cop/message_annotator.rb +7 -3
  193. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  194. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  195. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  196. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  197. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  198. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
  199. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  200. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  201. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  202. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
  203. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  204. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  205. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  206. data/lib/rubocop/cop/mixin/check_line_breakable.rb +13 -13
  207. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
  208. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  209. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  210. data/lib/rubocop/cop/mixin/dig_help.rb +1 -1
  211. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  212. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  213. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  214. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -2
  215. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  216. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  217. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  218. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  219. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  220. data/lib/rubocop/cop/mixin/line_length_help.rb +27 -10
  221. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  222. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -0
  223. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  224. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  225. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  226. data/lib/rubocop/cop/mixin/range_help.rb +15 -3
  227. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  228. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  229. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  230. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  231. data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
  232. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  233. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  234. data/lib/rubocop/cop/naming/block_forwarding.rb +19 -15
  235. data/lib/rubocop/cop/naming/file_name.rb +2 -2
  236. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  237. data/lib/rubocop/cop/naming/method_name.rb +185 -15
  238. data/lib/rubocop/cop/naming/predicate_method.rb +306 -0
  239. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
  240. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +4 -4
  241. data/lib/rubocop/cop/naming/variable_name.rb +51 -6
  242. data/lib/rubocop/cop/registry.rb +9 -6
  243. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  244. data/lib/rubocop/cop/security/eval.rb +2 -1
  245. data/lib/rubocop/cop/security/open.rb +1 -0
  246. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  247. data/lib/rubocop/cop/style/access_modifier_declarations.rb +66 -15
  248. data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
  249. data/lib/rubocop/cop/style/and_or.rb +1 -1
  250. data/lib/rubocop/cop/style/arguments_forwarding.rb +57 -44
  251. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  252. data/lib/rubocop/cop/style/array_intersect.rb +81 -40
  253. data/lib/rubocop/cop/style/block_delimiters.rb +27 -24
  254. data/lib/rubocop/cop/style/case_like_if.rb +1 -1
  255. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  256. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  257. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  258. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  259. data/lib/rubocop/cop/style/combinable_defined.rb +1 -1
  260. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  261. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  262. data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
  263. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  264. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  265. data/lib/rubocop/cop/style/conditional_assignment.rb +23 -7
  266. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  267. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  268. data/lib/rubocop/cop/style/dig_chain.rb +6 -7
  269. data/lib/rubocop/cop/style/documentation.rb +1 -1
  270. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  271. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  272. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  273. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  274. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  275. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  276. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  277. data/lib/rubocop/cop/style/endless_method.rb +163 -18
  278. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  279. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  280. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  281. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  282. data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
  283. data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
  284. data/lib/rubocop/cop/style/file_null.rb +20 -4
  285. data/lib/rubocop/cop/style/float_division.rb +8 -4
  286. data/lib/rubocop/cop/style/for.rb +1 -0
  287. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  288. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  289. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  290. data/lib/rubocop/cop/style/guard_clause.rb +2 -1
  291. data/lib/rubocop/cop/style/hash_conversion.rb +16 -8
  292. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  293. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  294. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  295. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  296. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  297. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  298. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  299. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  300. data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
  301. data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
  302. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  303. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -2
  304. data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
  305. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  306. data/lib/rubocop/cop/style/inverse_methods.rb +16 -12
  307. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  308. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  309. data/lib/rubocop/cop/style/it_assignment.rb +93 -0
  310. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  311. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  312. data/lib/rubocop/cop/style/lambda.rb +1 -0
  313. data/lib/rubocop/cop/style/lambda_call.rb +10 -3
  314. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  315. data/lib/rubocop/cop/style/map_into_array.rb +5 -2
  316. data/lib/rubocop/cop/style/map_to_hash.rb +13 -4
  317. data/lib/rubocop/cop/style/map_to_set.rb +4 -5
  318. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +27 -19
  319. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +18 -0
  320. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +3 -2
  321. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  322. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  323. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  324. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  325. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  326. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  327. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  328. data/lib/rubocop/cop/style/multiple_comparison.rb +34 -22
  329. data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
  330. data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -1
  331. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  332. data/lib/rubocop/cop/style/next.rb +44 -0
  333. data/lib/rubocop/cop/style/object_then.rb +15 -15
  334. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  335. data/lib/rubocop/cop/style/parallel_assignment.rb +33 -25
  336. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  337. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  338. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  339. data/lib/rubocop/cop/style/proc.rb +2 -2
  340. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  341. data/lib/rubocop/cop/style/raise_args.rb +14 -12
  342. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  343. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  344. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  345. data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
  346. data/lib/rubocop/cop/style/redundant_condition.rb +59 -2
  347. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  348. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  349. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  350. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  351. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
  352. data/lib/rubocop/cop/style/redundant_format.rb +262 -0
  353. data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
  354. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  355. data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
  356. data/lib/rubocop/cop/style/redundant_line_continuation.rb +39 -22
  357. data/lib/rubocop/cop/style/redundant_parentheses.rb +85 -17
  358. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +3 -0
  359. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  360. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  361. data/lib/rubocop/cop/style/redundant_self.rb +10 -6
  362. data/lib/rubocop/cop/style/redundant_self_assignment.rb +14 -28
  363. data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
  364. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  365. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  366. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  367. data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
  368. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  369. data/lib/rubocop/cop/style/safe_navigation.rb +46 -16
  370. data/lib/rubocop/cop/style/select_by_regexp.rb +4 -1
  371. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  372. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  373. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  374. data/lib/rubocop/cop/style/single_line_do_end_block.rb +4 -3
  375. data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
  376. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  377. data/lib/rubocop/cop/style/sole_nested_conditional.rb +68 -101
  378. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  379. data/lib/rubocop/cop/style/string_concatenation.rb +15 -14
  380. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  381. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  382. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  383. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  384. data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
  385. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  386. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  387. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  388. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  389. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  390. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  391. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  392. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  393. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  394. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  395. data/lib/rubocop/cop/team.rb +1 -1
  396. data/lib/rubocop/cop/util.rb +12 -5
  397. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  398. data/lib/rubocop/cop/variable_force/assignment.rb +7 -3
  399. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  400. data/lib/rubocop/cop/variable_force/variable.rb +10 -3
  401. data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
  402. data/lib/rubocop/cop/variable_force.rb +23 -8
  403. data/lib/rubocop/cops_documentation_generator.rb +32 -16
  404. data/lib/rubocop/directive_comment.rb +45 -11
  405. data/lib/rubocop/ext/regexp_node.rb +0 -1
  406. data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
  407. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  408. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  409. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  410. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  411. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  412. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  413. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  414. data/lib/rubocop/lsp/logger.rb +2 -2
  415. data/lib/rubocop/lsp/routes.rb +10 -26
  416. data/lib/rubocop/lsp/runtime.rb +18 -50
  417. data/lib/rubocop/lsp/server.rb +0 -2
  418. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  419. data/lib/rubocop/magic_comment.rb +11 -3
  420. data/lib/rubocop/options.rb +28 -12
  421. data/lib/rubocop/path_util.rb +15 -8
  422. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  423. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  424. data/lib/rubocop/plugin/load_error.rb +26 -0
  425. data/lib/rubocop/plugin/loader.rb +100 -0
  426. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  427. data/lib/rubocop/plugin.rb +46 -0
  428. data/lib/rubocop/rake_task.rb +4 -1
  429. data/lib/rubocop/result_cache.rb +26 -24
  430. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  431. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  432. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  433. data/lib/rubocop/rspec/support.rb +4 -2
  434. data/lib/rubocop/runner.rb +10 -7
  435. data/lib/rubocop/server/cache.rb +51 -13
  436. data/lib/rubocop/server/cli.rb +2 -2
  437. data/lib/rubocop/server/client_command/base.rb +10 -0
  438. data/lib/rubocop/server/client_command/exec.rb +2 -1
  439. data/lib/rubocop/server/client_command/start.rb +11 -1
  440. data/lib/rubocop/target_finder.rb +7 -2
  441. data/lib/rubocop/target_ruby.rb +16 -1
  442. data/lib/rubocop/version.rb +30 -8
  443. data/lib/rubocop.rb +27 -2
  444. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  445. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  446. metadata +72 -19
  447. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  448. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -144,6 +144,8 @@ module RuboCop
144
144
  end
145
145
 
146
146
  def autocorrect(corrector, node)
147
+ node = node.ancestors.find { |ancestor| ancestor.loc.end } unless node.loc.end
148
+
147
149
  case empty_else_style
148
150
  when :empty
149
151
  corrector.insert_before(node.loc.end, 'else; nil; ')
@@ -28,10 +28,10 @@ module RuboCop
28
28
  MSG = 'Avoid multi-line chains of blocks.'
29
29
 
30
30
  def on_block(node)
31
- node.send_node.each_node(:send, :csend) do |send_node|
31
+ node.send_node.each_node(:call) do |send_node|
32
32
  receiver = send_node.receiver
33
33
 
34
- next unless (receiver&.block_type? || receiver&.numblock_type?) && receiver&.multiline?
34
+ next unless receiver&.any_block_type? && receiver.multiline?
35
35
 
36
36
  range = range_between(receiver.loc.end.begin_pos, node.send_node.source_range.end_pos)
37
37
 
@@ -44,6 +44,7 @@ module RuboCop
44
44
  end
45
45
 
46
46
  alias on_numblock on_block
47
+ alias on_itblock on_block
47
48
  end
48
49
  end
49
50
  end
@@ -23,11 +23,13 @@ module RuboCop
23
23
  'clause in a multiline statement.'
24
24
 
25
25
  def on_if(node)
26
+ return if part_of_ignored_node?(node)
26
27
  return unless node.modifier_form? && node.body.multiline?
27
28
 
28
29
  add_offense(node, message: format(MSG, keyword: node.keyword)) do |corrector|
29
30
  corrector.replace(node, to_normal_if(node))
30
31
  end
32
+ ignore_node(node)
31
33
  end
32
34
 
33
35
  private
@@ -50,7 +50,7 @@ module RuboCop
50
50
  corrector.remove(range_by_whole_lines(arguments.loc.end, include_final_newline: true))
51
51
  end
52
52
 
53
- arguments_range = arguments_range(node)
53
+ arguments_range = range_with_surrounding_space(arguments_range(node), side: :left)
54
54
  # If the method name isn't on the same line as def, move it directly after def
55
55
  if arguments_range.first_line != opening_line(node)
56
56
  corrector.remove(node.loc.name)
@@ -66,14 +66,6 @@ module RuboCop
66
66
  processed_source[arguments.last_line - 1].strip
67
67
  end
68
68
 
69
- def arguments_range(node)
70
- range = range_between(
71
- node.first_argument.source_range.begin_pos, node.last_argument.source_range.end_pos
72
- )
73
-
74
- range_with_surrounding_space(range, side: :left)
75
- end
76
-
77
69
  def opening_line(node)
78
70
  node.first_line
79
71
  end
@@ -55,6 +55,22 @@ module RuboCop
55
55
  MSG = 'Avoid comparing a variable with multiple items ' \
56
56
  'in a conditional, use `Array#include?` instead.'
57
57
 
58
+ # @!method simple_double_comparison?(node)
59
+ def_node_matcher :simple_double_comparison?, <<~PATTERN
60
+ (send lvar :== lvar)
61
+ PATTERN
62
+
63
+ # @!method simple_comparison_lhs(node)
64
+ def_node_matcher :simple_comparison_lhs, <<~PATTERN
65
+ (send ${lvar call} :== $_)
66
+ PATTERN
67
+
68
+ # @!method simple_comparison_rhs(node)
69
+ def_node_matcher :simple_comparison_rhs, <<~PATTERN
70
+ (send $_ :== ${lvar call})
71
+ PATTERN
72
+
73
+ # rubocop:disable Metrics/AbcSize
58
74
  def on_or(node)
59
75
  root_of_or_node = root_of_or_node(node)
60
76
  return unless node == root_of_or_node
@@ -63,29 +79,20 @@ module RuboCop
63
79
  return unless (variable, values = find_offending_var(node))
64
80
  return if values.size < comparisons_threshold
65
81
 
66
- add_offense(node) do |corrector|
82
+ range = offense_range(values)
83
+
84
+ add_offense(range) do |corrector|
67
85
  elements = values.map(&:source).join(', ')
68
- prefer_method = "[#{elements}].include?(#{variable_name(variable)})"
86
+ argument = variable.lvar_type? ? variable_name(variable) : variable.source
87
+ prefer_method = "[#{elements}].include?(#{argument})"
69
88
 
70
- corrector.replace(node, prefer_method)
89
+ corrector.replace(range, prefer_method)
71
90
  end
72
91
  end
92
+ # rubocop:enable Metrics/AbcSize
73
93
 
74
94
  private
75
95
 
76
- # @!method simple_double_comparison?(node)
77
- def_node_matcher :simple_double_comparison?, '(send $lvar :== $lvar)'
78
-
79
- # @!method simple_comparison_lhs?(node)
80
- def_node_matcher :simple_comparison_lhs?, <<~PATTERN
81
- (send $lvar :== $_)
82
- PATTERN
83
-
84
- # @!method simple_comparison_rhs?(node)
85
- def_node_matcher :simple_comparison_rhs?, <<~PATTERN
86
- (send $_ :== $lvar)
87
- PATTERN
88
-
89
96
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
90
97
  def find_offending_var(node, variables = Set.new, values = [])
91
98
  if node.or_type?
@@ -93,8 +100,8 @@ module RuboCop
93
100
  find_offending_var(node.rhs, variables, values)
94
101
  elsif simple_double_comparison?(node)
95
102
  return
96
- elsif (var, obj = simple_comparison?(node))
97
- return if allow_method_comparison? && obj.send_type?
103
+ elsif (var, obj = simple_comparison(node))
104
+ return if allow_method_comparison? && obj.call_type?
98
105
 
99
106
  variables << var
100
107
  return if variables.size > 1
@@ -106,6 +113,10 @@ module RuboCop
106
113
  end
107
114
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
108
115
 
116
+ def offense_range(values)
117
+ values.first.parent.source_range.begin.join(values.last.parent.source_range.end)
118
+ end
119
+
109
120
  def variable_name(node)
110
121
  node.children[0]
111
122
  end
@@ -119,12 +130,13 @@ module RuboCop
119
130
  end
120
131
 
121
132
  def comparison?(node)
122
- simple_comparison?(node) || nested_comparison?(node)
133
+ !!simple_comparison(node) || nested_comparison?(node)
123
134
  end
124
135
 
125
- def simple_comparison?(node)
126
- if (var, obj = simple_comparison_lhs?(node)) ||
127
- (obj, var = simple_comparison_rhs?(node))
136
+ def simple_comparison(node)
137
+ if (var, obj = simple_comparison_lhs(node)) || (obj, var = simple_comparison_rhs(node))
138
+ return if var.call_type? && !allow_method_comparison?
139
+
128
140
  [var, obj]
129
141
  end
130
142
  end
@@ -19,7 +19,7 @@ module RuboCop
19
19
  # acceptable value other than none, it will suppress the offenses
20
20
  # raised by this cop. It enforces frozen state.
21
21
  #
22
- # NOTE: Regexp and Range literals are frozen objects since Ruby 3.0.
22
+ # NOTE: `Regexp` and `Range` literals are frozen objects since Ruby 3.0.
23
23
  #
24
24
  # NOTE: From Ruby 3.0, interpolated strings are not frozen when
25
25
  # `# frozen-string-literal: true` is used, so this cop enforces explicit
@@ -197,7 +197,7 @@ module RuboCop
197
197
  end
198
198
 
199
199
  def frozen_regexp_or_range_literals?(node)
200
- target_ruby_version >= 3.0 && (node.regexp_type? || node.range_type?)
200
+ target_ruby_version >= 3.0 && node.type?(:regexp, :range)
201
201
  end
202
202
 
203
203
  def requires_parentheses?(node)
@@ -238,7 +238,7 @@ module RuboCop
238
238
 
239
239
  # @!method range_enclosed_in_parentheses?(node)
240
240
  def_node_matcher :range_enclosed_in_parentheses?, <<~PATTERN
241
- (begin ({irange erange} _ _))
241
+ (begin (range _ _))
242
242
  PATTERN
243
243
  end
244
244
  end
@@ -74,7 +74,7 @@ module RuboCop
74
74
  end
75
75
 
76
76
  def unwrap_begin_nodes(node)
77
- node = node.children.first while node && (node.begin_type? || node.kwbegin_type?)
77
+ node = node.children.first while node&.type?(:begin, :kwbegin)
78
78
 
79
79
  node
80
80
  end
@@ -35,7 +35,7 @@ module RuboCop
35
35
  def on_send(node)
36
36
  return unless node.parenthesized?
37
37
 
38
- node.each_child_node(:send, :csend) do |nested|
38
+ node.each_child_node(:call) do |nested|
39
39
  next if allowed_omission?(nested)
40
40
 
41
41
  message = format(MSG, source: nested.source)
@@ -46,6 +46,38 @@ module RuboCop
46
46
  # next unless a == 1
47
47
  # puts a
48
48
  # end
49
+ #
50
+ # @example AllowConsecutiveConditionals: false (default)
51
+ # # bad
52
+ # [1, 2].each do |a|
53
+ # if a == 1
54
+ # puts a
55
+ # end
56
+ # if a == 2
57
+ # puts a
58
+ # end
59
+ # end
60
+ #
61
+ # # good
62
+ # [1, 2].each do |a|
63
+ # if a == 1
64
+ # puts a
65
+ # end
66
+ # next unless a == 2
67
+ # puts a
68
+ # end
69
+ #
70
+ # @example AllowConsecutiveConditionals: true
71
+ # # good
72
+ # [1, 2].each do |a|
73
+ # if a == 1
74
+ # puts a
75
+ # end
76
+ # if a == 2
77
+ # puts a
78
+ # end
79
+ # end
80
+ #
49
81
  class Next < Base
50
82
  include ConfigurableEnforcedStyle
51
83
  include MinBodyLength
@@ -72,6 +104,7 @@ module RuboCop
72
104
  end
73
105
 
74
106
  alias on_numblock on_block
107
+ alias on_itblock on_block
75
108
 
76
109
  def on_while(node)
77
110
  check(node)
@@ -86,6 +119,9 @@ module RuboCop
86
119
 
87
120
  offending_node = offense_node(node.body)
88
121
 
122
+ return if allowed_consecutive_conditionals? &&
123
+ consecutive_conditionals?(offending_node)
124
+
89
125
  add_offense(offense_location(offending_node)) do |corrector|
90
126
  if offending_node.modifier_form?
91
127
  autocorrect_modifier(corrector, offending_node)
@@ -227,6 +263,14 @@ module RuboCop
227
263
 
228
264
  corrector.remove_leading(buffer.line_range(lineno), adjustment) if adjustment.positive?
229
265
  end
266
+
267
+ def consecutive_conditionals?(if_node)
268
+ if_node.parent&.begin_type? && if_node.left_sibling&.if_type?
269
+ end
270
+
271
+ def allowed_consecutive_conditionals?
272
+ cop_config.fetch('AllowConsecutiveConditionals', false)
273
+ end
230
274
  end
231
275
  end
232
276
  end
@@ -30,41 +30,41 @@ module RuboCop
30
30
  minimum_target_ruby_version 2.6
31
31
 
32
32
  MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
33
+ RESTRICT_ON_SEND = %i[then yield_self].freeze
33
34
 
34
35
  def on_block(node)
36
+ return unless RESTRICT_ON_SEND.include?(node.method_name)
37
+
35
38
  check_method_node(node.send_node)
36
39
  end
37
-
38
40
  alias on_numblock on_block
41
+ alias on_itblock on_block
39
42
 
40
43
  def on_send(node)
41
44
  return unless node.arguments.one? && node.first_argument.block_pass_type?
42
45
 
43
46
  check_method_node(node)
44
47
  end
48
+ alias on_csend on_send
45
49
 
46
50
  private
47
51
 
48
52
  def check_method_node(node)
49
- return unless preferred_method?(node)
50
-
51
- message = message(node)
52
- add_offense(node.loc.selector, message: message) do |corrector|
53
- prefer = style == :then && node.receiver.nil? ? 'self.then' : style
53
+ if preferred_method?(node)
54
+ correct_style_detected
55
+ else
56
+ opposite_style_detected
57
+ message = message(node)
58
+ add_offense(node.loc.selector, message: message) do |corrector|
59
+ prefer = style == :then && node.receiver.nil? ? 'self.then' : style
54
60
 
55
- corrector.replace(node.loc.selector, prefer)
61
+ corrector.replace(node.loc.selector, prefer)
62
+ end
56
63
  end
57
64
  end
58
65
 
59
66
  def preferred_method?(node)
60
- case style
61
- when :then
62
- node.method?(:yield_self)
63
- when :yield_self
64
- node.method?(:then)
65
- else
66
- false
67
- end
67
+ node.method?(style)
68
68
  end
69
69
 
70
70
  def message(node)
@@ -3,15 +3,15 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Flags uses of OpenStruct, as it is now officially discouraged
6
+ # Flags uses of `OpenStruct`, as it is now officially discouraged
7
7
  # to be used for performance, version compatibility, and potential security issues.
8
8
  #
9
9
  # @safety
10
- #
11
10
  # Note that this cop may flag false positives; for instance, the following legal
12
11
  # use of a hand-rolled `OpenStruct` type would be considered an offense:
13
12
  #
14
- # ```
13
+ # [source,ruby]
14
+ # -----
15
15
  # module MyNamespace
16
16
  # class OpenStruct # not the OpenStruct we're looking for
17
17
  # end
@@ -20,7 +20,7 @@ module RuboCop
20
20
  # OpenStruct.new # resolves to MyNamespace::OpenStruct
21
21
  # end
22
22
  # end
23
- # ```
23
+ # -----
24
24
  #
25
25
  # @example
26
26
  #
@@ -61,7 +61,7 @@ module RuboCop
61
61
  def custom_class_or_module_definition?(node)
62
62
  parent = node.parent
63
63
 
64
- (parent.class_type? || parent.module_type?) && node.left_siblings.empty?
64
+ parent.type?(:class, :module) && node.left_siblings.empty?
65
65
  end
66
66
  end
67
67
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'tsort'
4
-
5
3
  module RuboCop
6
4
  module Cop
7
5
  module Style
@@ -29,6 +27,8 @@ module RuboCop
29
27
  MSG = 'Do not use parallel assignment.'
30
28
 
31
29
  def on_masgn(node) # rubocop:disable Metrics/AbcSize
30
+ return if part_of_ignored_node?(node)
31
+
32
32
  rhs = node.rhs
33
33
  rhs = rhs.body if rhs.rescue_type?
34
34
  rhs_elements = Array(rhs).compact # edge case for one constant
@@ -41,6 +41,7 @@ module RuboCop
41
41
  add_offense(range) do |corrector|
42
42
  autocorrect(corrector, node, rhs)
43
43
  end
44
+ ignore_node(node)
44
45
  end
45
46
 
46
47
  private
@@ -69,11 +70,7 @@ module RuboCop
69
70
  elements = Array(node).compact
70
71
 
71
72
  # Account for edge case of `Constant::CONSTANT`
72
- !node.array_type? || return_of_method_call?(node) || elements.any?(&:splat_type?)
73
- end
74
-
75
- def return_of_method_call?(node)
76
- node.block_type? || node.send_type?
73
+ !node.array_type? || elements.any?(&:splat_type?)
77
74
  end
78
75
 
79
76
  def assignment_corrector(node, rhs, order)
@@ -95,15 +92,9 @@ module RuboCop
95
92
  def find_valid_order(left_elements, right_elements)
96
93
  # arrange left_elements in an order such that no corresponding right
97
94
  # element refers to a left element earlier in the sequence
98
- # this can be done using an algorithm called a "topological sort"
99
- # fortunately for us, Ruby's stdlib contains an implementation
100
95
  assignments = left_elements.zip(right_elements)
101
96
 
102
- begin
103
- AssignmentSorter.new(assignments).tsort
104
- rescue TSort::Cyclic
105
- nil
106
- end
97
+ AssignmentSorter.new(assignments).tsort
107
98
  end
108
99
 
109
100
  # Converts (send nil :something) nodes to (send (:self) :something).
@@ -118,10 +109,9 @@ module RuboCop
118
109
  # @!method implicit_self_getter?(node)
119
110
  def_node_matcher :implicit_self_getter?, '(send nil? $_)'
120
111
 
121
- # Helper class necessitated by silly design of TSort prior to Ruby 2.1
122
- # Newer versions have a better API, but that doesn't help us
112
+ # Topologically sorts the assignments with Kahn's algorithm.
113
+ # https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm
123
114
  class AssignmentSorter
124
- include TSort
125
115
  extend RuboCop::NodePattern::Macros
126
116
 
127
117
  # @!method var_name(node)
@@ -137,21 +127,39 @@ module RuboCop
137
127
  @assignments = assignments
138
128
  end
139
129
 
140
- def tsort_each_node(...)
141
- @assignments.each(...)
130
+ def tsort
131
+ dependencies = @assignments.to_h do |assignment|
132
+ [assignment, dependencies_for_assignment(assignment)]
133
+ end
134
+ result = []
135
+
136
+ while (matched_node, = dependencies.find { |_node, edges| edges.empty? })
137
+ dependencies.delete(matched_node)
138
+ result.push(matched_node)
139
+
140
+ dependencies.each do |node, edges|
141
+ dependencies[node].delete(matched_node) if edges.include?(matched_node)
142
+ end
143
+ end
144
+ # Cyclic dependency
145
+ return nil if dependencies.any?
146
+
147
+ result
142
148
  end
143
149
 
144
- def tsort_each_child(assignment)
145
- # yield all the assignments which must come after `assignment`
146
- # (due to dependencies on the previous value of the assigned var)
150
+ # Returns all the assignments which must come after `assignment`
151
+ # (due to dependencies on the previous value of the assigned var)
152
+ def dependencies_for_assignment(assignment)
147
153
  my_lhs, _my_rhs = *assignment
148
154
 
149
- @assignments.each do |other|
150
- _other_lhs, other_rhs = *other
155
+ @assignments.filter_map do |other|
156
+ # Exclude self, there are no dependencies in cases such as `a, b = a, b`.
157
+ next if other == assignment
151
158
 
159
+ _other_lhs, other_rhs = *other
152
160
  next unless dependency?(my_lhs, other_rhs)
153
161
 
154
- yield other
162
+ other
155
163
  end
156
164
  end
157
165
 
@@ -94,8 +94,8 @@ module RuboCop
94
94
  end
95
95
 
96
96
  def require_parentheses?(node, condition_body)
97
- return false if !node.while_type? && !node.until_type?
98
- return false if !condition_body.block_type? && !condition_body.numblock_type?
97
+ return false unless node.type?(:while, :until)
98
+ return false unless condition_body.any_block_type?
99
99
 
100
100
  condition_body.send_node.block_literal? && condition_body.keywords?
101
101
  end
@@ -99,7 +99,7 @@ module RuboCop
99
99
  def string_source(node)
100
100
  if node.is_a?(String)
101
101
  node.scrub
102
- elsif node.respond_to?(:type) && (node.str_type? || node.sym_type?)
102
+ elsif node.respond_to?(:type) && node.type?(:str, :sym)
103
103
  node.source
104
104
  end
105
105
  end
@@ -45,7 +45,7 @@ module RuboCop
45
45
  # Report offense only if changing case doesn't change semantics,
46
46
  # i.e., if the string would become dynamic or has special characters.
47
47
  ast = parse(corrected(node.source)).ast
48
- return if node.children != ast.children
48
+ return if node.children != ast&.children
49
49
 
50
50
  add_offense(node.loc.begin) do |corrector|
51
51
  corrector.replace(node, corrected(node.source))
@@ -19,8 +19,7 @@ module RuboCop
19
19
  MSG = 'Use `proc` instead of `Proc.new`.'
20
20
 
21
21
  # @!method proc_new?(node)
22
- def_node_matcher :proc_new?,
23
- '({block numblock} $(send (const {nil? cbase} :Proc) :new) ...)'
22
+ def_node_matcher :proc_new?, '(any_block $(send (const {nil? cbase} :Proc) :new) ...)'
24
23
 
25
24
  def on_block(node)
26
25
  proc_new?(node) do |block_method|
@@ -31,6 +30,7 @@ module RuboCop
31
30
  end
32
31
 
33
32
  alias on_numblock on_block
33
+ alias on_itblock on_block
34
34
  end
35
35
  end
36
36
  end
@@ -98,7 +98,7 @@ module RuboCop
98
98
 
99
99
  def style
100
100
  return super unless super == :same_as_string_literals
101
- return :single_quotes unless string_literals_config['Enabled']
101
+ return :single_quotes unless config.cop_enabled?('Style/StringLiterals')
102
102
 
103
103
  string_literals_config['EnforcedStyle'].to_sym
104
104
  end
@@ -3,18 +3,18 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks the args passed to `fail` and `raise`. For exploded
7
- # style (default), it recommends passing the exception class and message
8
- # to `raise`, rather than construct an instance of the error. It will
9
- # still allow passing just a message, or the construction of an error
10
- # with more than one argument.
6
+ # Checks the args passed to `fail` and `raise`.
11
7
  #
12
- # The exploded style works identically, but with the addition that it
13
- # will also suggest constructing error objects when the exception is
14
- # passed multiple arguments.
8
+ # Exploded style (default) enforces passing the exception class and message
9
+ # arguments separately, rather than constructing an instance of the error.
10
+ #
11
+ # Compact style enforces constructing an error instance.
12
+ #
13
+ # Both styles allow passing just a message, or an error instance when there is more
14
+ # than one argument.
15
15
  #
16
16
  # The exploded style has an `AllowedCompactTypes` configuration
17
- # option that takes an Array of exception name Strings.
17
+ # option that takes an `Array` of exception name Strings.
18
18
  #
19
19
  # @safety
20
20
  # This cop is unsafe because `raise Foo` calls `Foo.exception`, not `Foo.new`.
@@ -50,6 +50,9 @@ module RuboCop
50
50
 
51
51
  EXPLODED_MSG = 'Provide an exception class and message as arguments to `%<method>s`.'
52
52
  COMPACT_MSG = 'Provide an exception object as an argument to `%<method>s`.'
53
+ ACCEPTABLE_ARG_TYPES = %i[
54
+ hash forwarded_restarg splat forwarded_restarg forwarded_args
55
+ ].freeze
53
56
 
54
57
  RESTRICT_ON_SEND = %i[raise fail].freeze
55
58
 
@@ -138,9 +141,8 @@ module RuboCop
138
141
 
139
142
  arg = args.first
140
143
 
141
- # Allow code like `raise Ex.new(kw: arg)`.
142
- # Allow code like `raise Ex.new(*args)`.
143
- arg.hash_type? || arg.splat_type?
144
+ # Allow nodes that may forward more than one argument
145
+ ACCEPTABLE_ARG_TYPES.include?(arg.type)
144
146
  end
145
147
 
146
148
  def allowed_non_exploded_type?(arg)
@@ -36,7 +36,7 @@ module RuboCop
36
36
  (send
37
37
  {nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
38
38
  :rand
39
- {int (irange int int) (erange int int)}))
39
+ {int (range int int)}))
40
40
  PATTERN
41
41
 
42
42
  # @!method rand_op_integer?(node)
@@ -45,7 +45,7 @@ module RuboCop
45
45
  (send
46
46
  {nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
47
47
  :rand
48
- {int (irange int int) (erange int int)})
48
+ {int (range int int)})
49
49
  {:+ :-}
50
50
  int)
51
51
  PATTERN
@@ -56,7 +56,7 @@ module RuboCop
56
56
  (send
57
57
  {nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
58
58
  :rand
59
- {int (irange int int) (erange int int)})
59
+ {int (range int int)})
60
60
  {:succ :pred :next})
61
61
  PATTERN
62
62
 
@@ -118,7 +118,9 @@ module RuboCop
118
118
  end
119
119
 
120
120
  def exclude_cntrl_character?(target_argument, redundant_argument)
121
- !target_argument.to_s.sub(/\A'/, '"').sub(/'\z/, '"').match?(/[[:cntrl:]]/) ||
121
+ return true unless (target_argument_string = target_argument.to_s).valid_encoding?
122
+
123
+ !target_argument_string.sub(/\A'/, '"').sub(/'\z/, '"').match?(/[[:cntrl:]]/) ||
122
124
  !redundant_argument.match?(/[[:cntrl:]]/)
123
125
  end
124
126
  end