Skip to content

Commit 9afba0b

Browse files
author
Vyacheslav
committed
feat: resolve #25
1 parent ba0601a commit 9afba0b

File tree

1 file changed

+85
-60
lines changed

1 file changed

+85
-60
lines changed

Src/StackMemoryCollections/Generator.cs

Lines changed: 85 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)