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
@@ -33,22 +33,19 @@ module RuboCop
33
33
  #
34
34
  class SingleArgumentDig < Base
35
35
  extend AutoCorrector
36
+ include DigHelp
36
37
 
37
38
  MSG = 'Use `%<receiver>s[%<argument>s]` instead of `%<original>s`.'
38
39
  RESTRICT_ON_SEND = %i[dig].freeze
39
40
  IGNORED_ARGUMENT_TYPES = %i[block_pass forwarded_restarg forwarded_args hash].freeze
40
41
 
41
- # @!method single_argument_dig?(node)
42
- def_node_matcher :single_argument_dig?, <<~PATTERN
43
- (send _ :dig $!splat)
44
- PATTERN
45
-
46
42
  def on_send(node)
47
43
  return unless node.receiver
48
44
 
49
45
  expression = single_argument_dig?(node)
50
46
  return unless expression
51
47
  return if IGNORED_ARGUMENT_TYPES.include?(expression.type)
48
+ return if ignore_dig_chain?(node)
52
49
 
53
50
  receiver = node.receiver.source
54
51
  argument = expression.source
@@ -63,6 +60,13 @@ module RuboCop
63
60
 
64
61
  ignore_node(node)
65
62
  end
63
+
64
+ private
65
+
66
+ def ignore_dig_chain?(node)
67
+ dig_chain_enabled? &&
68
+ (dig?(node.receiver) || dig?(node.parent))
69
+ end
66
70
  end
67
71
  end
68
72
  end
@@ -10,7 +10,7 @@ module RuboCop
10
10
  # parameters.
11
11
  #
12
12
  # Configuration option: Methods
13
- # Should be set to use this cop. Array of hashes, where each key is the
13
+ # Should be set to use this cop. `Array` of hashes, where each key is the
14
14
  # method name and value - array of argument names.
15
15
  #
16
16
  # @example Methods: [{reduce: %w[a b]}]
@@ -6,8 +6,13 @@ module RuboCop
6
6
  # Checks for single-line `do`...`end` block.
7
7
  #
8
8
  # In practice a single line `do`...`end` is autocorrected when `EnforcedStyle: semantic`
9
- # in `Style/BlockDelimiters`. The autocorrection maintains the `do` ... `end` syntax to
10
- # preserve semantics and does not change it to `{`...`}` block.
9
+ # is configured for `Style/BlockDelimiters`. The autocorrection maintains the
10
+ # `do` ... `end` syntax to preserve semantics and does not change it to `{`...`}` block.
11
+ #
12
+ # NOTE: If `InspectBlocks` is set to `true` for `Layout/RedundantLineBreak`, blocks will
13
+ # be autocorrected to be on a single line if possible. This cop respects that configuration
14
+ # by not registering an offense if it would subsequently cause a
15
+ # `Layout/RedundantLineBreak` offense.
11
16
  #
12
17
  # @example
13
18
  #
@@ -27,12 +32,14 @@ module RuboCop
27
32
  #
28
33
  class SingleLineDoEndBlock < Base
29
34
  extend AutoCorrector
35
+ include CheckSingleLineSuitability
30
36
 
31
37
  MSG = 'Prefer multiline `do`...`end` block.'
32
38
 
33
39
  # rubocop:disable Metrics/AbcSize
34
40
  def on_block(node)
35
41
  return if !node.single_line? || node.braces?
42
+ return if single_line_blocks_preferred? && suitable_as_single_line?(node)
36
43
 
37
44
  add_offense(node) do |corrector|
38
45
  corrector.insert_after(do_line(node), "\n")
@@ -49,18 +56,22 @@ module RuboCop
49
56
  end
50
57
  # rubocop:enable Metrics/AbcSize
51
58
  alias on_numblock on_block
59
+ alias on_itblock on_block
52
60
 
53
61
  private
54
62
 
55
63
  def do_line(node)
56
- if node.numblock_type? || node.arguments.children.empty? || node.send_node.lambda_literal?
64
+ if node.type?(:numblock, :itblock) ||
65
+ node.arguments.children.empty? || node.send_node.lambda_literal?
57
66
  node.loc.begin
58
67
  else
59
68
  node.arguments
60
69
  end
61
70
  end
62
71
 
63
- def x(corrector, node); end
72
+ def single_line_blocks_preferred?
73
+ @config.for_enabled_cop('Layout/RedundantLineBreak')['InspectBlocks']
74
+ end
64
75
  end
65
76
  end
66
77
  end
@@ -8,9 +8,9 @@ module RuboCop
8
8
  #
9
9
  # Endless methods added in Ruby 3.0 are also accepted by this cop.
10
10
  #
11
- # If `Style/EndlessMethod` is enabled with `EnforcedStyle: allow_single_line` or
12
- # `allow_always`, single-line methods will be autocorrected to endless
13
- # methods if there is only one statement in the body.
11
+ # If `Style/EndlessMethod` is enabled with `EnforcedStyle: allow_single_line`, `allow_always`,
12
+ # `require_single_line`, or `require_always`, single-line methods will be autocorrected
13
+ # to endless methods if there is only one statement in the body.
14
14
  #
15
15
  # @example
16
16
  # # bad
@@ -68,7 +68,7 @@ module RuboCop
68
68
  return false if body_node.parent.assignment_method? ||
69
69
  NOT_SUPPORTED_ENDLESS_METHOD_BODY_TYPES.include?(body_node.type)
70
70
 
71
- !(body_node.begin_type? || body_node.kwbegin_type?)
71
+ !body_node.type?(:begin, :kwbegin)
72
72
  end
73
73
 
74
74
  def correct_to_multiline(corrector, node)
@@ -134,10 +134,9 @@ module RuboCop
134
134
  end
135
135
 
136
136
  def disallow_endless_method_style?
137
- endless_method_config = config.for_cop('Style/EndlessMethod')
138
- return true unless endless_method_config['Enabled']
137
+ return true unless config.cop_enabled?('Style/EndlessMethod')
139
138
 
140
- endless_method_config['EnforcedStyle'] == 'disallow'
139
+ config.for_cop('Style/EndlessMethod')['EnforcedStyle'] == 'disallow'
141
140
  end
142
141
  end
143
142
  end
@@ -78,38 +78,67 @@ module RuboCop
78
78
  return unless node.arguments.one?
79
79
 
80
80
  range_node = node.first_argument
81
- selector = node.loc.selector
82
- unless (message, removal_range = offense_message_with_removal_range(range_node, selector))
83
- return
84
- end
81
+ offense_range = find_offense_range(node)
82
+ return unless (message, removal_range =
83
+ offense_message_with_removal_range(node, range_node, offense_range))
84
+
85
+ # Changing the range to beginningless or endless when unparenthesized
86
+ # changes the semantics of the code, and thus will not be considered
87
+ # an offense.
88
+ return if removal_range != offense_range && unparenthesized_call?(node)
85
89
 
86
- add_offense(selector, message: message) do |corrector|
90
+ add_offense(offense_range, message: message) do |corrector|
87
91
  corrector.remove(removal_range)
88
92
  end
89
93
  end
94
+ alias on_csend on_send
90
95
 
91
96
  private
92
97
 
93
- def offense_message_with_removal_range(range_node, selector)
98
+ def unparenthesized_call?(node)
99
+ node.loc.dot && !node.parenthesized?
100
+ end
101
+
102
+ def find_offense_range(node)
103
+ if node.loc.dot
104
+ node.loc.dot.join(node.source_range.end)
105
+ else
106
+ node.loc.selector
107
+ end
108
+ end
109
+
110
+ def offense_message_with_removal_range(node, range_node, offense_range)
94
111
  if range_from_zero_till_minus_one?(range_node)
95
- [format(MSG_USELESS_RANGE, prefer: selector.source), selector]
112
+ [format(MSG_USELESS_RANGE, prefer: offense_range.source), offense_range]
96
113
  elsif range_till_minus_one?(range_node)
97
114
  [
98
- format(MSG, prefer: endless(range_node), current: selector.source), range_node.end
115
+ offense_message_for_partial_range(node, endless(range_node), offense_range),
116
+ range_node.end
99
117
  ]
100
118
  elsif range_from_zero?(range_node) && target_ruby_version >= 2.7
101
119
  [
102
- format(MSG, prefer: beginless(range_node), current: selector.source), range_node.begin
120
+ offense_message_for_partial_range(node, beginless(range_node), offense_range),
121
+ range_node.begin
103
122
  ]
104
123
  end
105
124
  end
106
125
 
126
+ def offense_message_for_partial_range(node, prefer, offense_range)
127
+ current = node.loc.dot ? arguments_source(node) : offense_range.source
128
+ prefer = "[#{prefer}]" unless node.loc.dot
129
+ format(MSG, prefer: prefer, current: current)
130
+ end
131
+
107
132
  def endless(range_node)
108
- "[#{range_node.begin.source}#{range_node.loc.operator.source}]"
133
+ "#{range_node.begin.source}#{range_node.loc.operator.source}"
109
134
  end
110
135
 
111
136
  def beginless(range_node)
112
- "[#{range_node.loc.operator.source}#{range_node.end.source}]"
137
+ "#{range_node.loc.operator.source}#{range_node.end.source}"
138
+ end
139
+
140
+ def arguments_source(node)
141
+ node.first_argument.source_range.join(node.last_argument.source_range.end).source
113
142
  end
114
143
  end
115
144
  end
@@ -96,11 +96,7 @@ module RuboCop
96
96
  end
97
97
 
98
98
  def autocorrect(corrector, node, if_branch)
99
- if node.condition.or_type? || node.condition.assignment?
100
- corrector.wrap(node.condition, '(', ')')
101
- end
102
-
103
- if outer_condition_modify_form?(node, if_branch)
99
+ if node.modifier_form?
104
100
  autocorrect_outer_condition_modify_form(corrector, node, if_branch)
105
101
  else
106
102
  autocorrect_outer_condition_basic(corrector, node, if_branch)
@@ -108,74 +104,48 @@ module RuboCop
108
104
  end
109
105
 
110
106
  def autocorrect_outer_condition_basic(corrector, node, if_branch)
111
- correct_from_unless_to_if(corrector, node) if node.unless?
112
-
113
- outer_condition = node.condition
114
- correct_outer_condition(corrector, outer_condition)
107
+ correct_node(corrector, node)
115
108
 
116
- and_operator = if_branch.unless? ? ' && !' : ' && '
117
109
  if if_branch.modifier_form?
118
- correct_for_guard_condition_style(corrector, outer_condition, if_branch, and_operator)
110
+ correct_for_guard_condition_style(corrector, node, if_branch)
119
111
  else
120
- correct_for_basic_condition_style(corrector, node, if_branch, and_operator)
112
+ correct_for_basic_condition_style(corrector, node, if_branch)
121
113
  correct_for_comment(corrector, node, if_branch)
122
114
  end
123
115
  end
124
116
 
125
- def autocorrect_outer_condition_modify_form(corrector, node, if_branch)
126
- correct_from_unless_to_if(corrector, if_branch, is_modify_form: true) if if_branch.unless?
127
- correct_for_outer_condition_modify_form_style(corrector, node, if_branch)
117
+ def correct_node(corrector, node)
118
+ corrector.replace(node.loc.keyword, 'if') if node.unless?
119
+ corrector.replace(node.condition, chainable_condition(node))
128
120
  end
129
121
 
130
- def correct_from_unless_to_if(corrector, node, is_modify_form: false)
131
- corrector.replace(node.loc.keyword, 'if')
132
-
133
- insert_bang(corrector, node, is_modify_form)
134
- end
122
+ def correct_for_guard_condition_style(corrector, node, if_branch)
123
+ corrector.insert_after(node.condition, " && #{chainable_condition(if_branch)}")
135
124
 
136
- def correct_for_guard_condition_style(corrector, outer_condition, if_branch, and_operator)
137
- condition = if_branch.condition
138
- corrector.insert_after(outer_condition, "#{and_operator}#{replace_condition(condition)}")
139
-
140
- range = range_between(if_branch.loc.keyword.begin_pos, condition.source_range.end_pos)
125
+ range = range_between(
126
+ if_branch.loc.keyword.begin_pos, if_branch.condition.source_range.end_pos
127
+ )
141
128
  corrector.remove(range_with_surrounding_space(range, newlines: false))
142
- corrector.remove(if_branch.loc.keyword)
143
129
  end
144
130
 
145
- def correct_for_basic_condition_style(corrector, node, if_branch, and_operator)
131
+ def correct_for_basic_condition_style(corrector, node, if_branch)
146
132
  range = range_between(
147
133
  node.condition.source_range.end_pos, if_branch.condition.source_range.begin_pos
148
134
  )
149
- corrector.replace(range, and_operator)
150
- corrector.remove(range_by_whole_lines(node.loc.end, include_final_newline: true))
151
-
152
- wrap_condition(corrector, if_branch.condition)
153
- end
154
-
155
- def wrap_condition(corrector, condition)
156
- # Handle `send` and `block` nodes that need to be wrapped in parens
157
- # FIXME: autocorrection prevents syntax errors by wrapping the entire node in parens,
158
- # but wrapping the argument list would be a more ergonomic correction.
159
- node_to_check = condition&.block_type? ? condition.send_node : condition
160
- return unless wrap_condition?(node_to_check)
135
+ corrector.replace(range, ' && ')
161
136
 
162
- if condition.call_type?
163
- source = parenthesized_method_arguments(condition)
137
+ corrector.replace(if_branch.condition, chainable_condition(if_branch))
164
138
 
165
- corrector.replace(condition, source)
166
- else
167
- corrector.wrap(condition, '(', ')')
168
- end
139
+ corrector.remove(range_by_whole_lines(node.loc.end, include_final_newline: true))
169
140
  end
170
141
 
171
- def correct_for_outer_condition_modify_form_style(corrector, node, if_branch)
172
- condition = if_branch.condition
173
- corrector.insert_before(condition,
174
- "#{'!' if node.unless?}#{replace_condition(node.condition)} && ")
142
+ def autocorrect_outer_condition_modify_form(corrector, node, if_branch)
143
+ correct_node(corrector, if_branch)
175
144
 
176
- corrector.remove(node.condition)
177
- corrector.remove(range_with_surrounding_space(node.loc.keyword, newlines: false))
178
- corrector.replace(if_branch.loc.keyword, 'if')
145
+ corrector.insert_before(if_branch.condition, "#{chainable_condition(node)} && ")
146
+
147
+ range = range_between(node.loc.keyword.begin_pos, node.condition.source_range.end_pos)
148
+ corrector.remove(range_with_surrounding_space(range, newlines: false))
179
149
  end
180
150
 
181
151
  def correct_for_comment(corrector, node, if_branch)
@@ -187,68 +157,38 @@ module RuboCop
187
157
  corrector.insert_before(node.loc.keyword, comment_text) unless comments.empty?
188
158
  end
189
159
 
190
- def correct_outer_condition(corrector, condition)
191
- return unless require_parentheses?(condition)
160
+ def chainable_condition(node)
161
+ wrapped_condition = add_parentheses_if_needed(node.condition)
192
162
 
193
- end_pos = condition.loc.selector.end_pos
194
- begin_pos = condition.first_argument.source_range.begin_pos
195
- return if end_pos > begin_pos
163
+ return wrapped_condition if node.if?
196
164
 
197
- range = range_between(end_pos, begin_pos)
198
- corrector.remove(range)
199
- corrector.insert_after(range, '(')
200
- corrector.insert_after(condition.last_argument, ')')
165
+ node.condition.and_type? ? "!(#{wrapped_condition})" : "!#{wrapped_condition}"
201
166
  end
202
167
 
203
- def insert_bang(corrector, node, is_modify_form)
204
- condition = node.condition
168
+ def add_parentheses_if_needed(condition)
169
+ # Handle `send` and `block` nodes that need to be wrapped in parens
170
+ # FIXME: autocorrection prevents syntax errors by wrapping the entire node in parens,
171
+ # but wrapping the argument list would be a more ergonomic correction.
172
+ node_to_check = condition&.any_block_type? ? condition.send_node : condition
173
+ return condition.source unless add_parentheses?(node_to_check)
205
174
 
206
- if (condition.send_type? && condition.comparison_method? && !condition.parenthesized?) ||
207
- (is_modify_form && wrap_condition?(condition))
208
- corrector.wrap(node.condition, '!(', ')')
209
- elsif condition.and_type?
210
- insert_bang_for_and(corrector, node)
175
+ if parenthesize_method?(condition)
176
+ parenthesized_method_arguments(condition)
211
177
  else
212
- corrector.insert_before(condition, '!')
178
+ "(#{condition.source})"
213
179
  end
214
180
  end
215
181
 
216
- def insert_bang_for_and(corrector, node)
217
- lhs, rhs = *node
218
-
219
- if lhs.and_type?
220
- insert_bang_for_and(corrector, lhs)
221
- corrector.insert_before(rhs, '!') if rhs
222
- else
223
- corrector.insert_before(lhs, '!')
224
- corrector.insert_before(rhs, '!')
225
- end
182
+ def parenthesize_method?(node)
183
+ node.call_type? && node.arguments.any? && !node.parenthesized? &&
184
+ !node.comparison_method? && !node.operator_method?
226
185
  end
227
186
 
228
- def require_parentheses?(condition)
229
- condition.call_type? && !condition.arguments.empty? && !condition.parenthesized? &&
230
- !condition.comparison_method?
231
- end
187
+ def add_parentheses?(node)
188
+ return true if node.assignment? || (node.operator_keyword? && !node.and_type?)
189
+ return false unless node.call_type?
232
190
 
233
- def arguments_range(node)
234
- range_between(
235
- node.first_argument.source_range.begin_pos, node.last_argument.source_range.end_pos
236
- )
237
- end
238
-
239
- def wrap_condition?(node)
240
- node.and_type? || node.or_type? ||
241
- (node.call_type? && node.arguments.any? && !node.parenthesized?)
242
- end
243
-
244
- def replace_condition(condition)
245
- return condition.source unless wrap_condition?(condition)
246
-
247
- if condition.call_type?
248
- parenthesized_method_arguments(condition)
249
- else
250
- "(#{condition.source})"
251
- end
191
+ (node.arguments.any? && !node.parenthesized?) || node.prefix_not?
252
192
  end
253
193
 
254
194
  def parenthesized_method_arguments(node)
@@ -261,10 +201,6 @@ module RuboCop
261
201
  def allow_modifier?
262
202
  cop_config['AllowModifier']
263
203
  end
264
-
265
- def outer_condition_modify_form?(node, if_branch)
266
- node.condition.source_range.begin_pos > if_branch.condition.source_range.begin_pos
267
- end
268
204
  end
269
205
  end
270
206
  end
@@ -149,7 +149,7 @@ module RuboCop
149
149
  end
150
150
 
151
151
  def on_gvar(node)
152
- global_var, = *node
152
+ global_var = node.name
153
153
 
154
154
  return unless (preferred = preferred_names(global_var))
155
155
 
@@ -51,8 +51,6 @@ module RuboCop
51
51
  # Pathname.new('/') + 'test'
52
52
  #
53
53
  class StringConcatenation < Base
54
- include Util
55
- include RangeHelp
56
54
  extend AutoCorrector
57
55
 
58
56
  MSG = 'Prefer string interpolation to string concatenation.'
@@ -129,11 +127,11 @@ module RuboCop
129
127
  end
130
128
 
131
129
  def uncorrectable?(part)
132
- part.multiline? || heredoc?(part) || part.each_descendant(:block).any?
130
+ part.multiline? || heredoc?(part) || part.each_descendant(:any_block).any?
133
131
  end
134
132
 
135
133
  def heredoc?(node)
136
- return false unless node.str_type? || node.dstr_type?
134
+ return false unless node.type?(:str, :dstr)
137
135
 
138
136
  node.heredoc?
139
137
  end
@@ -143,22 +141,24 @@ module RuboCop
143
141
  end
144
142
 
145
143
  def replacement(parts)
146
- interpolated_parts =
147
- parts.map do |part|
148
- case part.type
149
- when :str
150
- value = part.value
151
- single_quoted?(part) ? value.gsub(/(\\|")/, '\\\\\&') : value.inspect[1..-2]
152
- when :dstr
153
- contents_range(part).source
154
- else
155
- "\#{#{part.source}}"
156
- end
144
+ interpolated_parts = parts.map do |part|
145
+ case part.type
146
+ when :str
147
+ adjust_str(part)
148
+ when :dstr
149
+ part.children.all?(&:str_type?) ? adjust_str(part) : part.value
150
+ else
151
+ "\#{#{part.source}}"
157
152
  end
153
+ end
158
154
 
159
155
  "\"#{handle_quotes(interpolated_parts).join}\""
160
156
  end
161
157
 
158
+ def adjust_str(node)
159
+ single_quoted?(node) ? node.value.gsub(/(\\|")/, '\\\\\&') : node.value.inspect[1..-2]
160
+ end
161
+
162
162
  def handle_quotes(parts)
163
163
  parts.map do |part|
164
164
  part == '"' ? '\"' : part
@@ -69,7 +69,7 @@ module RuboCop
69
69
  end
70
70
 
71
71
  def all_string_literals?(nodes)
72
- nodes.all? { |n| n.str_type? || n.dstr_type? }
72
+ nodes.all? { |n| n.type?(:str, :dstr) }
73
73
  end
74
74
 
75
75
  def detect_quote_styles(node)
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # Enforces the use of consistent method names
7
- # from the String class.
7
+ # from the `String` class.
8
8
  #
9
9
  # @example
10
10
  # # bad
@@ -3,7 +3,8 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for inheritance from Struct.new.
6
+ # Checks for inheritance from `Struct.new`. Inheriting from `Struct.new`
7
+ # adds a superfluous level in inheritance tree.
7
8
  #
8
9
  # @safety
9
10
  # Autocorrection is unsafe because it will change the inheritance
@@ -17,12 +18,18 @@ module RuboCop
17
18
  # end
18
19
  # end
19
20
  #
21
+ # Person.ancestors
22
+ # # => [Person, #<Class:0x000000010b4e14a0>, Struct, (...)]
23
+ #
20
24
  # # good
21
25
  # Person = Struct.new(:first_name, :last_name) do
22
26
  # def age
23
27
  # 42
24
28
  # end
25
29
  # end
30
+ #
31
+ # Person.ancestors
32
+ # # => [Person, Struct, (...)]
26
33
  class StructInheritance < Base
27
34
  include RangeHelp
28
35
  extend AutoCorrector