3
3
// See the LICENSE file in the project root for more information.
4
4
5
5
using System ;
6
- using System . Collections . Generic ;
7
- using System . Collections . Immutable ;
8
- using System . IO ;
9
6
using System . Linq ;
10
- using System . Reflection ;
7
+ using System . Threading . Tasks ;
11
8
using Microsoft . CodeAnalysis ;
12
9
using Microsoft . CodeAnalysis . CSharp ;
13
- using Microsoft . CodeAnalysis . Diagnostics ;
10
+ using Microsoft . CodeAnalysis . Testing ;
14
11
using Microsoft . ML . CodeAnalyzer . Tests . Helpers ;
15
12
using Xunit ;
13
+ using VerifyCS = Microsoft . ML . CodeAnalyzer . Tests . Helpers . CSharpCodeFixVerifier <
14
+ Microsoft . ML . InternalCodeAnalyzer . BestFriendAnalyzer ,
15
+ Microsoft . CodeAnalysis . Testing . EmptyCodeFixProvider > ;
16
16
17
17
namespace Microsoft . ML . InternalCodeAnalyzer . Tests
18
18
{
19
- public sealed class BestFriendTest : DiagnosticVerifier < BestFriendAnalyzer >
19
+ public sealed class BestFriendTest
20
20
{
21
21
// We do things in this somewhat odd way rather than just referencing the Core assembly directly,
22
22
// because we certainly want the best friend attribute itself to be internal, but the assembly
@@ -29,70 +29,67 @@ public sealed class BestFriendTest : DiagnosticVerifier<BestFriendAnalyzer>
29
29
private readonly Lazy < string > SourceUser = TestUtils . LazySource ( "BestFriendUser.cs" ) ;
30
30
31
31
[ Fact ]
32
- public void BestFriend ( )
32
+ public async Task BestFriend ( )
33
33
{
34
34
// The setup to this one is a bit more involved than many of the analyzer tests,
35
35
// because in this case we have to actually set up *two* assemblies, where the
36
36
// first considers the second a friend. But, setting up this dependency structure
37
37
// so that things actually compile to the point where the analyzer can actually do
38
38
// its work is rather involved.
39
- Solution solution = null ;
40
- var projA = CreateProject ( "ProjectA" , ref solution , SourceDeclaration . Value ) ;
41
- var projB = CreateProject ( "ProjectB" , ref solution , SourceUser . Value ) ;
42
- solution = solution . AddProjectReference ( projB . Id , new ProjectReference ( projA . Id ) ) ;
43
39
44
- var analyzer = new BestFriendAnalyzer ( ) ;
40
+ var expected = new DiagnosticResult [ ] {
41
+ VerifyCS . Diagnostic ( ) . WithLocation ( 10 , 31 ) . WithArguments ( "A" ) ,
42
+ VerifyCS . Diagnostic ( ) . WithLocation ( 11 , 31 ) . WithArguments ( "A" ) ,
43
+ VerifyCS . Diagnostic ( ) . WithLocation ( 11 , 33 ) . WithArguments ( "My" ) ,
44
+ VerifyCS . Diagnostic ( ) . WithLocation ( 14 , 33 ) . WithArguments ( "Awhile" ) ,
45
+ VerifyCS . Diagnostic ( ) . WithLocation ( 15 , 33 ) . WithArguments ( "And" ) ,
46
+ VerifyCS . Diagnostic ( ) . WithLocation ( 18 , 13 ) . WithArguments ( "A" ) ,
47
+ VerifyCS . Diagnostic ( ) . WithLocation ( 18 , 25 ) . WithArguments ( "A" ) ,
48
+ new DiagnosticResult ( "CS0122" , DiagnosticSeverity . Error ) . WithLocation ( 23 , 21 ) . WithMessage ( "'D.D(float)' is inaccessible due to its protection level" ) ,
49
+ VerifyCS . Diagnostic ( ) . WithLocation ( 25 , 13 ) . WithArguments ( "IA" ) ,
50
+ VerifyCS . Diagnostic ( ) . WithLocation ( 25 , 23 ) . WithArguments ( "IA" ) ,
51
+ VerifyCS . Diagnostic ( ) . WithLocation ( 32 , 38 ) . WithArguments ( ".ctor" ) ,
52
+ VerifyCS . Diagnostic ( ) . WithLocation ( 38 , 38 ) . WithArguments ( ".ctor" ) ,
53
+ } ;
45
54
46
- MetadataReference peRef ;
47
- var refs = new List < MetadataReference > {
48
- RefFromType < object > ( ) , RefFromType < Attribute > ( ) ,
49
- MetadataReference . CreateFromFile ( Assembly . Load ( "netstandard, Version=2.0.0.0" ) . Location ) ,
50
- MetadataReference . CreateFromFile ( Assembly . Load ( "System.Runtime, Version=0.0.0.0" ) . Location )
51
- } ;
52
- using ( var ms = new MemoryStream ( ) )
55
+ VerifyCS . Test test = null ;
56
+ test = new VerifyCS . Test
53
57
{
54
- // We also test whether private protected can be accessed, so we need C# 7.2 at least.
55
- var parseOpts = new CSharpParseOptions ( LanguageVersion . CSharp7_3 ) ;
56
- var tree = CSharpSyntaxTree . ParseText ( SourceDeclaration . Value , parseOpts ) ;
57
- var treeAttr = CSharpSyntaxTree . ParseText ( SourceAttribute . Value , parseOpts ) ;
58
-
59
- var compOpts = new CSharpCompilationOptions ( OutputKind . DynamicallyLinkedLibrary ) ;
60
- var innerComp = CSharpCompilation . Create ( projA . Name , new [ ] { tree , treeAttr } , refs , compOpts ) ;
61
-
62
- var emitResult = innerComp . Emit ( ms ) ;
63
- Assert . True ( emitResult . Success , $ "Compilation of { projA . Name } did not work. Diagnostics: { string . Join ( " || " , emitResult . Diagnostics ) } ") ;
58
+ LanguageVersion = LanguageVersion . CSharp7_2 ,
59
+ TestState =
60
+ {
61
+ Sources = { SourceUser . Value } ,
62
+ AdditionalReferences = { MetadataReference . CreateFromFile ( typeof ( Console ) . Assembly . Location ) } ,
63
+ } ,
64
+ SolutionTransforms =
65
+ {
66
+ ( solution , projectId ) =>
67
+ {
68
+ var projectA = solution . AddProject ( "ProjectA" , "ProjectA" , LanguageNames . CSharp ) ;
69
+ projectA = projectA . AddDocument ( "BestFriendAttribute.cs" , SourceAttribute . Value ) . Project ;
70
+ projectA = projectA . AddDocument ( "BestFriendDeclaration.cs" , SourceDeclaration . Value ) . Project ;
71
+ projectA = projectA . WithParseOptions ( ( ( CSharpParseOptions ) projectA . ParseOptions ) . WithLanguageVersion ( LanguageVersion . CSharp7_2 ) ) ;
72
+ projectA = projectA . WithCompilationOptions ( projectA . CompilationOptions . WithOutputKind ( OutputKind . DynamicallyLinkedLibrary ) ) ;
73
+ projectA = projectA . WithMetadataReferences ( solution . GetProject ( projectId ) . MetadataReferences . Concat ( test . TestState . AdditionalReferences ) ) ;
74
+ solution = projectA . Solution ;
64
75
65
- var peImage = ms . ToArray ( ) . ToImmutableArray ( ) ;
66
- peRef = MetadataReference . CreateFromImage ( peImage ) ;
67
- }
76
+ solution = solution . AddProjectReference ( projectId , new ProjectReference ( projectA . Id ) ) ;
77
+ solution = solution . WithProjectAssemblyName ( projectId , "ProjectB" ) ;
68
78
69
- refs . Add ( peRef ) ;
70
- var comp = projB . GetCompilationAsync ( ) . Result
71
- . WithReferences ( refs . ToArray ( ) ) ;
72
- var compilationWithAnalyzers = comp . WithAnalyzers ( ImmutableArray . Create ( ( DiagnosticAnalyzer ) analyzer ) ) ;
73
- var allDiags = compilationWithAnalyzers . GetAnalyzerDiagnosticsAsync ( ) . Result ;
74
-
75
- var projectTrees = new HashSet < SyntaxTree > ( projB . Documents . Select ( r => r . GetSyntaxTreeAsync ( ) . Result ) ) ;
76
- var diags = allDiags
77
- . Where ( d => d . Location == Location . None || d . Location . IsInMetadata || projectTrees . Contains ( d . Location . SourceTree ) )
78
- . OrderBy ( d => d . Location . SourceSpan . Start ) . ToArray ( ) ;
79
-
80
- var diag = analyzer . SupportedDiagnostics [ 0 ] ;
81
- var expected = new DiagnosticResult [ ] {
82
- diag . CreateDiagnosticResult ( 10 , 31 , "A" ) ,
83
- diag . CreateDiagnosticResult ( 11 , 31 , "A" ) ,
84
- diag . CreateDiagnosticResult ( 11 , 33 , "My" ) ,
85
- diag . CreateDiagnosticResult ( 14 , 33 , "Awhile" ) ,
86
- diag . CreateDiagnosticResult ( 15 , 33 , "And" ) ,
87
- diag . CreateDiagnosticResult ( 18 , 13 , "A" ) ,
88
- diag . CreateDiagnosticResult ( 18 , 25 , "A" ) ,
89
- diag . CreateDiagnosticResult ( 25 , 13 , "IA" ) ,
90
- diag . CreateDiagnosticResult ( 25 , 23 , "IA" ) ,
91
- diag . CreateDiagnosticResult ( 32 , 38 , ".ctor" ) ,
92
- diag . CreateDiagnosticResult ( 38 , 38 , ".ctor" ) ,
79
+ return solution ;
80
+ } ,
81
+ } ,
93
82
} ;
94
83
95
- VerifyDiagnosticResults ( diags , analyzer , expected ) ;
84
+ // Remove these assemblies, or an additional definition of BestFriendAttribute could exist and the
85
+ // compilation will not be able to locate a single definition for use in the analyzer.
86
+ test . TestState . AdditionalReferences . Remove ( AdditionalMetadataReferences . MLNetCoreReference ) ;
87
+ test . TestState . AdditionalReferences . Remove ( AdditionalMetadataReferences . MLNetDataReference ) ;
88
+ test . TestState . AdditionalReferences . Remove ( AdditionalMetadataReferences . MLNetStaticPipeReference ) ;
89
+
90
+ test . Exclusions &= ~ AnalysisExclusions . GeneratedCode ;
91
+ test . ExpectedDiagnostics . AddRange ( expected ) ;
92
+ await test . RunAsync ( ) ;
96
93
}
97
94
}
98
95
}
0 commit comments