-
Notifications
You must be signed in to change notification settings - Fork 127
Expand file tree
/
Copy pathCSharpAnalyzerTest{TAnalyzer}.cs
More file actions
100 lines (87 loc) · 4.53 KB
/
Copy pathCSharpAnalyzerTest{TAnalyzer}.cs
File metadata and controls
100 lines (87 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.UI.Xaml.Controls;
using Windows.ApplicationModel.Core;
namespace WindowsRuntime.SourceGenerator.Tests.Helpers;
/// <summary>
/// A custom <see cref="CSharpAnalyzerTest{TAnalyzer, TVerifier}"/> that uses a specific C# language version to parse code.
/// </summary>
/// <typeparam name="TAnalyzer">The type of the analyzer to test.</typeparam>
internal sealed class CSharpAnalyzerTest<TAnalyzer> : CSharpAnalyzerTest<TAnalyzer, DefaultVerifier>
where TAnalyzer : DiagnosticAnalyzer, new()
{
/// <summary>
/// Whether to enable unsafe blocks.
/// </summary>
private readonly bool _allowUnsafeBlocks;
/// <summary>
/// The C# language version to use to parse code.
/// </summary>
private readonly LanguageVersion _languageVersion;
/// <summary>
/// Creates a new <see cref="CSharpAnalyzerTest{TAnalyzer}"/> instance with the specified parameters.
/// </summary>
/// <param name="allowUnsafeBlocks">Whether to enable unsafe blocks.</param>
/// <param name="languageVersion">The C# language version to use to parse code.</param>
private CSharpAnalyzerTest(bool allowUnsafeBlocks, LanguageVersion languageVersion)
{
_allowUnsafeBlocks = allowUnsafeBlocks;
_languageVersion = languageVersion;
}
/// <inheritdoc/>
protected override CompilationOptions CreateCompilationOptions()
{
return new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: _allowUnsafeBlocks);
}
/// <inheritdoc/>
protected override ParseOptions CreateParseOptions()
{
return new CSharpParseOptions(_languageVersion, DocumentationMode.Diagnose);
}
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.VerifyAnalyzerAsync"/>
/// <param name="source">The source code to analyze.</param>
/// <param name="expectedDiagnostics">The list of expected diagnostic for the test (used as alternative to the markdown syntax).</param>
/// <param name="allowUnsafeBlocks">Whether to enable unsafe blocks.</param>
/// <param name="languageVersion">The language version to use to run the test.</param>
/// <param name="isCsWinRTComponent">Whether to set the <c>"CsWinRTComponent"</c> MSBuild property to <see langword="true"/>.</param>
/// <param name="generatedSource">An additional source file to add to the compilation as generated code, or <see langword="null"/> to not add one.</param>
public static Task VerifyAnalyzerAsync(
string source,
ReadOnlySpan<DiagnosticResult> expectedDiagnostics = default,
bool allowUnsafeBlocks = true,
LanguageVersion languageVersion = LanguageVersion.CSharp14,
bool isCsWinRTComponent = false,
string generatedSource = null)
{
CSharpAnalyzerTest<TAnalyzer> test = new(allowUnsafeBlocks, languageVersion) { TestCode = source };
test.TestState.ReferenceAssemblies = ReferenceAssemblies.Net.Net100;
test.TestState.AdditionalReferences.Add(MetadataReference.CreateFromFile(typeof(WindowsRuntimeObject).Assembly.Location));
test.TestState.AdditionalReferences.Add(MetadataReference.CreateFromFile(typeof(CoreApplication).Assembly.Location));
test.TestState.AdditionalReferences.Add(MetadataReference.CreateFromFile(typeof(Button).Assembly.Location));
test.TestState.ExpectedDiagnostics.AddRange([.. expectedDiagnostics]);
// Add an additional source file that is treated as generated code (the '.g.cs' suffix is recognized by the
// analysis framework). This is used to validate that diagnostics are suppressed for applications of the
// attribute that appear in generated code, when the analyzer opts out of generated code analysis.
if (generatedSource is not null)
{
test.TestState.Sources.Add(("NativeExposedTypes.g.cs", generatedSource));
}
// Configure the desired MSBuild properties via a global analyzer config file
if (isCsWinRTComponent)
{
test.TestState.AnalyzerConfigFiles.Add(("/.globalconfig", """
is_global = true
build_property.CsWinRTComponent = true
"""));
}
return test.RunAsync(CancellationToken.None);
}
}