rubocop 1.84.2 → 1.88.1

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 (357) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +183 -87
  3. data/config/obsoletion.yml +26 -1
  4. data/lib/rubocop/cache_config.rb +1 -1
  5. data/lib/rubocop/cli/command/auto_generate_config.rb +34 -2
  6. data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
  7. data/lib/rubocop/cli/command/mcp.rb +19 -0
  8. data/lib/rubocop/cli/command/show_cops.rb +2 -2
  9. data/lib/rubocop/cli/command/show_docs_url.rb +4 -8
  10. data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
  11. data/lib/rubocop/cli.rb +9 -7
  12. data/lib/rubocop/comment_config.rb +12 -15
  13. data/lib/rubocop/config.rb +14 -10
  14. data/lib/rubocop/config_finder.rb +1 -1
  15. data/lib/rubocop/config_loader.rb +17 -2
  16. data/lib/rubocop/config_loader_resolver.rb +13 -4
  17. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -2
  18. data/lib/rubocop/config_store.rb +2 -2
  19. data/lib/rubocop/config_validator.rb +1 -1
  20. data/lib/rubocop/cop/autocorrect_logic.rb +2 -1
  21. data/lib/rubocop/cop/base.rb +25 -4
  22. data/lib/rubocop/cop/bundler/gem_comment.rb +5 -3
  23. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  24. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +1 -1
  25. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -1
  26. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
  27. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
  28. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +33 -2
  29. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  30. data/lib/rubocop/cop/correctors.rb +28 -0
  31. data/lib/rubocop/cop/documentation.rb +2 -3
  32. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  33. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  34. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  35. data/lib/rubocop/cop/gemspec/require_mfa.rb +9 -6
  36. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
  37. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  38. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  39. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
  40. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  41. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -2
  42. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  43. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
  44. data/lib/rubocop/cop/layout/block_alignment.rb +58 -4
  45. data/lib/rubocop/cop/layout/class_structure.rb +8 -4
  46. data/lib/rubocop/cop/layout/condition_position.rb +13 -3
  47. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  48. data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
  49. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +23 -7
  50. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +15 -2
  51. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
  52. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12 -2
  53. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
  54. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  55. data/lib/rubocop/cop/layout/end_alignment.rb +8 -5
  56. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +20 -15
  57. data/lib/rubocop/cop/layout/hash_alignment.rb +1 -1
  58. data/lib/rubocop/cop/layout/indentation_width.rb +40 -0
  59. data/lib/rubocop/cop/layout/line_length.rb +5 -3
  60. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -2
  61. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
  62. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +53 -3
  63. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  64. data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -1
  65. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  66. data/lib/rubocop/cop/layout/space_around_keyword.rb +3 -1
  67. data/lib/rubocop/cop/layout/space_around_operators.rb +6 -2
  68. data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -1
  69. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -0
  70. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +1 -11
  71. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  72. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1 -10
  73. data/lib/rubocop/cop/lint/assignment_in_condition.rb +13 -1
  74. data/lib/rubocop/cop/lint/circular_argument_reference.rb +1 -3
  75. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  76. data/lib/rubocop/cop/lint/constant_reassignment.rb +93 -11
  77. data/lib/rubocop/cop/lint/constant_resolution.rb +6 -6
  78. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  79. data/lib/rubocop/cop/lint/debugger.rb +0 -1
  80. data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
  81. data/lib/rubocop/cop/lint/duplicate_methods.rb +55 -8
  82. data/lib/rubocop/cop/lint/empty_block.rb +4 -4
  83. data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -1
  84. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  85. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  86. data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
  87. data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -2
  88. data/lib/rubocop/cop/lint/float_comparison.rb +1 -0
  89. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
  90. data/lib/rubocop/cop/lint/interpolation_check.rb +25 -5
  91. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  92. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
  93. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +8 -11
  94. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +5 -5
  95. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  96. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  97. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +16 -0
  98. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
  99. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  100. data/lib/rubocop/cop/lint/number_conversion.rb +19 -10
  101. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  102. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +3 -0
  103. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
  104. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -13
  105. data/lib/rubocop/cop/lint/raise_exception.rb +1 -1
  106. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  107. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +4 -1
  108. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6 -12
  109. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15 -4
  110. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +36 -12
  111. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +4 -0
  112. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +10 -3
  113. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  114. data/lib/rubocop/cop/lint/redundant_with_object.rb +5 -0
  115. data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
  116. data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
  117. data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
  118. data/lib/rubocop/cop/lint/require_range_parentheses.rb +2 -1
  119. data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
  120. data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
  121. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +18 -0
  122. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +7 -1
  123. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  124. data/lib/rubocop/cop/lint/script_permission.rb +5 -1
  125. data/lib/rubocop/cop/lint/self_assignment.rb +24 -1
  126. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
  127. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  128. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14 -0
  129. data/lib/rubocop/cop/lint/shared_mutable_default.rb +3 -1
  130. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +12 -0
  131. data/lib/rubocop/cop/lint/symbol_conversion.rb +21 -4
  132. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  133. data/lib/rubocop/cop/lint/to_enum_arguments.rb +35 -2
  134. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  135. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
  136. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +36 -10
  137. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
  138. data/lib/rubocop/cop/lint/unreachable_code.rb +2 -2
  139. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  140. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  141. data/lib/rubocop/cop/lint/useless_assignment.rb +14 -14
  142. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +4 -4
  143. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
  144. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +8 -4
  145. data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -1
  146. data/lib/rubocop/cop/lint/useless_times.rb +22 -1
  147. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +35 -9
  148. data/lib/rubocop/cop/lint/void.rb +32 -12
  149. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  150. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  151. data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
  152. data/lib/rubocop/cop/metrics/method_length.rb +2 -2
  153. data/lib/rubocop/cop/metrics/perceived_complexity.rb +38 -7
  154. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  155. data/lib/rubocop/cop/migration/department_name.rb +12 -1
  156. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  157. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
  158. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  159. data/lib/rubocop/cop/mixin/hash_subset.rb +8 -0
  160. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  161. data/lib/rubocop/cop/mixin/hash_transform_method.rb +14 -60
  162. data/lib/rubocop/cop/mixin/project_index_help.rb +48 -0
  163. data/lib/rubocop/cop/mixin.rb +86 -0
  164. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  165. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  166. data/lib/rubocop/cop/naming/file_name.rb +4 -3
  167. data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
  168. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +10 -1
  169. data/lib/rubocop/cop/naming/predicate_method.rb +2 -2
  170. data/lib/rubocop/cop/naming/predicate_prefix.rb +1 -1
  171. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -4
  172. data/lib/rubocop/cop/offense.rb +8 -0
  173. data/lib/rubocop/cop/registry.rb +62 -38
  174. data/lib/rubocop/cop/security/eval.rb +15 -2
  175. data/lib/rubocop/cop/security/io_methods.rb +2 -2
  176. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  177. data/lib/rubocop/cop/style/access_modifier_declarations.rb +14 -2
  178. data/lib/rubocop/cop/style/accessor_grouping.rb +15 -3
  179. data/lib/rubocop/cop/style/alias.rb +15 -3
  180. data/lib/rubocop/cop/style/and_or.rb +2 -1
  181. data/lib/rubocop/cop/style/arguments_forwarding.rb +25 -7
  182. data/lib/rubocop/cop/style/array_first_last.rb +12 -1
  183. data/lib/rubocop/cop/style/array_intersect.rb +4 -0
  184. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +3 -0
  185. data/lib/rubocop/cop/style/array_join.rb +4 -2
  186. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  187. data/lib/rubocop/cop/style/attr.rb +5 -2
  188. data/lib/rubocop/cop/style/bare_percent_literals.rb +3 -1
  189. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  190. data/lib/rubocop/cop/style/block_delimiters.rb +37 -31
  191. data/lib/rubocop/cop/style/case_equality.rb +18 -2
  192. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  193. data/lib/rubocop/cop/style/class_and_module_children.rb +18 -2
  194. data/lib/rubocop/cop/style/class_equality_comparison.rb +21 -13
  195. data/lib/rubocop/cop/style/class_methods_definitions.rb +11 -5
  196. data/lib/rubocop/cop/style/collection_compact.rb +36 -16
  197. data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
  198. data/lib/rubocop/cop/style/combinable_loops.rb +5 -0
  199. data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
  200. data/lib/rubocop/cop/style/concat_array_literals.rb +7 -1
  201. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -5
  202. data/lib/rubocop/cop/style/constant_visibility.rb +4 -1
  203. data/lib/rubocop/cop/style/copyright.rb +22 -11
  204. data/lib/rubocop/cop/style/data_inheritance.rb +4 -0
  205. data/lib/rubocop/cop/style/date_time.rb +4 -4
  206. data/lib/rubocop/cop/style/dig_chain.rb +5 -0
  207. data/lib/rubocop/cop/style/dir_empty.rb +4 -0
  208. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
  209. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  210. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  211. data/lib/rubocop/cop/style/each_with_object.rb +2 -0
  212. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  213. data/lib/rubocop/cop/style/empty_case_condition.rb +12 -2
  214. data/lib/rubocop/cop/style/empty_class_definition.rb +51 -21
  215. data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
  216. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  217. data/lib/rubocop/cop/style/empty_literal.rb +7 -2
  218. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +30 -20
  219. data/lib/rubocop/cop/style/encoding.rb +7 -1
  220. data/lib/rubocop/cop/style/end_block.rb +3 -1
  221. data/lib/rubocop/cop/style/endless_method.rb +8 -3
  222. data/lib/rubocop/cop/style/env_home.rb +4 -0
  223. data/lib/rubocop/cop/style/even_odd.rb +11 -1
  224. data/lib/rubocop/cop/style/exact_regexp_match.rb +8 -1
  225. data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
  226. data/lib/rubocop/cop/style/file_null.rb +4 -2
  227. data/lib/rubocop/cop/style/file_open.rb +84 -0
  228. data/lib/rubocop/cop/style/file_write.rb +21 -16
  229. data/lib/rubocop/cop/style/for.rb +3 -0
  230. data/lib/rubocop/cop/style/format_string.rb +17 -4
  231. data/lib/rubocop/cop/style/format_string_token.rb +29 -2
  232. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  233. data/lib/rubocop/cop/style/guard_clause.rb +9 -6
  234. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +21 -5
  235. data/lib/rubocop/cop/style/hash_conversion.rb +1 -1
  236. data/lib/rubocop/cop/style/hash_lookup_method.rb +19 -7
  237. data/lib/rubocop/cop/style/hash_slice.rb +16 -0
  238. data/lib/rubocop/cop/style/hash_syntax.rb +2 -0
  239. data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
  240. data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
  241. data/lib/rubocop/cop/style/if_inside_else.rb +16 -7
  242. data/lib/rubocop/cop/style/if_unless_modifier.rb +15 -4
  243. data/lib/rubocop/cop/style/if_with_semicolon.rb +16 -6
  244. data/lib/rubocop/cop/style/inline_comment.rb +5 -2
  245. data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
  246. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
  247. data/lib/rubocop/cop/style/keyword_parameters_order.rb +7 -3
  248. data/lib/rubocop/cop/style/lambda.rb +7 -1
  249. data/lib/rubocop/cop/style/magic_comment_format.rb +3 -3
  250. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
  251. data/lib/rubocop/cop/style/map_into_array.rb +1 -1
  252. data/lib/rubocop/cop/style/map_join.rb +123 -0
  253. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -3
  254. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +6 -2
  255. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  256. data/lib/rubocop/cop/style/min_max_comparison.rb +4 -1
  257. data/lib/rubocop/cop/style/module_member_existence_check.rb +7 -14
  258. data/lib/rubocop/cop/style/multiline_if_then.rb +4 -2
  259. data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
  260. data/lib/rubocop/cop/style/multiline_method_signature.rb +11 -4
  261. data/lib/rubocop/cop/style/mutable_constant.rb +106 -12
  262. data/lib/rubocop/cop/style/nil_comparison.rb +2 -3
  263. data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
  264. data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
  265. data/lib/rubocop/cop/style/not.rb +2 -0
  266. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  267. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
  268. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  269. data/lib/rubocop/cop/style/one_line_conditional.rb +4 -3
  270. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  271. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  272. data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
  273. data/lib/rubocop/cop/style/parallel_assignment.rb +23 -3
  274. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  275. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +4 -0
  276. data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
  277. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  278. data/lib/rubocop/cop/style/proc.rb +3 -2
  279. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  280. data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
  281. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  282. data/lib/rubocop/cop/style/redundant_begin.rb +3 -3
  283. data/lib/rubocop/cop/style/redundant_constant_base.rb +5 -5
  284. data/lib/rubocop/cop/style/redundant_each.rb +3 -3
  285. data/lib/rubocop/cop/style/redundant_exception.rb +6 -0
  286. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
  287. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  288. data/lib/rubocop/cop/style/redundant_format.rb +29 -0
  289. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
  290. data/lib/rubocop/cop/style/redundant_line_continuation.rb +27 -3
  291. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  292. data/lib/rubocop/cop/style/redundant_parentheses.rb +25 -22
  293. data/lib/rubocop/cop/style/redundant_percent_q.rb +4 -1
  294. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
  295. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -4
  296. data/lib/rubocop/cop/style/redundant_return.rb +3 -1
  297. data/lib/rubocop/cop/style/redundant_self.rb +11 -2
  298. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
  299. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
  300. data/lib/rubocop/cop/style/regexp_literal.rb +31 -2
  301. data/lib/rubocop/cop/style/rescue_modifier.rb +3 -3
  302. data/lib/rubocop/cop/style/safe_navigation.rb +7 -7
  303. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  304. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  305. data/lib/rubocop/cop/style/select_by_regexp.rb +51 -21
  306. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  307. data/lib/rubocop/cop/style/semicolon.rb +22 -5
  308. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  309. data/lib/rubocop/cop/style/single_line_do_end_block.rb +18 -5
  310. data/lib/rubocop/cop/style/single_line_methods.rb +3 -1
  311. data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -2
  312. data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
  313. data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
  314. data/lib/rubocop/cop/style/struct_inheritance.rb +13 -0
  315. data/lib/rubocop/cop/style/symbol_proc.rb +7 -6
  316. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  317. data/lib/rubocop/cop/style/ternary_parentheses.rb +11 -0
  318. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -2
  319. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  320. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  321. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +7 -8
  322. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  323. data/lib/rubocop/cop/style/while_until_do.rb +7 -0
  324. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -0
  325. data/lib/rubocop/cop/style/word_array.rb +1 -0
  326. data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
  327. data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
  328. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
  329. data/lib/rubocop/cop/team.rb +86 -35
  330. data/lib/rubocop/cop/variable_force/branch.rb +2 -2
  331. data/lib/rubocop/directive_comment.rb +2 -1
  332. data/lib/rubocop/file_patterns.rb +9 -1
  333. data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -9
  334. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  335. data/lib/rubocop/formatter/junit_formatter.rb +1 -1
  336. data/lib/rubocop/formatter/simple_text_formatter.rb +0 -2
  337. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
  338. data/lib/rubocop/formatter.rb +22 -21
  339. data/lib/rubocop/lsp/diagnostic.rb +1 -0
  340. data/lib/rubocop/lsp/routes.rb +10 -3
  341. data/lib/rubocop/lsp/runtime.rb +1 -2
  342. data/lib/rubocop/mcp/server.rb +200 -0
  343. data/lib/rubocop/options.rb +35 -4
  344. data/lib/rubocop/path_util.rb +14 -2
  345. data/lib/rubocop/plugin/loader.rb +1 -1
  346. data/lib/rubocop/project_index_loader.rb +66 -0
  347. data/lib/rubocop/result_cache.rb +22 -10
  348. data/lib/rubocop/rspec/cop_helper.rb +8 -0
  349. data/lib/rubocop/rspec/shared_contexts.rb +32 -2
  350. data/lib/rubocop/runner.rb +126 -53
  351. data/lib/rubocop/server/cache.rb +5 -7
  352. data/lib/rubocop/server/core.rb +8 -0
  353. data/lib/rubocop/target_finder.rb +14 -7
  354. data/lib/rubocop/target_ruby.rb +18 -12
  355. data/lib/rubocop/version.rb +21 -3
  356. data/lib/rubocop.rb +22 -96
  357. metadata +27 -5
@@ -5,8 +5,10 @@ module RuboCop
5
5
  module Layout
6
6
  # Enforces empty line after guard clause.
7
7
  #
8
- # This cop allows `# :nocov:` directive after guard clause because
9
- # SimpleCov excludes code from the coverage report by wrapping it in `# :nocov:`:
8
+ # This cop allows a SimpleCov directive comment after guard clause because
9
+ # SimpleCov excludes code from the coverage report by wrapping it in such directives.
10
+ # Both the legacy `# :nocov:` comment and the newer `# simplecov:disable` /
11
+ # `# simplecov:enable` comments are recognized:
10
12
  #
11
13
  # [source,ruby]
12
14
  # ----
@@ -16,6 +18,13 @@ module RuboCop
16
18
  # # :nocov:
17
19
  # bar
18
20
  # end
21
+ #
22
+ # def foo
23
+ # # simplecov:disable
24
+ # return if condition
25
+ # # simplecov:enable
26
+ # bar
27
+ # end
19
28
  # ----
20
29
  #
21
30
  # Refer to SimpleCov's documentation for more details:
@@ -58,7 +67,12 @@ module RuboCop
58
67
 
59
68
  MSG = 'Add empty line after guard clause.'
60
69
  END_OF_HEREDOC_LINE = 1
61
- SIMPLE_DIRECTIVE_COMMENT_PATTERN = /\A# *:nocov:\z/.freeze
70
+ SIMPLECOV_COMMENT_PATTERN = /\A#\s*(?::nocov:|simplecov\s*:\s*(?:disable|enable)\b)/.freeze
71
+
72
+ # @!method guard_clause_branch?(node)
73
+ def_node_matcher :guard_clause_branch?, <<~PATTERN
74
+ {(send nil? {:raise :fail} ...) return break next}
75
+ PATTERN
62
76
 
63
77
  def on_if(node)
64
78
  return if correct_style?(node)
@@ -97,14 +111,16 @@ module RuboCop
97
111
  end
98
112
 
99
113
  def correct_style?(node)
100
- !contains_guard_clause?(node) ||
114
+ !node.if_branch&.guard_clause? ||
101
115
  next_line_rescue_or_ensure?(node) ||
102
116
  next_sibling_parent_empty_or_else?(node) ||
103
117
  next_sibling_empty_or_guard_clause?(node)
104
118
  end
105
119
 
106
120
  def contains_guard_clause?(node)
107
- node.if_branch&.guard_clause?
121
+ return false unless (branch = node.if_branch)
122
+
123
+ branch.guard_clause? || guard_clause_branch?(branch)
108
124
  end
109
125
 
110
126
  def next_line_empty_or_allowed_directive_comment?(line)
@@ -206,10 +222,10 @@ module RuboCop
206
222
  parent.begin_type? && same_line?(node, node.right_sibling)
207
223
  end
208
224
 
209
- # SimpleCov excludes code from the coverage report by wrapping it in `# :nocov:`:
225
+ # SimpleCov excludes code from the coverage report by wrapping it in directive comments:
210
226
  # https://github.com/simplecov-ruby/simplecov#ignoringskipping-code
211
227
  def simplecov_directive_comment?(comment)
212
- SIMPLE_DIRECTIVE_COMMENT_PATTERN.match?(comment.text)
228
+ SIMPLECOV_COMMENT_PATTERN.match?(comment.text)
213
229
  end
214
230
  end
215
231
  end
@@ -185,7 +185,7 @@ module RuboCop
185
185
  end
186
186
 
187
187
  def empty_line_between_macros
188
- cop_config.fetch('DefLikeMacros', []).map(&:to_sym)
188
+ @empty_line_between_macros ||= cop_config.fetch('DefLikeMacros', []).map(&:to_sym).freeze
189
189
  end
190
190
 
191
191
  def macro_candidate?(node)
@@ -274,7 +274,20 @@ module RuboCop
274
274
  end
275
275
 
276
276
  def end_loc(node)
277
- node.source_range.end
277
+ end_location = node.source_range.end
278
+ trailing_heredoc_end(node, end_location) || end_location
279
+ end
280
+
281
+ # For an endless method whose body is a heredoc (e.g. `def a = <<~TEXT`), the
282
+ # node's source range ends at the heredoc opening line, before the heredoc body.
283
+ # Use the heredoc's closing delimiter so the def's real end is located after the
284
+ # heredoc and blank-line insertion does not land inside the heredoc body.
285
+ def trailing_heredoc_end(node, end_location)
286
+ heredocs = node.each_descendant(:any_str).select(&:heredoc?)
287
+ return if heredocs.empty?
288
+
289
+ heredoc_end = heredocs.map { |heredoc| heredoc.loc.heredoc_end }.max_by(&:end_pos)
290
+ heredoc_end if heredoc_end.end_pos > end_location.end_pos
278
291
  end
279
292
 
280
293
  def autocorrect_remove_lines(corrector, newline_pos, count)
@@ -66,6 +66,7 @@ module RuboCop
66
66
  extend AutoCorrector
67
67
 
68
68
  MSG = 'Add an empty line after attribute accessor.'
69
+ RESTRICT_ON_SEND = %i[attr_reader attr_writer attr_accessor attr].freeze
69
70
 
70
71
  def on_send(node)
71
72
  return unless node.attribute_accessor?
@@ -7,15 +7,25 @@ module RuboCop
7
7
  # the configuration.
8
8
  #
9
9
  # @example EnforcedStyle: no_empty_lines (default)
10
- # # good
10
+ # # bad
11
+ # foo do |bar|
12
+ #
13
+ # # ...
14
+ #
15
+ # end
11
16
  #
17
+ # # good
12
18
  # foo do |bar|
13
19
  # # ...
14
20
  # end
15
21
  #
16
22
  # @example EnforcedStyle: empty_lines
17
- # # good
23
+ # # bad
24
+ # foo do |bar|
25
+ # # ...
26
+ # end
18
27
  #
28
+ # # good
19
29
  # foo do |bar|
20
30
  #
21
31
  # # ...
@@ -7,8 +7,16 @@ module RuboCop
7
7
  # the configuration.
8
8
  #
9
9
  # @example EnforcedStyle: no_empty_lines (default)
10
- # # good
10
+ # # bad
11
+ # class Foo
12
+ #
13
+ # def bar
14
+ # # ...
15
+ # end
16
+ #
17
+ # end
11
18
  #
19
+ # # good
12
20
  # class Foo
13
21
  # def bar
14
22
  # # ...
@@ -16,8 +24,14 @@ module RuboCop
16
24
  # end
17
25
  #
18
26
  # @example EnforcedStyle: empty_lines
19
- # # good
27
+ # # bad
28
+ # class Foo
29
+ # def bar
30
+ # # ...
31
+ # end
32
+ # end
20
33
  #
34
+ # # good
21
35
  # class Foo
22
36
  #
23
37
  # def bar
@@ -7,8 +7,16 @@ module RuboCop
7
7
  # the configuration.
8
8
  #
9
9
  # @example EnforcedStyle: no_empty_lines (default)
10
- # # good
10
+ # # bad
11
+ # module Foo
12
+ #
13
+ # def bar
14
+ # # ...
15
+ # end
16
+ #
17
+ # end
11
18
  #
19
+ # # good
12
20
  # module Foo
13
21
  # def bar
14
22
  # # ...
@@ -16,8 +24,14 @@ module RuboCop
16
24
  # end
17
25
  #
18
26
  # @example EnforcedStyle: empty_lines
19
- # # good
27
+ # # bad
28
+ # module Foo
29
+ # def bar
30
+ # # ...
31
+ # end
32
+ # end
20
33
  #
34
+ # # good
21
35
  # module Foo
22
36
  #
23
37
  # def bar
@@ -19,10 +19,10 @@ module RuboCop
19
19
  #
20
20
  # This `Layout/EndAlignment` cop aligns with keywords (e.g. `if`, `while`, `case`)
21
21
  # by default. On the other hand, `Layout/BeginEndAlignment` cop aligns with
22
- # `EnforcedStyleAlignWith: start_of_line` by default due to `||= begin` tends
22
+ # `EnforcedStyleAlignWith: start_of_line` by default because `||= begin` tends
23
23
  # to align with the start of the line. `Layout/DefEndAlignment` cop also aligns with
24
24
  # `EnforcedStyleAlignWith: start_of_line` by default.
25
- # These style can be configured by each cop.
25
+ # These styles can be configured by each cop.
26
26
  #
27
27
  # @example EnforcedStyleAlignWith: keyword (default)
28
28
  # # bad
@@ -123,20 +123,23 @@ module RuboCop
123
123
  AlignmentCorrector.align_end(corrector, processed_source, node, alignment_node(node))
124
124
  end
125
125
 
126
+ # rubocop:disable Metrics/CyclomaticComplexity
126
127
  def check_assignment(node, rhs)
127
128
  # If there are method calls chained to the right hand side of the
128
129
  # assignment, we let rhs be the receiver of those method calls before
129
130
  # we check if it's an if/unless/while/until.
130
131
  return unless (rhs = first_part_of_call_chain(rhs))
131
132
 
132
- # If `rhs` is a `begin` node, find the first non-`begin` child.
133
- rhs = rhs.child_nodes.first while rhs.begin_type?
133
+ # If `rhs` is a `begin` node or a logical operator,
134
+ # unwrap to find the leading conditional.
135
+ rhs = rhs.child_nodes.first while rhs&.type?(:begin, :or, :and)
134
136
 
135
- return unless rhs.conditional?
137
+ return unless rhs&.conditional?
136
138
  return if rhs.if_type? && rhs.ternary?
137
139
 
138
140
  check_asgn_alignment(node, rhs)
139
141
  end
142
+ # rubocop:enable Metrics/CyclomaticComplexity
140
143
 
141
144
  def check_asgn_alignment(outer_node, inner_node)
142
145
  align_with = {
@@ -28,10 +28,10 @@ module RuboCop
28
28
  # # bad
29
29
  # hash = {
30
30
  # key: :value
31
- # }
32
- # and_in_a_method_call({
33
- # no: :difference
34
- # })
31
+ # }
32
+ # in_a_method_call({
33
+ # foo: :bar
34
+ # })
35
35
  # takes_multi_pairs_hash(x: {
36
36
  # a: 1,
37
37
  # b: 2
@@ -42,13 +42,12 @@ module RuboCop
42
42
  # })
43
43
  #
44
44
  # # good
45
- # special_inside_parentheses
46
45
  # hash = {
47
46
  # key: :value
48
47
  # }
49
- # but_in_a_method_call({
50
- # its_like: :this
51
- # })
48
+ # in_a_method_call({
49
+ # foo: :bar
50
+ # })
52
51
  # takes_multi_pairs_hash(x: {
53
52
  # a: 1,
54
53
  # b: 2
@@ -67,17 +66,17 @@ module RuboCop
67
66
  # # bad
68
67
  # hash = {
69
68
  # key: :value
70
- # }
71
- # but_in_a_method_call({
72
- # its_like: :this
73
- # })
69
+ # }
70
+ # in_a_method_call({
71
+ # foo: :bar
72
+ # })
74
73
  #
75
74
  # # good
76
75
  # hash = {
77
76
  # key: :value
78
77
  # }
79
- # and_in_a_method_call({
80
- # no: :difference
78
+ # in_a_method_call({
79
+ # foo: :bar
81
80
  # })
82
81
  #
83
82
  #
@@ -135,7 +134,13 @@ module RuboCop
135
134
  private
136
135
 
137
136
  def autocorrect(corrector, node)
138
- AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
137
+ line_range = if !node.is_a?(AST::Node) || node.value.first_line <= node.key.first_line
138
+ node
139
+ else
140
+ processed_source.buffer.line_range(node.loc.line)
141
+ end
142
+
143
+ AlignmentCorrector.correct(corrector, processed_source, line_range, @column_delta)
139
144
  end
140
145
 
141
146
  def brace_alignment_style
@@ -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
  #
@@ -25,6 +25,17 @@ module RuboCop
25
25
  # end
26
26
  # end
27
27
  #
28
+ # @example
29
+ # # bad
30
+ # value = (
31
+ # foo - bar
32
+ # )
33
+ #
34
+ # # good
35
+ # value = (
36
+ # foo - bar
37
+ # )
38
+ #
28
39
  # @example AllowedPatterns: ['^\s*module']
29
40
  # # bad
30
41
  # module A
@@ -95,6 +106,16 @@ module RuboCop
95
106
  check_indentation(node.loc.end, node.children.first)
96
107
  end
97
108
 
109
+ def on_begin(node)
110
+ # Only a parenthesized grouping expression (e.g. `(\n foo\n)`) has
111
+ # explicit delimiters. Indent the body one step from the line
112
+ # the opening parenthesis is on, but only when the closing parenthesis is
113
+ # first on its line (a body on the opening line is skipped downstream).
114
+ return unless parentheses?(node) && begins_its_line?(node.loc.end)
115
+
116
+ check_indentation(opening_line_start(node.loc.begin), node.children.first)
117
+ end
118
+
98
119
  def on_block(node)
99
120
  end_loc = node.loc.end
100
121
 
@@ -188,6 +209,13 @@ module RuboCop
188
209
  AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
189
210
  end
190
211
 
212
+ # Returns a range at the first non-space column of the line the opening parenthesis is on,
213
+ # used as the base to indent the body from.
214
+ def opening_line_start(begin_loc)
215
+ column = begin_loc.source_line =~ /\S/
216
+ source_range(processed_source.buffer, begin_loc.line, column)
217
+ end
218
+
191
219
  def check_members(base, members)
192
220
  check_indentation(base, select_check_member(members.first))
193
221
 
@@ -473,8 +501,12 @@ module RuboCop
473
501
  end
474
502
 
475
503
  def block_body_indentation_base(node, end_loc)
504
+ return end_loc unless style == :relative_to_receiver
505
+
476
506
  if dot_on_new_line?(node)
477
507
  node.send_node.loc.dot
508
+ elsif selector_on_new_line?(node)
509
+ node.send_node.loc.selector
478
510
  else
479
511
  end_loc
480
512
  end
@@ -487,6 +519,14 @@ module RuboCop
487
519
  receiver = send_node.receiver
488
520
  receiver && receiver.last_line < send_node.loc.dot.line
489
521
  end
522
+
523
+ def selector_on_new_line?(node)
524
+ send_node = node.send_node
525
+ return false unless send_node.loc?(:dot) && send_node.loc?(:selector)
526
+
527
+ receiver = send_node.receiver
528
+ receiver && receiver.last_line < send_node.loc.selector.line
529
+ end
490
530
  end
491
531
  end
492
532
  end
@@ -406,9 +406,11 @@ module RuboCop
406
406
  end
407
407
 
408
408
  def string_delimiter(node)
409
- delimiter = node.loc.begin
410
- delimiter ||= node.parent.loc.begin if node.parent&.dstr_type? && node.parent.loc?(:begin)
411
- 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
412
414
 
413
415
  delimiter if %w[' "].include?(delimiter)
414
416
  end
@@ -69,14 +69,18 @@ module RuboCop
69
69
  SAME_LINE_OFFENSE = 'Right hand side of multi-line assignment is not ' \
70
70
  'on the same line as the assignment operator `=`.'
71
71
 
72
+ BLOCK_TYPES = %i[block numblock itblock].freeze
73
+
74
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
72
75
  def check_assignment(node, rhs)
73
76
  return if node.send_type? && node.loc.operator&.source != '='
74
77
  return unless rhs
75
78
  return unless supported_types.include?(rhs.type)
76
- return if rhs.single_line?
79
+ return if rhs.single_line? && (!rhs.block_type? || same_line?(node, rhs.loc.begin))
77
80
 
78
81
  check_by_enforced_style(node, rhs)
79
82
  end
83
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
80
84
 
81
85
  def check_by_enforced_style(node, rhs)
82
86
  case style
@@ -109,7 +113,10 @@ module RuboCop
109
113
  private
110
114
 
111
115
  def supported_types
112
- @supported_types ||= cop_config['SupportedTypes'].map(&:to_sym)
116
+ @supported_types ||= cop_config['SupportedTypes'].flat_map do |type|
117
+ sym = type.to_sym
118
+ sym == :block ? BLOCK_TYPES : sym
119
+ end
113
120
  end
114
121
  end
115
122
  end
@@ -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
@@ -128,12 +128,15 @@ module RuboCop
128
128
  if hash_pair_indented?(node, pair_ancestor, given_style)
129
129
  return check_hash_pair_indented_style(rhs, pair_ancestor)
130
130
  end
131
-
132
- return false if !pair_ancestor && not_for_this_cop?(node)
131
+ return false if skip_for_context?(node, pair_ancestor)
133
132
 
134
133
  check_regular_indentation(node, lhs, rhs, given_style)
135
134
  end
136
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
+
137
140
  def hash_pair_aligned?(pair_ancestor, given_style)
138
141
  pair_ancestor && given_style == :aligned
139
142
  end
@@ -152,7 +155,10 @@ module RuboCop
152
155
  end
153
156
 
154
157
  def check_hash_pair_indentation(node, lhs, rhs)
155
- @base = find_hash_pair_alignment_base(node) || lhs.source_range
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
156
162
  return if aligned_with_first_line_dot?(node, rhs)
157
163
 
158
164
  calculate_column_delta_offense(rhs, @base.column)
@@ -166,6 +172,50 @@ module RuboCop
166
172
  first_call.loc.dot.join(first_call.loc.selector)
167
173
  end
168
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
+
169
219
  def aligned_with_first_line_dot?(node, rhs)
170
220
  return false unless rhs.source.start_with?('.', '&.')
171
221
 
@@ -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
  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)
@@ -204,10 +204,14 @@ module RuboCop
204
204
 
205
205
  def autocorrect(corrector, range, right_operand)
206
206
  range_source = range.source
207
+ # Match the operator exactly, not by substring, so compound assignments
208
+ # like `**=` and `/=` are not mistaken for `**` and `/` (which would drop
209
+ # the `=` and silently change the program's behavior).
210
+ operator = range_source.strip
207
211
 
208
- if range_source.include?('**') && !space_around_exponent_operator?
212
+ if operator == '**' && !space_around_exponent_operator?
209
213
  corrector.replace(range, '**')
210
- elsif range_source.include?('/') && !space_around_slash_operator?(right_operand)
214
+ elsif operator == '/' && !space_around_slash_operator?(right_operand)
211
215
  corrector.replace(range, '/')
212
216
  elsif range_source.end_with?("\n")
213
217
  corrector.replace(range, " #{range_source.strip}\n")
@@ -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
  #
@@ -26,6 +26,7 @@ module RuboCop
26
26
 
27
27
  MSG_REQUIRE_SPACE = 'Use a space between `->` and `(` in lambda literals.'
28
28
  MSG_REQUIRE_NO_SPACE = 'Do not use spaces between `->` and `(` in lambda literals.'
29
+ RESTRICT_ON_SEND = %i[lambda].freeze
29
30
 
30
31
  def on_send(node)
31
32
  return unless arrow_lambda_with_args?(node)
@@ -28,7 +28,7 @@ module RuboCop
28
28
  MISTAKES = { '=-' => '-=', '=+' => '+=', '=*' => '*=', '=!' => '!=' }.freeze
29
29
 
30
30
  def on_asgn(node)
31
- return unless (rhs = rhs(node))
31
+ return unless (rhs = node.expression)
32
32
 
33
33
  range = range_between(node.loc.operator.end_pos - 1, rhs.source_range.begin_pos + 1)
34
34
  source = range.source
@@ -38,16 +38,6 @@ module RuboCop
38
38
  end
39
39
 
40
40
  SIMPLE_ASSIGNMENT_TYPES.each { |asgn_type| alias_method :"on_#{asgn_type}", :on_asgn }
41
-
42
- private
43
-
44
- def rhs(node)
45
- if node.casgn_type?
46
- node.children[2]
47
- else
48
- node.children[1]
49
- end
50
- end
51
41
  end
52
42
  end
53
43
  end
@@ -7,7 +7,7 @@ module RuboCop
7
7
  # when param passed without parentheses.
8
8
  #
9
9
  # This cop can customize allowed methods with `AllowedMethods`.
10
- # By default, there are no methods to allowed.
10
+ # By default, there are no allowed methods.
11
11
  #
12
12
  # @example
13
13
  #