Skip to content

Commit 34b9e78

Browse files
committed
FileCodeFix
1 parent 98b7729 commit 34b9e78

6 files changed

Lines changed: 85 additions & 8 deletions

File tree

System.IO.Abstractions.Analyzers/Analyzers/FileServiceInterfaceInjectionAnalyzer.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class FileServiceInterfaceInjectionAnalyzer : BaseFileSystemAnalyzer
1717
/// Diagnostic Identifier
1818
/// </summary>
1919
[UsedImplicitly]
20-
public const string DiagnosticId = "IO0001";
20+
public const string DiagnosticId = Constants.Io0001;
2121

2222
/// <summary>
2323
/// Diagnostic Title
@@ -61,8 +61,9 @@ protected override void AnalyzeCompilation(CompilationStartAnalysisContext compi
6161
return;
6262
}
6363

64-
var fileSystem = classDeclarationSyntax.Members.OfType<FieldDeclarationSyntax>().FirstOrDefault(x =>
65-
x.NormalizeWhitespace().ToFullString() == fileSystemContext.FileSystemType.Name);
64+
var fileSystem = classDeclarationSyntax.Members.OfType<FieldDeclarationSyntax>()
65+
.FirstOrDefault(x =>
66+
x.NormalizeWhitespace().ToFullString() == fileSystemContext.FileSystemType.Name);
6667

6768
if (fileSystem == null)
6869
{

System.IO.Abstractions.Analyzers/Analyzers/FileSystemTypeAnalyzers/FileAnalyzer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class FileAnalyzer : BaseFileSystemNodeAnalyzer
1313
/// Diagnostic Identifier
1414
/// </summary>
1515
[UsedImplicitly]
16-
public const string DiagnosticId = "IO0002";
16+
public const string DiagnosticId = Constants.Io0002;
1717

1818
/// <summary>
1919
/// Diagnostic Title
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System.Threading;
2+
using System.Threading.Tasks;
3+
using Microsoft.CodeAnalysis;
4+
using Microsoft.CodeAnalysis.CodeActions;
5+
using Microsoft.CodeAnalysis.CSharp.Syntax;
6+
using Microsoft.CodeAnalysis.Editing;
7+
using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
8+
9+
namespace System.IO.Abstractions.Analyzers.CodeActions
10+
{
11+
public class FileSystemInvokeCodeAction : CodeAction
12+
{
13+
private const string FieldFileSystemName = "_fileSystem";
14+
15+
private readonly Document _document;
16+
17+
private readonly InvocationExpressionSyntax _invocation;
18+
19+
public override string Title { get; }
20+
21+
public override string EquivalenceKey => Title;
22+
23+
public FileSystemInvokeCodeAction(string title, Document document, InvocationExpressionSyntax invocation)
24+
{
25+
Title = title;
26+
_document = document;
27+
_invocation = invocation;
28+
}
29+
30+
protected override async Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
31+
{
32+
var editor = await DocumentEditor.CreateAsync(_document, cancellationToken).ConfigureAwait(false);
33+
34+
editor.ReplaceNode(_invocation, SF.ParseExpression($"{FieldFileSystemName}.{_invocation.NormalizeWhitespace().ToFullString()}"));
35+
36+
return editor.GetChangedDocument();
37+
}
38+
}
39+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System.Collections.Immutable;
2+
using System.Composition;
3+
using System.IO.Abstractions.Analyzers.CodeActions;
4+
using System.Threading.Tasks;
5+
using Microsoft.CodeAnalysis;
6+
using Microsoft.CodeAnalysis.CodeFixes;
7+
using Microsoft.CodeAnalysis.CSharp.Syntax;
8+
9+
namespace System.IO.Abstractions.Analyzers.CodeFixes
10+
{
11+
[Shared]
12+
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(FileCodeFix))]
13+
public class FileCodeFix : CodeFixProvider
14+
{
15+
private const string Title = "Use IFileSystem.File for improved testablity";
16+
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+
context.RegisterCodeFix(new FileSystemInvokeCodeAction(Title,
27+
context.Document,
28+
invocation),
29+
context.Diagnostics);
30+
}
31+
}
32+
}

System.IO.Abstractions.Analyzers/CodeFixes/FileServiceInterfaceInjectionCodeFix.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class FileServiceInterfaceInjectionCodeFix : CodeFixProvider
1616
private const string Title = "Use System.IO.Abstractions";
1717

1818
public sealed override ImmutableArray<string> FixableDiagnosticIds =>
19-
ImmutableArray.Create(FileServiceInterfaceInjectionAnalyzer.DiagnosticId);
19+
ImmutableArray.Create(Constants.Io0001);
2020

2121
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
2222

System.IO.Abstractions.Analyzers/Constants.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ namespace System.IO.Abstractions.Analyzers
22
{
33
public static class Constants
44
{
5-
internal const string FileSystem = "System.IO.Abstractions.IFileSystem";
6-
internal const string FileSystemName = "IFileSystem";
5+
internal const string FileSystem = "System.IO.Abstractions.IFileSystem";
76

8-
internal const string FileSystemNameSpace = "System.IO.Abstractions";
7+
internal const string FileSystemName = "IFileSystem";
8+
9+
internal const string FileSystemNameSpace = "System.IO.Abstractions";
10+
11+
public const string Io0001 = "IO0001";
12+
13+
public const string Io0002 = "IO0002";
914
}
1015
}

0 commit comments

Comments
 (0)