Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 31 additions & 11 deletions TUnit.Analyzers.CodeFixers/XUnitMigrationCodeFixProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,22 @@ private static async Task<Document> ConvertCodeAsync(Document document, Cancella

// Always use the latest updatedRoot as input for the next transformation
var updatedRoot = UpdateInitializeDispose(compilation, root);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, updatedRoot);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, ref updatedRoot);

updatedRoot = UpdateClassAttributes(compilation, updatedRoot);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, updatedRoot);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, ref updatedRoot);

updatedRoot = RemoveInterfacesAndBaseClasses(compilation, updatedRoot);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, updatedRoot);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, ref updatedRoot);

updatedRoot = ConvertTheoryData(compilation, updatedRoot);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, updatedRoot);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, ref updatedRoot);

updatedRoot = ConvertTestOutputHelpers(ref compilation, ref syntaxTree, updatedRoot);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, updatedRoot);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, ref updatedRoot);

updatedRoot = RemoveUsingDirectives(updatedRoot);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, updatedRoot);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, ref updatedRoot);

// Apply all changes in one step
return document.WithSyntaxRoot(updatedRoot);
Expand Down Expand Up @@ -104,7 +104,7 @@ private static SyntaxNode ConvertTestOutputHelpers(ref Compilation compilation,
)
);

UpdateSyntaxTrees(ref compilation, ref syntaxTree, currentRoot);
UpdateSyntaxTrees(ref compilation, ref syntaxTree, ref currentRoot);
compilationValue = compilation;
}

Expand Down Expand Up @@ -494,10 +494,15 @@ public override SyntaxNode VisitAttributeList(AttributeListSyntax node)
SyntaxFactory.IdentifierName("Obsolete")))],
_ => [attr]
};

newAttributes.AddRange(converted);
}

if (node.Attributes.SequenceEqual(newAttributes))
{
return node;
}

// Preserve original trivia instead of forcing elastic trivia
return SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(newAttributes))
.WithLeadingTrivia(node.GetLeadingTrivia())
Expand Down Expand Up @@ -718,9 +723,24 @@ public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node)
}
}

private static void UpdateSyntaxTrees(ref Compilation compilation, ref SyntaxTree syntaxTree, SyntaxNode updatedRoot)
private static void UpdateSyntaxTrees(ref Compilation compilation, ref SyntaxTree syntaxTree, ref SyntaxNode updatedRoot)
{
compilation = compilation.ReplaceSyntaxTree(syntaxTree, updatedRoot.SyntaxTree);
syntaxTree = updatedRoot.SyntaxTree;
var parseOptions = syntaxTree.Options;
var newSyntaxTree = updatedRoot.SyntaxTree;

// If the parse options differ, re-parse the updatedRoot with the correct options
if (!Equals(newSyntaxTree.Options, parseOptions))
{
newSyntaxTree = CSharpSyntaxTree.ParseText(
updatedRoot.ToFullString(),
(CSharpParseOptions)parseOptions,
syntaxTree.FilePath
);
}

compilation = compilation.ReplaceSyntaxTree(syntaxTree, newSyntaxTree);
syntaxTree = newSyntaxTree;

updatedRoot = newSyntaxTree.GetRoot();
}
}
15 changes: 12 additions & 3 deletions TUnit.Analyzers.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Testing;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using Polly.CircuitBreaker;
using TUnit.Core;
using TUnit.TestProject.Library;
Expand All @@ -25,13 +26,18 @@ public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor)
=> CSharpAnalyzerVerifier<TAnalyzer, DefaultVerifier>.Diagnostic(descriptor);

/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.VerifyAnalyzerAsync(string, DiagnosticResult[])"/>
public static async Task VerifyAnalyzerAsync([StringSyntax("c#")] string source, params DiagnosticResult[] expected)
public static Task VerifyAnalyzerAsync([StringSyntax("c#")] string source, params DiagnosticResult[] expected)
{
return VerifyAnalyzerAsync(source, _ => { }, expected);
}

/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.VerifyAnalyzerAsync(string, DiagnosticResult[])"/>
public static async Task VerifyAnalyzerAsync([StringSyntax("c#")] string source, Action<Test> configureTest, params DiagnosticResult[] expected)
{
var test = new Test
{
TestCode = source,
ReferenceAssemblies = ReferenceAssemblies.Net.Net90
.AddPackages([new PackageIdentity("xunit.v3.extensibility.core", "2.0.0")]),
ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
TestState =
{
AdditionalReferences =
Expand All @@ -44,6 +50,9 @@ public static async Task VerifyAnalyzerAsync([StringSyntax("c#")] string source,
};

test.ExpectedDiagnostics.AddRange(expected);

configureTest(test);

await test.RunAsync(CancellationToken.None);
}
}
32 changes: 29 additions & 3 deletions TUnit.Analyzers.Tests/Verifiers/CSharpCodeFixVerifier`2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,16 @@ public static DiagnosticResult Diagnostic(string diagnosticId)
public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor)
=> CSharpCodeFixVerifier<TAnalyzer, TCodeFix, DefaultVerifier>.Diagnostic(descriptor);

/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.VerifyAnalyzerAsync(string, DiagnosticResult[])"/>
public static Task VerifyAnalyzerAsync([StringSyntax("c#")] string source, params DiagnosticResult[] expected)
{
return VerifyAnalyzerAsync(source, _ => { }, expected);
}

/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.VerifyAnalyzerAsync(string, DiagnosticResult[])"/>
public static async Task VerifyAnalyzerAsync(
[StringSyntax("c#")] string source,
Action<Test> configureTest,
params DiagnosticResult[] expected
)
{
Expand All @@ -47,6 +54,9 @@ params DiagnosticResult[] expected
};

test.ExpectedDiagnostics.AddRange(expected);

configureTest(test);

await test.RunAsync(CancellationToken.None);
}

Expand All @@ -58,19 +68,32 @@ public static async Task VerifyCodeFixAsync([StringSyntax("c#")] string source,
public static async Task VerifyCodeFixAsync([StringSyntax("c#")] string source, DiagnosticResult expected, [StringSyntax("c#")] string fixedSource)
=> await VerifyCodeFixAsync(source, [expected], fixedSource);

public static async Task VerifyCodeFixAsync([StringSyntax("c#")] string source, DiagnosticResult expected, [StringSyntax("c#")] string fixedSource, Action<Test> configureTest)
=> await VerifyCodeFixAsync(source, [expected], fixedSource, configureTest);

/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.VerifyCodeFixAsync(string, DiagnosticResult[], string)"/>
public static async Task VerifyCodeFixAsync(
public static Task VerifyCodeFixAsync(
[StringSyntax("c#")] string source,
IEnumerable<DiagnosticResult> expected,
[StringSyntax("c#")] string fixedSource
)
{
return VerifyCodeFixAsync(source, expected, fixedSource, _ => { });
}

/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.VerifyCodeFixAsync(string, DiagnosticResult[], string)"/>
public static async Task VerifyCodeFixAsync(
[StringSyntax("c#")] string source,
IEnumerable<DiagnosticResult> expected,
[StringSyntax("c#")] string fixedSource,
Action<Test> configureTest
)
{
var test = new Test
{
TestCode = source.NormalizeLineEndings(),
FixedCode = fixedSource.NormalizeLineEndings(),
ReferenceAssemblies = ReferenceAssemblies.Net.Net90
.AddPackages([new PackageIdentity("xunit.v3.extensibility.core", "2.0.0")]),
ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
TestState =
{
AdditionalReferences =
Expand All @@ -83,6 +106,9 @@ public static async Task VerifyCodeFixAsync(
};

test.ExpectedDiagnostics.AddRange(expected);

configureTest(test);

await test.RunAsync(CancellationToken.None);
}
}
Loading
Loading