Skip to content
This repository was archived by the owner on Nov 8, 2018. It is now read-only.

Commit 5cbfd10

Browse files
committed
Simplify AvoidAsyncVoidAnalyzer and add tests to improve coverage
1 parent a6642bd commit 5cbfd10

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

AsyncUsageAnalyzers/AsyncUsageAnalyzers.Test/Reliability/AvoidAsyncVoidUnitTests.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@ namespace AsyncUsageAnalyzers.Test.Reliability
77
using System.Threading;
88
using System.Threading.Tasks;
99
using AsyncUsageAnalyzers.Reliability;
10+
using Microsoft.CodeAnalysis;
1011
using Microsoft.CodeAnalysis.Diagnostics;
1112
using TestHelper;
1213
using Xunit;
1314

1415
public class AvoidAsyncVoidUnitTests : DiagnosticVerifier
1516
{
17+
private static readonly DiagnosticDescriptor CS1660 =
18+
new DiagnosticDescriptor("CS1660", "Error", "Cannot convert lambda expression to type '{0}' because it is not a delegate type", "Compiler", DiagnosticSeverity.Error, true);
19+
20+
private static readonly DiagnosticDescriptor CS1989 =
21+
new DiagnosticDescriptor("CS1989", "Error", "Async lambda expressions cannot be converted to expression trees", "Compiler", DiagnosticSeverity.Error, true);
22+
1623
[Fact]
1724
public async Task TestAsyncReturnVoidAsync()
1825
{
@@ -100,6 +107,82 @@ class ClassName
100107
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
101108
}
102109

110+
[Fact]
111+
public async Task TestNonAsyncLambdaReturnTaskAsync()
112+
{
113+
string testCode = @"
114+
using System;
115+
using System.Threading.Tasks;
116+
class ClassName
117+
{
118+
static Func<Task> ZeroArgumentFunction;
119+
static Func<object, Task> SingleArgumentFunction;
120+
121+
ClassName()
122+
{
123+
ZeroArgumentFunction = () => Task.Delay(42);
124+
SingleArgumentFunction = arg => Task.Delay(42);
125+
SingleArgumentFunction = (object arg) => Task.Delay(42);
126+
SingleArgumentFunction = delegate (object arg) { return Task.Delay(42); };
127+
}
128+
}
129+
";
130+
131+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
132+
}
133+
134+
[Fact]
135+
public async Task TestAsyncExpressionLambdaReturnTaskAsync()
136+
{
137+
string testCode = @"
138+
using System;
139+
using System.Linq.Expressions;
140+
using System.Threading.Tasks;
141+
class ClassName
142+
{
143+
static Expression<Func<Task>> ZeroArgumentFunction;
144+
static Expression<Func<object, Task>> SingleArgumentFunction;
145+
146+
ClassName()
147+
{
148+
ZeroArgumentFunction = async () => await Task.Delay(42);
149+
SingleArgumentFunction = async arg => await Task.Delay(42);
150+
SingleArgumentFunction = async (object arg) => await Task.Delay(42);
151+
}
152+
}
153+
";
154+
155+
DiagnosticResult[] expected =
156+
{
157+
this.CSharpDiagnostic(CS1989).WithLocation(12, 32),
158+
this.CSharpDiagnostic(CS1989).WithLocation(13, 34),
159+
this.CSharpDiagnostic(CS1989).WithLocation(14, 34),
160+
};
161+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
162+
}
163+
164+
[Fact]
165+
public async Task TestAsyncDynamicLambdaReturnTaskAsync()
166+
{
167+
string testCode = @"
168+
using System;
169+
using System.Linq.Expressions;
170+
using System.Threading.Tasks;
171+
class ClassName
172+
{
173+
static dynamic ZeroArgumentFunction;
174+
175+
ClassName()
176+
{
177+
ZeroArgumentFunction = async () => await Task.Delay(42);
178+
}
179+
}
180+
";
181+
182+
DiagnosticResult expected = this.CSharpDiagnostic(CS1660).WithArguments("dynamic").WithLocation(11, 32);
183+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
184+
}
185+
103186
[Fact]
104187
public async Task TestAsyncReturnTaskAsync()
105188
{

AsyncUsageAnalyzers/AsyncUsageAnalyzers/Reliability/AvoidAsyncVoidAnalyzer.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ private static void HandleCompilationStart(CompilationStartAnalysisContext conte
6161
private static void HandleAnonymousFunctionExpression(SyntaxNodeAnalysisContext context)
6262
{
6363
AnonymousFunctionExpressionSyntax node = (AnonymousFunctionExpressionSyntax)context.Node;
64-
if (node.AsyncKeyword.IsKind(SyntaxKind.None) || node.AsyncKeyword.IsMissing)
64+
if (node.AsyncKeyword.IsKind(SyntaxKind.None))
6565
{
6666
return;
6767
}
@@ -73,7 +73,8 @@ private static void HandleAnonymousFunctionExpression(SyntaxNodeAnalysisContext
7373
return;
7474
}
7575

76-
if (convertedType.TypeKind != TypeKind.Delegate || convertedType.DelegateInvokeMethod == null)
76+
// This checks that the type is a delegate and also that it is not ill-formed
77+
if (convertedType.DelegateInvokeMethod == null)
7778
{
7879
return;
7980
}

0 commit comments

Comments
 (0)