Skip to content

Commit

Permalink
Merge pull request #1245 from AArnott/fix1168
Browse files Browse the repository at this point in the history
Fix VSTHRD110 to not misfire due to parentheses in invocation expressions
  • Loading branch information
AArnott authored Oct 24, 2023
2 parents a74e8e8 + dc30848 commit 8a79cb7
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,33 @@ private void AnalyzeInvocation(OperationAnalysisContext context, CommonInterest.
return;
}

// Only consider invocations that are direct statements. Otherwise, we assume their
// result is awaited, assigned, or otherwise consumed.
if (operation.Parent is IExpressionStatementOperation || operation.Parent is IConditionalAccessOperation)
// Only consider invocations that are direct statements (or are statements through limited steps).
// Otherwise, we assume their result is awaited, assigned, or otherwise consumed.
IOperation? parentOperation = operation.Parent;
while (parentOperation is not null)
{
if (awaitableTypes.IsAwaitableType(operation.Type))
if (parentOperation is IExpressionStatementOperation)
{
context.ReportDiagnostic(Diagnostic.Create(Descriptor, operation.Syntax.GetLocation()));
// This expression is directly used in a statement.
break;
}

// This check is where we allow for specific operation types that may appear between the invocation
// and the statement that don't disqualify the invocation search for an invalid pattern.
if (parentOperation is IConditionalAccessOperation)
{
parentOperation = parentOperation.Parent;
}
else
{
// This expression is not directly used in a statement.
return;
}
}

if (awaitableTypes.IsAwaitableType(operation.Type))
{
context.ReportDiagnostic(Diagnostic.Create(Descriptor, operation.Syntax.GetLocation()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,24 @@ public async ValueTask DisposeAsync()
await CSVerify.VerifyAnalyzerAsync(test);
}

[Fact]
public async Task ParentheticalUseOfTaskResult_ProducesNoDiagnostic()
{
string test = """
using System;
using System.Threading.Tasks;

class Class1
{
public Func<Task<int>>? VCLoadMethod;

public int? VirtualCurrencyBalances => (VCLoadMethod?.Invoke()).GetAwaiter().GetResult();
}
""";

await CSVerify.VerifyAnalyzerAsync(test);
}

private DiagnosticResult CreateDiagnostic(int line, int column, int length)
=> CSVerify.Diagnostic().WithSpan(line, column, line, column + length);
}

0 comments on commit 8a79cb7

Please sign in to comment.