Skip to content

Commit e27512e

Browse files
committed
Implement BaseInvokeCodeFix
1 parent 1a7847b commit e27512e

5 files changed

Lines changed: 66 additions & 48 deletions

File tree

System.IO.Abstractions.Analyzers/CodeActions/FileServiceConstructorInitialCodeAction.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,24 @@ protected override async Task<Document> GetChangedDocumentAsync(CancellationToke
3434
{
3535
var editor = await DocumentEditor.CreateAsync(_document, cancellationToken).ConfigureAwait(false);
3636

37-
if (!RoslynClassFyleSystem.HasFileSystemProperty(_class))
37+
if (!RoslynClassFileSystem.HasFileSystemField(_class))
3838
{
3939
editor.InsertMembers(_class,
4040
0,
4141
new SyntaxNode[]
4242
{
43-
RoslynClassFyleSystem.CreateFileSystemPropertyDeclaration()
43+
RoslynClassFileSystem.CreateFileSystemFieldDeclaration()
4444
});
4545
}
4646

4747
ConstructorAddParameter(_class, editor);
4848

49-
var compilationUnitSyntax = RoslynClassFyleSystem.GetCompilationUnit(_class);
49+
var compilationUnitSyntax = RoslynClassFileSystem.GetCompilationUnit(_class);
5050

5151
if (compilationUnitSyntax.Usings.Any())
5252
{
53-
editor.ReplaceNode(RoslynClassFyleSystem.GetSystemIoUsing(compilationUnitSyntax),
54-
RoslynClassFyleSystem.GetFileSystemUsing());
53+
editor.ReplaceNode(RoslynClassFileSystem.GetSystemIoUsing(compilationUnitSyntax),
54+
RoslynClassFileSystem.GetFileSystemUsing());
5555
}
5656

5757
return editor.GetChangedDocument();
@@ -67,25 +67,25 @@ private static ExpressionStatementSyntax CreateAssignmentExpression()
6767

6868
private static void ConstructorAddParameter(ClassDeclarationSyntax classDeclaration, SyntaxEditor editor)
6969
{
70-
var constructor = RoslynClassFyleSystem.HasConstructor(classDeclaration)
71-
? RoslynClassFyleSystem.GetConstructor(classDeclaration)
70+
var constructor = RoslynClassFileSystem.HasConstructor(classDeclaration)
71+
? RoslynClassFileSystem.GetConstructor(classDeclaration)
7272
: SF.ConstructorDeclaration(classDeclaration.Identifier)
7373
.WithModifiers(SyntaxTokenList.Create(SyntaxFactory.Token(SyntaxKind.PublicKeyword)));
7474

7575
var newConstructor = constructor.WithAdditionalAnnotations(Formatter.Annotation, Simplifier.Annotation)
7676
.NormalizeWhitespace();
7777

78-
if (!RoslynClassFyleSystem.ConstructorHasAssignmentExpression(newConstructor))
78+
if (!RoslynClassFileSystem.ConstructorHasAssignmentExpression(newConstructor))
7979
{
8080
newConstructor = newConstructor.AddBodyStatements(CreateAssignmentExpression());
8181
}
8282

83-
if (RoslynClassFyleSystem.HasConstructor(classDeclaration))
83+
if (RoslynClassFileSystem.HasConstructor(classDeclaration))
8484
{
8585
editor.ReplaceNode(constructor, newConstructor);
8686
} else
8787
{
88-
editor.InsertBefore(RoslynClassFyleSystem.GetMethod(classDeclaration), newConstructor);
88+
editor.InsertBefore(RoslynClassFileSystem.GetMethod(classDeclaration), newConstructor);
8989
}
9090
}
9191
}

System.IO.Abstractions.Analyzers/CodeActions/FileServiceInterfaceInjectionCodeAction.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,24 @@ protected override async Task<Document> GetChangedDocumentAsync(CancellationToke
3434
{
3535
var editor = await DocumentEditor.CreateAsync(_document, cancellationToken).ConfigureAwait(false);
3636

37-
if (!RoslynClassFyleSystem.HasFileSystemProperty(_class))
37+
if (!RoslynClassFileSystem.HasFileSystemField(_class))
3838
{
3939
editor.InsertMembers(_class,
4040
0,
4141
new SyntaxNode[]
4242
{
43-
RoslynClassFyleSystem.CreateFileSystemPropertyDeclaration()
43+
RoslynClassFileSystem.CreateFileSystemFieldDeclaration()
4444
});
4545
}
4646

4747
ConstructorAddParameter(_class, editor);
4848

49-
var compilationUnitSyntax = RoslynClassFyleSystem.GetCompilationUnit(_class);
49+
var compilationUnitSyntax = RoslynClassFileSystem.GetCompilationUnit(_class);
5050

5151
if (compilationUnitSyntax.Usings.Any())
5252
{
53-
editor.ReplaceNode(RoslynClassFyleSystem.GetSystemIoUsing(compilationUnitSyntax),
54-
RoslynClassFyleSystem.GetFileSystemUsing());
53+
editor.ReplaceNode(RoslynClassFileSystem.GetSystemIoUsing(compilationUnitSyntax),
54+
RoslynClassFileSystem.GetFileSystemUsing());
5555
}
5656

5757
return editor.GetChangedDocument();
@@ -66,31 +66,31 @@ private static ExpressionStatementSyntax CreateAssignmentExpression()
6666

6767
private static void ConstructorAddParameter(ClassDeclarationSyntax classDeclaration, SyntaxEditor editor)
6868
{
69-
var constructor = RoslynClassFyleSystem.HasConstructor(classDeclaration)
70-
? RoslynClassFyleSystem.GetConstructor(classDeclaration)
69+
var constructor = RoslynClassFileSystem.HasConstructor(classDeclaration)
70+
? RoslynClassFileSystem.GetConstructor(classDeclaration)
7171
: SF.ConstructorDeclaration(classDeclaration.Identifier)
7272
.WithModifiers(SyntaxTokenList.Create(SyntaxFactory.Token(SyntaxKind.PublicKeyword)));
7373

7474
var newConstructor = constructor.WithAdditionalAnnotations(Formatter.Annotation, Simplifier.Annotation)
7575
.NormalizeWhitespace();
7676

77-
if (!RoslynClassFyleSystem.ConstructorHasAssignmentExpression(newConstructor))
77+
if (!RoslynClassFileSystem.ConstructorHasAssignmentExpression(newConstructor))
7878
{
7979
newConstructor = newConstructor.AddBodyStatements(CreateAssignmentExpression());
8080
}
8181

82-
if (!RoslynClassFyleSystem.ConstructorHasFileSystemParameter(newConstructor))
82+
if (!RoslynClassFileSystem.ConstructorHasFileSystemParameter(newConstructor))
8383
{
84-
var parameter = RoslynClassFyleSystem.CreateFileSystemParameterDeclaration();
84+
var parameter = RoslynClassFileSystem.CreateFileSystemParameterDeclaration();
8585
newConstructor = newConstructor.AddParameterListParameters(parameter);
8686
}
8787

88-
if (RoslynClassFyleSystem.HasConstructor(classDeclaration))
88+
if (RoslynClassFileSystem.HasConstructor(classDeclaration))
8989
{
9090
editor.ReplaceNode(constructor, newConstructor);
9191
} else
9292
{
93-
editor.InsertBefore(RoslynClassFyleSystem.GetMethod(classDeclaration), newConstructor);
93+
editor.InsertBefore(RoslynClassFileSystem.GetMethod(classDeclaration), newConstructor);
9494
}
9595
}
9696
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Collections.Immutable;
2+
using System.IO.Abstractions.Analyzers.CodeActions;
3+
using System.IO.Abstractions.Analyzers.RoslynToken;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
using Microsoft.CodeAnalysis.CodeFixes;
7+
using Microsoft.CodeAnalysis.CSharp.Syntax;
8+
9+
namespace System.IO.Abstractions.Analyzers.CodeFixes
10+
{
11+
public abstract class BaseInvokeCodeFix : CodeFixProvider
12+
{
13+
protected abstract string DiagnosticId { get; }
14+
15+
protected abstract string Title { get; }
16+
17+
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(DiagnosticId);
18+
19+
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
20+
21+
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
22+
{
23+
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
24+
25+
if (root.FindNode(context.Span).Ancestors().OfType<ClassDeclarationSyntax>().Any(RoslynClassFileSystem.HasFileSystemField))
26+
{
27+
var invocation = root.FindNode(context.Span).FirstAncestorOrSelf<InvocationExpressionSyntax>();
28+
29+
context.RegisterCodeFix(new FileSystemInvokeCodeAction(Title,
30+
context.Document,
31+
invocation),
32+
context.Diagnostics);
33+
}
34+
}
35+
}
36+
}
Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,15 @@
1-
using System.Collections.Immutable;
21
using System.Composition;
3-
using System.IO.Abstractions.Analyzers.CodeActions;
4-
using System.Threading.Tasks;
52
using Microsoft.CodeAnalysis;
63
using Microsoft.CodeAnalysis.CodeFixes;
7-
using Microsoft.CodeAnalysis.CSharp.Syntax;
84

95
namespace System.IO.Abstractions.Analyzers.CodeFixes
106
{
117
[Shared]
128
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(FileCodeFix))]
13-
public class FileCodeFix : CodeFixProvider
9+
public class FileCodeFix : BaseInvokeCodeFix
1410
{
15-
private const string Title = "Use IFileSystem.File for improved testablity";
11+
protected override string DiagnosticId => Constants.Io0002;
1612

17-
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(Constants.Io0002);
18-
19-
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
20-
21-
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
22-
{
23-
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
24-
var invocation = root.FindNode(context.Span).FirstAncestorOrSelf<InvocationExpressionSyntax>();
25-
26-
// TODO: Add check contains private property with Type IFileSystem
27-
context.RegisterCodeFix(new FileSystemInvokeCodeAction(Title,
28-
context.Document,
29-
invocation),
30-
context.Diagnostics);
31-
}
13+
protected override string Title => "Use IFileSystem.File for improved testablity";
3214
}
3315
}

System.IO.Abstractions.Analyzers/RoslynToken/RoslynClassFyleSystem.cs renamed to System.IO.Abstractions.Analyzers/RoslynToken/RoslynClassFileSystem.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace System.IO.Abstractions.Analyzers.RoslynToken
1010
{
11-
public class RoslynClassFyleSystem
11+
public static class RoslynClassFileSystem
1212
{
1313
public static bool HasConstructor(SyntaxNode classDeclaration)
1414
{
@@ -25,10 +25,10 @@ public static MethodDeclarationSyntax GetMethod(ClassDeclarationSyntax classDecl
2525
return classDeclaration.ChildNodes().OfType<MethodDeclarationSyntax>().FirstOrDefault();
2626
}
2727

28-
public static bool HasFileSystemProperty(TypeDeclarationSyntax classDeclaration)
28+
public static bool HasFileSystemField(TypeDeclarationSyntax classDeclaration)
2929
{
30-
return classDeclaration.Members.OfType<PropertyDeclarationSyntax>()
31-
.Any(x => x.Identifier.Text == Constants.FieldFileSystemName && x.Type == GetFileSystemType());
30+
return classDeclaration.Members.OfType<FieldDeclarationSyntax>()
31+
.Any(x => x.Declaration.Type.NormalizeWhitespace().ToFullString() == GetFileSystemType().ToFullString());
3232
}
3333

3434
private static TypeSyntax GetFileSystemType()
@@ -47,7 +47,7 @@ public static UsingDirectiveSyntax GetSystemIoUsing(CompilationUnitSyntax unit)
4747
x.Name.NormalizeWhitespace().ToFullString().Equals(typeof(Path).Namespace));
4848
}
4949

50-
public static FieldDeclarationSyntax CreateFileSystemPropertyDeclaration()
50+
public static FieldDeclarationSyntax CreateFileSystemFieldDeclaration()
5151
{
5252
return SF.FieldDeclaration(SF.VariableDeclaration(GetFileSystemType())
5353
.WithVariables(SF.SingletonSeparatedList(SF.VariableDeclarator(SF.Identifier(Constants.FieldFileSystemName)))))

0 commit comments

Comments
 (0)