@@ -40,7 +40,7 @@ public static string SymbolToName(ISymbol symbol)
40
40
}
41
41
42
42
public static void RegisterSourceOutputs (
43
- this IncrementalValuesProvider < KeyValuePair < string , string > > methods ,
43
+ this IncrementalValuesProvider < Scope . Extensions > methods ,
44
44
IncrementalGeneratorInitializationContext context
45
45
)
46
46
{
@@ -49,12 +49,12 @@ IncrementalGeneratorInitializationContext context
49
49
( context , method ) =>
50
50
{
51
51
context . AddSource (
52
- $ "{ string . Join ( "_" , method . Key . Split ( Path . GetInvalidFileNameChars ( ) ) ) } .cs",
52
+ $ "{ string . Join ( "_" , method . FullName . Split ( Path . GetInvalidFileNameChars ( ) ) ) } .cs",
53
53
$ """
54
54
// <auto-generated />
55
55
#nullable enable
56
56
57
- { method . Value }
57
+ { method }
58
58
"""
59
59
) ;
60
60
}
@@ -155,38 +155,24 @@ static string GetTypeInfoForNamedType(INamedTypeSymbol type)
155
155
}
156
156
}
157
157
158
- public static IEnumerable < IFieldSymbol > GetFields (
159
- TypeDeclarationSyntax typeSyntax ,
160
- INamedTypeSymbol type
158
+ // Polyfill for .NET methods from .NET Standard 2.1+:
159
+ private static StringBuilder AppendJoin < T > (
160
+ this StringBuilder sb ,
161
+ string separator ,
162
+ IEnumerable < T > values
161
163
)
162
164
{
163
- // Note: we could use naively use `type.GetMembers()` to get all fields of the type,
164
- // but some users add their own fields in extra partial declarations like this:
165
- //
166
- // ```csharp
167
- // [SpacetimeDB.Type]
168
- // partial class MyType
169
- // {
170
- // public int TableField;
171
- // }
172
- //
173
- // partial class MyType
174
- // {
175
- // public int ExtraField;
176
- // }
177
- // ```
178
- //
179
- // In this scenario, only fields declared inside the declaration with the `[SpacetimeDB.Type]` attribute
180
- // should be considered as BSATN fields, and others are expected to be ignored.
181
- //
182
- // To achieve this, we need to walk over the annotated type syntax node, collect the field names,
183
- // and look up the resolved field symbols only for those fields.
184
- return typeSyntax
185
- . Members . OfType < FieldDeclarationSyntax > ( )
186
- . SelectMany ( f => f . Declaration . Variables )
187
- . SelectMany ( v => type . GetMembers ( v . Identifier . Text ) )
188
- . OfType < IFieldSymbol > ( )
189
- . Where ( f => ! f . IsStatic ) ;
165
+ var first = true ;
166
+ foreach ( var value in values )
167
+ {
168
+ if ( ! first )
169
+ {
170
+ sb . Append ( separator ) ;
171
+ }
172
+ first = false ;
173
+ sb . Append ( value ) ;
174
+ }
175
+ return sb ;
190
176
}
191
177
192
178
// Borrowed & modified code for generating in-place extensions for partial structs/classes/etc. Source:
@@ -232,71 +218,70 @@ public Scope(MemberDeclarationSyntax? node)
232
218
233
219
public readonly record struct TypeScope ( string Keyword , string Name , string Constraints ) ;
234
220
235
- public string GenerateExtensions (
236
- string contents ,
237
- string ? interface_ = null ,
238
- string ? extraAttrs = null
239
- )
221
+ public sealed record Extensions ( Scope Scope , string FullName )
240
222
{
241
- var sb = new StringBuilder ( ) ;
223
+ public readonly StringBuilder Contents = new ( ) ;
224
+ public readonly List < string > BaseTypes = [ ] ;
225
+ public readonly List < string > ExtraAttrs = [ ] ;
242
226
243
- // Join all namespaces into a single namespace statement, starting with the outermost.
244
- if ( namespaces . Length > 0 )
227
+ public override string ToString ( )
245
228
{
246
- sb . Append ( "namespace " ) ;
247
- var first = true ;
248
- foreach ( var ns in namespaces . Reverse ( ) )
229
+ var sb = new StringBuilder ( ) ;
230
+
231
+ // Join all namespaces into a single namespace statement, starting with the outermost.
232
+ if ( Scope . namespaces . Length > 0 )
249
233
{
250
- if ( ! first )
251
- {
252
- sb . Append ( '.' ) ;
253
- }
254
- first = false ;
255
- sb . Append ( ns ) ;
234
+ sb . Append ( "namespace " )
235
+ . AppendJoin ( "." , Scope . namespaces . Reverse ( ) )
236
+ . AppendLine ( " {" ) ;
256
237
}
257
- sb . AppendLine ( " {" ) ;
258
- }
259
238
260
- // Loop through the full parent type hiearchy, starting with the outermost.
261
- foreach ( var ( i , typeScope ) in typeScopes . Select ( ( ts , i ) => ( i , ts ) ) . Reverse ( ) )
262
- {
263
- if ( i == 0 && extraAttrs is not null )
239
+ // Loop through the full parent type hiearchy, starting with the outermost.
240
+ foreach (
241
+ var ( i , typeScope ) in Scope . typeScopes . Select ( ( ts , i ) => ( i , ts ) ) . Reverse ( )
242
+ )
264
243
{
265
- sb . AppendLine ( extraAttrs ) ;
266
- }
244
+ if ( i == 0 )
245
+ {
246
+ foreach ( var extraAttr in ExtraAttrs )
247
+ {
248
+ sb . AppendLine ( extraAttr ) ;
249
+ }
250
+ }
267
251
268
- sb . Append ( "partial " )
269
- . Append ( typeScope . Keyword ) // e.g. class/struct/record
270
- . Append ( ' ' )
271
- . Append ( typeScope . Name ) // e.g. Outer/Generic<T>
272
- . Append ( ' ' ) ;
252
+ sb . Append ( "partial " )
253
+ . Append ( typeScope . Keyword ) // e.g. class/struct/record
254
+ . Append ( ' ' )
255
+ . Append ( typeScope . Name ) // e.g. Outer/Generic<T>
256
+ . Append ( ' ' ) ;
273
257
274
- if ( i == 0 && interface_ is not null )
275
- {
276
- sb . Append ( " : " ) . Append ( interface_ ) ;
258
+ if ( i == 0 && BaseTypes . Count > 0 )
259
+ {
260
+ sb . Append ( " : " ) . AppendJoin ( ", " , BaseTypes ) ;
261
+ }
262
+
263
+ sb . Append ( typeScope . Constraints ) . AppendLine ( " {" ) ;
277
264
}
278
265
279
- sb . Append ( typeScope . Constraints ) . AppendLine ( " {" ) ;
280
- }
266
+ sb . AppendLine ( ) ;
267
+ sb . Append ( Contents ) ;
268
+ sb . AppendLine ( ) ;
281
269
282
- sb . AppendLine ( ) ;
283
- sb . Append ( contents ) ;
284
- sb . AppendLine ( ) ;
270
+ // We need to "close" each of the parent types, so write
271
+ // the required number of '}'
272
+ foreach ( var typeScope in Scope . typeScopes )
273
+ {
274
+ sb . Append ( "} // " ) . AppendLine ( typeScope . Name ) ;
275
+ }
285
276
286
- // We need to "close" each of the parent types, so write
287
- // the required number of '}'
288
- foreach ( var typeScope in typeScopes )
289
- {
290
- sb . Append ( "} // " ) . AppendLine ( typeScope . Name ) ;
291
- }
277
+ // Close the namespace, if we had one
278
+ if ( Scope . namespaces . Length > 0 )
279
+ {
280
+ sb . AppendLine ( "} // namespace" ) ;
281
+ }
292
282
293
- // Close the namespace, if we had one
294
- if ( namespaces . Length > 0 )
295
- {
296
- sb . AppendLine ( "} // namespace" ) ;
283
+ return sb . ToString ( ) ;
297
284
}
298
-
299
- return sb . ToString ( ) ;
300
285
}
301
286
}
302
287
}
0 commit comments