From cc8842ae4a4c2109051c8ebece30748a5718b8e6 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 28 Dec 2022 14:17:25 +0900 Subject: [PATCH] Fix an error for `Style/GuardClause` 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' ``` --- changelog/fix_error_for_style_guard_clause.md | 1 + lib/rubocop/cop/style/guard_clause.rb | 18 +++++++------ spec/rubocop/cop/style/guard_clause_spec.rb | 25 +++++++++++++++++++ 3 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 changelog/fix_error_for_style_guard_clause.md diff --git a/changelog/fix_error_for_style_guard_clause.md b/changelog/fix_error_for_style_guard_clause.md new file mode 100644 index 00000000000..1e719c1100d --- /dev/null +++ b/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][]) diff --git a/lib/rubocop/cop/style/guard_clause.rb b/lib/rubocop/cop/style/guard_clause.rb index c2a6e99789a..3f5e01b486c 100644 --- a/lib/rubocop/cop/style/guard_clause.rb +++ b/lib/rubocop/cop/style/guard_clause.rb @@ -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 @@ -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) diff --git a/spec/rubocop/cop/style/guard_clause_spec.rb b/spec/rubocop/cop/style/guard_clause_spec.rb index dc459cc8f68..01b1078d5b1 100644 --- a/spec/rubocop/cop/style/guard_clause_spec.rb +++ b/spec/rubocop/cop/style/guard_clause_spec.rb @@ -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