Skip to content

Commit

Permalink
GH-153 - null checks for SyncOverAsyncThrowsCodeFixProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
tpodolak committed Oct 2, 2022
1 parent 154a51a commit f94b82c
Showing 1 changed file with 17 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,29 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)

var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

if (root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true) is not { } invocation)
if (root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true) is not { } invocationExpression)
{
return;
}

var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken);
var methodSymbol = (IMethodSymbol)semanticModel.GetSymbolInfo(invocation).Symbol;
if (semanticModel.GetOperation(invocationExpression) is not IInvocationOperation invocationOperation)
{
return;
}

var supportsThrowsAsync = SupportsThrowsAsync(semanticModel.Compilation);

if (!supportsThrowsAsync && methodSymbol.Parameters.Any(param => param.Type.IsCallInfoDelegate(semanticModel.Compilation)))
if (!supportsThrowsAsync && invocationOperation.TargetMethod.Parameters.Any(param => param.Type.IsCallInfoDelegate(semanticModel.Compilation)))
{
return;
}

var replacementMethod = GetReplacementMethodName(methodSymbol, useModernSyntax: supportsThrowsAsync);
var replacementMethod = GetReplacementMethodName(invocationOperation, useModernSyntax: supportsThrowsAsync);

var codeAction = CodeAction.Create(
$"Replace with {replacementMethod}",
ct => CreateChangedDocument(context, semanticModel, invocation, methodSymbol, supportsThrowsAsync, ct),
ct => CreateChangedDocument(context, semanticModel, invocationOperation, supportsThrowsAsync, ct),
nameof(AbstractSyncOverAsyncThrowsCodeFixProvider));

context.RegisterCodeFix(codeAction, diagnostic);
Expand All @@ -67,13 +71,12 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
private async Task<Document> CreateChangedDocument(
CodeFixContext context,
SemanticModel semanticModel,
SyntaxNode currentInvocationExpression,
IMethodSymbol invocationSymbol,
IInvocationOperation invocationOperation,
bool useModernSyntax,
CancellationToken cancellationToken)
{
var documentEditor = await DocumentEditor.CreateAsync(context.Document, cancellationToken);
var invocationOperation = (IInvocationOperation)semanticModel.GetOperation(currentInvocationExpression);
var invocationSymbol = (IMethodSymbol)semanticModel.GetSymbolInfo(invocationOperation.Syntax).Symbol;

var updatedInvocationExpression = useModernSyntax
? await CreateThrowsAsyncInvocationExpression(
Expand All @@ -85,7 +88,7 @@ private async Task<Document> CreateChangedDocument(
invocationSymbol,
context);

documentEditor.ReplaceNode(currentInvocationExpression, updatedInvocationExpression);
documentEditor.ReplaceNode(invocationOperation.Syntax, updatedInvocationExpression);

return documentEditor.GetChangedDocument();
}
Expand Down Expand Up @@ -209,16 +212,18 @@ private static bool SupportsThrowsAsync(Compilation compilation)
exceptionExtensionsTypeSymbol.GetMembers(MetadataNames.NSubstituteThrowsAsyncMethod).IsEmpty == false;
}

private static string GetReplacementMethodName(IMethodSymbol methodSymbol, bool useModernSyntax)
private static string GetReplacementMethodName(IInvocationOperation invocationOperation, bool useModernSyntax)
{
var isThrowsSyncMethod = invocationOperation.TargetMethod.IsThrowsSyncMethod();

if (useModernSyntax)
{
return methodSymbol.IsThrowsSyncMethod()
return isThrowsSyncMethod
? MetadataNames.NSubstituteThrowsAsyncMethod
: MetadataNames.NSubstituteThrowsAsyncForAnyArgsMethod;
}

return methodSymbol.IsThrowsSyncMethod()
return isThrowsSyncMethod
? MetadataNames.NSubstituteReturnsMethod
: MetadataNames.NSubstituteReturnsForAnyArgsMethod;
}
Expand Down

0 comments on commit f94b82c

Please sign in to comment.