@@ -27,10 +27,12 @@ private static class DiagnosticDescriptors {
27
27
28
28
private readonly GeneratorCache < ( IAssemblySymbol assembly , string ? excludePattern ) , ImmutableArray < ( string name , SourceText source ) > > _mockedAssemblyCache = new ( "MockedAssemblyCache" ) ;
29
29
private readonly GeneratorCache < INamedTypeSymbol , ( string name , SourceText source ) > _mockedTypeCache = new ( "MockedTypeCache" , NamedTypeSymbolCacheKeyEqualityComparer . Default ) ;
30
- private readonly MockClassGenerator _classGenerator = new ( ) ;
30
+ private readonly MockTargetModelFactory _modelFactory = new ( ) ;
31
+ private readonly MockClassGenerator _classGenerator ;
31
32
32
33
public MockGenerator ( ) {
33
34
GeneratorLog . Log ( "MockGenerator constructor" ) ;
35
+ _classGenerator = new ( _modelFactory ) ;
34
36
}
35
37
36
38
public void Initialize ( GeneratorInitializationContext context ) {
@@ -62,47 +64,55 @@ private void ProcessAssemblyAttribute(AttributeData attribute, in GeneratorExecu
62
64
case KnownTypes . GenerateMocksForAssemblyOfAttribute . Name :
63
65
if ( ! KnownTypes . GenerateMocksForAssemblyOfAttribute . NamespaceMatches ( attributeClass . ContainingNamespace ) )
64
66
return ;
65
- GenerateMocksForAttributeTargetAssembly ( attribute , context ) ;
67
+ ProcessGenerateMocksForAssemblyAttribute ( attribute , context ) ;
66
68
break ;
67
69
68
70
case KnownTypes . GenerateMocksForTypesAttribute . Name :
69
71
if ( ! KnownTypes . GenerateMocksForTypesAttribute . NamespaceMatches ( attributeClass . ContainingNamespace ) )
70
72
return ;
71
-
72
- if ( attribute . ConstructorArguments . ElementAtOrDefault ( 0 ) is not { Kind : TypedConstantKind . Array , Values : var typeofConstants } )
73
- return ;
74
-
75
- foreach ( var typeofConstant in typeofConstants ) {
76
- if ( typeofConstant is not { Value : INamedTypeSymbol type } )
77
- continue ;
78
- GenerateMockForType ( new MockTarget ( type , GetFullTypeName ( type ) ) , assemblyCacheBuilder : null , context ) ;
79
- }
73
+ ProcessGenerateMocksForTypesAttribute ( attribute , context ) ;
80
74
break ;
81
75
}
82
76
}
83
77
84
78
[ PerformanceSensitive ( "" ) ]
85
- private void GenerateMocksForAttributeTargetAssembly ( AttributeData attribute , in GeneratorExecutionContext context ) {
79
+ private void ProcessGenerateMocksForAssemblyAttribute ( AttributeData attribute , GeneratorExecutionContext context ) {
86
80
// intermediate code state? just in case
87
81
if ( attribute . ConstructorArguments . ElementAtOrDefault ( 0 ) . Value is not INamedTypeSymbol anyTypeInAssembly )
88
82
return ;
89
83
90
- var targetAssembly = anyTypeInAssembly . ContainingAssembly ;
91
84
string ? excludePattern = null ;
92
85
foreach ( var named in attribute . NamedArguments ) {
93
86
if ( named . Key == KnownTypes . GenerateMocksForAssemblyOfAttribute . NamedParameters . ExcludeRegex )
94
87
excludePattern = named . Value . Value as string ;
95
88
}
96
89
97
- if ( _mockedAssemblyCache . TryGetValue ( ( targetAssembly , excludePattern ) , out var sources ) ) {
98
- GeneratorLog . Log ( "Using cached mocks for assembly " + targetAssembly . Name ) ;
90
+ GenerateMocksForAssembly ( anyTypeInAssembly . ContainingAssembly , excludePattern , attribute . ApplicationSyntaxReference , context ) ;
91
+ }
92
+
93
+ [ PerformanceSensitive ( "" ) ]
94
+ private void ProcessGenerateMocksForTypesAttribute ( AttributeData attribute , GeneratorExecutionContext context ) {
95
+ if ( attribute . ConstructorArguments . ElementAtOrDefault ( 0 ) is not { Kind : TypedConstantKind . Array , Values : var typeConstants } )
96
+ return ;
97
+
98
+ foreach ( var typeConstant in typeConstants ) {
99
+ if ( typeConstant is not { Value : INamedTypeSymbol type } )
100
+ continue ;
101
+ GenerateMockForType ( _modelFactory . GetMockTarget ( type ) , assemblyCacheBuilder : null , context ) ;
102
+ }
103
+ }
104
+
105
+ [ PerformanceSensitive ( "" ) ]
106
+ private void GenerateMocksForAssembly ( IAssemblySymbol assembly , string ? excludePattern , SyntaxReference ? errorSyntaxReference , in GeneratorExecutionContext context ) {
107
+ if ( _mockedAssemblyCache . TryGetValue ( ( assembly , excludePattern ) , out var sources ) ) {
108
+ GeneratorLog . Log ( "Using cached mocks for assembly " + assembly . Name ) ;
99
109
foreach ( var ( name , source ) in sources ) {
100
110
context . AddSource ( name , source ) ;
101
111
}
102
112
return ;
103
113
}
104
114
105
- GeneratorLog . Log ( "Generating mocks for assembly " + targetAssembly . Name ) ;
115
+ GeneratorLog . Log ( "Generating mocks for assembly " + assembly . Name ) ;
106
116
107
117
Regex ? excludeRegex ;
108
118
try {
@@ -111,20 +121,19 @@ private void GenerateMocksForAttributeTargetAssembly(AttributeData attribute, in
111
121
#pragma warning restore HAA0502
112
122
}
113
123
catch ( ArgumentException ex ) {
114
- var attributeSyntax = attribute . ApplicationSyntaxReference ;
115
124
#pragma warning disable HAA0101 // Array allocation for params parameter -- Exceptional case: OK to allocate
116
125
context . ReportDiagnostic ( Diagnostic . Create (
117
126
DiagnosticDescriptors . RegexPatternFailedToParse ,
118
- attributeSyntax ? . SyntaxTree . GetLocation ( attributeSyntax . Span ) ,
127
+ errorSyntaxReference ? . SyntaxTree . GetLocation ( errorSyntaxReference . Span ) ,
119
128
excludePattern , ex . Message
120
129
) ) ;
121
130
#pragma warning restore HAA0101 // Array allocation for params parameter
122
131
return ;
123
132
}
124
133
125
134
var assemblyCacheBuilder = ImmutableArray . CreateBuilder < ( string , SourceText ) > ( ) ;
126
- GenerateMocksForNamespace ( targetAssembly . GlobalNamespace , excludeRegex , assemblyCacheBuilder , context ) ;
127
- _mockedAssemblyCache . TryAdd ( ( targetAssembly , excludePattern ) , assemblyCacheBuilder . ToImmutable ( ) ) ;
135
+ GenerateMocksForNamespace ( assembly . GlobalNamespace , excludeRegex , assemblyCacheBuilder , context ) ;
136
+ _mockedAssemblyCache . TryAdd ( ( assembly , excludePattern ) , assemblyCacheBuilder . ToImmutable ( ) ) ;
128
137
}
129
138
130
139
[ PerformanceSensitive ( "" ) ]
@@ -139,9 +148,10 @@ in GeneratorExecutionContext context
139
148
#pragma warning restore HAA0401
140
149
switch ( member ) {
141
150
case INamedTypeSymbol type :
142
- if ( ! ShouldIncludeInMocksForAssembly ( type , excludeRegex , out var fullName , context ) )
151
+ var target = _modelFactory . GetMockTarget ( type ) ;
152
+ if ( ! ShouldIncludeInMocksForAssembly ( target , excludeRegex , context ) )
143
153
continue ;
144
- GenerateMockForType ( new MockTarget ( type , fullName ! ) , assemblyCacheBuilder , context ) ;
154
+ GenerateMockForType ( target , assemblyCacheBuilder , context ) ;
145
155
break ;
146
156
147
157
case INamespaceSymbol nested :
@@ -152,13 +162,8 @@ in GeneratorExecutionContext context
152
162
}
153
163
154
164
[ PerformanceSensitive ( "" ) ]
155
- private bool ShouldIncludeInMocksForAssembly (
156
- INamedTypeSymbol type ,
157
- Regex ? excludeRegex ,
158
- out string ? fullName ,
159
- in GeneratorExecutionContext context
160
- ) {
161
- fullName = null ;
165
+ private bool ShouldIncludeInMocksForAssembly ( MockTarget target , Regex ? excludeRegex , in GeneratorExecutionContext context ) {
166
+ var type = target . Type ;
162
167
if ( type . TypeKind != TypeKind . Interface )
163
168
return false ;
164
169
@@ -169,18 +174,12 @@ in GeneratorExecutionContext context
169
174
return false ;
170
175
}
171
176
172
- fullName = GetFullTypeName ( type ) ;
173
- if ( excludeRegex != null && excludeRegex . IsMatch ( fullName ) )
177
+ if ( excludeRegex != null && excludeRegex . IsMatch ( target . FullTypeName ) )
174
178
return false ;
175
179
176
180
return true ;
177
181
}
178
182
179
- [ PerformanceSensitive ( "" ) ]
180
- private static string GetFullTypeName ( INamedTypeSymbol type ) {
181
- return type . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) ;
182
- }
183
-
184
183
[ PerformanceSensitive ( "" ) ]
185
184
private void GenerateMockForType (
186
185
MockTarget target ,
0 commit comments