Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The last line of initialize methods do not implicitly return #584

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions spec/ameba/rule/lint/unused_literal_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,32 @@ module Ameba::Rule::Lint
CRYSTAL
end

it "passes if an unused method call is the last line of a method with a Nil return type restriction" do
expect_no_issues subject, <<-CRYSTAL
def foo : Nil
bar("baz")
end
CRYSTAL
end

it "fails if an unused literal is the last line of a method with a Nil return type restriction" do
expect_issue subject, <<-CRYSTAL
def foo : Nil
1234
# ^^^^ error: Literal value is not used
end
CRYSTAL
end

it "fails if an unused literal is the last line of an initialize method" do
expect_issue subject, <<-CRYSTAL
def initialize
1234
# ^^^^ error: Literal value is not used
end
CRYSTAL
end

it "passes if a literal is used in outputting macro expression" do
expect_no_issues subject, <<-CRYSTAL
{{ "foo" }}
Expand Down
11 changes: 5 additions & 6 deletions src/ameba/ast/visitors/implicit_return_visitor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,13 @@ module Ameba::AST
node.block_arg.try &.accept(self)
end

if (return_type = node.return_type).is_a?(Crystal::Path)
case
when node.name == "initialize",
node.return_type.as?(Crystal::Path).try(&.names.join("::").in?("::Nil", "Nil"))
# Special case of the return type being nil, meaning the last
# line of the method body is ignored
if return_type.names.join("::").in?("::Nil", "Nil")
node.body.accept(self)
else
incr_stack { node.body.accept(self) }
end
# Last line of initialize methods are also ignored
swap_stack { node.body.accept(self) }
else
incr_stack { node.body.accept(self) }
end
Expand Down