@@ -59,11 +59,18 @@ private static AddStubClassInfo GetStubClassInfo(GeneratorSyntaxContext context)
59
59
var line = lineSpan . StartLinePosition . Line + 1 ;
60
60
var column = lineSpan . Span . Start . Character + context . Node . ToString ( ) . IndexOf ( "AddStub" , StringComparison . Ordinal ) + 1 ;
61
61
62
+ var properties = symbol . GetMembers ( )
63
+ . OfType < IPropertySymbol > ( )
64
+ . Where ( IsParameterOrCascadingParameter )
65
+ . Select ( CreateFromProperty )
66
+ . ToImmutableArray ( ) ;
67
+
62
68
return new AddStubClassInfo
63
69
{
64
70
StubClassName = $ "{ symbol . Name } Stub",
65
71
TargetTypeNamespace = symbol . ContainingNamespace . ToDisplayString ( ) ,
66
- TargetType = symbol ,
72
+ TargetTypeName = symbol . ToDisplayString ( ) ,
73
+ Properties = properties ,
67
74
Path = path ,
68
75
Line = line ,
69
76
Column = column ,
@@ -89,14 +96,31 @@ static string GetInterceptorFilePath(SyntaxTree tree, Compilation compilation)
89
96
{
90
97
return compilation . Options . SourceReferenceResolver ? . NormalizePath ( tree . FilePath , baseFilePath : null ) ?? tree . FilePath ;
91
98
}
99
+
100
+ static bool IsParameterOrCascadingParameter ( ISymbol member )
101
+ {
102
+ return member . GetAttributes ( ) . Any ( attr =>
103
+ attr . AttributeClass ? . ToDisplayString ( ) == "Microsoft.AspNetCore.Components.ParameterAttribute" ||
104
+ attr . AttributeClass ? . ToDisplayString ( ) == "Microsoft.AspNetCore.Components.CascadingParameterAttribute" ) ;
105
+ }
106
+
107
+ static StubPropertyInfo CreateFromProperty ( IPropertySymbol member )
108
+ {
109
+ return new StubPropertyInfo
110
+ {
111
+ Name = member . Name ,
112
+ Type = member . Type . ToDisplayString ( ) ,
113
+ AttributeLine = AttributeLineGenerator . GetAttributeLine ( member ) ,
114
+ } ;
115
+ }
92
116
}
93
117
94
118
private static void Execute ( ImmutableArray < AddStubClassInfo > classInfos , SourceProductionContext context )
95
119
{
96
120
foreach ( var stubClassGrouped in classInfos . GroupBy ( c => c . UniqueQualifier ) )
97
121
{
98
122
var stubbedComponentGroup = stubClassGrouped . First ( ) ;
99
- var didStubComponent = StubComponentBuilder . GenerateStubComponent ( stubbedComponentGroup , context ) ;
123
+ var didStubComponent = GenerateStubComponent ( stubbedComponentGroup , context ) ;
100
124
if ( didStubComponent )
101
125
{
102
126
GenerateInterceptorCode ( stubbedComponentGroup , stubClassGrouped , context ) ;
@@ -144,22 +168,65 @@ public InterceptsLocationAttribute(string filePath, int line, int column)
144
168
interceptorSource . AppendLine ( "\t \t \t where TComponent : global::Microsoft.AspNetCore.Components.IComponent" ) ;
145
169
interceptorSource . AppendLine ( "\t \t {" ) ;
146
170
interceptorSource . AppendLine (
147
- $ "\t \t \t return factories.Add<global::{ stubbedComponentGroup . TargetType . ToDisplayString ( ) } , global::{ stubbedComponentGroup . TargetTypeNamespace } .{ stubbedComponentGroup . StubClassName } >();") ;
171
+ $ "\t \t \t return factories.Add<global::{ stubbedComponentGroup . TargetTypeName } , global::{ stubbedComponentGroup . TargetTypeNamespace } .{ stubbedComponentGroup . StubClassName } >();") ;
148
172
interceptorSource . AppendLine ( "\t \t }" ) ;
149
173
interceptorSource . AppendLine ( "\t }" ) ;
150
174
interceptorSource . AppendLine ( "}" ) ;
151
175
152
176
context . AddSource ( $ "Interceptor{ stubbedComponentGroup . StubClassName } .g.cs", interceptorSource . ToString ( ) ) ;
153
177
}
178
+
179
+ private static bool GenerateStubComponent ( AddStubClassInfo classInfo , SourceProductionContext context )
180
+ {
181
+ var hasSomethingToStub = false ;
182
+ var sourceBuilder = new StringBuilder ( 1000 ) ;
183
+
184
+ sourceBuilder . AppendLine ( HeaderProvider . Header ) ;
185
+ sourceBuilder . AppendLine ( $ "namespace { classInfo . TargetTypeNamespace } ;") ;
186
+ sourceBuilder . AppendLine ( ) ;
187
+ sourceBuilder . AppendLine ( $ "internal partial class { classInfo . StubClassName } : global::Microsoft.AspNetCore.Components.ComponentBase") ;
188
+ sourceBuilder . Append ( "{" ) ;
189
+
190
+ foreach ( var member in classInfo . Properties )
191
+ {
192
+ sourceBuilder . AppendLine ( ) ;
193
+
194
+ hasSomethingToStub = true ;
195
+ var propertyType = member . Type ;
196
+ var propertyName = member . Name ;
197
+
198
+ var attributeLine = member . AttributeLine ;
199
+ sourceBuilder . AppendLine ( attributeLine ) ;
200
+
201
+ sourceBuilder . AppendLine ( $ "\t public { propertyType } { propertyName } {{ get; set; }} = default!;") ;
202
+ }
203
+
204
+ sourceBuilder . AppendLine ( "}" ) ;
205
+
206
+ if ( hasSomethingToStub )
207
+ {
208
+ context . AddSource ( $ "{ classInfo . StubClassName } .g.cs", sourceBuilder . ToString ( ) ) ;
209
+ }
210
+
211
+ return hasSomethingToStub ;
212
+ }
154
213
}
155
214
156
- internal sealed class AddStubClassInfo
215
+ internal sealed record AddStubClassInfo
157
216
{
158
217
public string StubClassName { get ; set ; }
159
218
public string TargetTypeNamespace { get ; set ; }
219
+ public string TargetTypeName { get ; set ; }
160
220
public string UniqueQualifier => $ "{ TargetTypeNamespace } .{ StubClassName } ";
161
- public ITypeSymbol TargetType { get ; set ; }
221
+ public ImmutableArray < StubPropertyInfo > Properties { get ; set ; } = ImmutableArray < StubPropertyInfo > . Empty ;
162
222
public string Path { get ; set ; }
163
223
public int Line { get ; set ; }
164
224
public int Column { get ; set ; }
165
225
}
226
+
227
+ internal sealed record StubPropertyInfo
228
+ {
229
+ public string Name { get ; set ; }
230
+ public string Type { get ; set ; }
231
+ public string AttributeLine { get ; set ; }
232
+ }
0 commit comments