Skip to content

Commit

Permalink
Fix return statement in child blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
GerardSmit committed Jan 26, 2024
1 parent 57c2746 commit 6e2ab0d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
22 changes: 18 additions & 4 deletions src/Zomp.SyncMethodGenerator/AsyncToSyncRewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -520,9 +520,11 @@ bool IsValidParameter(ParameterSyntax ps)
semanticModel.GetTypeInfo(returnExpression).Type is INamedTypeSymbol { Name: "Task" or "ValueTask", IsGenericType: false } returnType &&
returnType.ToString() is TaskType or ValueTaskType)
{
var result = (ExpressionSyntax)Visit(returnExpression);
var result = !ShouldRemoveArgument(returnExpression)
? (ExpressionSyntax)Visit(returnExpression)
: null;

if (node.Parent is not BlockSyntax)
if (result is not null && node.Parent is not BlockSyntax)
{
// The parent is not a block, for example: if (true) return ReturnAsync();
// We need to create a block with the expression and the return statement.
Expand All @@ -536,14 +538,26 @@ bool IsValidParameter(ParameterSyntax ps)
}

// Don't return if the return statement is the last statement in the method.
if (node.Parent.Parent is MethodDeclarationSyntax { Body.Statements: [.., var lastStatement] } &&
if (node.Parent?.Parent is MethodDeclarationSyntax { Body.Statements: [.., var lastStatement] } &&
lastStatement == node)
{
if (result is null)
{
return null;
}

return ExpressionStatement(result)
.WithLeadingTrivia(node.GetLeadingTrivia())
.WithTrailingTrivia(node.GetTrailingTrivia());
}

if (result is null)
{
return ReturnStatement()
.WithTrailingTrivia(node.GetTrailingTrivia())
.WithLeadingTrivia(node.GetLeadingTrivia());
}

// Create a block without the braces (eg. Return(); return;)
return Block(List(new StatementSyntax[]
{
Expand Down Expand Up @@ -1550,7 +1564,7 @@ private TypeSyntax ProcessSyntaxUsingSymbol(TypeSyntax typeSyntax)
IfStatementSyntax @if => ShouldRemoveArgument(@if.Condition),
ExpressionStatementSyntax e => ShouldRemoveArgument(e.Expression),
LocalDeclarationStatementSyntax l => CanDropDeclaration(l),
ReturnStatementSyntax { Expression: { } re } => ShouldRemoveArgument(re),
ReturnStatementSyntax { Parent.Parent: MethodDeclarationSyntax, Expression: { } re } => ShouldRemoveArgument(re),
_ => false,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//HintName: Test.Class.ReturnAsync.g.cs
private void Return(bool input)
{
if (input)
{
return;
}
global::System.Console.WriteLine("123");
}
14 changes: 14 additions & 0 deletions tests/Generator.Tests/UnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,20 @@ private Task ReturnAsync(bool input)

private Task ReturnAsync() => Task.CompletedTask;
private void Return() { }
""".Verify();

[Fact]
public Task ReturnDefaultValueTask() => """
[CreateSyncVersion]
private ValueTask ReturnAsync(bool input)
{
if (input)
{
return default;
}
Console.WriteLine("123");
return default;
}
""".Verify();

[Fact]
Expand Down

0 comments on commit 6e2ab0d

Please sign in to comment.