diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a203f6d9dd..169bcfd81f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * [#7793](https://github.com/rubocop-hq/rubocop/pull/7793): Prefer `include?` over `member?` in `Style/CollectionMethods`. ([@dmolesUC][]) * [#7654](https://github.com/rubocop-hq/rubocop/issues/7654): Support `with_fixed_indentation` option for `Layout/ArrayAlignment` cop. ([@nikitasakov][]) * [#7783](https://github.com/rubocop-hq/rubocop/pull/7783): Support Ruby 2.7's numbered parameter for `Style/RedundantSort`. ([@koic][]) +* [#7795](https://github.com/rubocop-hq/rubocop/issues/7795): Make `Layout/EmptyLineAfterGuardClause` aware of case where `and` or `or` is used before keyword that break control (e.g. `and return`). ([@koic][]) ### Bug fixes diff --git a/lib/rubocop/ast/node.rb b/lib/rubocop/ast/node.rb index b4b9a5e9d5e..a30d5e04f18 100644 --- a/lib/rubocop/ast/node.rb +++ b/lib/rubocop/ast/node.rb @@ -469,7 +469,13 @@ def range_type? irange_type? || erange_type? end - def_node_matcher :guard_clause?, <<~PATTERN + def guard_clause? + node = and_type? || or_type? ? rhs : self + + node.match_guard_clause? + end + + def_node_matcher :match_guard_clause?, <<~PATTERN [${(send nil? {:raise :fail} ...) return break next} single_line?] PATTERN diff --git a/spec/rubocop/cop/layout/empty_line_after_guard_clause_spec.rb b/spec/rubocop/cop/layout/empty_line_after_guard_clause_spec.rb index ad43986a4b2..0904c4e965b 100644 --- a/spec/rubocop/cop/layout/empty_line_after_guard_clause_spec.rb +++ b/spec/rubocop/cop/layout/empty_line_after_guard_clause_spec.rb @@ -163,6 +163,44 @@ def foo RUBY end + it 'registers an offense and corrects when using `and return` ' \ + 'before guard condition' do + expect_offense(<<~RUBY) + def foo + render :foo and return if condition + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Add empty line after guard clause. + do_something + end + RUBY + + expect_correction(<<~RUBY) + def foo + render :foo and return if condition + + do_something + end + RUBY + end + + it 'registers an offense and corrects when using `or return` ' \ + 'before guard condition' do + expect_offense(<<~RUBY) + def foo + render :foo or return if condition + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Add empty line after guard clause. + do_something + end + RUBY + + expect_correction(<<~RUBY) + def foo + render :foo or return if condition + + do_something + end + RUBY + end + it 'accepts modifier if' do expect_no_offenses(<<~RUBY) def foo