Skip to content

Commit ef75906

Browse files
committed
add codefix
1 parent 1040ce8 commit ef75906

File tree

3 files changed

+101
-1
lines changed

3 files changed

+101
-1
lines changed

src/ProgressOnderwijsUtils.Analyzers/IfNotFalseAnalyzer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public sealed class IfNotFalseAnalyzer : DiagnosticAnalyzer
2121
);
2222

2323
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
24-
=> ImmutableArray.Create(Rule);
24+
=> [Rule,];
2525

2626
public override void Initialize(AnalysisContext context)
2727
{
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System.Collections.Immutable;
2+
using System.Composition;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Microsoft.CodeAnalysis;
6+
using Microsoft.CodeAnalysis.CodeActions;
7+
using Microsoft.CodeAnalysis.CodeFixes;
8+
using Microsoft.CodeAnalysis.CSharp.Syntax;
9+
10+
namespace ProgressOnderwijsUtils.Analyzers;
11+
12+
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(RedundantAssertNotNullCodeFix))]
13+
[Shared]
14+
public sealed class IfNotFalseCodeFix : CodeFixProvider
15+
{
16+
public override ImmutableArray<string> FixableDiagnosticIds
17+
=> [IfNotFalseAnalyzer.Rule.Id,];
18+
19+
public override FixAllProvider GetFixAllProvider()
20+
=> WellKnownFixAllProviders.BatchFixer;
21+
22+
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
23+
{
24+
const string title = "Remove redundant if statement";
25+
var diagnostic = context.Diagnostics.First();
26+
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
27+
if (root is null) {
28+
return;
29+
}
30+
31+
var ifStatement = root.FindNode(diagnostic.Location.SourceSpan).FirstAncestorOrSelf<IfStatementSyntax>();
32+
if (ifStatement is null) {
33+
return;
34+
}
35+
36+
var newRoot = ifStatement.Statement is BlockSyntax { Statements.Count: > 0, } block
37+
? ReplaceWithBlockStatements(root, ifStatement, block)
38+
: root.RemoveNode(ifStatement, SyntaxRemoveOptions.KeepNoTrivia);
39+
40+
if (newRoot is null) {
41+
return;
42+
}
43+
44+
context.RegisterCodeFix(
45+
CodeAction.Create(
46+
title,
47+
_ => Task.FromResult(context.Document.WithSyntaxRoot(newRoot)),
48+
title
49+
),
50+
diagnostic
51+
);
52+
}
53+
54+
private static SyntaxNode ReplaceWithBlockStatements(SyntaxNode root, IfStatementSyntax ifStatement, BlockSyntax block)
55+
{
56+
var statements = block.Statements;
57+
var firstStatement = statements[0]
58+
.WithLeadingTrivia(ifStatement.GetLeadingTrivia())
59+
.WithTrailingTrivia(block.GetTrailingTrivia());
60+
61+
var newStatements = statements.Replace(statements[0], firstStatement);
62+
63+
return root.ReplaceNode(ifStatement, newStatements);
64+
}
65+
}

test/ProgressOnderwijsUtils.Analyzers.Tests/IfNotFalseAnalyzerTest.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Linq;
2+
using System.Threading.Tasks;
23
using ExpressionToCodeLib;
34
using Xunit;
45

@@ -38,4 +39,38 @@ void M()
3839
var diagnostics = DiagnosticHelper.GetDiagnostics(new IfNotFalseAnalyzer(), source);
3940
PAssert.That(() => diagnostics.None());
4041
}
42+
43+
[Fact]
44+
public async Task CodeFix_RemovesIfNotFalse()
45+
{
46+
var source = """
47+
class C
48+
{
49+
void M()
50+
{
51+
if (!false) { System.Console.WriteLine("Hello"); }
52+
}
53+
}
54+
""";
55+
var expected = """
56+
class C
57+
{
58+
void M()
59+
{
60+
System.Console.WriteLine("Hello");
61+
}
62+
}
63+
""";
64+
65+
var workspace = DiagnosticHelper.CreateProjectWithTestFile(source);
66+
var diagnostic = DiagnosticHelper.GetDiagnostics(new IfNotFalseAnalyzer(), workspace).Single();
67+
68+
var fixesMade = await DiagnosticHelper.ApplyAllCodeFixes(workspace, diagnostic, new IfNotFalseCodeFix());
69+
PAssert.That(() => fixesMade == 1);
70+
var result = await workspace.CurrentSolution.Projects.Single().Documents.Single().GetTextAsync();
71+
Assert.Equal(
72+
expected,
73+
result.ToString()
74+
);
75+
}
4176
}

0 commit comments

Comments
 (0)