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

Commit

Permalink
Treat ValueTask<TResult> as an asynchronous return type
Browse files Browse the repository at this point in the history
Fixes #68
  • Loading branch information
sharwell committed Aug 6, 2018
1 parent 68e64c0 commit 86945af
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.0" />
<PackageReference Include="Microsoft.CodeAnalysis" Version="1.2.1" />
<PackageReference Include="xunit" Version="2.3.0-beta3-build3705" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta3-build3705" PrivateAssets="all" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,16 @@ protected virtual Solution CreateSolution(ProjectId projectId, string language)
.AddMetadataReference(projectId, MetadataReferences.CSharpSymbolsReference)
.AddMetadataReference(projectId, MetadataReferences.CodeAnalysisReference);

if (MetadataReferences.SystemThreadingTasksReference != null)
{
solution = solution.AddMetadataReference(projectId, MetadataReferences.SystemThreadingTasksReference);
}

if (MetadataReferences.SystemThreadingTasksExtensionsReference != null)
{
solution = solution.AddMetadataReference(projectId, MetadataReferences.SystemThreadingTasksExtensionsReference);
}

var settings = this.GetSettings();
if (!string.IsNullOrEmpty(settings))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@

namespace AsyncUsageAnalyzers.Test.Helpers
{
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

Expand All @@ -18,5 +21,32 @@ internal static class MetadataReferences
internal static readonly MetadataReference SystemCoreReference = MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location);
internal static readonly MetadataReference CSharpSymbolsReference = MetadataReference.CreateFromFile(typeof(CSharpCompilation).Assembly.Location);
internal static readonly MetadataReference CodeAnalysisReference = MetadataReference.CreateFromFile(typeof(Compilation).Assembly.Location);

internal static readonly MetadataReference SystemThreadingTasksReference;
internal static readonly MetadataReference SystemThreadingTasksExtensionsReference;

static MetadataReferences()
{
if (typeof(ValueTask<>).Assembly == typeof(string).Assembly)
{
// mscorlib contains ValueTask<TResult>, so no need to add a separate reference
SystemThreadingTasksReference = null;
SystemThreadingTasksExtensionsReference = null;
}
else
{
Assembly systemThreadingTasks = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(x => x.GetName().Name == "System.Threading.Tasks");
if (systemThreadingTasks != null)
{
SystemThreadingTasksReference = MetadataReference.CreateFromFile(systemThreadingTasks.Location);
}

Assembly systemThreadingTasksExtensions = typeof(ValueTask<>).Assembly;
if (systemThreadingTasksExtensions != null)
{
SystemThreadingTasksExtensionsReference = MetadataReference.CreateFromFile(systemThreadingTasksExtensions.Location);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,21 @@ class ClassName
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task TestReturnValueTaskAsync()
{
string testCode = @"
using System.Threading.Tasks;
class ClassName
{
ValueTask<int> FirstMethod() { return new ValueTask<int>(3); }
ValueTask<int> SecondMethodAsync() { return new ValueTask<int>(3); }
}
";

await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
{
yield return new AvoidAsyncSuffixAnalyzer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,32 @@ class ClassName
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task TestReturnGenericValueTaskAsync()
{
string testCode = @"
using System.Threading.Tasks;
class ClassName
{
ValueTask<int> FirstMethod() { return new ValueTask<int>(3); }
ValueTask<int> SecondMethodAsync() { return new ValueTask<int>(3); }
}
";
string fixedCode = @"
using System.Threading.Tasks;
class ClassName
{
ValueTask<int> FirstMethodAsync() { return new ValueTask<int>(3); }
ValueTask<int> SecondMethodAsync() { return new ValueTask<int>(3); }
}
";

DiagnosticResult expected = this.CSharpDiagnostic().WithArguments("FirstMethod").WithLocation(5, 20);
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task TestPropertyGetterAndSetterTaskAsync()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public static bool HasAsyncSignature(this IMethodSymbol symbol, bool treatAsyncV
if (!symbol.IsAsync)
{
// This check conveniently covers Task and Task<T> by ignoring the `1 in Task<T>.
if (!string.Equals(nameof(Task), symbol.ReturnType?.Name, StringComparison.Ordinal))
if (!string.Equals(nameof(Task), symbol.ReturnType?.Name, StringComparison.Ordinal)
&& !string.Equals("ValueTask", symbol.ReturnType?.Name, StringComparison.Ordinal))
{
return false;
}
Expand Down

0 comments on commit 86945af

Please sign in to comment.