Add Roslyn analyzer and code fix for unique ownership
Some checks failed
Publish NuGet Packages / publish (pull_request) Has been cancelled
Some checks failed
Publish NuGet Packages / publish (pull_request) Has been cancelled
Introduce a Roslyn analyzer to enforce unique ownership semantics for structs marked with the `[NonCopyable]` attribute. Added a corresponding code fix to resolve violations by suggesting the use of `Share()` or other ownership transfer methods. Key changes: - Added `StructCopyCodeAnalyzer` to detect invalid struct copies. - Implemented `StructCopyCodeFixProvider` to provide code fixes. - Created `Misaki.HighPerformance.Analyzer` and `CodeFixes` projects. - Added unit tests for the analyzer and code fixes. - Introduced `UniquePtr<T>` and `SharedPtr<T>` for pointer ownership. - Added a Visual Studio extension project and packaging support. - Updated `UnsafeUtility` to use `nint`/`nuint` for indices.
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="1.3.2" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="1.3.2" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.3.1" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.MSTest" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.MSTest" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeRefactoring.Testing.MSTest" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic.Analyzer.Testing.MSTest" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic.CodeFix.Testing.MSTest" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic.CodeRefactoring.Testing.MSTest" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Misaki.HighPerformance.Analyzer.CodeFixes\Misaki.HighPerformance.Analyzer.CodeFixes.csproj" />
|
||||
<ProjectReference Include="..\Misaki.HighPerformance.Analyzer\Misaki.HighPerformance.Analyzer.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,59 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System.Threading.Tasks;
|
||||
using VerifyCS = Misaki.HighPerformance.Analyzer.Test.CSharpCodeFixVerifier<
|
||||
Misaki.HighPerformance.Analyzer.MisakiHighPerformanceAnalyzerAnalyzer,
|
||||
Misaki.HighPerformance.Analyzer.MisakiHighPerformanceAnalyzerCodeFixProvider>;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
[TestClass]
|
||||
public class MisakiHighPerformanceAnalyzerUnitTest
|
||||
{
|
||||
//No diagnostics expected to show up
|
||||
[TestMethod]
|
||||
public async Task TestMethod1()
|
||||
{
|
||||
var test = @"";
|
||||
|
||||
await VerifyCS.VerifyAnalyzerAsync(test);
|
||||
}
|
||||
|
||||
//Diagnostic and CodeFix both triggered and checked for
|
||||
[TestMethod]
|
||||
public async Task TestMethod2()
|
||||
{
|
||||
var test = @"
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ConsoleApplication1
|
||||
{
|
||||
class {|#0:TypeName|}
|
||||
{
|
||||
}
|
||||
}";
|
||||
|
||||
var fixtest = @"
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ConsoleApplication1
|
||||
{
|
||||
class TYPENAME
|
||||
{
|
||||
}
|
||||
}";
|
||||
|
||||
var expected = VerifyCS.Diagnostic("MisakiHighPerformanceAnalyzer").WithLocation(0).WithArguments("TypeName");
|
||||
await VerifyCS.VerifyCodeFixAsync(test, expected, fixtest);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Testing;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
public static partial class CSharpAnalyzerVerifier<TAnalyzer>
|
||||
where TAnalyzer : DiagnosticAnalyzer, new()
|
||||
{
|
||||
public class Test : CSharpAnalyzerTest<TAnalyzer, MSTestVerifier>
|
||||
{
|
||||
public Test()
|
||||
{
|
||||
SolutionTransforms.Add((solution, projectId) =>
|
||||
{
|
||||
var compilationOptions = solution.GetProject(projectId).CompilationOptions;
|
||||
compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(
|
||||
compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings));
|
||||
solution = solution.WithProjectCompilationOptions(projectId, compilationOptions);
|
||||
|
||||
return solution;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Testing;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Testing;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
public static partial class CSharpAnalyzerVerifier<TAnalyzer>
|
||||
where TAnalyzer : DiagnosticAnalyzer, new()
|
||||
{
|
||||
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.Diagnostic()"/>
|
||||
public static DiagnosticResult Diagnostic()
|
||||
=> CSharpAnalyzerVerifier<TAnalyzer, MSTestVerifier>.Diagnostic();
|
||||
|
||||
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.Diagnostic(string)"/>
|
||||
public static DiagnosticResult Diagnostic(string diagnosticId)
|
||||
=> CSharpAnalyzerVerifier<TAnalyzer, MSTestVerifier>.Diagnostic(diagnosticId);
|
||||
|
||||
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.Diagnostic(DiagnosticDescriptor)"/>
|
||||
public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor)
|
||||
=> CSharpAnalyzerVerifier<TAnalyzer, MSTestVerifier>.Diagnostic(descriptor);
|
||||
|
||||
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.VerifyAnalyzerAsync(string, DiagnosticResult[])"/>
|
||||
public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected)
|
||||
{
|
||||
var test = new Test
|
||||
{
|
||||
TestCode = source,
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.AddRange(expected);
|
||||
await test.RunAsync(CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Microsoft.CodeAnalysis.CodeFixes;
|
||||
using Microsoft.CodeAnalysis.CSharp.Testing;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
public static partial class CSharpCodeFixVerifier<TAnalyzer, TCodeFix>
|
||||
where TAnalyzer : DiagnosticAnalyzer, new()
|
||||
where TCodeFix : CodeFixProvider, new()
|
||||
{
|
||||
public class Test : CSharpCodeFixTest<TAnalyzer, TCodeFix, MSTestVerifier>
|
||||
{
|
||||
public Test()
|
||||
{
|
||||
SolutionTransforms.Add((solution, projectId) =>
|
||||
{
|
||||
var compilationOptions = solution.GetProject(projectId).CompilationOptions;
|
||||
compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(
|
||||
compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings));
|
||||
solution = solution.WithProjectCompilationOptions(projectId, compilationOptions);
|
||||
|
||||
return solution;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CodeFixes;
|
||||
using Microsoft.CodeAnalysis.CSharp.Testing;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Testing;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
public static partial class CSharpCodeFixVerifier<TAnalyzer, TCodeFix>
|
||||
where TAnalyzer : DiagnosticAnalyzer, new()
|
||||
where TCodeFix : CodeFixProvider, new()
|
||||
{
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.Diagnostic()"/>
|
||||
public static DiagnosticResult Diagnostic()
|
||||
=> CSharpCodeFixVerifier<TAnalyzer, TCodeFix, MSTestVerifier>.Diagnostic();
|
||||
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.Diagnostic(string)"/>
|
||||
public static DiagnosticResult Diagnostic(string diagnosticId)
|
||||
=> CSharpCodeFixVerifier<TAnalyzer, TCodeFix, MSTestVerifier>.Diagnostic(diagnosticId);
|
||||
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.Diagnostic(DiagnosticDescriptor)"/>
|
||||
public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor)
|
||||
=> CSharpCodeFixVerifier<TAnalyzer, TCodeFix, MSTestVerifier>.Diagnostic(descriptor);
|
||||
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.VerifyAnalyzerAsync(string, DiagnosticResult[])"/>
|
||||
public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected)
|
||||
{
|
||||
var test = new Test
|
||||
{
|
||||
TestCode = source,
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.AddRange(expected);
|
||||
await test.RunAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.VerifyCodeFixAsync(string, string)"/>
|
||||
public static async Task VerifyCodeFixAsync(string source, string fixedSource)
|
||||
=> await VerifyCodeFixAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource);
|
||||
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.VerifyCodeFixAsync(string, DiagnosticResult, string)"/>
|
||||
public static async Task VerifyCodeFixAsync(string source, DiagnosticResult expected, string fixedSource)
|
||||
=> await VerifyCodeFixAsync(source, new[] { expected }, fixedSource);
|
||||
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.VerifyCodeFixAsync(string, DiagnosticResult[], string)"/>
|
||||
public static async Task VerifyCodeFixAsync(string source, DiagnosticResult[] expected, string fixedSource)
|
||||
{
|
||||
var test = new Test
|
||||
{
|
||||
TestCode = source,
|
||||
FixedCode = fixedSource,
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.AddRange(expected);
|
||||
await test.RunAsync(CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.CodeAnalysis.CodeRefactorings;
|
||||
using Microsoft.CodeAnalysis.CSharp.Testing;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
public static partial class CSharpCodeRefactoringVerifier<TCodeRefactoring>
|
||||
where TCodeRefactoring : CodeRefactoringProvider, new()
|
||||
{
|
||||
public class Test : CSharpCodeRefactoringTest<TCodeRefactoring, MSTestVerifier>
|
||||
{
|
||||
public Test()
|
||||
{
|
||||
SolutionTransforms.Add((solution, projectId) =>
|
||||
{
|
||||
var compilationOptions = solution.GetProject(projectId).CompilationOptions;
|
||||
compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(
|
||||
compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings));
|
||||
solution = solution.WithProjectCompilationOptions(projectId, compilationOptions);
|
||||
|
||||
return solution;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Microsoft.CodeAnalysis.CodeRefactorings;
|
||||
using Microsoft.CodeAnalysis.Testing;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
public static partial class CSharpCodeRefactoringVerifier<TCodeRefactoring>
|
||||
where TCodeRefactoring : CodeRefactoringProvider, new()
|
||||
{
|
||||
/// <inheritdoc cref="CodeRefactoringVerifier{TCodeRefactoring, TTest, TVerifier}.VerifyRefactoringAsync(string, string)"/>
|
||||
public static async Task VerifyRefactoringAsync(string source, string fixedSource)
|
||||
{
|
||||
await VerifyRefactoringAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CodeRefactoringVerifier{TCodeRefactoring, TTest, TVerifier}.VerifyRefactoringAsync(string, DiagnosticResult, string)"/>
|
||||
public static async Task VerifyRefactoringAsync(string source, DiagnosticResult expected, string fixedSource)
|
||||
{
|
||||
await VerifyRefactoringAsync(source, new[] { expected }, fixedSource);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CodeRefactoringVerifier{TCodeRefactoring, TTest, TVerifier}.VerifyRefactoringAsync(string, DiagnosticResult[], string)"/>
|
||||
public static async Task VerifyRefactoringAsync(string source, DiagnosticResult[] expected, string fixedSource)
|
||||
{
|
||||
var test = new Test
|
||||
{
|
||||
TestCode = source,
|
||||
FixedCode = fixedSource,
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.AddRange(expected);
|
||||
await test.RunAsync(CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
internal static class CSharpVerifierHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// By default, the compiler reports diagnostics for nullable reference types at
|
||||
/// <see cref="DiagnosticSeverity.Warning"/>, and the analyzer test framework defaults to only validating
|
||||
/// diagnostics at <see cref="DiagnosticSeverity.Error"/>. This map contains all compiler diagnostic IDs
|
||||
/// related to nullability mapped to <see cref="ReportDiagnostic.Error"/>, which is then used to enable all
|
||||
/// of these warnings for default validation during analyzer and code fix tests.
|
||||
/// </summary>
|
||||
internal static ImmutableDictionary<string, ReportDiagnostic> NullableWarnings { get; } = GetNullableWarningsFromCompiler();
|
||||
|
||||
private static ImmutableDictionary<string, ReportDiagnostic> GetNullableWarningsFromCompiler()
|
||||
{
|
||||
string[] args = { "/warnaserror:nullable" };
|
||||
var commandLineArguments = CSharpCommandLineParser.Default.Parse(args, baseDirectory: Environment.CurrentDirectory, sdkDirectory: Environment.CurrentDirectory);
|
||||
var nullableWarnings = commandLineArguments.CompilationOptions.SpecificDiagnosticOptions;
|
||||
|
||||
// Workaround for https://github.com/dotnet/roslyn/issues/41610
|
||||
nullableWarnings = nullableWarnings
|
||||
.SetItem("CS8632", ReportDiagnostic.Error)
|
||||
.SetItem("CS8669", ReportDiagnostic.Error);
|
||||
|
||||
return nullableWarnings;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
using Microsoft.CodeAnalysis.VisualBasic.Testing;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
public static partial class VisualBasicAnalyzerVerifier<TAnalyzer>
|
||||
where TAnalyzer : DiagnosticAnalyzer, new()
|
||||
{
|
||||
public class Test : VisualBasicAnalyzerTest<TAnalyzer, MSTestVerifier>
|
||||
{
|
||||
public Test()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Testing;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
using Microsoft.CodeAnalysis.VisualBasic.Testing;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
public static partial class VisualBasicAnalyzerVerifier<TAnalyzer>
|
||||
where TAnalyzer : DiagnosticAnalyzer, new()
|
||||
{
|
||||
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.Diagnostic()"/>
|
||||
public static DiagnosticResult Diagnostic()
|
||||
=> VisualBasicAnalyzerVerifier<TAnalyzer, MSTestVerifier>.Diagnostic();
|
||||
|
||||
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.Diagnostic(string)"/>
|
||||
public static DiagnosticResult Diagnostic(string diagnosticId)
|
||||
=> VisualBasicAnalyzerVerifier<TAnalyzer, MSTestVerifier>.Diagnostic(diagnosticId);
|
||||
|
||||
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.Diagnostic(DiagnosticDescriptor)"/>
|
||||
public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor)
|
||||
=> VisualBasicAnalyzerVerifier<TAnalyzer, MSTestVerifier>.Diagnostic(descriptor);
|
||||
|
||||
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.VerifyAnalyzerAsync(string, DiagnosticResult[])"/>
|
||||
public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected)
|
||||
{
|
||||
var test = new Test
|
||||
{
|
||||
TestCode = source,
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.AddRange(expected);
|
||||
await test.RunAsync(CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Microsoft.CodeAnalysis.CodeFixes;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
using Microsoft.CodeAnalysis.VisualBasic.Testing;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
public static partial class VisualBasicCodeFixVerifier<TAnalyzer, TCodeFix>
|
||||
where TAnalyzer : DiagnosticAnalyzer, new()
|
||||
where TCodeFix : CodeFixProvider, new()
|
||||
{
|
||||
public class Test : VisualBasicCodeFixTest<TAnalyzer, TCodeFix, MSTestVerifier>
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CodeFixes;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Testing;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
using Microsoft.CodeAnalysis.VisualBasic.Testing;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
public static partial class VisualBasicCodeFixVerifier<TAnalyzer, TCodeFix>
|
||||
where TAnalyzer : DiagnosticAnalyzer, new()
|
||||
where TCodeFix : CodeFixProvider, new()
|
||||
{
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.Diagnostic()"/>
|
||||
public static DiagnosticResult Diagnostic()
|
||||
=> VisualBasicCodeFixVerifier<TAnalyzer, TCodeFix, MSTestVerifier>.Diagnostic();
|
||||
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.Diagnostic(string)"/>
|
||||
public static DiagnosticResult Diagnostic(string diagnosticId)
|
||||
=> VisualBasicCodeFixVerifier<TAnalyzer, TCodeFix, MSTestVerifier>.Diagnostic(diagnosticId);
|
||||
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.Diagnostic(DiagnosticDescriptor)"/>
|
||||
public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor)
|
||||
=> VisualBasicCodeFixVerifier<TAnalyzer, TCodeFix, MSTestVerifier>.Diagnostic(descriptor);
|
||||
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.VerifyAnalyzerAsync(string, DiagnosticResult[])"/>
|
||||
public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected)
|
||||
{
|
||||
var test = new Test
|
||||
{
|
||||
TestCode = source,
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.AddRange(expected);
|
||||
await test.RunAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.VerifyCodeFixAsync(string, string)"/>
|
||||
public static async Task VerifyCodeFixAsync(string source, string fixedSource)
|
||||
=> await VerifyCodeFixAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource);
|
||||
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.VerifyCodeFixAsync(string, DiagnosticResult, string)"/>
|
||||
public static async Task VerifyCodeFixAsync(string source, DiagnosticResult expected, string fixedSource)
|
||||
=> await VerifyCodeFixAsync(source, new[] { expected }, fixedSource);
|
||||
|
||||
/// <inheritdoc cref="CodeFixVerifier{TAnalyzer, TCodeFix, TTest, TVerifier}.VerifyCodeFixAsync(string, DiagnosticResult[], string)"/>
|
||||
public static async Task VerifyCodeFixAsync(string source, DiagnosticResult[] expected, string fixedSource)
|
||||
{
|
||||
var test = new Test
|
||||
{
|
||||
TestCode = source,
|
||||
FixedCode = fixedSource,
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.AddRange(expected);
|
||||
await test.RunAsync(CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Microsoft.CodeAnalysis.CodeRefactorings;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
using Microsoft.CodeAnalysis.VisualBasic.Testing;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
public static partial class VisualBasicCodeRefactoringVerifier<TCodeRefactoring>
|
||||
where TCodeRefactoring : CodeRefactoringProvider, new()
|
||||
{
|
||||
public class Test : VisualBasicCodeRefactoringTest<TCodeRefactoring, MSTestVerifier>
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Microsoft.CodeAnalysis.CodeRefactorings;
|
||||
using Microsoft.CodeAnalysis.Testing;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Misaki.HighPerformance.Analyzer.Test
|
||||
{
|
||||
public static partial class VisualBasicCodeRefactoringVerifier<TCodeRefactoring>
|
||||
where TCodeRefactoring : CodeRefactoringProvider, new()
|
||||
{
|
||||
/// <inheritdoc cref="CodeRefactoringVerifier{TCodeRefactoring, TTest, TVerifier}.VerifyRefactoringAsync(string, string)"/>
|
||||
public static async Task VerifyRefactoringAsync(string source, string fixedSource)
|
||||
{
|
||||
await VerifyRefactoringAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CodeRefactoringVerifier{TCodeRefactoring, TTest, TVerifier}.VerifyRefactoringAsync(string, DiagnosticResult, string)"/>
|
||||
public static async Task VerifyRefactoringAsync(string source, DiagnosticResult expected, string fixedSource)
|
||||
{
|
||||
await VerifyRefactoringAsync(source, new[] { expected }, fixedSource);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CodeRefactoringVerifier{TCodeRefactoring, TTest, TVerifier}.VerifyRefactoringAsync(string, DiagnosticResult[], string)"/>
|
||||
public static async Task VerifyRefactoringAsync(string source, DiagnosticResult[] expected, string fixedSource)
|
||||
{
|
||||
var test = new Test
|
||||
{
|
||||
TestCode = source,
|
||||
FixedCode = fixedSource,
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.AddRange(expected);
|
||||
await test.RunAsync(CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user