rubocop 1.84.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 (313) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +180 -86
  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 +2 -2
  23. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  24. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
  25. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +33 -2
  26. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  27. data/lib/rubocop/cop/correctors.rb +28 -0
  28. data/lib/rubocop/cop/documentation.rb +2 -3
  29. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  30. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  31. data/lib/rubocop/cop/gemspec/require_mfa.rb +5 -5
  32. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
  33. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  34. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  35. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
  36. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  37. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -2
  38. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  39. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
  40. data/lib/rubocop/cop/layout/block_alignment.rb +41 -4
  41. data/lib/rubocop/cop/layout/class_structure.rb +1 -1
  42. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  43. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +23 -7
  44. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
  45. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
  46. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12 -2
  47. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
  48. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  49. data/lib/rubocop/cop/layout/end_alignment.rb +8 -5
  50. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +7 -1
  51. data/lib/rubocop/cop/layout/hash_alignment.rb +1 -1
  52. data/lib/rubocop/cop/layout/indentation_width.rb +12 -0
  53. data/lib/rubocop/cop/layout/line_length.rb +5 -3
  54. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -2
  55. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
  56. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +53 -3
  57. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  58. data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -1
  59. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  60. data/lib/rubocop/cop/layout/space_around_keyword.rb +3 -1
  61. data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -1
  62. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -0
  63. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +1 -11
  64. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  65. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1 -10
  66. data/lib/rubocop/cop/lint/circular_argument_reference.rb +1 -3
  67. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  68. data/lib/rubocop/cop/lint/constant_reassignment.rb +93 -11
  69. data/lib/rubocop/cop/lint/constant_resolution.rb +6 -6
  70. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  71. data/lib/rubocop/cop/lint/debugger.rb +0 -1
  72. data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
  73. data/lib/rubocop/cop/lint/duplicate_methods.rb +55 -8
  74. data/lib/rubocop/cop/lint/empty_block.rb +4 -4
  75. data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -1
  76. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  77. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  78. data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
  79. data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -2
  80. data/lib/rubocop/cop/lint/float_comparison.rb +1 -0
  81. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
  82. data/lib/rubocop/cop/lint/interpolation_check.rb +25 -5
  83. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  84. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
  85. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +8 -11
  86. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +5 -5
  87. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  88. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  89. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +16 -0
  90. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
  91. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  92. data/lib/rubocop/cop/lint/number_conversion.rb +19 -10
  93. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  94. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +3 -0
  95. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
  96. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -13
  97. data/lib/rubocop/cop/lint/raise_exception.rb +1 -1
  98. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  99. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +4 -1
  100. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6 -12
  101. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15 -4
  102. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +36 -12
  103. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +4 -0
  104. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +10 -3
  105. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  106. data/lib/rubocop/cop/lint/redundant_with_object.rb +5 -0
  107. data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
  108. data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
  109. data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
  110. data/lib/rubocop/cop/lint/require_range_parentheses.rb +2 -1
  111. data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
  112. data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
  113. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +18 -0
  114. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +7 -1
  115. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  116. data/lib/rubocop/cop/lint/script_permission.rb +5 -1
  117. data/lib/rubocop/cop/lint/self_assignment.rb +24 -1
  118. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
  119. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  120. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14 -0
  121. data/lib/rubocop/cop/lint/shared_mutable_default.rb +3 -1
  122. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +12 -0
  123. data/lib/rubocop/cop/lint/symbol_conversion.rb +21 -4
  124. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  125. data/lib/rubocop/cop/lint/to_enum_arguments.rb +28 -1
  126. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  127. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
  128. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +4 -2
  129. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
  130. data/lib/rubocop/cop/lint/unreachable_code.rb +2 -2
  131. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  132. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  133. data/lib/rubocop/cop/lint/useless_assignment.rb +14 -14
  134. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +4 -4
  135. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
  136. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +8 -4
  137. data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -1
  138. data/lib/rubocop/cop/lint/useless_times.rb +22 -1
  139. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +35 -9
  140. data/lib/rubocop/cop/lint/void.rb +32 -12
  141. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  142. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  143. data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
  144. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  145. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  146. data/lib/rubocop/cop/migration/department_name.rb +12 -1
  147. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  148. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
  149. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  150. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  151. data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -60
  152. data/lib/rubocop/cop/mixin/project_index_help.rb +48 -0
  153. data/lib/rubocop/cop/mixin.rb +86 -0
  154. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  155. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  156. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  157. data/lib/rubocop/cop/naming/predicate_method.rb +2 -2
  158. data/lib/rubocop/cop/naming/predicate_prefix.rb +1 -1
  159. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
  160. data/lib/rubocop/cop/offense.rb +8 -0
  161. data/lib/rubocop/cop/registry.rb +62 -38
  162. data/lib/rubocop/cop/security/eval.rb +15 -2
  163. data/lib/rubocop/cop/security/io_methods.rb +1 -1
  164. data/lib/rubocop/cop/style/access_modifier_declarations.rb +14 -2
  165. data/lib/rubocop/cop/style/accessor_grouping.rb +4 -2
  166. data/lib/rubocop/cop/style/alias.rb +15 -3
  167. data/lib/rubocop/cop/style/and_or.rb +2 -1
  168. data/lib/rubocop/cop/style/arguments_forwarding.rb +25 -7
  169. data/lib/rubocop/cop/style/array_first_last.rb +12 -1
  170. data/lib/rubocop/cop/style/array_intersect.rb +4 -0
  171. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +3 -0
  172. data/lib/rubocop/cop/style/array_join.rb +4 -2
  173. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  174. data/lib/rubocop/cop/style/attr.rb +5 -2
  175. data/lib/rubocop/cop/style/bare_percent_literals.rb +3 -1
  176. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  177. data/lib/rubocop/cop/style/block_delimiters.rb +37 -31
  178. data/lib/rubocop/cop/style/case_equality.rb +18 -2
  179. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  180. data/lib/rubocop/cop/style/class_and_module_children.rb +18 -2
  181. data/lib/rubocop/cop/style/class_equality_comparison.rb +21 -13
  182. data/lib/rubocop/cop/style/class_methods_definitions.rb +11 -5
  183. data/lib/rubocop/cop/style/collection_compact.rb +36 -16
  184. data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
  185. data/lib/rubocop/cop/style/combinable_loops.rb +5 -0
  186. data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
  187. data/lib/rubocop/cop/style/concat_array_literals.rb +7 -1
  188. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -5
  189. data/lib/rubocop/cop/style/constant_visibility.rb +4 -1
  190. data/lib/rubocop/cop/style/copyright.rb +22 -11
  191. data/lib/rubocop/cop/style/date_time.rb +4 -4
  192. data/lib/rubocop/cop/style/dig_chain.rb +5 -0
  193. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
  194. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  195. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  196. data/lib/rubocop/cop/style/each_with_object.rb +2 -0
  197. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  198. data/lib/rubocop/cop/style/empty_class_definition.rb +43 -20
  199. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  200. data/lib/rubocop/cop/style/encoding.rb +7 -1
  201. data/lib/rubocop/cop/style/end_block.rb +3 -1
  202. data/lib/rubocop/cop/style/endless_method.rb +8 -3
  203. data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
  204. data/lib/rubocop/cop/style/file_open.rb +84 -0
  205. data/lib/rubocop/cop/style/file_write.rb +21 -16
  206. data/lib/rubocop/cop/style/for.rb +3 -0
  207. data/lib/rubocop/cop/style/format_string.rb +4 -3
  208. data/lib/rubocop/cop/style/format_string_token.rb +29 -2
  209. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  210. data/lib/rubocop/cop/style/guard_clause.rb +9 -6
  211. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +21 -5
  212. data/lib/rubocop/cop/style/hash_conversion.rb +1 -1
  213. data/lib/rubocop/cop/style/hash_lookup_method.rb +19 -7
  214. data/lib/rubocop/cop/style/hash_slice.rb +16 -0
  215. data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
  216. data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
  217. data/lib/rubocop/cop/style/if_inside_else.rb +16 -7
  218. data/lib/rubocop/cop/style/if_unless_modifier.rb +15 -4
  219. data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
  220. data/lib/rubocop/cop/style/inline_comment.rb +4 -1
  221. data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
  222. data/lib/rubocop/cop/style/magic_comment_format.rb +3 -3
  223. data/lib/rubocop/cop/style/map_join.rb +123 -0
  224. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -3
  225. data/lib/rubocop/cop/style/min_max_comparison.rb +1 -1
  226. data/lib/rubocop/cop/style/module_member_existence_check.rb +7 -14
  227. data/lib/rubocop/cop/style/multiline_if_then.rb +3 -1
  228. data/lib/rubocop/cop/style/mutable_constant.rb +106 -12
  229. data/lib/rubocop/cop/style/nil_comparison.rb +2 -3
  230. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  231. data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
  232. data/lib/rubocop/cop/style/not.rb +2 -0
  233. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  234. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  235. data/lib/rubocop/cop/style/one_line_conditional.rb +4 -3
  236. data/lib/rubocop/cop/style/parallel_assignment.rb +12 -1
  237. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  238. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -0
  239. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  240. data/lib/rubocop/cop/style/proc.rb +3 -2
  241. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  242. data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
  243. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  244. data/lib/rubocop/cop/style/redundant_begin.rb +3 -3
  245. data/lib/rubocop/cop/style/redundant_constant_base.rb +5 -5
  246. data/lib/rubocop/cop/style/redundant_each.rb +3 -3
  247. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
  248. data/lib/rubocop/cop/style/redundant_format.rb +1 -0
  249. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
  250. data/lib/rubocop/cop/style/redundant_line_continuation.rb +16 -0
  251. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  252. data/lib/rubocop/cop/style/redundant_parentheses.rb +25 -22
  253. data/lib/rubocop/cop/style/redundant_percent_q.rb +4 -1
  254. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
  255. data/lib/rubocop/cop/style/redundant_return.rb +3 -1
  256. data/lib/rubocop/cop/style/redundant_self.rb +2 -2
  257. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
  258. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +114 -0
  259. data/lib/rubocop/cop/style/regexp_literal.rb +31 -2
  260. data/lib/rubocop/cop/style/rescue_modifier.rb +3 -3
  261. data/lib/rubocop/cop/style/safe_navigation.rb +7 -7
  262. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  263. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  264. data/lib/rubocop/cop/style/select_by_regexp.rb +51 -21
  265. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  266. data/lib/rubocop/cop/style/semicolon.rb +18 -1
  267. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  268. data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -1
  269. data/lib/rubocop/cop/style/single_line_methods.rb +3 -1
  270. data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -2
  271. data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
  272. data/lib/rubocop/cop/style/struct_inheritance.rb +13 -0
  273. data/lib/rubocop/cop/style/symbol_proc.rb +7 -6
  274. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  275. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -2
  276. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  277. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  278. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  279. data/lib/rubocop/cop/style/while_until_do.rb +7 -0
  280. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -0
  281. data/lib/rubocop/cop/style/word_array.rb +1 -0
  282. data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
  283. data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
  284. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
  285. data/lib/rubocop/cop/team.rb +86 -35
  286. data/lib/rubocop/cop/variable_force/branch.rb +2 -2
  287. data/lib/rubocop/directive_comment.rb +2 -1
  288. data/lib/rubocop/file_patterns.rb +9 -1
  289. data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -9
  290. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  291. data/lib/rubocop/formatter/junit_formatter.rb +1 -1
  292. data/lib/rubocop/formatter/simple_text_formatter.rb +0 -2
  293. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
  294. data/lib/rubocop/formatter.rb +22 -21
  295. data/lib/rubocop/lsp/diagnostic.rb +1 -0
  296. data/lib/rubocop/lsp/routes.rb +10 -3
  297. data/lib/rubocop/lsp/runtime.rb +1 -2
  298. data/lib/rubocop/mcp/server.rb +200 -0
  299. data/lib/rubocop/options.rb +35 -4
  300. data/lib/rubocop/path_util.rb +14 -2
  301. data/lib/rubocop/plugin/loader.rb +1 -1
  302. data/lib/rubocop/project_index_loader.rb +66 -0
  303. data/lib/rubocop/result_cache.rb +22 -10
  304. data/lib/rubocop/rspec/cop_helper.rb +8 -0
  305. data/lib/rubocop/rspec/shared_contexts.rb +32 -2
  306. data/lib/rubocop/runner.rb +124 -53
  307. data/lib/rubocop/server/cache.rb +5 -7
  308. data/lib/rubocop/server/core.rb +8 -0
  309. data/lib/rubocop/target_finder.rb +14 -7
  310. data/lib/rubocop/target_ruby.rb +18 -12
  311. data/lib/rubocop/version.rb +21 -3
  312. data/lib/rubocop.rb +22 -96
  313. metadata +27 -5
@@ -13,8 +13,7 @@ module RuboCop
13
13
  buffer = node.source_range.source_buffer
14
14
  corrector.remove(range_with_surrounding_space(range: node.loc.begin, buffer: buffer,
15
15
  side: :right, whitespace: true))
16
- corrector.remove(range_with_surrounding_space(range: node.loc.end, buffer: buffer,
17
- side: :left))
16
+ remove_close_paren(corrector, node, buffer)
18
17
  handle_orphaned_comma(corrector, node)
19
18
 
20
19
  return unless ternary_condition?(node) && next_char_is_question_mark?(node)
@@ -24,6 +23,38 @@ module RuboCop
24
23
 
25
24
  private
26
25
 
26
+ # When the line above `)` ends with a comment and a chained call follows `)`,
27
+ # crossing the newline would pull the chain into the comment. Preserve the newline.
28
+ def remove_close_paren(corrector, node, buffer)
29
+ newlines = !comment_above_close_paren_swallows_chain?(node, buffer)
30
+ corrector.remove(range_with_surrounding_space(range: node.loc.end, buffer: buffer,
31
+ side: :left, newlines: newlines))
32
+ end
33
+
34
+ def comment_above_close_paren_swallows_chain?(node, buffer)
35
+ last_child = node.children.last
36
+ return false unless last_child
37
+
38
+ body_end = last_child.source_range.end_pos
39
+ close_paren_begin = node.loc.end.begin_pos
40
+ return false if body_end >= close_paren_begin
41
+
42
+ source_between = buffer.source[body_end...close_paren_begin]
43
+ return false unless source_between.match?(/#[^\n]*\n/)
44
+
45
+ chained_after_close_paren?(node)
46
+ end
47
+
48
+ def chained_after_close_paren?(node)
49
+ close_paren = node.loc.end
50
+ line_text = close_paren.source_line
51
+ after_paren = line_text[(close_paren.column + 1)..]
52
+ return false if after_paren.nil?
53
+
54
+ trimmed = after_paren.lstrip
55
+ !trimmed.empty? && !trimmed.start_with?('#')
56
+ end
57
+
27
58
  def ternary_condition?(node)
28
59
  node.parent&.if_type? && node.parent.ternary?
29
60
  end
@@ -97,8 +97,8 @@ module RuboCop
97
97
  if delimiters.first != delimiters.last
98
98
  # With different delimiters (eg. `[]`, `()`), if there are the same
99
99
  # number of each, escaping is not necessary
100
- delimiter_counts = delimiters.each_with_object({}) do |delimiter, counts|
101
- counts[delimiter] = content.count(delimiter)
100
+ delimiter_counts = delimiters.to_h do |delimiter|
101
+ [delimiter, content.count(delimiter)]
102
102
  end
103
103
 
104
104
  return content if delimiter_counts[delimiters.first] == delimiter_counts[delimiters.last]
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop # rubocop:disable Style/Documentation
5
+ # Autoloads corrector classes used by cops. Classes are autoloaded to reduce the number of
6
+ # required classes because they're referenced only when autocorrection is performed.
7
+
8
+ # rubocop:disable Layout/LineLength
9
+ autoload :AlignmentCorrector, 'rubocop/cop/correctors/alignment_corrector'
10
+ autoload :ConditionCorrector, 'rubocop/cop/correctors/condition_corrector'
11
+ autoload :EachToForCorrector, 'rubocop/cop/correctors/each_to_for_corrector'
12
+ autoload :EmptyLineCorrector, 'rubocop/cop/correctors/empty_line_corrector'
13
+ autoload :ForToEachCorrector, 'rubocop/cop/correctors/for_to_each_corrector'
14
+ autoload :IfThenCorrector, 'rubocop/cop/correctors/if_then_corrector'
15
+ autoload :LambdaLiteralToMethodCorrector, 'rubocop/cop/correctors/lambda_literal_to_method_corrector'
16
+ autoload :LineBreakCorrector, 'rubocop/cop/correctors/line_break_corrector'
17
+ autoload :MultilineLiteralBraceCorrector, 'rubocop/cop/correctors/multiline_literal_brace_corrector'
18
+ autoload :OrderedGemCorrector, 'rubocop/cop/correctors/ordered_gem_corrector'
19
+ autoload :ParenthesesCorrector, 'rubocop/cop/correctors/parentheses_corrector'
20
+ autoload :PercentLiteralCorrector, 'rubocop/cop/correctors/percent_literal_corrector'
21
+ autoload :PunctuationCorrector, 'rubocop/cop/correctors/punctuation_corrector'
22
+ autoload :RequireLibraryCorrector, 'rubocop/cop/correctors/require_library_corrector'
23
+ autoload :SpaceCorrector, 'rubocop/cop/correctors/space_corrector'
24
+ autoload :StringLiteralCorrector, 'rubocop/cop/correctors/string_literal_corrector'
25
+ autoload :UnusedArgCorrector, 'rubocop/cop/correctors/unused_arg_corrector'
26
+ # rubocop:enable Layout/LineLength
27
+ end
28
+ end
@@ -55,10 +55,9 @@ module RuboCop
55
55
 
56
56
  # @api private
57
57
  def builtin?(cop_class)
58
- # any custom method will do
59
- return false unless (m = cop_class.instance_methods(false).first)
58
+ return false unless (name = cop_class.name)
60
59
 
61
- path, _line = cop_class.instance_method(m).source_location
60
+ path, _line = Module.const_source_location(name)
62
61
  path.start_with?(__dir__)
63
62
  end
64
63
  end
@@ -4,16 +4,42 @@ module RuboCop
4
4
  # Allows specified configuration options to have an exclude limit
5
5
  # ie. a maximum value tracked that it can be used by `--auto-gen-config`.
6
6
  module ExcludeLimit
7
+ class << self
8
+ attr_accessor :tmp_dir
9
+
10
+ # Reads the aggregated exclude limit values for a cop from tmp files.
11
+ # Returns a hash like { 'Max' => 81 } or an empty hash if no values were written.
12
+ def read_limits(cop_name)
13
+ cop_dir = cop_dir_for(cop_name)
14
+ return {} unless cop_dir&.directory?
15
+
16
+ limits = {}
17
+ cop_dir.children.each do |filepath|
18
+ next unless filepath.file?
19
+
20
+ values = filepath.readlines.map(&:to_i)
21
+ limits[filepath.basename.to_s] = values.max unless values.empty?
22
+ end
23
+ limits
24
+ end
25
+
26
+ # Returns the tmp directory path for a given cop, or nil if tmp_dir is not set.
27
+ def cop_dir_for(cop_name)
28
+ tmp_dir&.join(cop_name.tr('/', '-'))
29
+ end
30
+ end
31
+
7
32
  # Sets up a configuration option to have an exclude limit tracked.
8
33
  # The parameter name given is transformed into a method name (eg. `Max`
9
34
  # becomes `self.max=` and `MinDigits` becomes `self.min_digits=`).
10
35
  def exclude_limit(parameter_name, method_name: transform(parameter_name))
11
36
  define_method(:"#{method_name}=") do |value|
12
- cfg = config_to_allow_offenses
13
- cfg[:exclude_limit] ||= {}
14
- current_max = cfg[:exclude_limit][parameter_name]
15
- value = [current_max, value].max if current_max
16
- cfg[:exclude_limit][parameter_name] = value
37
+ cop_dir = RuboCop::ExcludeLimit.cop_dir_for(self.class.badge.to_s)
38
+ return unless cop_dir
39
+
40
+ cop_dir.mkpath
41
+ filepath = cop_dir.join(parameter_name)
42
+ filepath.write("#{value}\n", mode: 'a')
17
43
  end
18
44
  end
19
45
 
@@ -3,12 +3,12 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Gemspec
6
- # An attribute assignment method calls should be listed only once
6
+ # An attribute assignment method call should be listed only once
7
7
  # in a gemspec.
8
8
  #
9
9
  # Assigning to an attribute with the same name using `spec.foo =` or
10
10
  # `spec.attribute#[]=` will be an unintended usage. On the other hand,
11
- # duplication of methods such # as `spec.requirements`,
11
+ # duplication of methods such as `spec.requirements`,
12
12
  # `spec.add_runtime_dependency`, and others are permitted because it is
13
13
  # the intended use of appending values.
14
14
  #
@@ -6,7 +6,7 @@ module RuboCop
6
6
  # Requires a gemspec to have `rubygems_mfa_required` metadata set.
7
7
  #
8
8
  # This setting tells RubyGems that MFA (Multi-Factor Authentication) is
9
- # required for accounts to be able perform privileged operations, such as
9
+ # required for accounts to be able to perform privileged operations, such as
10
10
  # (see RubyGems' documentation for the full list of privileged
11
11
  # operations):
12
12
  #
@@ -70,7 +70,7 @@ module RuboCop
70
70
  def_node_matcher :metadata, <<~PATTERN
71
71
  `{
72
72
  (send _ :metadata= $_)
73
- (send (send _ :metadata) :[]= (str "rubygems_mfa_required") $_)
73
+ (send (send _ :metadata) :[]= {(str "rubygems_mfa_required") (sym :rubygems_mfa_required)} $_)
74
74
  }
75
75
  PATTERN
76
76
 
@@ -78,13 +78,13 @@ module RuboCop
78
78
  def_node_search :metadata_assignment, <<~PATTERN
79
79
  `{
80
80
  (send _ :metadata= _)
81
- (send (send _ :metadata) :[]= (str _) _)
81
+ (send (send _ :metadata) :[]= {str sym} _)
82
82
  }
83
83
  PATTERN
84
84
 
85
85
  # @!method rubygems_mfa_required(node)
86
86
  def_node_search :rubygems_mfa_required, <<~PATTERN
87
- (pair (str "rubygems_mfa_required") $_)
87
+ (pair {(str "rubygems_mfa_required") (sym :rubygems_mfa_required)} $_)
88
88
  PATTERN
89
89
 
90
90
  # @!method true_string?(node)
@@ -92,7 +92,7 @@ module RuboCop
92
92
  (str "true")
93
93
  PATTERN
94
94
 
95
- def on_block(node) # rubocop:disable Metrics/MethodLength, InternalAffairs/NumblockHandler
95
+ def on_block(node) # rubocop:disable Metrics/MethodLength, InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
96
96
  gem_specification(node) do |block_var|
97
97
  metadata_value = metadata(node)
98
98
  mfa_value = mfa_value(metadata_value)
@@ -4,10 +4,10 @@ module RuboCop
4
4
  module Cop
5
5
  module Gemspec
6
6
  # Checks that `RUBY_VERSION` and `Ruby::VERSION` constants are not used in gemspec.
7
- # Using `RUBY_VERSION` and `Ruby::VERSION` are dangerous because value of the
7
+ # Using `RUBY_VERSION` and `Ruby::VERSION` is dangerous because the value of the
8
8
  # constant is determined by `rake release`.
9
- # It's possible to have dependency based on ruby version used
10
- # to execute `rake release` and not user's ruby version.
9
+ # It's possible to have a dependency based on the Ruby version used
10
+ # to execute `rake release` and not the user's Ruby version.
11
11
  #
12
12
  # @example
13
13
  #
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # Checks for missing `itblock` handlers. The blocks with the `it`
7
+ # parameter introduced in Ruby 3.4 are parsed with a node type of
8
+ # `itblock` instead of block. Cops that define `block` handlers
9
+ # need to define `itblock` handlers or disable this cop for them.
10
+ #
11
+ # @example
12
+ #
13
+ # # bad
14
+ # class BlockRelatedCop < Base
15
+ # def on_block(node)
16
+ # end
17
+ # end
18
+ #
19
+ # # good
20
+ # class BlockRelatedCop < Base
21
+ # def on_block(node)
22
+ # end
23
+ #
24
+ # alias on_itblock on_block
25
+ # end
26
+ #
27
+ # class BlockRelatedCop < Base
28
+ # def on_block(node)
29
+ # end
30
+ #
31
+ # alias_method :on_itblock, :on_block
32
+ # end
33
+ #
34
+ # class BlockRelatedCop < Base
35
+ # def on_block(node)
36
+ # end
37
+ #
38
+ # def on_itblock(node)
39
+ # end
40
+ # end
41
+ class ItblockHandler < Base
42
+ MSG = 'Define on_itblock to handle blocks with the `it` parameter.'
43
+
44
+ def on_def(node)
45
+ return unless block_handler?(node)
46
+ return unless node.parent
47
+
48
+ add_offense(node) unless itblock_handler?(node.parent)
49
+ end
50
+
51
+ private
52
+
53
+ # @!method block_handler?(node)
54
+ def_node_matcher :block_handler?, <<~PATTERN
55
+ (def :on_block (args (arg :node)) ...)
56
+ PATTERN
57
+
58
+ # @!method itblock_handler?(node)
59
+ def_node_matcher :itblock_handler?, <<~PATTERN
60
+ {
61
+ `(def :on_itblock (args (arg :node)) ...)
62
+ `(alias (sym :on_itblock) (sym :on_block))
63
+ `(send nil? :alias_method (sym :on_itblock) (sym :on_block))
64
+ }
65
+ PATTERN
66
+ end
67
+ end
68
+ end
69
+ end
@@ -25,6 +25,7 @@ module RuboCop
25
25
  def_node_matcher :line_send, <<~PATTERN
26
26
  {
27
27
  (send (send _ {:loc :source_range}) {:line :first_line})
28
+ (send (send (send _ :loc) {:begin :end}) :line)
28
29
  (send _ :first_line)
29
30
  }
30
31
  PATTERN
@@ -46,8 +46,7 @@ module RuboCop
46
46
 
47
47
  def on_block(node)
48
48
  return unless let_rubocop_config_new?(node)
49
-
50
- describe = find_describe_method_node(node)
49
+ return unless (describe = find_describe_method_node(node))
51
50
 
52
51
  unless (exist_config = describe.last_argument.source == ':config')
53
52
  additional_message = ' and specify `:config` in `describe`'
@@ -65,7 +64,10 @@ module RuboCop
65
64
  private
66
65
 
67
66
  def find_describe_method_node(block_node)
68
- block_node.ancestors.find { |node| node.block_type? && node.method?(:describe) }.send_node
67
+ describe = block_node.ancestors.find do |ancestor|
68
+ ancestor.block_type? && ancestor.method?(:describe)
69
+ end
70
+ describe&.send_node
69
71
  end
70
72
  end
71
73
  end
@@ -7,6 +7,7 @@ require_relative 'internal_affairs/empty_line_between_expect_offense_and_correct
7
7
  require_relative 'internal_affairs/example_description'
8
8
  require_relative 'internal_affairs/example_heredoc_delimiter'
9
9
  require_relative 'internal_affairs/inherit_deprecated_cop_class'
10
+ require_relative 'internal_affairs/itblock_handler'
10
11
  require_relative 'internal_affairs/lambda_or_proc'
11
12
  require_relative 'internal_affairs/location_exists'
12
13
  require_relative 'internal_affairs/location_expression'
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # Check that the arguments on a multi-line method call are aligned.
6
+ # Checks that the arguments on a multi-line method call are aligned.
7
7
  #
8
8
  # @example EnforcedStyle: with_first_argument (default)
9
9
  # # good
@@ -52,7 +52,7 @@ module RuboCop
52
52
  'following the first line of a multi-line method call.'
53
53
 
54
54
  def on_send(node)
55
- return if !multiple_arguments?(node) || (node.send_type? && node.method?(:[]=)) ||
55
+ return if !multiple_arguments?(node) || (node.call_type? && node.method?(:[]=)) ||
56
56
  autocorrect_incompatible_with_other_cops?
57
57
 
58
58
  items = flattened_arguments(node)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # Check that the elements of a multi-line array literal are
6
+ # Checks that the elements of a multi-line array literal are
7
7
  # aligned.
8
8
  #
9
9
  # @example EnforcedStyle: with_first_element (default)
@@ -14,7 +14,7 @@ module RuboCop
14
14
  # `Layout/EndAlignment` cop aligns with keywords (e.g. `if`, `while`, `case`)
15
15
  # by default. On the other hand, `||= begin` that this cop targets tends to
16
16
  # align with the start of the line, it defaults to `EnforcedStyleAlignWith: start_of_line`.
17
- # These style can be configured by each cop.
17
+ # These styles can be configured by each cop.
18
18
  #
19
19
  # @example EnforcedStyleAlignWith: start_of_line (default)
20
20
  # # bad
@@ -18,6 +18,10 @@ module RuboCop
18
18
  # `either` (which is the default) : the `end` is allowed to be in either
19
19
  # location. The autocorrect will default to `start_of_line`.
20
20
  #
21
+ # When the `do` or `{` appears on a continuation line of multiline
22
+ # method arguments, the start of the line where the method is called
23
+ # is used as the alignment target instead of that continuation line.
24
+ #
21
25
  # @example EnforcedStyleAlignWith: either (default)
22
26
  # # bad
23
27
  #
@@ -116,6 +120,7 @@ module RuboCop
116
120
  end_loc = block_node.loc.end
117
121
  return unless begins_its_line?(end_loc)
118
122
 
123
+ start_node = start_for_line_node(block_node) if style == :start_of_line
119
124
  start_loc = start_node.source_range
120
125
  return unless start_loc.column != end_loc.column || style == :start_of_block
121
126
 
@@ -196,23 +201,34 @@ module RuboCop
196
201
 
197
202
  def compute_do_source_line_column(node, end_loc)
198
203
  do_loc = node.loc.begin # Actually it's either do or {.
204
+ anchor_loc = do_line_anchor_loc(node, do_loc)
199
205
 
200
206
  # We've found that "end" is not aligned with the start node (which
201
207
  # can be a block, a variable assignment, etc). But we also allow
202
208
  # the "end" to be aligned with the start of the line where the "do"
203
209
  # is, which is a style some people use in multi-line chains of
204
210
  # blocks.
205
- match = /\S.*/.match(do_loc.source_line)
211
+ match = /\S.*/.match(anchor_loc.source_line)
206
212
  indentation_of_do_line = match.begin(0)
207
- return unless end_loc.column != indentation_of_do_line || style == :start_of_line
213
+ permitted_columns = permitted_do_line_columns(do_loc, indentation_of_do_line)
214
+ return if permitted_columns.include?(end_loc.column) && style != :start_of_line
208
215
 
209
216
  {
210
217
  source: match[0],
211
- line: do_loc.line,
218
+ line: anchor_loc.line,
212
219
  column: indentation_of_do_line
213
220
  }
214
221
  end
215
222
 
223
+ # `end` aligned with an argument continuation line that holds the `do`
224
+ # was accepted before the anchor moved to the method dispatch line;
225
+ # keep accepting it so that such code does not become an offense.
226
+ def permitted_do_line_columns(do_loc, indentation_of_do_line)
227
+ columns = [indentation_of_do_line]
228
+ columns << (do_loc.source_line =~ /\S/) if style == :either
229
+ columns
230
+ end
231
+
216
232
  def loc_to_source_line_column(loc)
217
233
  {
218
234
  source: loc.source.lines.to_a.first.chomp,
@@ -239,7 +255,7 @@ module RuboCop
239
255
  def compute_start_col(ancestor_node, node)
240
256
  if style == :start_of_block
241
257
  do_loc = node.loc.begin
242
- return do_loc.source_line =~ /\S/
258
+ return do_line_anchor_loc(node, do_loc).source_line =~ /\S/
243
259
  end
244
260
  (ancestor_node || node).source_range.column
245
261
  end
@@ -253,6 +269,27 @@ module RuboCop
253
269
 
254
270
  corrector.remove(range)
255
271
  end
272
+
273
+ # When the `do` or `{` is on a continuation line of multiline method
274
+ # arguments, the indentation of that line is not a meaningful
275
+ # alignment target; anchor on the method dispatch position instead.
276
+ def do_line_anchor_loc(node, do_loc)
277
+ if do_line_begins_inside_argument?(node, do_loc)
278
+ node.send_node.selector || node.send_node.source_range
279
+ else
280
+ do_loc
281
+ end
282
+ end
283
+
284
+ def do_line_begins_inside_argument?(node, do_loc)
285
+ line_begin_pos = do_loc.begin_pos - do_loc.column
286
+ first_char_pos = line_begin_pos + (do_loc.source_line =~ /\S/)
287
+
288
+ (node.send_node.arguments + node.arguments).any? do |argument|
289
+ argument.source_range.begin_pos <= first_char_pos &&
290
+ first_char_pos < argument.source_range.end_pos
291
+ end
292
+ end
256
293
  end
257
294
  end
258
295
  end
@@ -49,7 +49,7 @@ module RuboCop
49
49
  # - private_methods
50
50
  # ----
51
51
  #
52
- # Instead of putting all literals in the expected order, is also
52
+ # Instead of putting all literals in the expected order, it is also
53
53
  # possible to group categories of macros. Visibility levels are handled
54
54
  # automatically.
55
55
  #
@@ -112,7 +112,7 @@ module RuboCop
112
112
  end
113
113
 
114
114
  def last_heredoc_line(node)
115
- if node.send_type?
115
+ if node.call_type?
116
116
  node.arguments.select { |arg| heredoc?(arg) }.map { |arg| arg.loc.heredoc_end.line }.max
117
117
  elsif heredoc?(node)
118
118
  node.loc.heredoc_end.line
@@ -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)
@@ -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