-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[GH-1] - adapting to the dev changes - first stage
- Loading branch information
Showing
34 changed files
with
702 additions
and
341 deletions.
There are no files selected for viewing
28 changes: 28 additions & 0 deletions
28
src/NSubstitute.Analyzers.CSharp/DiagnosticAnalyzers/SubstituteAnalyzer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using NSubstitute.Analyzers.Shared.DiagnosticAnalyzers; | ||
|
||
namespace NSubstitute.Analyzers.CSharp.DiagnosticAnalyzers | ||
{ | ||
internal class SubstituteAnalyzer : AbstractSubstituteAnalyzer<SyntaxKind, InvocationExpressionSyntax, ExpressionSyntax> | ||
{ | ||
public SubstituteAnalyzer() : base(new DiagnosticDescriptorsProvider()) | ||
{ | ||
} | ||
|
||
protected override SyntaxKind InvocationExpressionKind { get; } = SyntaxKind.InvocationExpression; | ||
|
||
protected override IEnumerable<ExpressionSyntax> GetTypeOfLikeExpressions(IList<ExpressionSyntax> arrayParameters) | ||
{ | ||
return arrayParameters.OfType<TypeOfExpressionSyntax>(); | ||
} | ||
|
||
protected override ConstructorContext CollectConstructorContext(SubstituteContext substituteContext, ITypeSymbol proxyTypeSymbol) | ||
{ | ||
throw new System.NotImplementedException(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
...lyzers.Shared/CodeFixProviders/AbstractConstructorArgumentsForInterfaceCodeFixProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
using System.Reflection.Metadata; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CodeActions; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
|
||
namespace NSubstitute.Analyzers.Shared.CodeFixProviders | ||
{ | ||
#if CSHARP | ||
[ExportCodeFixProvider(LanguageNames.CSharp)] | ||
#elif VISUAL_BASIC | ||
[ExportCodeFixProvider(LanguageNames.VisualBasic)] | ||
#endif | ||
public class AbstractConstructorArgumentsForInterfaceCodeFixProvider : CodeFixProvider | ||
{ | ||
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; | ||
|
||
public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(DiagnosticIdentifiers.SubstituteConstructorArgumentsForInterface); | ||
|
||
public override Task RegisterCodeFixesAsync(CodeFixContext context) | ||
{ | ||
var diagnostic = context.Diagnostics.FirstOrDefault(diag => diag.Descriptor.Id == DiagnosticIdentifiers.SubstituteConstructorArgumentsForInterface); | ||
if (diagnostic != null) | ||
{ | ||
var codeAction = CodeAction.Create("Use Substitute.For", ct => CreateChangedDocument(ct, context, diagnostic), "equvalencyKey"); | ||
context.RegisterCodeFix(codeAction, diagnostic); | ||
} | ||
|
||
return Task.CompletedTask; | ||
} | ||
|
||
private async Task<Document> CreateChangedDocument(CancellationToken cancellationToken, CodeFixContext context, Diagnostic diagnostic) | ||
{ | ||
var root = await context.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); | ||
|
||
var invocation = (InvocationExpressionSyntax)root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); | ||
var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken); | ||
ArgumentListSyntax argumentListSyntax; | ||
if (semanticModel.GetSymbolInfo(invocation).Symbol is IMethodSymbol methodSymbol && methodSymbol.IsGenericMethod) | ||
{ | ||
argumentListSyntax = ArgumentList(); | ||
} | ||
else | ||
{ | ||
// TODO consider making the vb and c# analyzers/fixproviders independent | ||
#if CSHARP | ||
var nullSyntax = Argument(LiteralExpression(SyntaxKind.NullLiteralExpression)); | ||
var seconArgument = invocation.ArgumentList.Arguments.Skip(1).First(); | ||
argumentListSyntax = invocation.ArgumentList.ReplaceNode(seconArgument, nullSyntax); | ||
#elif VISUAL_BASIC | ||
var nullSyntax = SimpleArgument(LiteralExpression(SyntaxKind.NothingLiteralExpression, Token(SyntaxKind.NothingKeyword))); | ||
var seconArgument = invocation.ArgumentList.Arguments.Skip(1).First(); | ||
argumentListSyntax = invocation.ArgumentList.ReplaceNode(seconArgument, nullSyntax); | ||
#endif | ||
} | ||
|
||
var updatedInvocation = invocation.WithArgumentList(argumentListSyntax); | ||
var replacedRoot = root.ReplaceNode(invocation, updatedInvocation); | ||
return context.Document.WithSyntaxRoot(replacedRoot); | ||
} | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
...lyzers.Shared/CodeFixProviders/AbstractForPartsOfUsedForUnsupportedTypeCodeFixProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CodeActions; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
#if CSHARP | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; | ||
#elif VISUAL_BASIC | ||
using Microsoft.CodeAnalysis.VisualBasic.Syntax; | ||
using static Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory; | ||
#endif | ||
|
||
namespace NSubstitute.Analyzers.Shared.CodeFixProviders | ||
{ | ||
#if CSHARP | ||
[ExportCodeFixProvider(LanguageNames.CSharp)] | ||
#elif VISUAL_BASIC | ||
[ExportCodeFixProvider(LanguageNames.VisualBasic)] | ||
#endif | ||
public class AbstractForPartsOfUsedForUnsupportedTypeCodeFixProvider : CodeFixProvider | ||
{ | ||
// no completed task in .net standard | ||
private static Task _completedTask = Task.FromResult(1); | ||
|
||
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; | ||
|
||
public override ImmutableArray<string> FixableDiagnosticIds { get; } = | ||
ImmutableArray.Create(DiagnosticIdentifiers.SubstituteForPartsOfUsedForInterface); | ||
|
||
public override Task RegisterCodeFixesAsync(CodeFixContext context) | ||
{ | ||
var diagnostic = context.Diagnostics.FirstOrDefault(diag => diag.Descriptor.Id == DiagnosticIdentifiers.SubstituteForPartsOfUsedForInterface); | ||
if (diagnostic != null) | ||
{ | ||
var codeAction = CodeAction.Create("Use Substitute.For", ct => CreateChangedDocument(ct, context, diagnostic), "equvalencyKey"); | ||
context.RegisterCodeFix(codeAction, diagnostic); | ||
} | ||
|
||
return _completedTask; | ||
} | ||
|
||
private async Task<Document> CreateChangedDocument(CancellationToken cancellationToken, CodeFixContext context, Diagnostic diagnostic) | ||
{ | ||
var root = await context.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); | ||
|
||
var forPartsOfNode = (InvocationExpressionSyntax)root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); | ||
var nameNode = GetGenericNameSyntax(forPartsOfNode); | ||
var forNode = forPartsOfNode.ReplaceNode(nameNode, nameNode.WithIdentifier(IdentifierName("For").Identifier)); | ||
|
||
var replaceNode = root.ReplaceNode(forPartsOfNode, forNode); | ||
|
||
return context.Document.WithSyntaxRoot(replaceNode); | ||
} | ||
|
||
private static GenericNameSyntax GetGenericNameSyntax(InvocationExpressionSyntax methodInvocationNode) | ||
{ | ||
var memberAccess = (MemberAccessExpressionSyntax)methodInvocationNode.Expression; | ||
return (GenericNameSyntax)memberAccess.Name; | ||
} | ||
} | ||
} |
Oops, something went wrong.