rubocop 1.79.2 → 1.88.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 (421) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +259 -90
  5. data/config/obsoletion.yml +30 -1
  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 +36 -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 +25 -4
  26. data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
  27. data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
  28. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -2
  29. data/lib/rubocop/cop/correctors/alignment_corrector.rb +26 -7
  30. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  31. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
  32. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
  33. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +33 -2
  34. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  35. data/lib/rubocop/cop/correctors.rb +28 -0
  36. data/lib/rubocop/cop/documentation.rb +2 -3
  37. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  38. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  39. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -2
  40. data/lib/rubocop/cop/gemspec/require_mfa.rb +5 -5
  41. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
  42. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
  43. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  44. data/lib/rubocop/cop/internal_affairs/location_exists.rb +28 -2
  45. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  46. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +9 -9
  47. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
  48. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +3 -1
  49. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
  50. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
  51. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
  52. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  53. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -2
  54. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  55. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
  56. data/lib/rubocop/cop/layout/block_alignment.rb +41 -4
  57. data/lib/rubocop/cop/layout/case_indentation.rb +3 -1
  58. data/lib/rubocop/cop/layout/class_structure.rb +14 -7
  59. data/lib/rubocop/cop/layout/dot_position.rb +2 -2
  60. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +26 -7
  61. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +31 -13
  62. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +2 -2
  63. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
  64. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12 -2
  65. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
  66. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  67. data/lib/rubocop/cop/layout/end_alignment.rb +10 -3
  68. data/lib/rubocop/cop/layout/first_argument_indentation.rb +34 -1
  69. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
  70. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +7 -1
  71. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
  72. data/lib/rubocop/cop/layout/hash_alignment.rb +3 -6
  73. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
  74. data/lib/rubocop/cop/layout/heredoc_indentation.rb +33 -3
  75. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  76. data/lib/rubocop/cop/layout/indentation_width.rb +123 -7
  77. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
  78. data/lib/rubocop/cop/layout/line_length.rb +26 -9
  79. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
  80. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -2
  81. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
  82. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
  83. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
  84. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +229 -39
  85. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +8 -4
  86. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  87. data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -1
  88. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +13 -3
  89. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
  90. data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
  91. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  92. data/lib/rubocop/cop/layout/space_around_keyword.rb +4 -2
  93. data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -1
  94. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
  95. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  96. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +1 -11
  97. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  98. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1 -10
  99. data/lib/rubocop/cop/lint/circular_argument_reference.rb +45 -3
  100. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
  101. data/lib/rubocop/cop/lint/constant_reassignment.rb +93 -11
  102. data/lib/rubocop/cop/lint/constant_resolution.rb +6 -6
  103. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +14 -8
  104. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  105. data/lib/rubocop/cop/lint/debugger.rb +0 -3
  106. data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
  107. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4 -1
  108. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
  109. data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -12
  110. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
  111. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  112. data/lib/rubocop/cop/lint/empty_block.rb +4 -4
  113. data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -1
  114. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  115. data/lib/rubocop/cop/lint/empty_interpolation.rb +11 -0
  116. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  117. data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
  118. data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -2
  119. data/lib/rubocop/cop/lint/float_comparison.rb +2 -1
  120. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
  121. data/lib/rubocop/cop/lint/interpolation_check.rb +25 -5
  122. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  123. data/lib/rubocop/cop/lint/literal_as_condition.rb +5 -1
  124. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
  125. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +9 -12
  126. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +19 -10
  127. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  128. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  129. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
  130. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
  131. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  132. data/lib/rubocop/cop/lint/number_conversion.rb +19 -10
  133. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  134. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +3 -0
  135. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
  136. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -13
  137. data/lib/rubocop/cop/lint/raise_exception.rb +1 -1
  138. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  139. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +27 -10
  140. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6 -12
  141. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15 -4
  142. data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -2
  143. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +36 -12
  144. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +12 -2
  145. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +10 -3
  146. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  147. data/lib/rubocop/cop/lint/redundant_with_object.rb +5 -0
  148. data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
  149. data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
  150. data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
  151. data/lib/rubocop/cop/lint/require_range_parentheses.rb +2 -1
  152. data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
  153. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
  154. data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
  155. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +18 -0
  156. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +7 -1
  157. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  158. data/lib/rubocop/cop/lint/script_permission.rb +5 -1
  159. data/lib/rubocop/cop/lint/self_assignment.rb +39 -7
  160. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
  161. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  162. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  163. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14 -0
  164. data/lib/rubocop/cop/lint/shared_mutable_default.rb +3 -1
  165. data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
  166. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +12 -0
  167. data/lib/rubocop/cop/lint/symbol_conversion.rb +21 -4
  168. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  169. data/lib/rubocop/cop/lint/to_enum_arguments.rb +28 -1
  170. data/lib/rubocop/cop/lint/to_json.rb +12 -16
  171. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  172. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
  173. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +4 -2
  174. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
  175. data/lib/rubocop/cop/lint/unreachable_code.rb +7 -5
  176. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  177. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  178. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  179. data/lib/rubocop/cop/lint/useless_assignment.rb +53 -25
  180. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +4 -4
  181. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
  182. data/lib/rubocop/cop/lint/useless_or.rb +15 -2
  183. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +8 -4
  184. data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -1
  185. data/lib/rubocop/cop/lint/useless_times.rb +22 -1
  186. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +37 -11
  187. data/lib/rubocop/cop/lint/void.rb +39 -12
  188. data/lib/rubocop/cop/message_annotator.rb +1 -1
  189. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  190. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  191. data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
  192. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  193. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
  194. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  195. data/lib/rubocop/cop/migration/department_name.rb +12 -1
  196. data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
  197. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +4 -6
  198. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  199. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  200. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  201. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +5 -5
  202. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  203. data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -60
  204. data/lib/rubocop/cop/mixin/line_length_help.rb +21 -2
  205. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  206. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  207. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  208. data/lib/rubocop/cop/mixin/project_index_help.rb +48 -0
  209. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  210. data/lib/rubocop/cop/mixin/statement_modifier.rb +0 -6
  211. data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -5
  212. data/lib/rubocop/cop/mixin.rb +86 -0
  213. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  214. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  215. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  216. data/lib/rubocop/cop/naming/method_name.rb +5 -3
  217. data/lib/rubocop/cop/naming/predicate_method.rb +32 -8
  218. data/lib/rubocop/cop/naming/predicate_prefix.rb +12 -12
  219. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
  220. data/lib/rubocop/cop/offense.rb +17 -1
  221. data/lib/rubocop/cop/registry.rb +62 -38
  222. data/lib/rubocop/cop/security/eval.rb +15 -2
  223. data/lib/rubocop/cop/security/io_methods.rb +1 -1
  224. data/lib/rubocop/cop/security/json_load.rb +33 -11
  225. data/lib/rubocop/cop/style/access_modifier_declarations.rb +15 -4
  226. data/lib/rubocop/cop/style/accessor_grouping.rb +4 -2
  227. data/lib/rubocop/cop/style/alias.rb +15 -3
  228. data/lib/rubocop/cop/style/and_or.rb +2 -1
  229. data/lib/rubocop/cop/style/arguments_forwarding.rb +25 -7
  230. data/lib/rubocop/cop/style/array_first_last.rb +12 -1
  231. data/lib/rubocop/cop/style/array_intersect.rb +50 -12
  232. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +50 -0
  233. data/lib/rubocop/cop/style/array_join.rb +4 -2
  234. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  235. data/lib/rubocop/cop/style/attr.rb +5 -2
  236. data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
  237. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  238. data/lib/rubocop/cop/style/bitwise_predicate.rb +8 -1
  239. data/lib/rubocop/cop/style/block_delimiters.rb +39 -32
  240. data/lib/rubocop/cop/style/case_equality.rb +29 -15
  241. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  242. data/lib/rubocop/cop/style/class_and_module_children.rb +19 -2
  243. data/lib/rubocop/cop/style/class_equality_comparison.rb +21 -13
  244. data/lib/rubocop/cop/style/class_methods_definitions.rb +11 -5
  245. data/lib/rubocop/cop/style/collection_compact.rb +36 -16
  246. data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
  247. data/lib/rubocop/cop/style/combinable_loops.rb +5 -0
  248. data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
  249. data/lib/rubocop/cop/style/concat_array_literals.rb +7 -1
  250. data/lib/rubocop/cop/style/conditional_assignment.rb +14 -19
  251. data/lib/rubocop/cop/style/constant_visibility.rb +20 -12
  252. data/lib/rubocop/cop/style/copyright.rb +22 -11
  253. data/lib/rubocop/cop/style/date_time.rb +4 -4
  254. data/lib/rubocop/cop/style/dig_chain.rb +5 -0
  255. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
  256. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  257. data/lib/rubocop/cop/style/documentation.rb +6 -6
  258. data/lib/rubocop/cop/style/documentation_method.rb +8 -8
  259. data/lib/rubocop/cop/style/double_negation.rb +1 -1
  260. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  261. data/lib/rubocop/cop/style/each_with_object.rb +2 -0
  262. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  263. data/lib/rubocop/cop/style/empty_class_definition.rb +119 -0
  264. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  265. data/lib/rubocop/cop/style/empty_method.rb +0 -6
  266. data/lib/rubocop/cop/style/encoding.rb +7 -1
  267. data/lib/rubocop/cop/style/end_block.rb +3 -1
  268. data/lib/rubocop/cop/style/endless_method.rb +23 -5
  269. data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
  270. data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
  271. data/lib/rubocop/cop/style/file_open.rb +84 -0
  272. data/lib/rubocop/cop/style/file_write.rb +21 -16
  273. data/lib/rubocop/cop/style/float_division.rb +15 -1
  274. data/lib/rubocop/cop/style/for.rb +3 -0
  275. data/lib/rubocop/cop/style/format_string.rb +4 -3
  276. data/lib/rubocop/cop/style/format_string_token.rb +49 -5
  277. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  278. data/lib/rubocop/cop/style/guard_clause.rb +27 -22
  279. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
  280. data/lib/rubocop/cop/style/hash_conversion.rb +1 -1
  281. data/lib/rubocop/cop/style/hash_lookup_method.rb +106 -0
  282. data/lib/rubocop/cop/style/hash_slice.rb +16 -0
  283. data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
  284. data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
  285. data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
  286. data/lib/rubocop/cop/style/if_inside_else.rb +16 -7
  287. data/lib/rubocop/cop/style/if_unless_modifier.rb +58 -18
  288. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12 -12
  289. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +4 -1
  290. data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
  291. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  292. data/lib/rubocop/cop/style/inline_comment.rb +4 -1
  293. data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
  294. data/lib/rubocop/cop/style/lambda_call.rb +8 -8
  295. data/lib/rubocop/cop/style/magic_comment_format.rb +3 -3
  296. data/lib/rubocop/cop/style/map_join.rb +123 -0
  297. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
  298. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17 -4
  299. data/lib/rubocop/cop/style/method_def_parentheses.rb +2 -4
  300. data/lib/rubocop/cop/style/min_max_comparison.rb +1 -1
  301. data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
  302. data/lib/rubocop/cop/style/multiline_if_then.rb +4 -4
  303. data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -4
  304. data/lib/rubocop/cop/style/mutable_constant.rb +106 -12
  305. data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
  306. data/lib/rubocop/cop/style/nil_comparison.rb +11 -10
  307. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  308. data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
  309. data/lib/rubocop/cop/style/not.rb +2 -0
  310. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  311. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  312. data/lib/rubocop/cop/style/one_line_conditional.rb +21 -12
  313. data/lib/rubocop/cop/style/operator_method_call.rb +11 -2
  314. data/lib/rubocop/cop/style/parallel_assignment.rb +14 -3
  315. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  316. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -0
  317. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  318. data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
  319. data/lib/rubocop/cop/style/proc.rb +3 -2
  320. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  321. data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
  322. data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
  323. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  324. data/lib/rubocop/cop/style/redundant_begin.rb +37 -3
  325. data/lib/rubocop/cop/style/redundant_condition.rb +6 -3
  326. data/lib/rubocop/cop/style/redundant_constant_base.rb +5 -5
  327. data/lib/rubocop/cop/style/redundant_each.rb +3 -3
  328. data/lib/rubocop/cop/style/redundant_exception.rb +1 -1
  329. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
  330. data/lib/rubocop/cop/style/redundant_format.rb +27 -5
  331. data/lib/rubocop/cop/style/redundant_interpolation.rb +11 -2
  332. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
  333. data/lib/rubocop/cop/style/redundant_line_continuation.rb +16 -0
  334. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  335. data/lib/rubocop/cop/style/redundant_parentheses.rb +36 -30
  336. data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
  337. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +9 -0
  338. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
  339. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -0
  340. data/lib/rubocop/cop/style/redundant_return.rb +3 -1
  341. data/lib/rubocop/cop/style/redundant_self.rb +2 -2
  342. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
  343. data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
  344. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +114 -0
  345. data/lib/rubocop/cop/style/regexp_literal.rb +31 -2
  346. data/lib/rubocop/cop/style/rescue_modifier.rb +3 -3
  347. data/lib/rubocop/cop/style/reverse_find.rb +51 -0
  348. data/lib/rubocop/cop/style/safe_navigation.rb +25 -8
  349. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  350. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  351. data/lib/rubocop/cop/style/select_by_regexp.rb +51 -21
  352. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  353. data/lib/rubocop/cop/style/semicolon.rb +41 -8
  354. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  355. data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -1
  356. data/lib/rubocop/cop/style/single_line_methods.rb +3 -1
  357. data/lib/rubocop/cop/style/sole_nested_conditional.rb +12 -3
  358. data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
  359. data/lib/rubocop/cop/style/string_concatenation.rb +17 -13
  360. data/lib/rubocop/cop/style/struct_inheritance.rb +13 -0
  361. data/lib/rubocop/cop/style/super_arguments.rb +2 -2
  362. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  363. data/lib/rubocop/cop/style/symbol_proc.rb +7 -6
  364. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  365. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -2
  366. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45 -0
  367. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  368. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  369. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +11 -11
  370. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  371. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  372. data/lib/rubocop/cop/style/while_until_do.rb +7 -0
  373. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -0
  374. data/lib/rubocop/cop/style/word_array.rb +1 -0
  375. data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
  376. data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
  377. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
  378. data/lib/rubocop/cop/team.rb +87 -36
  379. data/lib/rubocop/cop/util.rb +2 -3
  380. data/lib/rubocop/cop/utils/format_string.rb +10 -0
  381. data/lib/rubocop/cop/variable_force/branch.rb +30 -6
  382. data/lib/rubocop/cop/variable_force/variable.rb +1 -1
  383. data/lib/rubocop/cop/variable_force.rb +9 -7
  384. data/lib/rubocop/cops_documentation_generator.rb +4 -4
  385. data/lib/rubocop/directive_comment.rb +48 -4
  386. data/lib/rubocop/file_patterns.rb +9 -1
  387. data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
  388. data/lib/rubocop/formatter/disabled_config_formatter.rb +38 -14
  389. data/lib/rubocop/formatter/formatter_set.rb +2 -2
  390. data/lib/rubocop/formatter/junit_formatter.rb +1 -1
  391. data/lib/rubocop/formatter/simple_text_formatter.rb +0 -2
  392. data/lib/rubocop/formatter/tap_formatter.rb +5 -2
  393. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
  394. data/lib/rubocop/formatter.rb +22 -21
  395. data/lib/rubocop/lsp/diagnostic.rb +18 -33
  396. data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
  397. data/lib/rubocop/lsp/routes.rb +43 -7
  398. data/lib/rubocop/lsp/runtime.rb +13 -4
  399. data/lib/rubocop/lsp/stdin_runner.rb +8 -17
  400. data/lib/rubocop/magic_comment.rb +20 -0
  401. data/lib/rubocop/mcp/server.rb +200 -0
  402. data/lib/rubocop/options.rb +35 -4
  403. data/lib/rubocop/path_util.rb +14 -2
  404. data/lib/rubocop/plugin/loader.rb +1 -1
  405. data/lib/rubocop/project_index_loader.rb +66 -0
  406. data/lib/rubocop/rake_task.rb +1 -1
  407. data/lib/rubocop/remote_config.rb +10 -8
  408. data/lib/rubocop/result_cache.rb +61 -38
  409. data/lib/rubocop/rspec/cop_helper.rb +8 -0
  410. data/lib/rubocop/rspec/shared_contexts.rb +39 -5
  411. data/lib/rubocop/rspec/support.rb +2 -1
  412. data/lib/rubocop/runner.rb +134 -57
  413. data/lib/rubocop/server/cache.rb +6 -29
  414. data/lib/rubocop/server/core.rb +8 -0
  415. data/lib/rubocop/target_finder.rb +17 -10
  416. data/lib/rubocop/target_ruby.rb +31 -14
  417. data/lib/rubocop/version.rb +21 -3
  418. data/lib/rubocop.rb +28 -96
  419. data/lib/ruby_lsp/rubocop/addon.rb +23 -8
  420. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +49 -15
  421. metadata +38 -9
@@ -28,66 +28,66 @@ module RuboCop
28
28
  #
29
29
  # @example EnforcedStyle: symmetrical (default)
30
30
  #
31
- # # bad
32
- # { a: 1,
33
- # b: 2
34
- # }
35
- # # bad
36
- # {
37
- # a: 1,
38
- # b: 2 }
39
- #
40
- # # good
41
- # { a: 1,
42
- # b: 2 }
43
- #
44
- # # good
45
- # {
46
- # a: 1,
47
- # b: 2
48
- # }
31
+ # # bad
32
+ # { a: 1,
33
+ # b: 2
34
+ # }
35
+ # # bad
36
+ # {
37
+ # a: 1,
38
+ # b: 2 }
39
+ #
40
+ # # good
41
+ # { a: 1,
42
+ # b: 2 }
43
+ #
44
+ # # good
45
+ # {
46
+ # a: 1,
47
+ # b: 2
48
+ # }
49
49
  #
50
50
  # @example EnforcedStyle: new_line
51
- # # bad
52
- # {
53
- # a: 1,
54
- # b: 2 }
55
- #
56
- # # bad
57
- # { a: 1,
58
- # b: 2 }
59
- #
60
- # # good
61
- # { a: 1,
62
- # b: 2
63
- # }
64
- #
65
- # # good
66
- # {
67
- # a: 1,
68
- # b: 2
69
- # }
51
+ # # bad
52
+ # {
53
+ # a: 1,
54
+ # b: 2 }
55
+ #
56
+ # # bad
57
+ # { a: 1,
58
+ # b: 2 }
59
+ #
60
+ # # good
61
+ # { a: 1,
62
+ # b: 2
63
+ # }
64
+ #
65
+ # # good
66
+ # {
67
+ # a: 1,
68
+ # b: 2
69
+ # }
70
70
  #
71
71
  # @example EnforcedStyle: same_line
72
- # # bad
73
- # { a: 1,
74
- # b: 2
75
- # }
76
- #
77
- # # bad
78
- # {
79
- # a: 1,
80
- # b: 2
81
- # }
82
- #
83
- # # good
84
- # {
85
- # a: 1,
86
- # b: 2 }
87
- #
88
- # # good
89
- # { a: 1,
90
- # b: 2 }
72
+ # # bad
73
+ # { a: 1,
74
+ # b: 2
75
+ # }
76
+ #
77
+ # # bad
78
+ # {
79
+ # a: 1,
80
+ # b: 2
81
+ # }
82
+ #
83
+ # # good
84
+ # {
85
+ # a: 1,
86
+ # b: 2 }
87
+ #
88
+ # # good
89
+ # { a: 1,
90
+ # b: 2 }
91
91
  class MultilineHashBraceLayout < Base
92
92
  include MultilineLiteralBraceLayout
93
93
  extend AutoCorrector
@@ -124,7 +124,7 @@ module RuboCop
124
124
  def single_line_ignoring_receiver?(node)
125
125
  return false unless node.loc.begin && node.loc.end
126
126
 
127
- node.loc.begin.line == node.loc.end.line
127
+ same_line?(node.loc.begin, node.loc.end)
128
128
  end
129
129
  end
130
130
  end
@@ -46,10 +46,12 @@ module RuboCop
46
46
  # .a
47
47
  # .b
48
48
  # .c
49
- class MultilineMethodCallIndentation < Base
49
+ #
50
+ class MultilineMethodCallIndentation < Base # rubocop:disable Metrics/ClassLength
50
51
  include ConfigurableEnforcedStyle
51
52
  include Alignment
52
53
  include MultilineExpressionIndentation
54
+ include RangeHelp
53
55
  extend AutoCorrector
54
56
 
55
57
  def validate_config
@@ -64,8 +66,39 @@ module RuboCop
64
66
 
65
67
  private
66
68
 
69
+ def find_base_receiver(node)
70
+ base_receiver = node
71
+ base_receiver = base_receiver.receiver while base_receiver.receiver
72
+ base_receiver
73
+ end
74
+
75
+ def find_pair_ancestor(node)
76
+ node.each_ancestor.find(&:pair_type?)
77
+ end
78
+
79
+ def unwrap_block_node(node)
80
+ node&.any_block_type? ? node.send_node : node
81
+ end
82
+
67
83
  def autocorrect(corrector, node)
68
- AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
84
+ if @send_node.block_node
85
+ correct_selector_only(corrector, node)
86
+ correct_block(corrector, @send_node.block_node)
87
+ else
88
+ AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
89
+ end
90
+ end
91
+
92
+ def correct_selector_only(corrector, node)
93
+ selector_line = processed_source.buffer.line_range(node.first_line)
94
+ selector_range = range_between(selector_line.begin_pos, selector_line.end_pos)
95
+ AlignmentCorrector.correct(corrector, processed_source, selector_range, @column_delta)
96
+ end
97
+
98
+ def correct_block(corrector, block_node)
99
+ AlignmentCorrector.correct(corrector, processed_source, block_node.body, @column_delta)
100
+ end_range = range_by_whole_lines(block_node.loc.end, include_final_newline: false)
101
+ AlignmentCorrector.correct(corrector, processed_source, end_range, @column_delta)
69
102
  end
70
103
 
71
104
  def relevant_node?(send_node)
@@ -86,27 +119,138 @@ module RuboCop
86
119
 
87
120
  def offending_range(node, lhs, rhs, given_style)
88
121
  return false unless begins_its_line?(rhs)
89
- return false if not_for_this_cop?(node)
90
122
 
123
+ @send_node = node # Store for use in autocorrect
124
+ pair_ancestor = find_pair_ancestor(node)
125
+ if hash_pair_aligned?(pair_ancestor, given_style)
126
+ return check_hash_pair_indentation(node, lhs, rhs)
127
+ end
128
+ if hash_pair_indented?(node, pair_ancestor, given_style)
129
+ return check_hash_pair_indented_style(rhs, pair_ancestor)
130
+ end
131
+ return false if skip_for_context?(node, pair_ancestor)
132
+
133
+ check_regular_indentation(node, lhs, rhs, given_style)
134
+ end
135
+
136
+ def skip_for_context?(node, pair_ancestor)
137
+ pair_ancestor ? inside_multiline_chain_arg?(node) : not_for_this_cop?(node)
138
+ end
139
+
140
+ def hash_pair_aligned?(pair_ancestor, given_style)
141
+ pair_ancestor && given_style == :aligned
142
+ end
143
+
144
+ def hash_pair_indented?(node, pair_ancestor, given_style)
145
+ pair_ancestor && given_style == :indented && find_base_receiver(node).hash_type?
146
+ end
147
+
148
+ def check_hash_pair_indented_style(rhs, pair_ancestor)
149
+ pair_key = pair_ancestor.key
150
+ double_indentation = configured_indentation_width * 2
151
+ correct_column = pair_key.source_range.column + double_indentation
152
+ @hash_pair_base_column = pair_key.source_range.column + configured_indentation_width
153
+
154
+ calculate_column_delta_offense(rhs, correct_column)
155
+ end
156
+
157
+ def check_hash_pair_indentation(node, lhs, rhs)
158
+ @base = find_hash_pair_alignment_base(node)
159
+ return false if !@base && inside_multiline_chain_arg?(node)
160
+
161
+ @base ||= first_dot_alignment_base(node, rhs) || lhs.source_range
162
+ return if aligned_with_first_line_dot?(node, rhs)
163
+
164
+ calculate_column_delta_offense(rhs, @base.column)
165
+ end
166
+
167
+ def find_hash_pair_alignment_base(node)
168
+ base_receiver = find_base_receiver(node.receiver)
169
+ return unless base_receiver.hash_type?
170
+
171
+ first_call = first_call_has_a_dot(node)
172
+ first_call.loc.dot.join(first_call.loc.selector)
173
+ end
174
+
175
+ def first_dot_alignment_base(node, rhs)
176
+ return unless rhs.source.start_with?('.', '&.')
177
+
178
+ first_call = first_call_has_a_dot(node)
179
+ dot = first_call.loc.dot
180
+ return unless dot
181
+ return if first_call == node
182
+
183
+ after_block_base = after_multiline_block_base(first_call, node)
184
+ return after_block_base if after_block_base
185
+
186
+ return unless same_line?(dot, first_call.receiver.source_range)
187
+
188
+ dot.join(first_call.loc.selector)
189
+ end
190
+
191
+ def after_multiline_block_base(first_call, node)
192
+ return unless first_call.block_node&.multiline?
193
+
194
+ after_block = first_call.block_node.parent
195
+ return unless after_block&.call_type? && after_block.loc?(:dot) && after_block != node
196
+
197
+ after_block.loc.dot.join(after_block.loc.selector)
198
+ end
199
+
200
+ def inside_multiline_chain_arg?(node)
201
+ enclosing_call = find_enclosing_chain_call(node)
202
+ return false unless enclosing_call
203
+
204
+ !same_line?(enclosing_call.loc.selector, enclosing_call.receiver.source_range)
205
+ end
206
+
207
+ def find_enclosing_chain_call(node)
208
+ hash_ancestor = find_pair_ancestor(node).parent
209
+ enclosing_call = hash_ancestor.parent
210
+ return unless hash_arg_in_chain?(enclosing_call, hash_ancestor)
211
+
212
+ enclosing_call
213
+ end
214
+
215
+ def hash_arg_in_chain?(call, hash_node)
216
+ call&.call_type? && call.receiver != hash_node && call.loc?(:dot)
217
+ end
218
+
219
+ def aligned_with_first_line_dot?(node, rhs)
220
+ return false unless rhs.source.start_with?('.', '&.')
221
+
222
+ first_call = first_call_has_a_dot(node)
223
+ return false if first_call == node.receiver
224
+
225
+ dot = first_call.loc.dot
226
+ dot.line == node.first_line && dot.column == rhs.column
227
+ end
228
+
229
+ def check_regular_indentation(node, lhs, rhs, given_style)
91
230
  @base = alignment_base(node, rhs, given_style)
92
231
  correct_column = if @base
93
- @base.column + extra_indentation(given_style, node.parent)
232
+ parent = node.parent
233
+ parent = parent.parent if parent&.any_block_type?
234
+ @base.column + extra_indentation(given_style, parent)
94
235
  else
95
236
  indentation(lhs) + correct_indentation(node)
96
237
  end
238
+
239
+ calculate_column_delta_offense(rhs, correct_column)
240
+ end
241
+
242
+ def calculate_column_delta_offense(rhs, correct_column)
97
243
  @column_delta = correct_column - rhs.column
98
244
  rhs if @column_delta.nonzero?
99
245
  end
100
246
 
101
247
  def extra_indentation(given_style, parent)
102
- if given_style == :indented_relative_to_receiver
103
- if parent&.type?(:splat, :kwsplat)
104
- configured_indentation_width - parent.loc.operator.length
105
- else
106
- configured_indentation_width
107
- end
248
+ return 0 unless given_style == :indented_relative_to_receiver
249
+
250
+ if parent&.type?(:splat, :kwsplat)
251
+ configured_indentation_width - parent.loc.operator.length
108
252
  else
109
- 0
253
+ configured_indentation_width
110
254
  end
111
255
  end
112
256
 
@@ -125,7 +269,7 @@ module RuboCop
125
269
  end
126
270
 
127
271
  def should_align_with_base?
128
- @base && style != :indented_relative_to_receiver
272
+ @base && style == :aligned
129
273
  end
130
274
 
131
275
  def relative_to_receiver_message(rhs)
@@ -142,10 +286,16 @@ module RuboCop
142
286
  end
143
287
 
144
288
  def no_base_message(lhs, rhs, node)
145
- used_indentation = rhs.column - indentation(lhs)
289
+ if @hash_pair_base_column
290
+ used_indentation = rhs.column - @hash_pair_base_column
291
+ expected_indentation = configured_indentation_width
292
+ else
293
+ used_indentation = rhs.column - indentation(lhs)
294
+ expected_indentation = correct_indentation(node)
295
+ end
146
296
  what = operation_description(node, rhs)
147
297
 
148
- "Use #{correct_indentation(node)} (not #{used_indentation}) " \
298
+ "Use #{expected_indentation} (not #{used_indentation}) " \
149
299
  "spaces for indenting #{what} spanning multiple lines."
150
300
  end
151
301
 
@@ -153,8 +303,6 @@ module RuboCop
153
303
  case given_style
154
304
  when :aligned
155
305
  semantic_alignment_base(node, rhs) || syntactic_alignment_base(node, rhs)
156
- when :indented
157
- nil
158
306
  when :indented_relative_to_receiver
159
307
  receiver_alignment_base(node)
160
308
  end
@@ -182,7 +330,7 @@ module RuboCop
182
330
  return unless rhs.source.start_with?('.', '&.')
183
331
 
184
332
  node = semantic_alignment_node(node)
185
- return unless node&.loc&.selector && node.loc.dot
333
+ return unless node&.loc?(:selector) && node.loc.dot
186
334
 
187
335
  node.loc.dot.join(node.loc.selector)
188
336
  end
@@ -191,29 +339,55 @@ module RuboCop
191
339
  # .b
192
340
  # .c
193
341
  def receiver_alignment_base(node)
194
- node = node.receiver while node.receiver
195
- node = node.parent
196
- node = node.parent until node.loc.dot
342
+ hash_method_base = find_hash_method_base_in_receiver_chain(node)
343
+ return hash_method_base if hash_method_base
197
344
 
198
- node&.receiver&.source_range
345
+ first_call = first_call_has_a_dot(node)
346
+ first_call.receiver.source_range
347
+ end
348
+
349
+ def find_hash_method_base_in_receiver_chain(node)
350
+ receiver_chain = unwrap_block_node(node.receiver)
351
+ while receiver_chain&.call_type?
352
+ base_receiver = unwrap_block_node(receiver_chain.receiver)
353
+ if alignment_base_for_chained_receiver?(receiver_chain, base_receiver)
354
+ return receiver_chain.loc.dot.join(receiver_chain.loc.selector)
355
+ end
356
+
357
+ receiver_chain = base_receiver
358
+ end
359
+ end
360
+
361
+ def alignment_base_for_chained_receiver?(receiver_chain, base_receiver)
362
+ base_receiver&.hash_type? ||
363
+ method_on_receiver_last_line?(receiver_chain, base_receiver, :begin)
199
364
  end
200
365
 
201
366
  def semantic_alignment_node(node)
202
367
  return if argument_in_method_call(node, :with_parentheses)
203
368
 
204
- dot_right_above = get_dot_right_above(node)
205
- return dot_right_above if dot_right_above
206
-
207
- if (multiline_block_chain_node = find_multiline_block_chain_node(node))
208
- return multiline_block_chain_node
209
- end
369
+ get_dot_right_above(node) ||
370
+ find_multiline_block_chain_node(node) ||
371
+ first_call_alignment_node(node)
372
+ end
210
373
 
374
+ def first_call_alignment_node(node)
211
375
  node = first_call_has_a_dot(node)
376
+ base_receiver = find_base_receiver(node)
377
+
378
+ return node if method_on_receiver_last_line?(node, base_receiver, :array)
212
379
  return if node.loc.dot.line != node.first_line
380
+ return if method_on_receiver_last_line?(node, base_receiver, :begin)
213
381
 
214
382
  node
215
383
  end
216
384
 
385
+ def method_on_receiver_last_line?(node, base_receiver, type)
386
+ return false unless base_receiver
387
+
388
+ same_line?(node.loc.dot, base_receiver.source_range.end) && base_receiver.type?(type)
389
+ end
390
+
217
391
  def get_dot_right_above(node)
218
392
  node.each_ancestor.find do |a|
219
393
  dot = a.loc.dot if a.loc?(:dot)
@@ -224,23 +398,39 @@ module RuboCop
224
398
  end
225
399
 
226
400
  def find_multiline_block_chain_node(node)
227
- return unless (block_node = node.each_descendant(:any_block).first)
228
- return unless block_node.multiline? && block_node.parent.call_type?
401
+ return find_continuation_node(node) if node.block_node
229
402
 
230
- if node.receiver.call_type?
231
- node.receiver
232
- else
233
- block_node.parent
234
- end
403
+ handle_descendant_block(node)
404
+ end
405
+
406
+ def find_continuation_node(node)
407
+ receiver = node.receiver
408
+ return receiver.send_node if single_line_block_receiver?(receiver)
409
+ return unless receiver.call_type? && receiver.loc.dot
410
+ return receiver if receiver.receiver.begin_type? && node.block_node.single_line?
411
+ return unless receiver.loc.dot.line > receiver.receiver.last_line
412
+
413
+ receiver
414
+ end
415
+
416
+ def single_line_block_receiver?(receiver)
417
+ receiver.single_line? && receiver.any_block_type?
418
+ end
419
+
420
+ def handle_descendant_block(node)
421
+ receiver = node.receiver
422
+ return receiver.send_node if single_line_block_receiver?(receiver)
423
+
424
+ block_node = node.each_descendant(:any_block).first
425
+ return unless block_node&.multiline?
426
+
427
+ receiver.call_type? ? receiver : block_node.parent
235
428
  end
236
429
 
237
430
  def first_call_has_a_dot(node)
238
- # descend to root of method chain
239
- node = node.receiver while node.receiver
240
- # ascend to first call which has a dot
241
- node = node.parent
431
+ base = find_base_receiver(node)
432
+ node = base.parent
242
433
  node = node.parent until node.loc?(:dot)
243
-
244
434
  node
245
435
  end
246
436
 
@@ -10,6 +10,8 @@ module RuboCop
10
10
  # condition, an explicit `return` statement, etc. In other contexts, the second operand should
11
11
  # be indented regardless of enforced style.
12
12
  #
13
+ # In both styles, operators should be aligned when an assignment begins on the next line.
14
+ #
13
15
  # @example EnforcedStyle: aligned (default)
14
16
  # # bad
15
17
  # if a +
@@ -100,10 +102,12 @@ module RuboCop
100
102
  return true if begins_its_line?(assignment_rhs.source_range)
101
103
  end
102
104
 
103
- given_style == :aligned &&
104
- (kw_node_with_special_indentation(node) ||
105
- assignment_node ||
106
- argument_in_method_call(node, :with_or_without_parentheses))
105
+ return false unless given_style == :aligned
106
+ return true if kw_node_with_special_indentation(node) || assignment_node
107
+
108
+ node = argument_in_method_call(node, :with_or_without_parentheses)
109
+
110
+ node.respond_to?(:def_modifier?) && !node.def_modifier?
107
111
  end
108
112
 
109
113
  def message(node, lhs, rhs)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # Check that the parameters on a multi-line method call or definition are aligned.
6
+ # Checks that the parameters on a multi-line method call or definition are aligned.
7
7
  #
8
8
  # To set the alignment of the first argument, use the
9
9
  # `Layout/FirstParameterIndentation` cop.
@@ -114,7 +114,9 @@ module RuboCop
114
114
 
115
115
  def other_cop_takes_precedence?(node)
116
116
  single_line_block_chain_enabled? && any_descendant?(node, :any_block) do |block_node|
117
- block_node.parent.send_type? && block_node.parent.loc.dot && !block_node.multiline?
117
+ next unless (parent = block_node.parent)
118
+
119
+ parent.call_type? && parent.loc.dot && block_node.single_line?
118
120
  end
119
121
  end
120
122
 
@@ -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 any_def class module any_block].freeze
32
+ ANCESTOR_TYPES = %i[kwbegin any_def class module sclass any_block].freeze
33
33
  ALTERNATIVE_ACCESS_MODIFIERS = %i[public_class_method private_class_method].freeze
34
34
 
35
35
  def on_resbody(node)
@@ -91,7 +91,7 @@ module RuboCop
91
91
  )
92
92
  end
93
93
 
94
- # rubocop:disable Metrics/AbcSize
94
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
95
95
  def alignment_source(node, starting_loc)
96
96
  ending_loc =
97
97
  case node.type
@@ -100,6 +100,8 @@ module RuboCop
100
100
  when :def, :defs, :class, :module,
101
101
  :lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
102
102
  node.loc.name
103
+ when :sclass
104
+ node.identifier.source_range
103
105
  when :masgn
104
106
  node.lhs.source_range
105
107
  else
@@ -109,7 +111,7 @@ module RuboCop
109
111
 
110
112
  range_between(starting_loc.begin_pos, ending_loc.end_pos).source
111
113
  end
112
- # rubocop:enable Metrics/AbcSize
114
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
113
115
 
114
116
  # We will use ancestor or wrapper with access modifier.
115
117
 
@@ -194,6 +196,14 @@ module RuboCop
194
196
  def alignment_location(alignment_node)
195
197
  if begin_end_alignment_style == 'start_of_line'
196
198
  start_line_range(alignment_node)
199
+ elsif alignment_node.any_block_type?
200
+ # If the alignment node is a block, the `rescue`/`ensure` keyword should
201
+ # be aligned to the start of the block. It is possible that the block's
202
+ # `send_node` spans multiple lines, in which case it should align to the
203
+ # start of the last line.
204
+ send_node = alignment_node.send_node
205
+ range = processed_source.buffer.line_range(send_node.last_line)
206
+ range.adjust(begin_pos: range.source =~ /\S/)
197
207
  else
198
208
  alignment_node.source_range
199
209
  end
@@ -23,16 +23,8 @@ module RuboCop
23
23
  cfg['EnforcedStyle'] || 'space'
24
24
  end
25
25
 
26
- def kind(token)
27
- 'comma' if token.comma? && !before_semicolon?(token)
28
- end
29
-
30
- private
31
-
32
- def before_semicolon?(token)
33
- tokens = processed_source.tokens
34
-
35
- tokens[tokens.index(token) + 1].semicolon?
26
+ def kind(token, next_token)
27
+ 'comma' if token.comma? && !next_token.semicolon?
36
28
  end
37
29
  end
38
30
  end
@@ -20,7 +20,7 @@ module RuboCop
20
20
  cfg['EnforcedStyle'] || 'space'
21
21
  end
22
22
 
23
- def kind(token)
23
+ def kind(token, _next_token)
24
24
  'semicolon' if token.semicolon?
25
25
  end
26
26
 
@@ -29,7 +29,7 @@ module RuboCop
29
29
  include RangeHelp
30
30
  extend AutoCorrector
31
31
 
32
- def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
32
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
33
33
  arguments = node.arguments
34
34
 
35
35
  return unless node.arguments? && pipes?(arguments)
@@ -47,9 +47,11 @@ module RuboCop
47
47
  check(node, [:operator].freeze) if node.keyword?
48
48
  end
49
49
 
50
- def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
50
+ def on_block(node)
51
51
  check(node, %i[begin end].freeze)
52
52
  end
53
+ alias on_numblock on_block
54
+ alias on_itblock on_block
53
55
 
54
56
  def on_break(node)
55
57
  check(node, [:keyword].freeze)
@@ -167,7 +169,7 @@ module RuboCop
167
169
 
168
170
  def check(node, locations, begin_keyword = DO)
169
171
  locations.each do |loc|
170
- next unless node.loc.respond_to?(loc)
172
+ next unless node.loc?(loc)
171
173
 
172
174
  range = node.loc.public_send(loc)
173
175
  next unless range
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Layout
6
6
  # Checks for space between the name of a receiver and a left
7
- # brackets.
7
+ # bracket.
8
8
  #
9
9
  # @example
10
10
  #