From 08712062d3ae2c88cb0375f07f400da13153292d Mon Sep 17 00:00:00 2001 From: Margret Riegert Date: Sat, 25 Jan 2025 05:42:22 -0500 Subject: [PATCH] ExceptionHandler implicit return fixes Last line of `ensure` isn't returned, and last line of body isn't returned if there's an `else` --- spec/ameba/rule/lint/unused_literal_spec.cr | 69 ++++++++++++------- .../ast/visitors/implicit_return_visitor.cr | 12 +++- 2 files changed, 53 insertions(+), 28 deletions(-) diff --git a/spec/ameba/rule/lint/unused_literal_spec.cr b/spec/ameba/rule/lint/unused_literal_spec.cr index 5bf63f56f..8907f6537 100644 --- a/spec/ameba/rule/lint/unused_literal_spec.cr +++ b/spec/ameba/rule/lint/unused_literal_spec.cr @@ -245,32 +245,49 @@ module Ameba::Rule::Lint it "fails if unused literals in rescue/ensure/else block" do expect_issue subject, <<-CRYSTAL - a = begin - 1234 - # ^^^^ error: Literal value is not used - 1234_f32 - rescue ASDF - "hello world" - # ^^^^^^^^^^^^^ error: Literal value is not used - "interp \#{string}" - rescue QWERTY - [1, 2, 3, 4, 5] - # ^^^^^^^^^^^^^^^ error: Literal value is not used - {"hello" => "world"} - else - '\t' - # ^^^ error: Literal value is not used - <<-HEREDOC - # ^^^^^^^^^^ error: Literal value is not used - this is a heredoc - HEREDOC - 1..2 - ensure - {goodnight: moon} - # ^^^^^^^^^^^^^^^^^ error: Literal value is not used - {1, 2, 3} - end - CRYSTAL + a = begin + 1234 + # ^^^^ error: Literal value is not used + 1234_f32 + # ^^^^^^^^ error: Literal value is not used + rescue ASDF + "hello world" + # ^^^^^^^^^^^^^ error: Literal value is not used + "interp \#{string}" + rescue QWERTY + [1, 2, 3, 4, 5] + # ^^^^^^^^^^^^^^^ error: Literal value is not used + {"hello" => "world"} + else + '\t' + # ^^^ error: Literal value is not used + <<-HEREDOC + # ^^^^^^^^^^ error: Literal value is not used + this is a heredoc + HEREDOC + 1..2 + ensure + {goodnight: moon} + # ^^^^^^^^^^^^^^^^^ error: Literal value is not used + {1, 2, 3} + # ^^^^^^^^^ error: Literal value is not used + end + + b = begin + 1234 + # ^^^^ error: Literal value is not used + 1234_f32 + rescue ASDF + "hello world" + # ^^^^^^^^^^^^^ error: Literal value is not used + "interp \#{string}" + ensure + {goodnight: moon} + # ^^^^^^^^^^^^^^^^^ error: Literal value is not used + {1, 2, 3} + # ^^^^^^^^^ error: Literal value is not used + end + CRYSTAL end # Locations for Regex literals were added in Crystal v1.15.0 diff --git a/src/ameba/ast/visitors/implicit_return_visitor.cr b/src/ameba/ast/visitors/implicit_return_visitor.cr index 27828aa12..f7048d448 100644 --- a/src/ameba/ast/visitors/implicit_return_visitor.cr +++ b/src/ameba/ast/visitors/implicit_return_visitor.cr @@ -225,10 +225,18 @@ module Ameba::AST def visit(node : Crystal::ExceptionHandler) : Bool @rule.test(@source, node, @stack > 0) - node.body.accept(self) + if node.else + # Last line of body isn't implicitly returned if there's an else + swap_stack { node.body.try &.accept(self) } + else + node.body.accept(self) + end + node.rescues.try &.each &.accept(self) node.else.try &.accept(self) - node.ensure.try &.accept(self) + + # Last line of ensure isn't implicitly returned + swap_stack { node.ensure.try &.accept(self) } false end