Skip to content

Commit

Permalink
Merge pull request #1251 from AArnott/analyzerFixes
Browse files Browse the repository at this point in the history
Analyzer fixes
  • Loading branch information
AArnott authored Oct 25, 2023
2 parents c1368fb + 73ee84e commit 4b595ea
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -171,22 +171,30 @@ private static bool IsInTaskReturningMethodOrDelegate(SyntaxNodeAnalysisContext
// We want to scan invocations that occur inside Task and Task<T>-returning delegates or methods.
// That is: methods that either are or could be made async.
IMethodSymbol? methodSymbol = null;
AnonymousFunctionExpressionSyntax? anonymousFunc = context.Node.FirstAncestorOrSelf<AnonymousFunctionExpressionSyntax>();
if (anonymousFunc is object)
for (SyntaxNode? focusedNode = context.Node; focusedNode is not null; focusedNode = focusedNode.Parent)
{
SymbolInfo symbolInfo = context.SemanticModel.GetSymbolInfo(anonymousFunc, context.CancellationToken);
methodSymbol = symbolInfo.Symbol as IMethodSymbol;
}
else
{
MethodDeclarationSyntax? methodDecl = context.Node.FirstAncestorOrSelf<MethodDeclarationSyntax>();
if (methodDecl is object)
switch (focusedNode)
{
methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodDecl, context.CancellationToken);
case AnonymousFunctionExpressionSyntax anonFunc:
SymbolInfo symbolInfo = context.SemanticModel.GetSymbolInfo(anonFunc, context.CancellationToken);
methodSymbol = symbolInfo.Symbol as IMethodSymbol;
break;
case LocalFunctionStatementSyntax localFunc:
methodSymbol = context.SemanticModel.GetDeclaredSymbol(localFunc, context.CancellationToken) as IMethodSymbol;
break;
case MethodDeclarationSyntax methodDecl:
methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodDecl, context.CancellationToken);
break;
default:
// We want to continue iteration of the for loop.
continue;
}

// We encountered one of our case statements, so whether or not we have a methodSymbol, we shouldn't look further.
break;
}

return methodSymbol.HasAsyncCompatibleReturnType();
return methodSymbol?.HasAsyncCompatibleReturnType() is true;
}

private static bool InspectMemberAccess(SyntaxNodeAnalysisContext context, ExpressionSyntax memberName, IEnumerable<CommonInterest.SyncBlockingMethod> problematicMethods)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1314,6 +1314,31 @@ Task MethodAsync()
await CSVerify.VerifyAnalyzerAsync(test);
}

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

class SomeClass {
Task Foo()
{
return Task.CompletedTask;

void CompletionHandler()
{
this.Bar();
}
}

void Bar() {}
Task BarAsync() => Task.CompletedTask;
}
""";

await CSVerify.VerifyAnalyzerAsync(test);
}

private DiagnosticResult CreateDiagnostic(int line, int column, int length, string methodName)
=> CSVerify.Diagnostic(DescriptorNoAlternativeMethod).WithSpan(line, column, line, column + length).WithArguments(methodName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,21 @@ async Task Foo(Test? tester)
await CSVerify.VerifyAnalyzerAsync(test);
}

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

class Tree {
static Task ShakeTreeAsync(Tree? tree) => tree?.ShakeAsync() ?? Task.CompletedTask;
Task ShakeAsync() => Task.CompletedTask;
}
""";

await CSVerify.VerifyAnalyzerAsync(test);
}

[Fact]
public async Task TaskInFinalizer()
{
Expand Down Expand Up @@ -470,7 +485,4 @@ class Class1

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 4b595ea

Please sign in to comment.