Skip to content

Commit e5ab8d9

Browse files
authored
change of codefixbase (#18)
1 parent b50cdba commit e5ab8d9

File tree

6 files changed

+71
-76
lines changed

6 files changed

+71
-76
lines changed

src/Amusoft.CodeAnalysis.Analyzers/CS0123/FixByIntroducingMethod.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313
using Microsoft.CodeAnalysis.CSharp.Syntax;
1414
using Microsoft.CodeAnalysis.Formatting;
1515
using Microsoft.CodeAnalysis.Simplification;
16+
using Microsoft.CodeAnalysis.Text;
1617
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
1718

1819
namespace Amusoft.CodeAnalysis.Analyzers.CS0123
1920
{
2021
[ExportCodeFixProvider(LanguageNames.CSharp, Name = "CS0123-FixByIntroducingMethod"), Shared]
21-
public class FixByIntroducingMethod : CodeFixProviderBase
22+
public class FixByIntroducingMethod : SingleDiagnosticDocumentCodeFixProviderBase
2223
{
2324
/// <inheritdoc />
2425
protected override string DiagnosticId { get; } = "CS0123";
@@ -38,15 +39,17 @@ protected override string GetTitle(SyntaxNode rootNode)
3839
}
3940

4041
/// <inheritdoc />
41-
protected override async Task<SyntaxNode> FixedDiagnosticAsync(SyntaxNode rootNode, SyntaxNode diagnosticNode,
42-
CodeFixContext context,
43-
CancellationToken cancellationToken)
42+
protected override async Task<Document> GetFixedDiagnosticAsync(Document document, TextSpan span, CancellationToken cancellationToken)
4443
{
45-
var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
44+
var semanticModel = await document.GetSemanticModelAsync(cancellationToken)
45+
.ConfigureAwait(false);
46+
var rootNode = await document.GetSyntaxRootAsync(cancellationToken)
47+
.ConfigureAwait(false);
48+
var diagnosticNode = rootNode.FindNode(span);
4649

4750
if (!SymbolHelper.TryGetExpectedMethodSymbol(out var methodSymbol, out var memberSymbolInfo, diagnosticNode, semanticModel))
48-
return rootNode;
49-
51+
return document;
52+
5053
if (memberSymbolInfo.CandidateReason == CandidateReason.OverloadResolutionFailure &&
5154
memberSymbolInfo.CandidateSymbols.Length > 0)
5255
{
@@ -58,16 +61,16 @@ protected override async Task<SyntaxNode> FixedDiagnosticAsync(SyntaxNode rootNo
5861
.WithReturnType(IdentifierName(methodSymbol.ReturnType.MetadataName))
5962
.WithAdditionalAnnotations(SyntaxAnnotation.ElasticAnnotation, Formatter.Annotation, Simplifier.Annotation);
6063

61-
var newRoot = rootNode.InsertNodesAfter(methodDeclarationSyntax, new []{ rewritten })
64+
var newRoot = rootNode.InsertNodesAfter(methodDeclarationSyntax, new[] { rewritten })
6265
.WithAdditionalAnnotations(
6366
new SyntaxAnnotation(MemberAnnotation, methodDeclarationSyntax.Identifier.Text),
6467
new SyntaxAnnotation(TypeAnnotation, methodSymbol.ReturnType.Name)
6568
);
6669

67-
return newRoot;
70+
return document.WithSyntaxRoot(newRoot);
6871
}
6972

70-
return rootNode;
73+
return document;
7174
}
7275

7376
private ParameterListSyntax CreateParameterList(SemanticModel semanticModel, IMethodSymbol methodSymbol,

src/Amusoft.CodeAnalysis.Analyzers/CS0123/FixByRewritingParameters.cs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313
using Microsoft.CodeAnalysis.CSharp.Syntax;
1414
using Microsoft.CodeAnalysis.Formatting;
1515
using Microsoft.CodeAnalysis.Simplification;
16+
using Microsoft.CodeAnalysis.Text;
1617
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
1718

1819
namespace Amusoft.CodeAnalysis.Analyzers.CS0123
1920
{
2021
[ExportCodeFixProvider(LanguageNames.CSharp, Name = "CS0123-FixByRewritingParameters"), Shared]
21-
public class FixByRewritingParameters : CodeFixProviderBase
22+
public class FixByRewritingParameters : SingleDiagnosticDocumentCodeFixProviderBase
2223
{
2324
/// <inheritdoc />
2425
protected override string DiagnosticId { get; } = "CS0123";
@@ -37,17 +38,19 @@ protected override string GetTitle(SyntaxNode rootNode)
3738
}
3839

3940
/// <inheritdoc />
40-
protected override async Task<SyntaxNode> FixedDiagnosticAsync(SyntaxNode rootNode, SyntaxNode diagnosticNode,
41-
CodeFixContext context,
42-
CancellationToken cancellationToken)
41+
protected override async Task<Document> GetFixedDiagnosticAsync(Document document, TextSpan span, CancellationToken cancellationToken)
4342
{
44-
var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
43+
var semanticModel = await document.GetSemanticModelAsync(cancellationToken)
44+
.ConfigureAwait(false);
45+
var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken)
46+
.ConfigureAwait(false);
47+
var diagnosticNode = syntaxRoot.FindNode(span);
4548

4649
if (!SymbolHelper.TryGetExpectedMethodSymbol(out var methodSymbol, out var memberSymbolInfo, diagnosticNode, semanticModel))
47-
return rootNode;
50+
return document;
4851

4952
if (memberSymbolInfo.CandidateReason == CandidateReason.OverloadResolutionFailure &&
50-
memberSymbolInfo.CandidateSymbols.Length > 0)
53+
memberSymbolInfo.CandidateSymbols.Length > 0)
5154
{
5255
var methodDeclarationSyntax = memberSymbolInfo.CandidateSymbols[0].DeclaringSyntaxReferences[0].GetSyntax(cancellationToken) as MethodDeclarationSyntax;
5356

@@ -56,18 +59,18 @@ protected override async Task<SyntaxNode> FixedDiagnosticAsync(SyntaxNode rootNo
5659
.WithParameterList(CreateParameterList(semanticModel, methodSymbol, methodDeclarationSyntax))
5760
.WithAdditionalAnnotations(SyntaxAnnotation.ElasticAnnotation, Formatter.Annotation, Simplifier.Annotation);
5861

59-
var newRoot = rootNode.ReplaceNode(methodDeclarationSyntax, new[] { rewritten })
62+
var newRoot = syntaxRoot.ReplaceNode(methodDeclarationSyntax, new[] { rewritten })
6063
.WithAdditionalAnnotations(
6164
new SyntaxAnnotation(MemberAnnotation, methodDeclarationSyntax.Identifier.Text),
6265
new SyntaxAnnotation(TypeAnnotation, methodSymbol.ReturnType.Name)
6366
);
6467

65-
return newRoot;
68+
return document.WithSyntaxRoot(newRoot);
6669
}
6770

68-
return rootNode;
71+
return document;
6972
}
70-
73+
7174
private ParameterListSyntax CreateParameterList(SemanticModel semanticModel, IMethodSymbol methodSymbol,
7275
MethodDeclarationSyntax methodDeclarationSyntax)
7376
{

src/Amusoft.CodeAnalysis.Analyzers/CS0161/FixByReplacingWithThrowExpression.cs

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
using Microsoft.CodeAnalysis.Editing;
1717
using Microsoft.CodeAnalysis.Formatting;
1818
using Microsoft.CodeAnalysis.Simplification;
19+
using Microsoft.CodeAnalysis.Text;
1920

2021
namespace Amusoft.CodeAnalysis.Analyzers.CS0161
2122
{
2223
[ExportCodeFixProvider(LanguageNames.CSharp, Name = "CS0161-FixByReplacingWithThrowExpression"), Shared]
23-
public class FixByReplacingWithThrowExpression : CodeFixProviderBase
24+
public class FixByReplacingWithThrowExpression : SingleDiagnosticDocumentCodeFixProviderBase
2425
{
2526
/// <inheritdoc />
2627
protected override string DiagnosticId { get; } = "CS0161";
@@ -40,43 +41,46 @@ protected override string GetTitle(SyntaxNode rootNode)
4041
}
4142

4243
/// <inheritdoc />
43-
protected override async Task<SyntaxNode> FixedDiagnosticAsync(SyntaxNode rootNode, SyntaxNode diagnosticNode,
44-
CodeFixContext context,
45-
CancellationToken cancellationToken)
44+
protected override async Task<Document> GetFixedDiagnosticAsync(Document document, TextSpan span, CancellationToken cancellationToken)
4645
{
47-
var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
46+
var semanticModel = await document.GetSemanticModelAsync(cancellationToken)
47+
.ConfigureAwait(false);
48+
var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken)
49+
.ConfigureAwait(false);
50+
var diagnosticNode = syntaxRoot.FindNode(span);
51+
4852
if (diagnosticNode is MethodDeclarationSyntax methodDeclarationSyntax)
4953
{
50-
return await FixMethodAsync(context, semanticModel, methodDeclarationSyntax);
54+
return await FixMethodAsync(document, semanticModel, methodDeclarationSyntax);
5155
}
5256

53-
return rootNode;
57+
return document;
5458
}
55-
56-
private async Task<SyntaxNode> FixMethodAsync(CodeFixContext context, SemanticModel semanticModel,
59+
60+
private async Task<Document> FixMethodAsync(Document document, SemanticModel semanticModel,
5761
MethodDeclarationSyntax methodDeclarationSyntax)
5862
{
59-
var editor = await DocumentEditor.CreateAsync(context.Document);
63+
var editor = await DocumentEditor.CreateAsync(document);
6064
foreach (var conditionStatement in methodDeclarationSyntax.DescendantNodes().OfType<IfStatementSyntax>())
6165
{
6266
if (RequiresFix(semanticModel, conditionStatement.Statement))
6367
{
6468
editor.ReplaceNode(conditionStatement.Statement,
65-
GetFixedStatement(semanticModel, conditionStatement.Statement));
69+
GetFixedStatement(conditionStatement.Statement));
6670
}
6771

6872
if (RequiresFix(semanticModel, conditionStatement.Else.Statement))
6973
{
70-
var fixedStatement = GetFixedStatement(semanticModel, conditionStatement.Else.Statement);
74+
var fixedStatement = GetFixedStatement(conditionStatement.Else.Statement);
7175
editor.ReplaceNode(conditionStatement.Else.Statement,
7276
fixedStatement);
7377
}
7478
}
7579

76-
return editor.GetChangedRoot();
80+
return editor.GetChangedDocument();
7781
}
7882

79-
private SyntaxNode GetFixedStatement(SemanticModel semanticModel, StatementSyntax statementSyntax)
83+
private SyntaxNode GetFixedStatement(StatementSyntax statementSyntax)
8084
{
8185
if (statementSyntax is BlockSyntax blockSyntax)
8286
{
@@ -111,22 +115,4 @@ private bool RequiresFix(SemanticModel semanticModel, StatementSyntax statementS
111115
return controlFlow.ExitPoints.Length == 0;
112116
}
113117
}
114-
115-
//
116-
// public class Test
117-
// {
118-
// public static int Main() // CS0161
119-
// {
120-
// int i = 5;
121-
// if (i < 10)
122-
// {
123-
// return i;
124-
// }
125-
// else
126-
// {
127-
// // Uncomment the following line to resolve.
128-
// // return 1;
129-
// }
130-
// }
131-
// }
132118
}

src/Amusoft.CodeAnalysis.Analyzers/CS0407/FixByReplacingMethodReturnType.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Composition;
22
using System.Linq;
3+
using System.Runtime.InteropServices;
34
using System.Threading;
45
using System.Threading.Tasks;
56
using Amusoft.CodeAnalysis.Analyzers.Shared;
@@ -10,11 +11,12 @@
1011
using Microsoft.CodeAnalysis.FindSymbols;
1112
using Microsoft.CodeAnalysis.Formatting;
1213
using Microsoft.CodeAnalysis.Simplification;
14+
using Microsoft.CodeAnalysis.Text;
1315

1416
namespace Amusoft.CodeAnalysis.Analyzers.CS0407
1517
{
1618
[ExportCodeFixProvider(LanguageNames.CSharp, Name = "CS0407-FixByReplacingMethodReturnType"), Shared]
17-
public class FixByReplacingMethodReturnType : CodeFixProviderBase
19+
public class FixByReplacingMethodReturnType : SingleDiagnosticDocumentCodeFixProviderBase
1820
{
1921
/// <inheritdoc />
2022
protected override string DiagnosticId { get; } = "CS0407";
@@ -34,13 +36,15 @@ protected override string GetTitle(SyntaxNode rootNode)
3436
}
3537

3638
/// <inheritdoc />
37-
protected override async Task<SyntaxNode> FixedDiagnosticAsync(SyntaxNode rootNode, SyntaxNode diagnosticNode, CodeFixContext context,
38-
CancellationToken cancellationToken)
39+
protected override async Task<Document> GetFixedDiagnosticAsync(Document document, TextSpan span, CancellationToken cancellationToken)
3940
{
40-
var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
41+
var semanticModel = await document.GetSemanticModelAsync(cancellationToken)
42+
.ConfigureAwait(false);
43+
var rootNode = await document.GetSyntaxRootAsync(cancellationToken);
44+
var diagnosticNode = rootNode.FindNode(span);
4145

4246
if (!SymbolHelper.TryGetExpectedMethodSymbol(out var typeSymbol, out var memberSymbolInfo, diagnosticNode, semanticModel))
43-
return rootNode;
47+
return document;
4448

4549
if (memberSymbolInfo.CandidateReason == CandidateReason.OverloadResolutionFailure &&
4650
memberSymbolInfo.CandidateSymbols.Length > 0)
@@ -57,10 +61,10 @@ protected override async Task<SyntaxNode> FixedDiagnosticAsync(SyntaxNode rootNo
5761
new SyntaxAnnotation(TypeAnnotation, typeSymbol.ReturnType.Name)
5862
);
5963

60-
return newRoot;
64+
return document.WithSyntaxRoot(newRoot);
6165
}
6266

63-
return rootNode;
67+
return document;
6468
}
6569
}
6670
}

src/Amusoft.CodeAnalysis.Analyzers/CS1998/FixByWrappingInTaskResult.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
using Microsoft.CodeAnalysis.Editing;
1717
using Microsoft.CodeAnalysis.Formatting;
1818
using Microsoft.CodeAnalysis.Simplification;
19+
using Microsoft.CodeAnalysis.Text;
1920

2021
namespace Amusoft.CodeAnalysis.Analyzers.CS1998
2122
{
2223
[ExportCodeFixProvider(LanguageNames.CSharp, Name = "CS1998-FixByWrappingInTaskResult"), Shared]
23-
public class FixByWrappingInTaskResult : CodeFixProviderBase
24+
public class FixByWrappingInTaskResult : SingleDiagnosticDocumentCodeFixProviderBase
2425
{
2526
/// <inheritdoc />
2627
protected override string DiagnosticId { get; } = "CS1998";
@@ -38,18 +39,19 @@ protected override string GetTitle(SyntaxNode rootNode)
3839
}
3940

4041
/// <inheritdoc />
41-
protected override async Task<SyntaxNode> FixedDiagnosticAsync(SyntaxNode rootNode, SyntaxNode diagnosticNode,
42-
CodeFixContext context,
43-
CancellationToken cancellationToken)
42+
protected override async Task<Document> GetFixedDiagnosticAsync(Document document, TextSpan span, CancellationToken cancellationToken)
4443
{
45-
var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken)
44+
var semanticModel = await document.GetSemanticModelAsync(cancellationToken)
4645
.ConfigureAwait(false);
46+
var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken);
47+
var diagnosticNode = syntaxRoot.FindNode(span);
48+
4749
if (diagnosticNode is MethodDeclarationSyntax methodDeclarationSyntax)
4850
{
4951
var controlFlowAnalysis = semanticModel.AnalyzeControlFlow(methodDeclarationSyntax.Body);
5052
if (controlFlowAnalysis.ReturnStatements.Length > 0)
5153
{
52-
var documentEditor = await DocumentEditor.CreateAsync(context.Document, cancellationToken)
54+
var documentEditor = await DocumentEditor.CreateAsync(document, cancellationToken)
5355
.ConfigureAwait(false);
5456

5557
RemoveAsyncFromMethod(documentEditor, methodDeclarationSyntax, semanticModel);
@@ -65,11 +67,11 @@ protected override async Task<SyntaxNode> FixedDiagnosticAsync(SyntaxNode rootNo
6567
}
6668
}
6769

68-
return await documentEditor.GetChangedDocument().GetSyntaxRootAsync(cancellationToken);
70+
return documentEditor.GetChangedDocument();
6971
}
7072
}
7173

72-
return rootNode;
74+
return document;
7375
}
7476

7577
private static void RemoveAsyncFromMethod(DocumentEditor documentEditor, MethodDeclarationSyntax methodDeclarationSyntax, SemanticModel semanticModel)

src/Amusoft.CodeAnalysis.Analyzers/Shared/CodeFixProviderBase.cs renamed to src/Amusoft.CodeAnalysis.Analyzers/Shared/SingleDiagnosticDocumentCodeFixProviderBase.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
using Microsoft.CodeAnalysis;
77
using Microsoft.CodeAnalysis.CodeActions;
88
using Microsoft.CodeAnalysis.CodeFixes;
9+
using Microsoft.CodeAnalysis.Text;
910

1011
namespace Amusoft.CodeAnalysis.Analyzers.Shared
1112
{
1213
/// <summary>
1314
/// <inheritdoc />
1415
/// </summary>
15-
public abstract class CodeFixProviderBase : CodeFixProvider
16+
public abstract class SingleDiagnosticDocumentCodeFixProviderBase : CodeFixProvider
1617
{
1718
public sealed override FixAllProvider GetFixAllProvider()
1819
{
@@ -35,17 +36,13 @@ public sealed override FixAllProvider GetFixAllProvider()
3536
protected virtual async Task<Document> GetFixedDocumentAsync(CodeFixContext context,
3637
CancellationToken cancellationToken, Diagnostic diagnostic)
3738
{
38-
var rootNode = await context.Document.GetSyntaxRootAsync(cancellationToken)
39-
.ConfigureAwait(false);
40-
var fixedRoot = await FixedDiagnosticAsync(rootNode, rootNode.FindNode(diagnostic.Location.SourceSpan), context, cancellationToken)
39+
var fixedDocument = await GetFixedDiagnosticAsync(context.Document, diagnostic.Location.SourceSpan, cancellationToken)
4140
.ConfigureAwait(false);
4241

43-
return context.Document
44-
.WithSyntaxRoot(fixedRoot);
42+
return fixedDocument;
4543
}
4644

47-
protected abstract Task<SyntaxNode> FixedDiagnosticAsync(SyntaxNode rootNode, SyntaxNode diagnosticNode,
48-
CodeFixContext context, CancellationToken cancellationToken);
45+
protected abstract Task<Document> GetFixedDiagnosticAsync(Document document, TextSpan span, CancellationToken cancellationToken);
4946

5047
/// <inheritdoc />
5148
public override async Task RegisterCodeFixesAsync(CodeFixContext context)

0 commit comments

Comments
 (0)