Skip to content

Commit

Permalink
GH-153 - code fix providers clean-up
Browse files Browse the repository at this point in the history
  • Loading branch information
tpodolak committed Oct 2, 2022
1 parent a2fa5cf commit 9529446
Show file tree
Hide file tree
Showing 18 changed files with 121 additions and 112 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
Expand All @@ -12,18 +13,27 @@ internal sealed class InternalSetupSpecificationCodeFixProvider : AbstractIntern
{
protected override string ReplaceModifierCodeFixTitle { get; } = "Replace internal with public modifier";

protected override Task<Document> AddModifierRefactoring(Document document, SyntaxNode node, Accessibility accessibility)
protected override Task<Document> AddModifierRefactoring(
Document document,
SyntaxNode node,
Accessibility accessibility,
CancellationToken cancellationToken)
{
return Refactorings.AddModifierRefactoring.RefactorAsync(document, node, accessibility);
return Refactorings.AddModifierRefactoring.RefactorAsync(document, node, accessibility, cancellationToken);
}

protected override Task<Document> ReplaceModifierRefactoring(Document document, SyntaxNode node, Accessibility fromAccessibility, Accessibility toAccessibility)
protected override Task<Document> ReplaceModifierRefactoring(
Document document,
SyntaxNode node,
Accessibility fromAccessibility,
Accessibility toAccessibility,
CancellationToken cancellationToken)
{
return Refactorings.ReplaceModifierRefactoring.RefactorAsync(document, node, fromAccessibility, toAccessibility);
return Refactorings.ReplaceModifierRefactoring.RefactorAsync(document, node, fromAccessibility, toAccessibility, cancellationToken);
}

protected override void RegisterAddInternalsVisibleToAttributeCodeFix(CodeFixContext context, Diagnostic diagnostic, CompilationUnitSyntax compilationUnitSyntax)
protected override void RegisterAddInternalsVisibleToAttributeCodeFix(CodeFixContext context, CompilationUnitSyntax compilationUnitSyntax)
{
AddInternalsVisibleToAttributeRefactoring.RegisterCodeFix(context, diagnostic, compilationUnitSyntax);
AddInternalsVisibleToAttributeRefactoring.RegisterCodeFix(context, compilationUnitSyntax);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public SubstituteForInternalMemberCodeFixProvider()
{
}

protected override void RegisterCodeFix(CodeFixContext context, Diagnostic diagnostic, CompilationUnitSyntax compilationUnitSyntax)
protected override void RegisterCodeFix(CodeFixContext context, CompilationUnitSyntax compilationUnitSyntax)
{
AddInternalsVisibleToAttributeRefactoring.RegisterCodeFix(context, diagnostic, compilationUnitSyntax);
AddInternalsVisibleToAttributeRefactoring.RegisterCodeFix(context, compilationUnitSyntax);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace NSubstitute.Analyzers.CSharp.Refactorings;

internal static class AddInternalsVisibleToAttributeRefactoring
{
public static Task<Document> RefactorAsync(Document document, CompilationUnitSyntax compilationUnitSyntax, CancellationToken cancellationToken = default)
public static Task<Document> RefactorAsync(Document document, CompilationUnitSyntax compilationUnitSyntax, CancellationToken cancellationToken)
{
var attributeList = GetGenerator(document)
.InternalVisibleToDynamicProxyAttributeList()
Expand All @@ -25,12 +25,11 @@ public static Task<Document> RefactorAsync(Document document, CompilationUnitSyn
return document.ReplaceNodeAsync(compilationUnitSyntax, updatedCompilationUnitSyntax, cancellationToken);
}

public static void RegisterCodeFix(CodeFixContext context, Diagnostic diagnostic, CompilationUnitSyntax compilationUnitSyntax)
public static void RegisterCodeFix(CodeFixContext context, CompilationUnitSyntax compilationUnitSyntax)
{
var codeAction = CodeAction.Create(
"Add InternalsVisibleTo attribute",
cancellationToken => RefactorAsync(context.Document, compilationUnitSyntax, cancellationToken),
diagnostic.Id);
cancellationToken => RefactorAsync(context.Document, compilationUnitSyntax, cancellationToken));

context.RegisterCodeFix(codeAction, context.Diagnostics);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
Expand All @@ -10,7 +11,7 @@ namespace NSubstitute.Analyzers.CSharp.Refactorings;

internal static class AddModifierRefactoring
{
public static Task<Document> RefactorAsync(Document document, SyntaxNode node, Accessibility accessibility)
public static Task<Document> RefactorAsync(Document document, SyntaxNode node, Accessibility accessibility, CancellationToken cancellationToken)
{
var syntaxKind = accessibility switch
{
Expand All @@ -20,7 +21,7 @@ public static Task<Document> RefactorAsync(Document document, SyntaxNode node, A

var newNode = Insert(node, syntaxKind);

return document.ReplaceNodeAsync(node, newNode);
return document.ReplaceNodeAsync(node, newNode, cancellationToken: cancellationToken);
}

private static SyntaxNode Insert(SyntaxNode node, SyntaxKind syntaxKind)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
Expand All @@ -11,14 +12,19 @@ namespace NSubstitute.Analyzers.CSharp.Refactorings;

internal class ReplaceModifierRefactoring
{
public static Task<Document> RefactorAsync(Document document, SyntaxNode node, Accessibility fromAccessibility, Accessibility toAccessibility)
public static Task<Document> RefactorAsync(
Document document,
SyntaxNode node,
Accessibility fromAccessibility,
Accessibility toAccessibility,
CancellationToken cancellationToken)
{
var fromSyntaxKind = InferSyntaxKind(fromAccessibility);
var toSyntaxKind = InferSyntaxKind(toAccessibility);

var newNode = ReplaceModifier(node, fromSyntaxKind, toSyntaxKind);

return document.ReplaceNodeAsync(node, newNode);
return document.ReplaceNodeAsync(node, newNode, cancellationToken: cancellationToken);
}

private static SyntaxKind InferSyntaxKind(Accessibility fromAccessibility)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,11 @@ internal abstract class AbstractConstructorArgumentsForInterfaceCodeFixProvider

public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
var diagnostic = context.Diagnostics.FirstOrDefault(diag =>
diag.Descriptor.Id == DiagnosticIdentifiers.SubstituteConstructorArgumentsForInterface);
if (diagnostic == null)
{
return Task.CompletedTask;
}

var codeAction = CodeAction.Create(
"Remove constructor arguments",
ct => CreateChangedDocument(ct, context, diagnostic),
ct => CreateChangedDocument(context, ct),
nameof(AbstractConstructorArgumentsForInterfaceCodeFixProvider));
context.RegisterCodeFix(codeAction, diagnostic);
context.RegisterCodeFix(codeAction, context.Diagnostics);

return Task.CompletedTask;
}
Expand All @@ -40,13 +33,13 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)

protected abstract SyntaxNode GetInvocationExpressionSyntaxWithNullConstructorArgument(IInvocationOperation invocationOperation);

private async Task<Document> CreateChangedDocument(CancellationToken cancellationToken, CodeFixContext context, Diagnostic diagnostic)
private async Task<Document> CreateChangedDocument(CodeFixContext context, CancellationToken cancellationToken)
{
var documentEditor = await DocumentEditor.CreateAsync(context.Document, cancellationToken);

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

var invocation = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
var invocation = root.FindNode(context.Span, getInnermostNodeForTie: true);
var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken);
if (semanticModel.GetOperation(invocation) is not IInvocationOperation invocationOperation)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
Expand All @@ -16,16 +17,8 @@ internal abstract class AbstractInternalSetupSpecificationCodeFixProvider<TCompi

public override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var diagnostic =
context.Diagnostics.FirstOrDefault(diag => diag.Id == DiagnosticIdentifiers.InternalSetupSpecification);

if (diagnostic == null)
{
return;
}

var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var invocationExpression = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
var invocationExpression = root.FindNode(context.Span, getInnermostNodeForTie: true);
var syntaxReference = await GetDeclaringSyntaxReference(context, invocationExpression);

if (syntaxReference == null)
Expand All @@ -40,8 +33,12 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
return;
}

context.RegisterCodeFix(CodeAction.Create("Add protected modifier", token => AddModifierRefactoring(context.Document, syntaxNode, Accessibility.Protected)), diagnostic);
context.RegisterCodeFix(CodeAction.Create(ReplaceModifierCodeFixTitle, token => ReplaceModifierRefactoring(context.Document, syntaxNode, Accessibility.Internal, Accessibility.Public)), diagnostic);
context.RegisterCodeFix(
CodeAction.Create("Add protected modifier", token => AddModifierRefactoring(context.Document, syntaxNode, Accessibility.Protected, token)),
context.Diagnostics);
context.RegisterCodeFix(
CodeAction.Create(ReplaceModifierCodeFixTitle, token => ReplaceModifierRefactoring(context.Document, syntaxNode, Accessibility.Internal, Accessibility.Public, token)),
context.Diagnostics);

var compilationUnitSyntax = FindCompilationUnitSyntax(syntaxNode);

Expand All @@ -50,14 +47,23 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
return;
}

RegisterAddInternalsVisibleToAttributeCodeFix(context, diagnostic, compilationUnitSyntax);
RegisterAddInternalsVisibleToAttributeCodeFix(context, compilationUnitSyntax);
}

protected abstract Task<Document> AddModifierRefactoring(Document document, SyntaxNode node, Accessibility accessibility);
protected abstract Task<Document> AddModifierRefactoring(
Document document,
SyntaxNode node,
Accessibility accessibility,
CancellationToken cancellationToken);

protected abstract Task<Document> ReplaceModifierRefactoring(Document document, SyntaxNode node, Accessibility fromAccessibility, Accessibility toAccessibility);
protected abstract Task<Document> ReplaceModifierRefactoring(
Document document,
SyntaxNode node,
Accessibility fromAccessibility,
Accessibility toAccessibility,
CancellationToken cancellationToken);

protected abstract void RegisterAddInternalsVisibleToAttributeCodeFix(CodeFixContext context, Diagnostic diagnostic, TCompilationUnitSyntax compilationUnitSyntax);
protected abstract void RegisterAddInternalsVisibleToAttributeCodeFix(CodeFixContext context, TCompilationUnitSyntax compilationUnitSyntax);

private async Task<SyntaxReference> GetDeclaringSyntaxReference(CodeFixContext context, SyntaxNode invocationExpression)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
Expand All @@ -19,15 +18,8 @@ internal abstract class AbstractPartialSubstituteUsedForUnsupportedTypeCodeFixPr

public override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var diagnostic = context.Diagnostics.FirstOrDefault(diag =>
diag.Descriptor.Id == DiagnosticIdentifiers.PartialSubstituteForUnsupportedType);
if (diagnostic == null)
{
return;
}

var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var syntaxNode = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
var syntaxNode = root.FindNode(context.Span, getInnermostNodeForTie: true);
var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken);

if (semanticModel.GetOperation(syntaxNode) is not IInvocationOperation invocationOperation)
Expand All @@ -43,7 +35,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
title,
ct => CreateChangedDocument(context, invocationOperation, ct),
nameof(AbstractPartialSubstituteUsedForUnsupportedTypeCodeFixProvider));
context.RegisterCodeFix(codeAction, diagnostic);
context.RegisterCodeFix(codeAction, context.Diagnostics);
}

protected abstract SyntaxNode UpdateInvocationExpression(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,9 @@ internal abstract class AbstractReEntrantSetupCodeFixProvider<TArgumentSyntax> :

public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var diagnostic = context.Diagnostics.FirstOrDefault(diag =>
diag.Descriptor.Id == DiagnosticIdentifiers.ReEntrantSubstituteCall);

if (diagnostic == null)
{
return;
}

var semanticModel = await context.Document.GetSemanticModelAsync();
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
var node = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
var node = root.FindNode(context.Span, getInnermostNodeForTie: true);

if (semanticModel.GetOperation(node) is not { } nodeOperation)
{
Expand Down Expand Up @@ -59,7 +51,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
ct => CreateChangedDocument(context, semanticModel, invocationOperation, methodSymbol, ct),
nameof(AbstractReEntrantSetupCodeFixProvider<TArgumentSyntax>));

context.RegisterCodeFix(codeAction, diagnostic);
context.RegisterCodeFix(codeAction, context.Diagnostics);
}

protected abstract string LambdaParameterName { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@ internal abstract class AbstractReceivedInReceivedInOrderCodeFixProvider : CodeF

public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
var diagnostic = context.Diagnostics.FirstOrDefault(diag => diag.Descriptor.Id == DiagnosticIdentifiers.ReceivedUsedInReceivedInOrder);
if (diagnostic != null)
{
var codeAction = CodeAction.Create("Remove redundant Received checks", ct => CreateChangedDocument(ct, context, diagnostic), nameof(AbstractReceivedInReceivedInOrderCodeFixProvider));
context.RegisterCodeFix(codeAction, diagnostic);
}
var codeAction = CodeAction.Create(
"Remove redundant Received checks",
ct => CreateChangedDocument(ct, context),
nameof(AbstractReceivedInReceivedInOrderCodeFixProvider));

context.RegisterCodeFix(codeAction, context.Diagnostics);

return Task.CompletedTask;
}

private async Task<Document> CreateChangedDocument(CancellationToken cancellationToken, CodeFixContext context, Diagnostic diagnostic)
private async Task<Document> CreateChangedDocument(CancellationToken cancellationToken, CodeFixContext context)
{
var root = await context.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

var invocation = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
var invocation = root.FindNode(context.Span, getInnermostNodeForTie: true);

var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken);
if (semanticModel.GetOperation(invocation) is not IInvocationOperation invocationOperation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,9 @@ protected AbstractSubstituteForInternalMemberCodeFixProvider(ISubstituteProxyAna

public override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var diagnostic = context.Diagnostics.FirstOrDefault(diag => diag.Descriptor.Id == DiagnosticIdentifiers.SubstituteForInternalMember);
if (diagnostic == null)
{
return;
}

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

var invocationExpression = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
var invocationExpression = root.FindNode(context.Span, getInnermostNodeForTie: true);
var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken);

if (semanticModel.GetOperation(invocationExpression) is not IInvocationOperation invocationOperation)
Expand All @@ -52,10 +46,10 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
return;
}

RegisterCodeFix(context, diagnostic, compilationUnitSyntax);
RegisterCodeFix(context, compilationUnitSyntax);
}

protected abstract void RegisterCodeFix(CodeFixContext context, Diagnostic diagnostic, TCompilationUnitSyntax compilationUnitSyntax);
protected abstract void RegisterCodeFix(CodeFixContext context, TCompilationUnitSyntax compilationUnitSyntax);

private SyntaxReference GetDeclaringSyntaxReference(IInvocationOperation invocationOperation)
{
Expand Down
Loading

0 comments on commit 9529446

Please sign in to comment.