rubocop 1.66.1 → 1.72.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 (434) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +162 -14
  5. data/config/internal_affairs.yml +11 -0
  6. data/lib/rubocop/cached_data.rb +12 -4
  7. data/lib/rubocop/cli/command/auto_generate_config.rb +6 -7
  8. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  9. data/lib/rubocop/cli/command/lsp.rb +2 -2
  10. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  11. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  12. data/lib/rubocop/cli/command/version.rb +2 -2
  13. data/lib/rubocop/comment_config.rb +2 -2
  14. data/lib/rubocop/config.rb +17 -4
  15. data/lib/rubocop/config_loader.rb +48 -8
  16. data/lib/rubocop/config_loader_resolver.rb +36 -11
  17. data/lib/rubocop/config_validator.rb +20 -9
  18. data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
  19. data/lib/rubocop/cop/base.rb +13 -3
  20. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  21. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  22. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  23. data/lib/rubocop/cop/bundler/gem_version.rb +1 -0
  24. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  25. data/lib/rubocop/cop/cop.rb +8 -0
  26. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  27. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  28. data/lib/rubocop/cop/correctors/parentheses_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/required_ruby_version.rb +0 -2
  32. data/lib/rubocop/cop/generator.rb +6 -0
  33. data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
  34. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  35. data/lib/rubocop/cop/internal_affairs/example_description.rb +4 -2
  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 +229 -0
  44. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  45. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  46. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  47. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  48. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  49. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  50. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  51. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +11 -2
  52. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  53. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  54. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
  55. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
  56. data/lib/rubocop/cop/internal_affairs.rb +6 -0
  57. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -2
  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/class_structure.rb +9 -9
  63. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  64. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  65. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  66. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  67. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  68. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +3 -3
  69. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  70. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  71. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  72. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  73. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  74. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  75. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  76. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  77. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  78. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  79. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  80. data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
  81. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  82. data/lib/rubocop/cop/layout/indentation_width.rb +11 -12
  83. data/lib/rubocop/cop/layout/leading_comment_space.rb +71 -1
  84. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  85. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  86. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  87. data/lib/rubocop/cop/layout/line_length.rb +119 -4
  88. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  89. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  90. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  91. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  92. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  93. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
  94. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  95. data/lib/rubocop/cop/layout/redundant_line_break.rb +10 -41
  96. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -3
  97. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  98. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  99. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  100. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  101. data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
  102. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  103. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  104. data/lib/rubocop/cop/layout/space_around_operators.rb +19 -20
  105. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  106. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  107. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  108. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -0
  109. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
  110. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
  111. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  112. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  113. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  114. data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
  115. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
  116. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  117. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  118. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  119. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  120. data/lib/rubocop/cop/lint/circular_argument_reference.rb +6 -0
  121. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  122. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  123. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  124. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  125. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
  126. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  127. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  128. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  129. data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
  130. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  131. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  132. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  133. data/lib/rubocop/cop/lint/ensure_return.rb +1 -4
  134. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  135. data/lib/rubocop/cop/lint/float_comparison.rb +20 -9
  136. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  137. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  138. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  139. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +11 -5
  140. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  141. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +8 -14
  142. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -0
  143. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  144. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +49 -8
  145. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  146. data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -6
  147. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  148. data/lib/rubocop/cop/lint/nested_method_definition.rb +9 -5
  149. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  150. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  151. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  152. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  153. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  154. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  155. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  156. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  157. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
  158. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  159. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +6 -11
  160. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  161. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  162. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +13 -8
  163. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  164. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  165. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +231 -0
  166. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  167. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  168. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  169. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  170. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  171. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +109 -41
  172. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  173. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  174. data/lib/rubocop/cop/lint/shared_mutable_default.rb +65 -0
  175. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  176. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  177. data/lib/rubocop/cop/lint/symbol_conversion.rb +2 -2
  178. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  179. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  180. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
  181. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  182. data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
  183. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
  184. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  185. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  186. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
  187. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
  188. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +80 -0
  189. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  190. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  191. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  192. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  193. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
  194. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  195. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  196. data/lib/rubocop/cop/lint/void.rb +8 -11
  197. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  198. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  199. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  200. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  201. data/lib/rubocop/cop/metrics/method_length.rb +8 -1
  202. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  203. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  204. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  205. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -3
  206. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  207. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  208. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  209. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  210. data/lib/rubocop/cop/mixin/check_line_breakable.rb +20 -10
  211. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  212. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  213. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  214. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  215. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -2
  216. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  217. data/lib/rubocop/cop/mixin/hash_subset.rb +188 -0
  218. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  219. data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
  220. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  221. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
  222. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  223. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  224. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  225. data/lib/rubocop/cop/mixin/range_help.rb +3 -4
  226. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  227. data/lib/rubocop/cop/mixin/statement_modifier.rb +11 -5
  228. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  229. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  230. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  231. data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
  232. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  233. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  234. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  235. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  236. data/lib/rubocop/cop/naming/inclusive_language.rb +12 -3
  237. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
  238. data/lib/rubocop/cop/naming/predicate_name.rb +45 -1
  239. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  240. data/lib/rubocop/cop/naming/variable_name.rb +3 -4
  241. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  242. data/lib/rubocop/cop/offense.rb +4 -5
  243. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  244. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  245. data/lib/rubocop/cop/style/access_modifier_declarations.rb +96 -28
  246. data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
  247. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  248. data/lib/rubocop/cop/style/and_or.rb +1 -1
  249. data/lib/rubocop/cop/style/arguments_forwarding.rb +78 -22
  250. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  251. data/lib/rubocop/cop/style/array_intersect.rb +5 -4
  252. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  253. data/lib/rubocop/cop/style/block_delimiters.rb +49 -19
  254. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  255. data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
  256. data/lib/rubocop/cop/style/collection_compact.rb +10 -10
  257. data/lib/rubocop/cop/style/collection_methods.rb +1 -1
  258. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  259. data/lib/rubocop/cop/style/combinable_loops.rb +9 -2
  260. data/lib/rubocop/cop/style/commented_keyword.rb +17 -1
  261. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  262. data/lib/rubocop/cop/style/conditional_assignment.rb +26 -26
  263. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  264. data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
  265. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  266. data/lib/rubocop/cop/style/documentation.rb +1 -1
  267. data/lib/rubocop/cop/style/double_negation.rb +3 -3
  268. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  269. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  270. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  271. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  272. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  273. data/lib/rubocop/cop/style/endless_method.rb +1 -14
  274. data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
  275. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  276. data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
  277. data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
  278. data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
  279. data/lib/rubocop/cop/style/file_null.rb +89 -0
  280. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  281. data/lib/rubocop/cop/style/float_division.rb +8 -4
  282. data/lib/rubocop/cop/style/for.rb +0 -1
  283. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  284. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  285. data/lib/rubocop/cop/style/guard_clause.rb +16 -3
  286. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  287. data/lib/rubocop/cop/style/hash_each_methods.rb +9 -6
  288. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  289. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  290. data/lib/rubocop/cop/style/hash_syntax.rb +8 -5
  291. data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
  292. data/lib/rubocop/cop/style/if_inside_else.rb +1 -2
  293. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
  294. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -3
  295. data/lib/rubocop/cop/style/if_with_semicolon.rb +26 -11
  296. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  297. data/lib/rubocop/cop/style/inverse_methods.rb +6 -7
  298. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  299. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  300. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
  301. data/lib/rubocop/cop/style/lambda.rb +1 -1
  302. data/lib/rubocop/cop/style/lambda_call.rb +3 -2
  303. data/lib/rubocop/cop/style/map_into_array.rb +60 -9
  304. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  305. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  306. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +32 -20
  307. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  308. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  309. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
  310. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  311. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  312. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  313. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  314. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  315. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  316. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  317. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  318. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  319. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -2
  320. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  321. data/lib/rubocop/cop/style/not.rb +1 -1
  322. data/lib/rubocop/cop/style/object_then.rb +14 -15
  323. data/lib/rubocop/cop/style/one_line_conditional.rb +29 -4
  324. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  325. data/lib/rubocop/cop/style/operator_method_call.rb +25 -7
  326. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  327. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  328. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  329. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  330. data/lib/rubocop/cop/style/proc.rb +1 -2
  331. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  332. data/lib/rubocop/cop/style/raise_args.rb +7 -5
  333. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  334. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  335. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  336. data/lib/rubocop/cop/style/redundant_begin.rb +5 -1
  337. data/lib/rubocop/cop/style/redundant_condition.rb +39 -24
  338. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
  339. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  340. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  341. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  342. data/lib/rubocop/cop/style/redundant_format.rb +238 -0
  343. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
  344. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  345. data/lib/rubocop/cop/style/redundant_line_continuation.rb +56 -17
  346. data/lib/rubocop/cop/style/redundant_parentheses.rb +37 -25
  347. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  348. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  349. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  350. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  351. data/lib/rubocop/cop/style/redundant_self.rb +8 -15
  352. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  353. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  354. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  355. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  356. data/lib/rubocop/cop/style/require_order.rb +1 -1
  357. data/lib/rubocop/cop/style/rescue_modifier.rb +15 -4
  358. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  359. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
  360. data/lib/rubocop/cop/style/safe_navigation.rb +105 -51
  361. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  362. data/lib/rubocop/cop/style/select_by_regexp.rb +10 -7
  363. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  364. data/lib/rubocop/cop/style/semicolon.rb +2 -2
  365. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  366. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  367. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  368. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  369. data/lib/rubocop/cop/style/single_line_do_end_block.rb +12 -3
  370. data/lib/rubocop/cop/style/single_line_methods.rb +3 -4
  371. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  372. data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -5
  373. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  374. data/lib/rubocop/cop/style/string_concatenation.rb +14 -13
  375. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  376. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  377. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  378. data/lib/rubocop/cop/style/super_arguments.rb +65 -17
  379. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  380. data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
  381. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  382. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
  383. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  384. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  385. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  386. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  387. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  388. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  389. data/lib/rubocop/cop/team.rb +8 -1
  390. data/lib/rubocop/cop/util.rb +12 -5
  391. data/lib/rubocop/cop/utils/format_string.rb +7 -5
  392. data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
  393. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  394. data/lib/rubocop/cop/variable_force/variable.rb +18 -2
  395. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  396. data/lib/rubocop/cop/variable_force.rb +4 -10
  397. data/lib/rubocop/cops_documentation_generator.rb +100 -51
  398. data/lib/rubocop/directive_comment.rb +44 -10
  399. data/lib/rubocop/file_finder.rb +9 -4
  400. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  401. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  402. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  403. data/lib/rubocop/lsp/logger.rb +2 -2
  404. data/lib/rubocop/lsp/routes.rb +7 -23
  405. data/lib/rubocop/lsp/runtime.rb +18 -48
  406. data/lib/rubocop/lsp/server.rb +0 -3
  407. data/lib/rubocop/lsp/stdin_runner.rb +83 -0
  408. data/lib/rubocop/magic_comment.rb +3 -3
  409. data/lib/rubocop/options.rb +28 -12
  410. data/lib/rubocop/path_util.rb +15 -8
  411. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  412. data/lib/rubocop/plugin/load_error.rb +26 -0
  413. data/lib/rubocop/plugin/loader.rb +100 -0
  414. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  415. data/lib/rubocop/plugin.rb +39 -0
  416. data/lib/rubocop/rake_task.rb +4 -1
  417. data/lib/rubocop/result_cache.rb +13 -13
  418. data/lib/rubocop/rspec/cop_helper.rb +9 -0
  419. data/lib/rubocop/rspec/expect_offense.rb +7 -2
  420. data/lib/rubocop/rspec/shared_contexts.rb +4 -1
  421. data/lib/rubocop/rspec/support.rb +1 -2
  422. data/lib/rubocop/runner.rb +22 -12
  423. data/lib/rubocop/server/cache.rb +39 -1
  424. data/lib/rubocop/server/cli.rb +2 -2
  425. data/lib/rubocop/server/core.rb +1 -0
  426. data/lib/rubocop/target_finder.rb +1 -0
  427. data/lib/rubocop/target_ruby.rb +28 -13
  428. data/lib/rubocop/version.rb +42 -6
  429. data/lib/rubocop/yaml_duplication_checker.rb +20 -27
  430. data/lib/rubocop.rb +29 -0
  431. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  432. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
  433. metadata +75 -19
  434. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -3,13 +3,12 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # Checks for indentation that doesn't use the specified number
7
- # of spaces.
6
+ # Checks for indentation that doesn't use the specified number of spaces.
7
+ # The indentation width can be configured using the `Width` setting. The default width is 2.
8
8
  #
9
- # See also the IndentationConsistency cop which is the companion to this
10
- # one.
9
+ # See also the `Layout/IndentationConsistency` cop which is the companion to this one.
11
10
  #
12
- # @example
11
+ # @example Width: 2 (default)
13
12
  # # bad
14
13
  # class A
15
14
  # def test
@@ -59,16 +58,17 @@ module RuboCop
59
58
  PATTERN
60
59
 
61
60
  def on_rescue(node)
62
- _begin_node, *_rescue_nodes, else_node = *node
63
- check_indentation(node.loc.else, else_node)
61
+ check_indentation(node.loc.else, node.else_branch)
64
62
  end
65
63
 
66
- def on_ensure(node)
64
+ def on_resbody(node)
67
65
  check_indentation(node.loc.keyword, node.body)
68
66
  end
67
+ alias on_for on_resbody
69
68
 
70
- alias on_resbody on_ensure
71
- alias on_for on_ensure
69
+ def on_ensure(node)
70
+ check_indentation(node.loc.keyword, node.branch)
71
+ end
72
72
 
73
73
  def on_kwbegin(node)
74
74
  # Check indentation against end keyword but only if it's first on its
@@ -326,8 +326,7 @@ module RuboCop
326
326
  if body_node.rescue_type?
327
327
  check_rescue?(body_node)
328
328
  elsif body_node.ensure_type?
329
- block_body, = *body_node
330
-
329
+ block_body, = *body_node # rubocop:disable InternalAffairs/NodeDestructuring
331
330
  if block_body&.rescue_type?
332
331
  check_rescue?(block_body)
333
332
  else
@@ -49,18 +49,58 @@ module RuboCop
49
49
  # #ruby=2.7.0
50
50
  # #ruby-gemset=myproject
51
51
  #
52
+ # @example AllowRBSInlineAnnotation: false (default)
53
+ #
54
+ # # bad
55
+ #
56
+ # include Enumerable #[Integer]
57
+ #
58
+ # attr_reader :name #: String
59
+ # attr_reader :age #: Integer?
60
+ #
61
+ # @example AllowRBSInlineAnnotation: true
62
+ #
63
+ # # good
64
+ #
65
+ # include Enumerable #[Integer]
66
+ #
67
+ # attr_reader :name #: String
68
+ # attr_reader :age #: Integer?
69
+ #
70
+ # @example AllowSteepAnnotation: false (default)
71
+ #
72
+ # # bad
73
+ # [1, 2, 3].each_with_object([]) do |n, list| #$ Array[Integer]
74
+ # list << n
75
+ # end
76
+ #
77
+ # name = 'John' #: String
78
+ #
79
+ # @example AllowSteepAnnotation: true
80
+ #
81
+ # # good
82
+ #
83
+ # [1, 2, 3].each_with_object([]) do |n, list| #$ Array[Integer]
84
+ # list << n
85
+ # end
86
+ #
87
+ # name = 'John' #: String
88
+ #
52
89
  class LeadingCommentSpace < Base
53
90
  include RangeHelp
54
91
  extend AutoCorrector
55
92
 
56
93
  MSG = 'Missing space after `#`.'
57
94
 
58
- def on_new_investigation
95
+ def on_new_investigation # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
59
96
  processed_source.comments.each do |comment|
60
97
  next unless /\A(?!#\+\+|#--)(#+[^#\s=])/.match?(comment.text)
61
98
  next if comment.loc.line == 1 && allowed_on_first_line?(comment)
99
+ next if shebang_continuation?(comment)
62
100
  next if doxygen_comment_style?(comment)
63
101
  next if gemfile_ruby_comment?(comment)
102
+ next if rbs_inline_annotation?(comment)
103
+ next if steep_annotation?(comment)
64
104
 
65
105
  add_offense(comment) do |corrector|
66
106
  expr = comment.source_range
@@ -84,6 +124,20 @@ module RuboCop
84
124
  comment.text.start_with?('#!')
85
125
  end
86
126
 
127
+ def shebang_continuation?(comment)
128
+ return false unless shebang?(comment)
129
+ return true if comment.loc.line == 1
130
+
131
+ previous_line_comment = processed_source.comment_at_line(comment.loc.line - 1)
132
+ return false unless previous_line_comment
133
+
134
+ # If the comment is a shebang but not on the first line, check if the previous
135
+ # line has a shebang comment that wasn't marked as an offense; if so, this comment
136
+ # continues the shebang and is acceptable.
137
+ shebang?(previous_line_comment) &&
138
+ !current_offense_locations.include?(previous_line_comment.source_range)
139
+ end
140
+
87
141
  def rackup_options?(comment)
88
142
  comment.text.start_with?('#\\')
89
143
  end
@@ -115,6 +169,22 @@ module RuboCop
115
169
  def gemfile_ruby_comment?(comment)
116
170
  allow_gemfile_ruby_comment? && ruby_comment_in_gemfile?(comment)
117
171
  end
172
+
173
+ def allow_rbs_inline_annotation?
174
+ cop_config['AllowRBSInlineAnnotation']
175
+ end
176
+
177
+ def rbs_inline_annotation?(comment)
178
+ allow_rbs_inline_annotation? && comment.text.start_with?(/#:|#\[.+\]/)
179
+ end
180
+
181
+ def allow_steep_annotation?
182
+ cop_config['AllowSteepAnnotation']
183
+ end
184
+
185
+ def steep_annotation?(comment)
186
+ allow_steep_annotation? && comment.text.start_with?(/#[$:]/)
187
+ end
118
188
  end
119
189
  end
120
190
  end
@@ -51,6 +51,15 @@ module RuboCop
51
51
  private_constant :LINE_1_ENDING, :LINE_2_BEGINNING,
52
52
  :LEADING_STYLE_OFFENSE, :TRAILING_STYLE_OFFENSE
53
53
 
54
+ # When both cops are activated and run in the same iteration of the correction loop,
55
+ # `Style/StringLiterals` undoes the moving of spaces that
56
+ # `Layout/LineContinuationLeadingSpace` performs. This is because `Style/StringLiterals`
57
+ # takes the original string content and transforms it, rather than just modifying the
58
+ # delimiters, in order to handle escaping for quotes within the string.
59
+ def self.autocorrect_incompatible_with
60
+ [Style::StringLiterals]
61
+ end
62
+
54
63
  def on_dstr(node)
55
64
  # Quick check if we possibly have line continuations.
56
65
  return unless node.source.include?('\\')
@@ -129,9 +138,9 @@ module RuboCop
129
138
 
130
139
  def message(_range)
131
140
  if enforced_style_leading?
132
- 'Move trailing spaces to the start of next line.'
141
+ 'Move trailing spaces to the start of the next line.'
133
142
  else
134
- 'Move leading spaces to the end of previous line.'
143
+ 'Move leading spaces to the end of the previous line.'
135
144
  end
136
145
  end
137
146
 
@@ -101,7 +101,7 @@ module RuboCop
101
101
  ranges << loc.expression
102
102
  elsif literal.heredoc?
103
103
  ranges << loc.heredoc_body
104
- elsif loc.respond_to?(:begin) && loc.begin
104
+ elsif (loc.respond_to?(:begin) && loc.begin) || ignored_parent?(literal)
105
105
  ranges << loc.expression
106
106
  end
107
107
  end
@@ -127,6 +127,12 @@ module RuboCop
127
127
  comment_ranges(processed_source.comments)
128
128
  end
129
129
 
130
+ def ignored_parent?(node)
131
+ return false unless node.parent
132
+
133
+ node.parent.type?(:regexp, :xstr)
134
+ end
135
+
130
136
  def no_space_style?
131
137
  cop_config['EnforcedStyle'] == 'no_space'
132
138
  end
@@ -102,7 +102,7 @@ module RuboCop
102
102
 
103
103
  def strings_concatenated_with_backslash?(dstr_node)
104
104
  dstr_node.multiline? &&
105
- dstr_node.children.all? { |c| c.str_type? || c.dstr_type? } &&
105
+ dstr_node.children.all? { |c| c.type?(:str, :dstr) } &&
106
106
  dstr_node.children.none?(&:multiline?)
107
107
  end
108
108
 
@@ -127,7 +127,7 @@ module RuboCop
127
127
 
128
128
  def base_column(child)
129
129
  grandparent = child.parent.parent
130
- if grandparent&.type == :pair
130
+ if grandparent&.pair_type?
131
131
  grandparent.loc.column
132
132
  else
133
133
  child.source_range.source_line =~ /\S/
@@ -38,7 +38,7 @@ module RuboCop
38
38
  # * `Layout/MultilineHashKeyLineBreaks`
39
39
  # * `Layout/MultilineMethodArgumentLineBreaks`
40
40
  # * `Layout/MultilineMethodParameterLineBreaks`
41
- # * `Layout//ParameterAlignment`
41
+ # * `Layout/ParameterAlignment`
42
42
  # * `Style/BlockDelimiters`
43
43
  #
44
44
  # Together, these cops will pretty print hashes, arrays,
@@ -60,7 +60,7 @@ module RuboCop
60
60
  # bar: "0000000000",
61
61
  # baz: "0000000000",
62
62
  # }
63
- class LineLength < Base
63
+ class LineLength < Base # rubocop:disable Metrics/ClassLength
64
64
  include CheckLineBreakable
65
65
  include AllowedPattern
66
66
  include RangeHelp
@@ -74,15 +74,23 @@ module RuboCop
74
74
  def on_block(node)
75
75
  check_for_breakable_block(node)
76
76
  end
77
-
78
77
  alias on_numblock on_block
79
78
 
79
+ def on_str(node)
80
+ check_for_breakable_str(node)
81
+ end
82
+
83
+ def on_dstr(node)
84
+ check_for_breakable_dstr(node)
85
+ end
86
+
80
87
  def on_potential_breakable_node(node)
81
88
  check_for_breakable_node(node)
82
89
  end
83
90
  alias on_array on_potential_breakable_node
84
91
  alias on_hash on_potential_breakable_node
85
92
  alias on_send on_potential_breakable_node
93
+ alias on_csend on_potential_breakable_node
86
94
  alias on_def on_potential_breakable_node
87
95
 
88
96
  def on_new_investigation
@@ -132,6 +140,42 @@ module RuboCop
132
140
  breakable_range_by_line_index[line_index] = range_between(pos, pos + 1)
133
141
  end
134
142
 
143
+ def check_for_breakable_str(node)
144
+ line_index = node.loc.line - 1
145
+ return if breakable_range_by_line_index[line_index]
146
+
147
+ return unless breakable_string?(node)
148
+ return unless (delimiter = string_delimiter(node))
149
+ return unless (pos = breakable_string_position(node))
150
+
151
+ breakable_range_by_line_index[line_index] = range_between(pos, pos + 1)
152
+ breakable_string_delimiters[line_index] = delimiter
153
+ end
154
+
155
+ def check_for_breakable_dstr(node) # rubocop:disable Metrics/AbcSize
156
+ line_index = node.loc.line - 1
157
+ return if breakable_range_by_line_index[line_index]
158
+
159
+ return unless breakable_dstr?(node)
160
+ return unless (delimiter = string_delimiter(node))
161
+
162
+ node.each_child_node(:begin).detect do |begin_node|
163
+ next unless (pos = breakable_dstr_begin_position(begin_node))
164
+
165
+ breakable_range_by_line_index[line_index] = range_between(pos, pos + 1)
166
+ breakable_string_delimiters[line_index] = delimiter
167
+ end
168
+ end
169
+
170
+ def breakable_string?(node)
171
+ allow_string_split? &&
172
+ node.single_line? &&
173
+ !node.heredoc? &&
174
+ # TODO: strings inside hashes, kwargs and arrays are currently ignored,
175
+ # but could be considered in the future
176
+ !node.parent&.type?(:pair, :kwoptarg, :array)
177
+ end
178
+
135
179
  def breakable_block_range(block_node)
136
180
  if block_node.arguments? && !block_node.lambda?
137
181
  block_node.arguments.loc.end
@@ -153,10 +197,47 @@ module RuboCop
153
197
  next_range
154
198
  end
155
199
 
200
+ def breakable_string_position(node)
201
+ source_range = node.source_range
202
+ return if source_range.last_column < max
203
+ return unless (pos = breakable_string_range(node))
204
+
205
+ pos.end_pos unless pos.end_pos == source_range.begin_pos
206
+ end
207
+
208
+ # Locate where to break a string that is too long, ensuring that escape characters
209
+ # are not bisected.
210
+ # If the string contains spaces, use them to determine a place for a clean break;
211
+ # otherwise, the string will be broken at the line length limit.
212
+ def breakable_string_range(node) # rubocop:disable Metrics/AbcSize
213
+ source_range = node.source_range
214
+ relevant_substr = largest_possible_string(node)
215
+
216
+ if (space_pos = relevant_substr.rindex(/\s/))
217
+ source_range.resize(space_pos + 1)
218
+ elsif (escape_pos = relevant_substr.rindex(/\\(u[\da-f]{0,4}|x[\da-f]{0,2})?\z/))
219
+ source_range.resize(escape_pos)
220
+ else
221
+ adjustment = max - source_range.last_column - 3
222
+ return if adjustment.abs > source_range.size
223
+
224
+ source_range.adjust(end_pos: max - source_range.last_column - 3)
225
+ end
226
+ end
227
+
228
+ def breakable_dstr_begin_position(node)
229
+ source_range = node.source_range
230
+ source_range.begin_pos if source_range.begin_pos < max && source_range.end_pos >= max
231
+ end
232
+
156
233
  def breakable_range_by_line_index
157
234
  @breakable_range_by_line_index ||= {}
158
235
  end
159
236
 
237
+ def breakable_string_delimiters
238
+ @breakable_string_delimiters ||= {}
239
+ end
240
+
160
241
  def heredocs
161
242
  @heredocs ||= extract_heredocs(processed_source.ast)
162
243
  end
@@ -197,7 +278,14 @@ module RuboCop
197
278
 
198
279
  add_offense(loc, message: message) do |corrector|
199
280
  self.max = line_length(line)
200
- corrector.insert_before(breakable_range, "\n") unless breakable_range.nil?
281
+
282
+ insertion = if (delimiter = breakable_string_delimiters[line_index])
283
+ [delimiter, " \\\n", delimiter].join
284
+ else
285
+ "\n"
286
+ end
287
+
288
+ corrector.insert_before(breakable_range, insertion) unless breakable_range.nil?
201
289
  end
202
290
  end
203
291
 
@@ -224,6 +312,10 @@ module RuboCop
224
312
  cop_config['AllowHeredoc']
225
313
  end
226
314
 
315
+ def allow_string_split?
316
+ cop_config['SplitStrings']
317
+ end
318
+
227
319
  def extract_heredocs(ast)
228
320
  return [] unless ast
229
321
 
@@ -270,6 +362,29 @@ module RuboCop
270
362
 
271
363
  register_offense(excess_range(uri_range, line, line_index), line, line_index)
272
364
  end
365
+
366
+ def breakable_dstr?(node)
367
+ # If the `dstr` only contains one child, it cannot be broken
368
+ breakable_string?(node) && !node.child_nodes.one?
369
+ end
370
+
371
+ def string_delimiter(node)
372
+ delimiter = node.loc.begin
373
+ delimiter ||= node.parent.loc.begin if node.parent&.dstr_type?
374
+ delimiter = delimiter&.source
375
+
376
+ delimiter if %w[' "].include?(delimiter)
377
+ end
378
+
379
+ # Find the largest possible substring of a string node to retain before a break
380
+ def largest_possible_string(node)
381
+ # The maximum allowed length of a string value is:
382
+ # `Max` - end delimiter (quote) - continuation characters (space and slash)
383
+ max_length = max - 3
384
+ # If the string doesn't start at the beginning of the line, the max length is offset
385
+ max_length -= column_offset_between(node.loc, node.parent.loc) if node.parent
386
+ node.source[0...(max_length)]
387
+ end
273
388
  end
274
389
  end
275
390
  end
@@ -52,7 +52,7 @@ module RuboCop
52
52
  def on_hash(node)
53
53
  # This cop only deals with hashes wrapped by a set of curly
54
54
  # braces like {foo: 1}. That is, not a kwargs hashes.
55
- # Style/MultilineMethodArgumentLineBreaks handles those.
55
+ # Layout/MultilineMethodArgumentLineBreaks handles those.
56
56
  return unless starts_with_curly_brace?(node)
57
57
  return unless node.loc.begin
58
58
 
@@ -33,6 +33,18 @@ module RuboCop
33
33
  #
34
34
  # @example AllowMultilineFinalElement: false (default)
35
35
  #
36
+ # # bad
37
+ # foo(a, b,
38
+ # c
39
+ # )
40
+ #
41
+ # # bad
42
+ # foo(
43
+ # a, b, {
44
+ # foo: "bar",
45
+ # }
46
+ # )
47
+ #
36
48
  # # good
37
49
  # foo(
38
50
  # a,
@@ -44,6 +56,18 @@ module RuboCop
44
56
  #
45
57
  # @example AllowMultilineFinalElement: true
46
58
  #
59
+ # # bad
60
+ # foo(a, b,
61
+ # c
62
+ # )
63
+ #
64
+ # # good
65
+ # foo(
66
+ # a, b, {
67
+ # foo: "bar",
68
+ # }
69
+ # )
70
+ #
47
71
  # # good
48
72
  # foo(
49
73
  # a,
@@ -75,6 +99,7 @@ module RuboCop
75
99
 
76
100
  check_line_breaks(node, args, ignore_last: ignore_last_element?)
77
101
  end
102
+ alias on_csend on_send
78
103
 
79
104
  private
80
105
 
@@ -12,7 +12,7 @@ module RuboCop
12
12
  # argument of the call, then the closing brace should be on the same
13
13
  # line as the last argument of the call.
14
14
  #
15
- # If an method call's opening brace is on the line above the first
15
+ # If a method call's opening brace is on the line above the first
16
16
  # argument of the call, then the closing brace should be on the line
17
17
  # below the last argument of the call.
18
18
  #
@@ -109,6 +109,7 @@ module RuboCop
109
109
  def on_send(node)
110
110
  check_brace_layout(node)
111
111
  end
112
+ alias on_csend on_send
112
113
 
113
114
  private
114
115
 
@@ -100,7 +100,7 @@ module RuboCop
100
100
 
101
101
  def extra_indentation(given_style, parent)
102
102
  if given_style == :indented_relative_to_receiver
103
- if parent && (parent.splat_type? || parent.kwsplat_type?)
103
+ if parent&.type?(:splat, :kwsplat)
104
104
  configured_indentation_width - parent.loc.operator.length
105
105
  else
106
106
  configured_indentation_width
@@ -216,7 +216,7 @@ module RuboCop
216
216
 
217
217
  def get_dot_right_above(node)
218
218
  node.each_ancestor.find do |a|
219
- dot = a.loc.respond_to?(:dot) && a.loc.dot
219
+ dot = a.loc.dot if a.loc?(:dot)
220
220
  next unless dot
221
221
 
222
222
  dot.line == node.loc.dot.line - 1 && dot.column == node.loc.dot.column
@@ -224,7 +224,7 @@ module RuboCop
224
224
  end
225
225
 
226
226
  def find_multiline_block_chain_node(node)
227
- return unless (block_node = node.each_descendant(:block, :numblock).first)
227
+ return unless (block_node = node.each_descendant(:any_block).first)
228
228
  return unless block_node.multiline? && block_node.parent.call_type?
229
229
 
230
230
  if node.receiver.call_type?
@@ -239,7 +239,7 @@ module RuboCop
239
239
  node = node.receiver while node.receiver
240
240
  # ascend to first call which has a dot
241
241
  node = node.parent
242
- node = node.parent until node.loc.respond_to?(:dot) && node.loc.dot
242
+ node = node.parent until node.loc?(:dot)
243
243
 
244
244
  node
245
245
  end
@@ -12,7 +12,7 @@ module RuboCop
12
12
  # first parameter of the definition, then the closing brace should be
13
13
  # on the same line as the last parameter of the definition.
14
14
  #
15
- # If an method definition's opening brace is on the line above the first
15
+ # If a method definition's opening brace is on the line above the first
16
16
  # parameter of the definition, then the closing brace should be on the
17
17
  # line below the last parameter of the definition.
18
18
  #
@@ -76,9 +76,8 @@ module RuboCop
76
76
  end
77
77
 
78
78
  def check_and_or(node)
79
- lhs, rhs = *node
80
- range = offending_range(node, lhs, rhs.source_range, style)
81
- check(range, node, lhs, rhs.source_range)
79
+ range = offending_range(node, node.lhs, node.rhs.source_range, style)
80
+ check(range, node, node.lhs, node.rhs.source_range)
82
81
  end
83
82
 
84
83
  def offending_range(node, lhs, rhs, given_style)
@@ -3,11 +3,10 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # Here we check if the parameters on a multi-line method call or
7
- # definition are aligned.
6
+ # Check that the parameters on a multi-line method call or definition are aligned.
8
7
  #
9
- # To set the alignment of the first argument, use the cop
10
- # FirstParameterIndentation.
8
+ # To set the alignment of the first argument, use the
9
+ # `Layout/FirstParameterIndentation` cop.
11
10
  #
12
11
  # @example EnforcedStyle: with_first_parameter (default)
13
12
  # # good
@@ -44,6 +44,7 @@ module RuboCop
44
44
  #
45
45
  class RedundantLineBreak < Base
46
46
  include CheckAssignment
47
+ include CheckSingleLineSuitability
47
48
  extend AutoCorrector
48
49
 
49
50
  MSG = 'Redundant line break detected.'
@@ -84,8 +85,8 @@ module RuboCop
84
85
  end
85
86
 
86
87
  def offense?(node)
87
- return false if !node.multiline? || too_long?(node) || !suitable_as_single_line?(node)
88
- return require_backslash?(node) if node.and_type? || node.or_type?
88
+ return false unless node.multiline? && suitable_as_single_line?(node)
89
+ return require_backslash?(node) if node.operator_keyword?
89
90
 
90
91
  !index_access_call_chained?(node) && !configured_to_not_be_inspected?(node)
91
92
  end
@@ -102,58 +103,26 @@ module RuboCop
102
103
 
103
104
  def configured_to_not_be_inspected?(node)
104
105
  return true if other_cop_takes_precedence?(node)
106
+ return false if cop_config['InspectBlocks']
105
107
 
106
- !cop_config['InspectBlocks'] && (node.block_type? ||
107
- any_descendant?(node, :block, &:multiline?))
108
+ node.any_block_type? || any_descendant?(node, :any_block, &:multiline?)
108
109
  end
109
110
 
110
111
  def other_cop_takes_precedence?(node)
111
- single_line_block_chain_enabled? && any_descendant?(node, :block) do |block_node|
112
+ single_line_block_chain_enabled? && any_descendant?(node, :any_block) do |block_node|
112
113
  block_node.parent.send_type? && block_node.parent.loc.dot && !block_node.multiline?
113
114
  end
114
115
  end
115
116
 
116
117
  def single_line_block_chain_enabled?
117
- @config.for_cop('Layout/SingleLineBlockChain')['Enabled']
118
- end
119
-
120
- def suitable_as_single_line?(node)
121
- !comment_within?(node) &&
122
- node.each_descendant(:if, :case, :kwbegin, :def, :defs).none? &&
123
- node.each_descendant(:dstr, :str).none? { |n| n.heredoc? || n.value.include?("\n") } &&
124
- node.each_descendant(:begin, :sym).none? { |b| !b.single_line? }
118
+ @config.cop_enabled?('Layout/SingleLineBlockChain')
125
119
  end
126
120
 
127
121
  def convertible_block?(node)
128
- parent = node.parent
129
- parent&.block_type? && node == parent.send_node &&
130
- (node.parenthesized? || !node.arguments?)
131
- end
122
+ return false unless (parent = node.parent)
132
123
 
133
- def comment_within?(node)
134
- comment_line_numbers = processed_source.comments.map { |comment| comment.loc.line }
135
-
136
- comment_line_numbers.any? do |comment_line_number|
137
- comment_line_number >= node.first_line && comment_line_number <= node.last_line
138
- end
139
- end
140
-
141
- def too_long?(node)
142
- lines = processed_source.lines[(node.first_line - 1)...node.last_line]
143
- to_single_line(lines.join("\n")).length > max_line_length
144
- end
145
-
146
- def to_single_line(source)
147
- source
148
- .gsub(/" *\\\n\s*'/, %q(" + ')) # Double quote, backslash, and then single quote
149
- .gsub(/' *\\\n\s*"/, %q(' + ")) # Single quote, backslash, and then double quote
150
- .gsub(/(["']) *\\\n\s*\1/, '') # Double or single quote, backslash, then same quote
151
- .gsub(/\n\s*(?=(&)?\.\w)/, '') # Extra space within method chaining which includes `&.`
152
- .gsub(/\s*\\?\n\s*/, ' ') # Any other line break, with or without backslash
153
- end
154
-
155
- def max_line_length
156
- config.for_cop('Layout/LineLength')['Max']
124
+ parent.any_block_type? && node == parent.send_node &&
125
+ (node.parenthesized? || !node.arguments?)
157
126
  end
158
127
  end
159
128
  end
@@ -29,7 +29,7 @@ module RuboCop
29
29
  MSG = '`%<kw_loc>s` at %<kw_loc_line>d, %<kw_loc_column>d is not ' \
30
30
  'aligned with `%<beginning>s` at ' \
31
31
  '%<begin_loc_line>d, %<begin_loc_column>d.'
32
- ANCESTOR_TYPES = %i[kwbegin def defs class module block numblock].freeze
32
+ ANCESTOR_TYPES = %i[kwbegin def defs class module any_block].freeze
33
33
  ANCESTOR_TYPES_WITH_ACCESS_MODIFIERS = %i[def defs].freeze
34
34
  ALTERNATIVE_ACCESS_MODIFIERS = %i[public_class_method private_class_method].freeze
35
35
 
@@ -92,6 +92,7 @@ module RuboCop
92
92
  )
93
93
  end
94
94
 
95
+ # rubocop:disable Metrics/AbcSize
95
96
  def alignment_source(node, starting_loc)
96
97
  ending_loc =
97
98
  case node.type
@@ -101,8 +102,7 @@ module RuboCop
101
102
  :lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
102
103
  node.loc.name
103
104
  when :masgn
104
- mlhs_node, = *node
105
- mlhs_node.source_range
105
+ node.lhs.source_range
106
106
  else
107
107
  # It is a wrapper with receiver of object attribute or access modifier.
108
108
  node.receiver&.source_range || node.child_nodes.first.loc.name
@@ -110,6 +110,7 @@ module RuboCop
110
110
 
111
111
  range_between(starting_loc.begin_pos, ending_loc.end_pos).source
112
112
  end
113
+ # rubocop:enable Metrics/AbcSize
113
114
 
114
115
  # We will use ancestor or wrapper with access modifier.
115
116