rubocop 1.79.2 → 1.87.0

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 (376) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +185 -20
  5. data/config/obsoletion.yml +9 -0
  6. data/exe/rubocop +1 -8
  7. data/lib/rubocop/cache_config.rb +29 -0
  8. data/lib/rubocop/cli/command/auto_generate_config.rb +30 -4
  9. data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
  10. data/lib/rubocop/cli/command/lsp.rb +1 -1
  11. data/lib/rubocop/cli/command/mcp.rb +19 -0
  12. data/lib/rubocop/cli/command/show_cops.rb +2 -2
  13. data/lib/rubocop/cli/command/show_docs_url.rb +4 -8
  14. data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
  15. data/lib/rubocop/cli.rb +35 -9
  16. data/lib/rubocop/comment_config.rb +59 -17
  17. data/lib/rubocop/config.rb +14 -10
  18. data/lib/rubocop/config_finder.rb +1 -1
  19. data/lib/rubocop/config_loader.rb +37 -23
  20. data/lib/rubocop/config_loader_resolver.rb +20 -10
  21. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -2
  22. data/lib/rubocop/config_store.rb +7 -2
  23. data/lib/rubocop/config_validator.rb +1 -1
  24. data/lib/rubocop/cop/autocorrect_logic.rb +10 -5
  25. data/lib/rubocop/cop/base.rb +8 -2
  26. data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
  27. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -2
  28. data/lib/rubocop/cop/correctors/alignment_corrector.rb +26 -7
  29. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  30. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
  31. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
  32. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +33 -2
  33. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  34. data/lib/rubocop/cop/correctors.rb +28 -0
  35. data/lib/rubocop/cop/documentation.rb +2 -3
  36. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  37. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  38. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -2
  39. data/lib/rubocop/cop/gemspec/require_mfa.rb +5 -5
  40. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
  41. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
  42. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  43. data/lib/rubocop/cop/internal_affairs/location_exists.rb +28 -2
  44. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  45. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +9 -9
  46. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
  47. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +3 -1
  48. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
  49. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
  50. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  51. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -2
  52. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  53. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
  54. data/lib/rubocop/cop/layout/case_indentation.rb +3 -1
  55. data/lib/rubocop/cop/layout/class_structure.rb +14 -7
  56. data/lib/rubocop/cop/layout/dot_position.rb +2 -2
  57. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +26 -7
  58. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +31 -13
  59. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +2 -2
  60. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
  61. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12 -2
  62. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
  63. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  64. data/lib/rubocop/cop/layout/end_alignment.rb +10 -3
  65. data/lib/rubocop/cop/layout/first_argument_indentation.rb +34 -1
  66. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
  67. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +7 -1
  68. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
  69. data/lib/rubocop/cop/layout/hash_alignment.rb +3 -6
  70. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
  71. data/lib/rubocop/cop/layout/heredoc_indentation.rb +33 -3
  72. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  73. data/lib/rubocop/cop/layout/indentation_width.rb +123 -7
  74. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
  75. data/lib/rubocop/cop/layout/line_length.rb +26 -9
  76. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
  77. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -2
  78. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
  79. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
  80. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
  81. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +229 -39
  82. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +8 -4
  83. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  84. data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -1
  85. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +13 -3
  86. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
  87. data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
  88. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  89. data/lib/rubocop/cop/layout/space_around_keyword.rb +4 -2
  90. data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -1
  91. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
  92. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  93. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  94. data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -3
  95. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
  96. data/lib/rubocop/cop/lint/constant_reassignment.rb +93 -11
  97. data/lib/rubocop/cop/lint/constant_resolution.rb +6 -6
  98. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +14 -8
  99. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  100. data/lib/rubocop/cop/lint/debugger.rb +0 -2
  101. data/lib/rubocop/cop/lint/deprecated_constants.rb +1 -1
  102. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4 -1
  103. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
  104. data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -12
  105. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
  106. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  107. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  108. data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -1
  109. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  110. data/lib/rubocop/cop/lint/empty_interpolation.rb +11 -0
  111. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  112. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  113. data/lib/rubocop/cop/lint/float_comparison.rb +1 -1
  114. data/lib/rubocop/cop/lint/interpolation_check.rb +7 -2
  115. data/lib/rubocop/cop/lint/literal_as_condition.rb +5 -1
  116. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  117. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +18 -9
  118. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  119. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  120. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +4 -0
  121. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
  122. data/lib/rubocop/cop/lint/number_conversion.rb +6 -6
  123. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  124. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -13
  125. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +23 -9
  126. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +2 -11
  127. data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -2
  128. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +23 -6
  129. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -2
  130. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +3 -3
  131. data/lib/rubocop/cop/lint/require_relative_self_path.rb +3 -1
  132. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
  133. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -0
  134. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +7 -1
  135. data/lib/rubocop/cop/lint/self_assignment.rb +15 -6
  136. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  137. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  138. data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
  139. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  140. data/lib/rubocop/cop/lint/to_json.rb +12 -16
  141. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -0
  142. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -1
  143. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
  144. data/lib/rubocop/cop/lint/unreachable_code.rb +7 -5
  145. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  146. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  147. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  148. data/lib/rubocop/cop/lint/useless_assignment.rb +48 -25
  149. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +4 -4
  150. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
  151. data/lib/rubocop/cop/lint/useless_or.rb +15 -2
  152. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +1 -1
  153. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +37 -11
  154. data/lib/rubocop/cop/lint/void.rb +39 -12
  155. data/lib/rubocop/cop/message_annotator.rb +1 -1
  156. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  157. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  158. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  159. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
  160. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  161. data/lib/rubocop/cop/migration/department_name.rb +12 -1
  162. data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
  163. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +4 -6
  164. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  165. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  166. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  167. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +5 -5
  168. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  169. data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -60
  170. data/lib/rubocop/cop/mixin/line_length_help.rb +21 -2
  171. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  172. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  173. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  174. data/lib/rubocop/cop/mixin/project_index_help.rb +48 -0
  175. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  176. data/lib/rubocop/cop/mixin/statement_modifier.rb +0 -6
  177. data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -5
  178. data/lib/rubocop/cop/mixin.rb +86 -0
  179. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  180. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  181. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  182. data/lib/rubocop/cop/naming/method_name.rb +5 -3
  183. data/lib/rubocop/cop/naming/predicate_method.rb +32 -8
  184. data/lib/rubocop/cop/naming/predicate_prefix.rb +12 -12
  185. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
  186. data/lib/rubocop/cop/offense.rb +17 -1
  187. data/lib/rubocop/cop/registry.rb +62 -38
  188. data/lib/rubocop/cop/security/eval.rb +15 -2
  189. data/lib/rubocop/cop/security/io_methods.rb +1 -1
  190. data/lib/rubocop/cop/security/json_load.rb +33 -11
  191. data/lib/rubocop/cop/style/access_modifier_declarations.rb +15 -4
  192. data/lib/rubocop/cop/style/accessor_grouping.rb +4 -2
  193. data/lib/rubocop/cop/style/alias.rb +14 -2
  194. data/lib/rubocop/cop/style/and_or.rb +1 -0
  195. data/lib/rubocop/cop/style/arguments_forwarding.rb +25 -7
  196. data/lib/rubocop/cop/style/array_intersect.rb +46 -12
  197. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
  198. data/lib/rubocop/cop/style/array_join.rb +4 -2
  199. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  200. data/lib/rubocop/cop/style/attr.rb +5 -2
  201. data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
  202. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  203. data/lib/rubocop/cop/style/bitwise_predicate.rb +8 -1
  204. data/lib/rubocop/cop/style/block_delimiters.rb +27 -34
  205. data/lib/rubocop/cop/style/case_equality.rb +15 -13
  206. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  207. data/lib/rubocop/cop/style/class_and_module_children.rb +19 -2
  208. data/lib/rubocop/cop/style/collection_compact.rb +36 -16
  209. data/lib/rubocop/cop/style/colon_method_call.rb +3 -1
  210. data/lib/rubocop/cop/style/concat_array_literals.rb +2 -0
  211. data/lib/rubocop/cop/style/conditional_assignment.rb +8 -18
  212. data/lib/rubocop/cop/style/constant_visibility.rb +17 -12
  213. data/lib/rubocop/cop/style/copyright.rb +22 -11
  214. data/lib/rubocop/cop/style/date_time.rb +2 -2
  215. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
  216. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  217. data/lib/rubocop/cop/style/documentation.rb +6 -6
  218. data/lib/rubocop/cop/style/documentation_method.rb +8 -8
  219. data/lib/rubocop/cop/style/double_negation.rb +1 -1
  220. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  221. data/lib/rubocop/cop/style/each_with_object.rb +2 -0
  222. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  223. data/lib/rubocop/cop/style/empty_class_definition.rb +119 -0
  224. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  225. data/lib/rubocop/cop/style/empty_method.rb +0 -6
  226. data/lib/rubocop/cop/style/encoding.rb +7 -1
  227. data/lib/rubocop/cop/style/end_block.rb +3 -1
  228. data/lib/rubocop/cop/style/endless_method.rb +23 -5
  229. data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
  230. data/lib/rubocop/cop/style/file_open.rb +84 -0
  231. data/lib/rubocop/cop/style/file_write.rb +18 -16
  232. data/lib/rubocop/cop/style/float_division.rb +15 -1
  233. data/lib/rubocop/cop/style/for.rb +3 -0
  234. data/lib/rubocop/cop/style/format_string.rb +4 -3
  235. data/lib/rubocop/cop/style/format_string_token.rb +49 -5
  236. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  237. data/lib/rubocop/cop/style/guard_clause.rb +27 -22
  238. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
  239. data/lib/rubocop/cop/style/hash_conversion.rb +1 -1
  240. data/lib/rubocop/cop/style/hash_lookup_method.rb +106 -0
  241. data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
  242. data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
  243. data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
  244. data/lib/rubocop/cop/style/if_inside_else.rb +16 -7
  245. data/lib/rubocop/cop/style/if_unless_modifier.rb +57 -17
  246. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12 -12
  247. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +4 -1
  248. data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
  249. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  250. data/lib/rubocop/cop/style/inline_comment.rb +4 -1
  251. data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
  252. data/lib/rubocop/cop/style/lambda_call.rb +8 -8
  253. data/lib/rubocop/cop/style/magic_comment_format.rb +3 -3
  254. data/lib/rubocop/cop/style/map_join.rb +123 -0
  255. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
  256. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17 -4
  257. data/lib/rubocop/cop/style/method_def_parentheses.rb +2 -4
  258. data/lib/rubocop/cop/style/min_max_comparison.rb +1 -1
  259. data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
  260. data/lib/rubocop/cop/style/multiline_if_then.rb +4 -4
  261. data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -4
  262. data/lib/rubocop/cop/style/mutable_constant.rb +1 -1
  263. data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
  264. data/lib/rubocop/cop/style/nil_comparison.rb +11 -10
  265. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  266. data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
  267. data/lib/rubocop/cop/style/not.rb +2 -0
  268. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  269. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  270. data/lib/rubocop/cop/style/one_line_conditional.rb +21 -12
  271. data/lib/rubocop/cop/style/operator_method_call.rb +11 -2
  272. data/lib/rubocop/cop/style/parallel_assignment.rb +6 -2
  273. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  274. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -0
  275. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  276. data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
  277. data/lib/rubocop/cop/style/proc.rb +3 -2
  278. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  279. data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
  280. data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
  281. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  282. data/lib/rubocop/cop/style/redundant_begin.rb +37 -3
  283. data/lib/rubocop/cop/style/redundant_condition.rb +6 -3
  284. data/lib/rubocop/cop/style/redundant_constant_base.rb +5 -5
  285. data/lib/rubocop/cop/style/redundant_each.rb +3 -3
  286. data/lib/rubocop/cop/style/redundant_exception.rb +1 -1
  287. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
  288. data/lib/rubocop/cop/style/redundant_format.rb +26 -5
  289. data/lib/rubocop/cop/style/redundant_interpolation.rb +11 -2
  290. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
  291. data/lib/rubocop/cop/style/redundant_line_continuation.rb +16 -0
  292. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  293. data/lib/rubocop/cop/style/redundant_parentheses.rb +36 -30
  294. data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
  295. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +9 -0
  296. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
  297. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -0
  298. data/lib/rubocop/cop/style/redundant_return.rb +3 -1
  299. data/lib/rubocop/cop/style/redundant_self.rb +2 -2
  300. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
  301. data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
  302. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +114 -0
  303. data/lib/rubocop/cop/style/regexp_literal.rb +31 -2
  304. data/lib/rubocop/cop/style/rescue_modifier.rb +3 -3
  305. data/lib/rubocop/cop/style/reverse_find.rb +51 -0
  306. data/lib/rubocop/cop/style/safe_navigation.rb +25 -8
  307. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  308. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  309. data/lib/rubocop/cop/style/select_by_regexp.rb +51 -21
  310. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  311. data/lib/rubocop/cop/style/semicolon.rb +25 -7
  312. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  313. data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -1
  314. data/lib/rubocop/cop/style/single_line_methods.rb +3 -1
  315. data/lib/rubocop/cop/style/sole_nested_conditional.rb +12 -3
  316. data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
  317. data/lib/rubocop/cop/style/string_concatenation.rb +17 -13
  318. data/lib/rubocop/cop/style/struct_inheritance.rb +13 -0
  319. data/lib/rubocop/cop/style/super_arguments.rb +2 -2
  320. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  321. data/lib/rubocop/cop/style/symbol_proc.rb +7 -6
  322. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  323. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -2
  324. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45 -0
  325. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  326. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  327. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +11 -11
  328. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  329. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  330. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -0
  331. data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
  332. data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
  333. data/lib/rubocop/cop/team.rb +87 -36
  334. data/lib/rubocop/cop/util.rb +2 -3
  335. data/lib/rubocop/cop/utils/format_string.rb +10 -0
  336. data/lib/rubocop/cop/variable_force/branch.rb +30 -6
  337. data/lib/rubocop/cop/variable_force/variable.rb +1 -1
  338. data/lib/rubocop/cop/variable_force.rb +9 -7
  339. data/lib/rubocop/cops_documentation_generator.rb +4 -4
  340. data/lib/rubocop/directive_comment.rb +48 -4
  341. data/lib/rubocop/file_patterns.rb +9 -1
  342. data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
  343. data/lib/rubocop/formatter/disabled_config_formatter.rb +24 -7
  344. data/lib/rubocop/formatter/formatter_set.rb +2 -2
  345. data/lib/rubocop/formatter/junit_formatter.rb +1 -1
  346. data/lib/rubocop/formatter/simple_text_formatter.rb +0 -2
  347. data/lib/rubocop/formatter/tap_formatter.rb +5 -2
  348. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
  349. data/lib/rubocop/formatter.rb +22 -21
  350. data/lib/rubocop/lsp/diagnostic.rb +18 -33
  351. data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
  352. data/lib/rubocop/lsp/routes.rb +43 -7
  353. data/lib/rubocop/lsp/runtime.rb +13 -4
  354. data/lib/rubocop/lsp/stdin_runner.rb +8 -17
  355. data/lib/rubocop/magic_comment.rb +20 -0
  356. data/lib/rubocop/mcp/server.rb +200 -0
  357. data/lib/rubocop/options.rb +35 -4
  358. data/lib/rubocop/path_util.rb +14 -2
  359. data/lib/rubocop/plugin/loader.rb +1 -1
  360. data/lib/rubocop/project_index_loader.rb +66 -0
  361. data/lib/rubocop/rake_task.rb +1 -1
  362. data/lib/rubocop/remote_config.rb +10 -8
  363. data/lib/rubocop/result_cache.rb +61 -38
  364. data/lib/rubocop/rspec/cop_helper.rb +8 -0
  365. data/lib/rubocop/rspec/shared_contexts.rb +39 -5
  366. data/lib/rubocop/rspec/support.rb +2 -1
  367. data/lib/rubocop/runner.rb +134 -57
  368. data/lib/rubocop/server/cache.rb +6 -29
  369. data/lib/rubocop/server/core.rb +2 -0
  370. data/lib/rubocop/target_finder.rb +17 -10
  371. data/lib/rubocop/target_ruby.rb +31 -14
  372. data/lib/rubocop/version.rb +21 -3
  373. data/lib/rubocop.rb +28 -96
  374. data/lib/ruby_lsp/rubocop/addon.rb +23 -8
  375. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +49 -15
  376. metadata +38 -9
@@ -172,7 +172,40 @@ module RuboCop
172
172
  end
173
173
 
174
174
  def autocorrect(corrector, node)
175
- AlignmentCorrector.correct(corrector, processed_source, node, column_delta)
175
+ return unless node
176
+
177
+ send_node = node.parent
178
+ return unless send_node
179
+
180
+ top_level_send = find_top_level_send(send_node)
181
+ node_to_correct =
182
+ should_correct_entire_chain?(send_node, top_level_send) ? top_level_send : node
183
+
184
+ AlignmentCorrector.correct(corrector, processed_source, node_to_correct, column_delta)
185
+ end
186
+
187
+ def should_correct_entire_chain?(send_node, top_level_send)
188
+ return false unless style == :special_for_inner_method_call_in_parentheses
189
+ return false unless inner_call?(top_level_send)
190
+ return false unless display_column(send_node.source_range) < column_delta.abs
191
+
192
+ top_level_send != send_node || begins_its_line?(top_level_send.loc.end)
193
+ end
194
+
195
+ def inner_call?(top_level_send)
196
+ outer_call = top_level_send.parent
197
+
198
+ outer_call&.send_type? && outer_call.parenthesized?
199
+ end
200
+
201
+ def find_top_level_send(send_node)
202
+ top_level_send = send_node
203
+ while top_level_send.parent&.send_type? &&
204
+ top_level_send.parent.receiver == top_level_send &&
205
+ top_level_send.parent.loc.dot
206
+ top_level_send = top_level_send.parent
207
+ end
208
+ top_level_send
176
209
  end
177
210
 
178
211
  def bare_operator?(node)
@@ -20,6 +20,27 @@ module RuboCop
20
20
  # # good
21
21
  # [:a, :b]
22
22
  #
23
+ # @example AllowImplicitArrayLiterals: false (default)
24
+ #
25
+ # # bad
26
+ # a = b,
27
+ # c
28
+ #
29
+ # # good
30
+ # a =
31
+ # b,
32
+ # c
33
+ #
34
+ # @example AllowImplicitArrayLiterals: true
35
+ #
36
+ # # good
37
+ # a = b,
38
+ # c
39
+ #
40
+ # a =
41
+ # b,
42
+ # c
43
+ #
23
44
  # @example AllowMultilineFinalElement: false (default)
24
45
  #
25
46
  # # bad
@@ -48,6 +69,7 @@ module RuboCop
48
69
 
49
70
  def on_array(node)
50
71
  return if !node.loc.begin && !assignment_on_same_line?(node)
72
+ return if allow_implicit_array_brackets? && !node.bracketed?
51
73
 
52
74
  check_children_line_break(node, node.children, ignore_last: ignore_last_element?)
53
75
  end
@@ -59,6 +81,10 @@ module RuboCop
59
81
  /\s*=\s*$/.match?(source)
60
82
  end
61
83
 
84
+ def allow_implicit_array_brackets?
85
+ !!cop_config['AllowImplicitArrayLiterals']
86
+ end
87
+
62
88
  def ignore_last_element?
63
89
  !!cop_config['AllowMultilineFinalElement']
64
90
  end
@@ -135,7 +135,13 @@ module RuboCop
135
135
  private
136
136
 
137
137
  def autocorrect(corrector, node)
138
- AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
138
+ line_range = if !node.is_a?(AST::Node) || node.value.first_line <= node.key.first_line
139
+ node
140
+ else
141
+ processed_source.buffer.line_range(node.loc.line)
142
+ end
143
+
144
+ AlignmentCorrector.correct(corrector, processed_source, line_range, @column_delta)
139
145
  end
140
146
 
141
147
  def brace_alignment_style
@@ -8,40 +8,40 @@ module RuboCop
8
8
  #
9
9
  # @example
10
10
  #
11
- # # bad
12
- # { a: 1,
13
- # b: 2}
11
+ # # bad
12
+ # { a: 1,
13
+ # b: 2}
14
14
  #
15
- # # good
16
- # {
17
- # a: 1,
18
- # b: 2 }
15
+ # # good
16
+ # {
17
+ # a: 1,
18
+ # b: 2 }
19
19
  #
20
- # # good
21
- # {
22
- # a: 1, b: {
23
- # c: 3
24
- # }}
20
+ # # good
21
+ # {
22
+ # a: 1, b: {
23
+ # c: 3
24
+ # }}
25
25
  #
26
26
  # @example AllowMultilineFinalElement: false (default)
27
27
  #
28
- # # bad
29
- # { a: 1, b: {
30
- # c: 3
31
- # }}
28
+ # # bad
29
+ # { a: 1, b: {
30
+ # c: 3
31
+ # }}
32
32
  #
33
33
  # @example AllowMultilineFinalElement: true
34
34
  #
35
- # # bad
36
- # { a: 1,
37
- # b: {
38
- # c: 3
39
- # }}
35
+ # # bad
36
+ # { a: 1,
37
+ # b: {
38
+ # c: 3
39
+ # }}
40
40
  #
41
- # # good
42
- # { a: 1, b: {
43
- # c: 3
44
- # }}
41
+ # # good
42
+ # { a: 1, b: {
43
+ # c: 3
44
+ # }}
45
45
  #
46
46
  class FirstHashElementLineBreak < Base
47
47
  include FirstElementLineBreak
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # Check that the keys, separators, and values of a multi-line hash
6
+ # Checks that the keys, separators, and values of a multi-line hash
7
7
  # literal are aligned according to configuration. The configuration
8
8
  # options are:
9
9
  #
@@ -193,7 +193,6 @@ module RuboCop
193
193
  SEPARATOR_ALIGNMENT_STYLES = %w[EnforcedColonStyle EnforcedHashRocketStyle].freeze
194
194
 
195
195
  def on_send(node)
196
- return if double_splat?(node)
197
196
  return unless node.arguments?
198
197
 
199
198
  last_argument = node.last_argument
@@ -233,6 +232,8 @@ module RuboCop
233
232
  end
234
233
 
235
234
  def argument_before_hash(hash_node)
235
+ return hash_node.children.first.children.first if hash_node.children.first.kwsplat_type?
236
+
236
237
  hash_node.left_sibling.respond_to?(:loc) ? hash_node.left_sibling : nil
237
238
  end
238
239
 
@@ -241,10 +242,6 @@ module RuboCop
241
242
  self.column_deltas = Hash.new { |hash, key| hash[key] = {} }
242
243
  end
243
244
 
244
- def double_splat?(node)
245
- node.children.last.is_a?(Symbol)
246
- end
247
-
248
245
  def check_pairs(node)
249
246
  first_pair = node.pairs.first
250
247
  reset!
@@ -168,7 +168,7 @@ module RuboCop
168
168
 
169
169
  def subsequent_closing_parentheses_in_same_line?(outermost_send)
170
170
  last_arg_of_outer_send = outermost_send.last_argument
171
- return false unless last_arg_of_outer_send&.loc.respond_to?(:end) &&
171
+ return false unless last_arg_of_outer_send&.loc?(:end) &&
172
172
  (end_of_last_arg_of_outer_send = last_arg_of_outer_send.loc.end)
173
173
 
174
174
  end_of_outer_send = outermost_send.loc.end
@@ -230,7 +230,7 @@ module RuboCop
230
230
 
231
231
  def find_most_bottom_of_heredoc_end(arguments)
232
232
  arguments.filter_map do |argument|
233
- argument.loc.heredoc_end.end_pos if argument.loc.respond_to?(:heredoc_end)
233
+ argument.loc.heredoc_end.end_pos if argument.loc?(:heredoc_end)
234
234
  end.max
235
235
  end
236
236
 
@@ -21,6 +21,23 @@ module RuboCop
21
21
  # something
22
22
  # RUBY
23
23
  #
24
+ # @example AllCops:ActiveSupportExtensionsEnabled: false (default)
25
+ # # good
26
+ # <<-RUBY.squish
27
+ # something
28
+ # RUBY
29
+ #
30
+ # @example AllCops:ActiveSupportExtensionsEnabled: true
31
+ # # bad
32
+ # <<-RUBY.squish
33
+ # something
34
+ # RUBY
35
+ #
36
+ # # good
37
+ # <<~RUBY.squish
38
+ # something
39
+ # RUBY
40
+ #
24
41
  class HeredocIndentation < Base
25
42
  include Alignment
26
43
  include Heredoc
@@ -33,6 +50,11 @@ module RuboCop
33
50
  'heredoc by using `<<~` instead of `%<current_indent_type>s`.'
34
51
  WIDTH_MSG = 'Use %<indentation_width>d spaces for indentation in a heredoc.'
35
52
 
53
+ # @!method squish_method?(node)
54
+ def_node_matcher :squish_method?, <<~PATTERN
55
+ (send _ {:squish :squish!})
56
+ PATTERN
57
+
36
58
  def on_heredoc(node)
37
59
  body = heredoc_body(node)
38
60
  return if body.strip.empty?
@@ -44,7 +66,7 @@ module RuboCop
44
66
  expected_indent_level = base_indent_level(node) + configured_indentation_width
45
67
  return if expected_indent_level == body_indent_level
46
68
  else
47
- return unless body_indent_level.zero?
69
+ return unless body_indent_level.zero? || heredoc_squish?(node)
48
70
  end
49
71
 
50
72
  return if line_too_long?(node)
@@ -60,6 +82,8 @@ module RuboCop
60
82
  add_offense(node.loc.heredoc_body, message: message) do |corrector|
61
83
  if heredoc_indent_type == '~'
62
84
  adjust_squiggly(corrector, node)
85
+ elsif heredoc_squish?(node)
86
+ adjust_heredoc_squish(corrector, node)
63
87
  else
64
88
  adjust_minus(corrector, node)
65
89
  end
@@ -89,6 +113,7 @@ module RuboCop
89
113
  end
90
114
 
91
115
  def line_too_long?(node)
116
+ return false unless max_line_length
92
117
  return false if unlimited_heredoc_length?
93
118
 
94
119
  body = heredoc_body(node)
@@ -108,8 +133,9 @@ module RuboCop
108
133
  config.for_cop('Layout/LineLength')['AllowHeredoc']
109
134
  end
110
135
 
111
- def max_line_length
112
- config.for_cop('Layout/LineLength')['Max']
136
+ def adjust_heredoc_squish(corrector, node)
137
+ adjust_squiggly(corrector, node)
138
+ adjust_minus(corrector, node)
113
139
  end
114
140
 
115
141
  def adjust_squiggly(corrector, node)
@@ -159,6 +185,10 @@ module RuboCop
159
185
  def heredoc_end(node)
160
186
  node.loc.heredoc_end.source
161
187
  end
188
+
189
+ def heredoc_squish?(node)
190
+ active_support_extensions_enabled? && squish_method?(node.parent)
191
+ end
162
192
  end
163
193
  end
164
194
  end
@@ -99,7 +99,7 @@ module RuboCop
99
99
 
100
100
  if str.heredoc?
101
101
  ranges << loc.heredoc_body
102
- elsif loc.respond_to?(:begin) && loc.begin
102
+ elsif str.loc?(:begin)
103
103
  ranges << loc.expression
104
104
  end
105
105
  end
@@ -5,6 +5,8 @@ module RuboCop
5
5
  module Layout
6
6
  # Checks for indentation that doesn't use the specified number of spaces.
7
7
  # The indentation width can be configured using the `Width` setting. The default width is 2.
8
+ # The block body indentation for method chain blocks can be configured using the
9
+ # `EnforcedStyleAlignWith` setting.
8
10
  #
9
11
  # See also the `Layout/IndentationConsistency` cop which is the companion to this one.
10
12
  #
@@ -41,7 +43,22 @@ module RuboCop
41
43
  # end
42
44
  # end
43
45
  # end
46
+ #
47
+ # @example EnforcedStyleAlignWith: start_of_line (default)
48
+ # # good
49
+ # records.uniq { |el| el[:profile_id] }
50
+ # .map do |message|
51
+ # SomeJob.perform_later(message[:id])
52
+ # end
53
+ #
54
+ # @example EnforcedStyleAlignWith: relative_to_receiver
55
+ # # good
56
+ # records.uniq { |el| el[:profile_id] }
57
+ # .map do |message|
58
+ # SomeJob.perform_later(message[:id])
59
+ # end
44
60
  class IndentationWidth < Base # rubocop:disable Metrics/ClassLength
61
+ include ConfigurableEnforcedStyle
45
62
  include EndKeywordAlignment
46
63
  include Alignment
47
64
  include CheckAssignment
@@ -50,7 +67,7 @@ module RuboCop
50
67
  extend AutoCorrector
51
68
 
52
69
  MSG = 'Use %<configured_indentation_width>d (not %<indentation>d) ' \
53
- 'spaces for%<name>s indentation.'
70
+ '%<indentation_type>s for%<name>s indentation.'
54
71
 
55
72
  # @!method access_modifier?(node)
56
73
  def_node_matcher :access_modifier?, <<~PATTERN
@@ -83,9 +100,11 @@ module RuboCop
83
100
 
84
101
  return unless begins_its_line?(end_loc)
85
102
 
86
- check_indentation(end_loc, node.body)
103
+ base_loc = block_body_indentation_base(node, end_loc)
104
+ check_indentation(base_loc, node.body)
87
105
 
88
106
  return unless indented_internal_methods_style?
107
+ return unless contains_access_modifier?(node.body)
89
108
 
90
109
  check_members(end_loc, [node.body])
91
110
  end
@@ -145,7 +164,7 @@ module RuboCop
145
164
  end
146
165
 
147
166
  def on_case_match(case_match)
148
- case_match.each_in_pattern do |in_pattern_node|
167
+ case_match.in_pattern_branches.each do |in_pattern_node|
149
168
  check_indentation(in_pattern_node.loc.keyword, in_pattern_node.body)
150
169
  end
151
170
 
@@ -164,6 +183,8 @@ module RuboCop
164
183
  private
165
184
 
166
185
  def autocorrect(corrector, node)
186
+ return unless node
187
+
167
188
  AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
168
189
  end
169
190
 
@@ -172,7 +193,7 @@ module RuboCop
172
193
 
173
194
  return unless members.any? && members.first.begin_type?
174
195
 
175
- if indentation_consistency_style == 'indented_internal_methods'
196
+ if indented_internal_methods_style?
176
197
  check_members_for_indented_internal_methods_style(members)
177
198
  else
178
199
  check_members_for_normal_style(base, members)
@@ -301,10 +322,32 @@ module RuboCop
301
322
  end
302
323
 
303
324
  def message(configured_indentation_width, indentation, name)
325
+ if using_tabs?
326
+ message_for_tabs(configured_indentation_width, indentation, name)
327
+ else
328
+ message_for_spaces(configured_indentation_width, indentation, name)
329
+ end
330
+ end
331
+
332
+ def message_for_tabs(configured_indentation_width, indentation, name)
333
+ configured_tabs = 1
334
+ actual_tabs = indentation / configured_indentation_width
335
+
336
+ format(
337
+ MSG,
338
+ configured_indentation_width: configured_tabs,
339
+ indentation: actual_tabs,
340
+ indentation_type: 'tabs',
341
+ name: name
342
+ )
343
+ end
344
+
345
+ def message_for_spaces(configured_indentation_width, indentation, name)
304
346
  format(
305
347
  MSG,
306
348
  configured_indentation_width: configured_indentation_width,
307
349
  indentation: indentation,
350
+ indentation_type: 'spaces',
308
351
  name: name
309
352
  )
310
353
  end
@@ -360,7 +403,13 @@ module RuboCop
360
403
  def offending_range(body_node, indentation)
361
404
  expr = body_node.source_range
362
405
  begin_pos = expr.begin_pos
363
- ind = expr.begin_pos - indentation
406
+
407
+ ind = if using_tabs?
408
+ begin_pos - line_indentation(expr).length
409
+ else
410
+ begin_pos - indentation
411
+ end
412
+
364
413
  pos = indentation >= 0 ? ind..begin_pos : begin_pos..ind
365
414
  range_between(pos.begin, pos.end)
366
415
  end
@@ -374,8 +423,47 @@ module RuboCop
374
423
  starting_node.send_type? && starting_node.bare_access_modifier?
375
424
  end
376
425
 
377
- def configured_indentation_width
378
- cop_config['Width']
426
+ def contains_access_modifier?(body_node)
427
+ return false unless body_node&.begin_type?
428
+
429
+ body_node.children.any? { |child| child.send_type? && child.bare_access_modifier? }
430
+ end
431
+
432
+ def indentation_style
433
+ config.for_cop('Layout/IndentationStyle')['EnforcedStyle'] || 'spaces'
434
+ end
435
+
436
+ def using_tabs?
437
+ indentation_style == 'tabs'
438
+ end
439
+
440
+ def column_offset_between(base_range, range)
441
+ return super unless using_tabs?
442
+
443
+ base_uses_tabs = line_uses_tabs?(base_range)
444
+ range_uses_tabs = line_uses_tabs?(range)
445
+
446
+ return super unless base_uses_tabs || range_uses_tabs
447
+
448
+ visual_column(base_range) - visual_column(range)
449
+ end
450
+
451
+ def line_indentation(range)
452
+ line = processed_source.lines[range.line - 1]
453
+ line[0...range.column]
454
+ end
455
+
456
+ def line_uses_tabs?(range)
457
+ line_indentation(range).include?("\t")
458
+ end
459
+
460
+ def visual_column(range)
461
+ indentation = line_indentation(range)
462
+
463
+ tab_count = indentation.count("\t")
464
+ space_count = indentation.count(' ')
465
+
466
+ (tab_count * configured_indentation_width) + space_count
379
467
  end
380
468
 
381
469
  def leftmost_modifier_of(node)
@@ -383,6 +471,34 @@ module RuboCop
383
471
 
384
472
  leftmost_modifier_of(node.parent)
385
473
  end
474
+
475
+ def block_body_indentation_base(node, end_loc)
476
+ return end_loc unless style == :relative_to_receiver
477
+
478
+ if dot_on_new_line?(node)
479
+ node.send_node.loc.dot
480
+ elsif selector_on_new_line?(node)
481
+ node.send_node.loc.selector
482
+ else
483
+ end_loc
484
+ end
485
+ end
486
+
487
+ def dot_on_new_line?(node)
488
+ send_node = node.send_node
489
+ return false unless send_node.loc?(:dot)
490
+
491
+ receiver = send_node.receiver
492
+ receiver && receiver.last_line < send_node.loc.dot.line
493
+ end
494
+
495
+ def selector_on_new_line?(node)
496
+ send_node = node.send_node
497
+ return false unless send_node.loc?(:dot) && send_node.loc?(:selector)
498
+
499
+ receiver = send_node.receiver
500
+ receiver && receiver.last_line < send_node.loc.selector.line
501
+ end
386
502
  end
387
503
  end
388
504
  end
@@ -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) || ignored_parent?(literal)
104
+ elsif literal.loc?(:begin) || ignored_parent?(literal)
105
105
  ranges << loc.expression
106
106
  end
107
107
  end
@@ -134,6 +134,7 @@ module RuboCop
134
134
 
135
135
  def check_for_breakable_block(block_node)
136
136
  return unless block_node.single_line?
137
+ return if receiver_contains_heredoc?(block_node)
137
138
 
138
139
  line_index = block_node.loc.line - 1
139
140
  range = breakable_block_range(block_node)
@@ -251,17 +252,22 @@ module RuboCop
251
252
  [max - indentation_difference(line), 0].max
252
253
  end
253
254
 
255
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
254
256
  def check_line(line, line_index)
255
257
  return if line_length(line) <= max
256
258
  return if allowed_line?(line, line_index)
259
+ if allow_rbs_inline_annotation? && rbs_inline_annotation_on_source_line?(line_index)
260
+ return
261
+ end
257
262
 
258
- if ignore_cop_directives? && directive_on_source_line?(line_index)
263
+ if allow_cop_directives? && directive_on_source_line?(line_index)
259
264
  return check_directive_line(line, line_index)
260
265
  end
261
266
  return check_line_for_exemptions(line, line_index) if allow_uri? || allow_qualified_name?
262
267
 
263
268
  register_offense(excess_range(nil, line, line_index), line, line_index)
264
269
  end
270
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
265
271
 
266
272
  def allowed_line?(line, line_index)
267
273
  matches_allowed_pattern?(line) ||
@@ -305,6 +311,7 @@ module RuboCop
305
311
  def max
306
312
  cop_config['Max']
307
313
  end
314
+ alias max_line_length max
308
315
 
309
316
  def allow_heredoc?
310
317
  allowed_heredoc
@@ -321,7 +328,7 @@ module RuboCop
321
328
  def extract_heredocs(ast)
322
329
  return [] unless ast
323
330
 
324
- ast.each_node(:str, :dstr, :xstr).select(&:heredoc?).map do |node|
331
+ ast.each_node(:any_str).select(&:heredoc?).map do |node|
325
332
  body = node.location.heredoc_body
326
333
  delimiter = node.location.heredoc_end.source.strip
327
334
  [body.first_line...body.last_line, delimiter]
@@ -341,6 +348,13 @@ module RuboCop
341
348
  heredocs.any? { |range, _delimiter| range.cover?(line_number) }
342
349
  end
343
350
 
351
+ def receiver_contains_heredoc?(node)
352
+ return false unless (receiver = node.receiver)
353
+ return true if receiver.any_str_type? && receiver.heredoc?
354
+
355
+ receiver.each_descendant(:any_str).any?(&:heredoc?)
356
+ end
357
+
344
358
  def check_directive_line(line, line_index)
345
359
  length_without_directive = line_length_without_directive(line)
346
360
  return if length_without_directive <= max
@@ -392,11 +406,11 @@ module RuboCop
392
406
  end
393
407
 
394
408
  def string_delimiter(node)
395
- delimiter = node.loc.begin
396
- if node.parent&.dstr_type? && node.parent.loc.respond_to?(:begin)
397
- delimiter ||= node.parent.loc.begin
398
- end
399
- delimiter = delimiter&.source
409
+ delimiter = if node.loc?(:begin)
410
+ node.loc.begin
411
+ elsif node.parent&.dstr_type? && node.parent.loc?(:begin)
412
+ node.parent.loc.begin
413
+ end&.source
400
414
 
401
415
  delimiter if %w[' "].include?(delimiter)
402
416
  end
@@ -406,8 +420,11 @@ module RuboCop
406
420
  # The maximum allowed length of a string value is:
407
421
  # `Max` - end delimiter (quote) - continuation characters (space and slash)
408
422
  max_length = max - 3
409
- # If the string doesn't start at the beginning of the line, the max length is offset
410
- max_length -= column_offset_between(node.loc, node.parent.loc) if node.parent
423
+ # If the string is on the same line as its parent, offset by the column difference
424
+ # (Only apply when on same line to avoid negative offsets for multi-line dstr)
425
+ if same_line?(node, node.parent)
426
+ max_length -= column_offset_between(node.loc, node.parent.loc)
427
+ end
411
428
  node.source[0...(max_length)]
412
429
  end
413
430
  end