Skip to content

Commit

Permalink
Fix an error for Style/GuardClause
Browse files Browse the repository at this point in the history
This PR fixes the following error for `Style/GuardClause`
when using heredoc as an argument of raise in `then` branch
and it does not have `else` branch:

```ruby
def func
  if condition
    raise <<~MESSAGE
      oops
    MESSAGE
  end
end
```

```console
% bundle exec rubocop --only Style/GuardClause -d
(snip)

An error occurred while Style/GuardClause cop was inspecting /Users/koic/src/github.com/koic/rubocop-issues/guard_clause/example.rb:1:0.
undefined method `source_range' for nil:NilClass
/Users/koic/src/github.com/rubocop/rubocop/lib/rubocop/cop/style/guard_clause.rb:209:in `autocorrect_heredoc_argument'
/Users/koic/src/github.com/rubocop/rubocop/lib/rubocop/cop/style/guard_clause.rb:191:in `autocorrect'
/Users/koic/src/github.com/rubocop/rubocop/lib/rubocop/cop/style/guard_clause.rb:179:in `block in register_offense'
```
  • Loading branch information
koic authored and bbatsov committed Dec 28, 2022
1 parent 75c1963 commit cc8842a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
1 change: 1 addition & 0 deletions changelog/fix_error_for_style_guard_clause.md
@@ -0,0 +1 @@
* [#11344](https://github.com/rubocop/rubocop/pull/11344): Fix an error for `Style/GuardClause` when using heredoc as an argument of raise in `then` branch and it does not have `else` branch. ([@koic][])
18 changes: 11 additions & 7 deletions lib/rubocop/cop/style/guard_clause.rb
Expand Up @@ -196,7 +196,7 @@ def autocorrect(corrector, node, condition, replacement, guard)
return unless node.else?

corrector.remove(node.loc.else)
corrector.remove(branch_to_remove(node, guard))
corrector.remove(range_of_branch_to_remove(node, guard))
end
end
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
Expand All @@ -206,20 +206,24 @@ def heredoc?(argument)
end

def autocorrect_heredoc_argument(corrector, node, heredoc_branch, leave_branch, guard)
return unless node.else?

remove_whole_lines(corrector, leave_branch.source_range)
remove_whole_lines(corrector, node.loc.else)
remove_whole_lines(corrector, node.loc.end)
remove_whole_lines(corrector, branch_to_remove(node, guard).source_range)
remove_whole_lines(corrector, range_of_branch_to_remove(node, guard))
corrector.insert_after(
heredoc_branch.last_argument.loc.heredoc_end, "\n#{leave_branch.source}"
)
end

def branch_to_remove(node, guard)
case guard
when :if then node.if_branch
when :else then node.else_branch
end
def range_of_branch_to_remove(node, guard)
branch = case guard
when :if then node.if_branch
when :else then node.else_branch
end

branch.source_range
end

def guard_clause_source(guard_clause)
Expand Down
25 changes: 25 additions & 0 deletions spec/rubocop/cop/style/guard_clause_spec.rb
Expand Up @@ -297,6 +297,31 @@ def func
RUBY
end

it 'registers an offense when using heredoc as an argument of raise in `then` branch and it does not have `else` branch' do
expect_offense(<<~'RUBY')
def func
if condition
^^ Use a guard clause (`return unless condition`) instead of wrapping the code inside a conditional expression.
raise <<~MESSAGE
oops
MESSAGE
end
end
RUBY

# NOTE: Let `Layout/HeredocIndentation`, `Layout/ClosingHeredocIndentation`, and
# `Layout/IndentationConsistency` cops autocorrect inconsistent indentations.
expect_correction(<<~RUBY)
def func
return unless condition
raise <<~MESSAGE
oops
MESSAGE
end
end
RUBY
end

it 'registers an offense when using xstr heredoc as an argument of raise in `else` branch' do
expect_offense(<<~RUBY)
def func
Expand Down

0 comments on commit cc8842a

Please sign in to comment.