@@ -207,46 +207,51 @@ in Dictionary<string, TypeInfo> typeInfos
207207 continue ;
208208 }
209209
210- if ( propertySymbol . Type . IsReferenceType )
210+ if ( propertySymbol . Type . IsAbstract )
211211 {
212- throw new Exception ( $ "Nested reference properties are not supported, property name: '{ member . Name } '") ;
212+ throw new Exception ( $ "Abstract type are not supported, property name: '{ member . Name } '") ;
213213 }
214214
215- if ( propertySymbol . Type . IsValueType )
215+ if ( propertySymbol . Type . IsRecord )
216216 {
217- if ( typeInfos . TryGetValue ( $ "{ propertySymbol . Type . ContainingNamespace } .{ propertySymbol . Type . Name } ", out var tInfo ) )
217+ throw new Exception ( $ "Record type are not supported, property name: '{ member . Name } '") ;
218+ }
219+
220+ if ( typeInfos . TryGetValue ( $ "{ propertySymbol . Type . ContainingNamespace } .{ propertySymbol . Type . Name } ", out var tInfo ) )
221+ {
222+ var memberInfo = new MemberInfo ( ) ;
223+ memberInfo . Size = tInfo . Members . Sum ( s => s . Size ) ;
224+ memberInfo . TypeName = $ "{ propertySymbol . Type . ContainingNamespace } .{ propertySymbol . Type . Name } ";
225+ memberInfo . MemberName = propertySymbol . Name ;
226+ memberInfo . Offset = offset ;
227+ memberInfo . IsUnmanagedType = propertySymbol . Type . IsUnmanagedType ;
228+ memberInfo . IsValueType = true ;
229+ offset += memberInfo . Size ;
230+ info . Members . Add ( memberInfo ) ;
231+ continue ;
232+ }
233+ else
234+ {
235+ var attributes = propertySymbol . Type . GetAttributes ( ) ;
236+ if ( ! HelperMustGenerated ( attributes ) )
218237 {
219- var memberInfo = new MemberInfo ( ) ;
220- memberInfo . Size = tInfo . Members . Sum ( s => s . Size ) ;
221- memberInfo . TypeName = $ "{ propertySymbol . Type . ContainingNamespace } .{ propertySymbol . Type . Name } ";
222- memberInfo . MemberName = propertySymbol . Name ;
223- memberInfo . Offset = offset ;
224- memberInfo . IsUnmanagedType = propertySymbol . Type . IsUnmanagedType ;
225- memberInfo . IsValueType = true ;
226- offset += memberInfo . Size ;
227- info . Members . Add ( memberInfo ) ;
228- continue ;
238+ throw new Exception ( $ "A type '{ propertySymbol . Type . Name } ' nested in a type '{ currentType . Name } ' is not marked with an generate attribute") ;
229239 }
230- else
240+
241+ if ( ! ( propertySymbol . Type is INamedTypeSymbol namedTypeSymbol ) )
231242 {
232- var attributes = propertySymbol . Type . GetAttributes ( ) ;
233- var hasHelper = attributes . Any ( wh => wh . AttributeClass . Name == "GenerateHelperAttribute" ) ;
234- if ( ! hasHelper )
235- {
236- throw new Exception ( $ "A type '{ propertySymbol . Type . Name } ' nested in a type '{ currentType . Name } ' is not marked with an attribute 'GenerateHelperAttribute'") ;
237- }
238-
239- if ( ! ( propertySymbol . Type is INamedTypeSymbol namedTypeSymbol ) )
240- {
241- throw new Exception ( $ "A type '{ propertySymbol . Type . Name } ' nested in a type '{ currentType . Name } ' is not 'INamedTypeSymbol'") ;
242- }
243- stackCurrentTypes . Push ( namedTypeSymbol ) ;
244- needSkip = true ;
245- break ;
243+ throw new Exception ( $ "A type '{ propertySymbol . Type . Name } ' nested in a type '{ currentType . Name } ' is not 'INamedTypeSymbol'") ;
244+ }
245+
246+ if ( stackCurrentTypes . Contains ( namedTypeSymbol , SymbolEqualityComparer . Default ) )
247+ {
248+ throw new Exception ( $ "Cyclic dependency detected: type '{ propertySymbol . Type . Name } '; property '{ propertySymbol . Name } '") ;
246249 }
247- }
248250
249- throw new Exception ( $ "The property must be a struct or unmanaged type, property name: '{ member . Name } '") ;
251+ stackCurrentTypes . Push ( namedTypeSymbol ) ;
252+ needSkip = true ;
253+ break ;
254+ }
250255 }
251256 else
252257 if ( member is Microsoft . CodeAnalysis . IFieldSymbol fieldSymbol )
@@ -274,43 +279,50 @@ in Dictionary<string, TypeInfo> typeInfos
274279 continue ;
275280 }
276281
277- if ( fieldSymbol . Type . IsReferenceType )
282+ if ( fieldSymbol . Type . IsAbstract )
278283 {
279- throw new Exception ( $ "Nested reference field are not supported, field name: '{ member . Name } '") ;
284+ throw new Exception ( $ "Abstract type are not supported, field name: '{ member . Name } '") ;
280285 }
281286
282- if ( fieldSymbol . Type . IsValueType )
287+ if ( fieldSymbol . Type . IsRecord )
283288 {
284- if ( typeInfos . TryGetValue ( $ "{ fieldSymbol . Type . ContainingNamespace } .{ fieldSymbol . Type . Name } ", out var tInfo ) )
289+ throw new Exception ( $ "Record type are not supported, field name: '{ member . Name } '") ;
290+ }
291+
292+ if ( typeInfos . TryGetValue ( $ "{ fieldSymbol . Type . ContainingNamespace } .{ fieldSymbol . Type . Name } ", out var tInfo ) )
293+ {
294+ var memberInfo = new MemberInfo ( ) ;
295+ memberInfo . Size = tInfo . Members . Sum ( s => s . Size ) ;
296+ memberInfo . TypeName = $ "{ fieldSymbol . Type . ContainingNamespace } .{ fieldSymbol . Type . Name } ";
297+ memberInfo . MemberName = fieldSymbol . Name ;
298+ memberInfo . Offset = offset ;
299+ memberInfo . IsUnmanagedType = fieldSymbol . Type . IsUnmanagedType ;
300+ memberInfo . IsValueType = true ;
301+ offset += memberInfo . Size ;
302+ info . Members . Add ( memberInfo ) ;
303+ continue ;
304+ }
305+ else
306+ {
307+ var attributes = fieldSymbol . Type . GetAttributes ( ) ;
308+ if ( ! HelperMustGenerated ( attributes ) )
285309 {
286- var memberInfo = new MemberInfo ( ) ;
287- memberInfo . Size = tInfo . Members . Sum ( s => s . Size ) ;
288- memberInfo . TypeName = $ "{ fieldSymbol . Type . ContainingNamespace } .{ fieldSymbol . Type . Name } ";
289- memberInfo . MemberName = fieldSymbol . Name ;
290- memberInfo . Offset = offset ;
291- memberInfo . IsUnmanagedType = fieldSymbol . Type . IsUnmanagedType ;
292- memberInfo . IsValueType = true ;
293- offset += memberInfo . Size ;
294- info . Members . Add ( memberInfo ) ;
295- continue ;
310+ throw new Exception ( $ "A type '{ fieldSymbol . Type . Name } ' nested in a type '{ currentType . Name } ' is not marked with an generate attribute") ;
296311 }
297- else
312+
313+ if ( ! ( fieldSymbol . Type is INamedTypeSymbol namedTypeSymbol ) )
298314 {
299- var attributes = fieldSymbol . Type . GetAttributes ( ) ;
300- var hasHelper = attributes . Any ( wh => wh . AttributeClass . Name == "GenerateHelperAttribute" ) ;
301- if ( ! hasHelper )
302- {
303- throw new Exception ( $ "A type '{ fieldSymbol . Type . Name } ' nested in a type '{ currentType . Name } ' is not marked with an attribute 'GenerateHelperAttribute'") ;
304- }
305-
306- if ( ! ( fieldSymbol . Type is INamedTypeSymbol namedTypeSymbol ) )
307- {
308- throw new Exception ( $ "A type '{ fieldSymbol . Type . Name } ' nested in a type '{ currentType . Name } ' is not 'INamedTypeSymbol'") ;
309- }
310- stackCurrentTypes . Push ( namedTypeSymbol ) ;
311- needSkip = true ;
312- break ;
315+ throw new Exception ( $ "A type '{ fieldSymbol . Type . Name } ' nested in a type '{ currentType . Name } ' is not 'INamedTypeSymbol'") ;
313316 }
317+
318+ if ( stackCurrentTypes . Contains ( namedTypeSymbol , SymbolEqualityComparer . Default ) )
319+ {
320+ throw new Exception ( $ "Cyclic dependency detected: type '{ fieldSymbol . Type . Name } '; field '{ fieldSymbol . Name } '") ;
321+ }
322+
323+ stackCurrentTypes . Push ( namedTypeSymbol ) ;
324+ needSkip = true ;
325+ break ;
314326 }
315327 }
316328 }
@@ -327,6 +339,19 @@ in Dictionary<string, TypeInfo> typeInfos
327339 }
328340 }
329341
342+ private bool HelperMustGenerated ( in System . Collections . Immutable . ImmutableArray < AttributeData > attributes )
343+ {
344+ return
345+ attributes . Any ( wh =>
346+ wh . AttributeClass . Name == "GenerateHelperAttribute" ||
347+ wh . AttributeClass . Name == "GenerateStackAttribute" ||
348+ wh . AttributeClass . Name == "GenerateQueueAttribute" ||
349+ wh . AttributeClass . Name == "GenerateListAttribute" ||
350+ wh . AttributeClass . Name == "GenerateDictionaryAttribute" ||
351+ wh . AttributeClass . Name == "GenerateWrapperAttribute"
352+ ) ;
353+ }
354+
330355 private int TypeToSize ( string typeName )
331356 {
332357 switch ( typeName )
0 commit comments