Skip to content

Commit

Permalink
Support array/list of all yamlserializable types
Browse files Browse the repository at this point in the history
  • Loading branch information
EdwardCooke committed Jan 29, 2023
1 parent d8f282c commit 61573a9
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 30 deletions.
50 changes: 39 additions & 11 deletions YamlDotNet.Analyzers.StaticGenerator/StaticObjectFactoryFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,26 @@ public override void Write(ClassSyntaxReceiver classSyntaxReceiver)

Write("public override Array CreateArray(Type type, int count)");
Write("{"); Indent();
foreach (var o in classSyntaxReceiver.Classes.Where(c => c.Value.IsArray))
foreach (var o in classSyntaxReceiver.Classes)
{
var classObject = o.Value;
Write($"if (type == typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)})) return new {classObject.ModuleSymbol.GetFullName(false).Replace("?", string.Empty)}[count];");
if (classObject.IsArray)
{
Write($"if (type == typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)})) return new {classObject.ModuleSymbol.GetFullName(false).Replace("?", string.Empty)}[count];");
}
else
{
Write($"if (type == typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)}[])) return new {classObject.ModuleSymbol.GetFullName(false).Replace("?", string.Empty)}[count];");
}
}
Write($"throw new ArgumentOutOfRangeException(\"Unknown type: \" + type.ToString());");
UnIndent(); Write("}");

Write("public override bool IsDictionary(Type type)");
Write("{"); Indent();
foreach (var o in classSyntaxReceiver.Classes)
foreach (var o in classSyntaxReceiver.Classes.Where(c => c.Value.IsDictionary))
{
var classObject = o.Value;
Write($"if (type == typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)})) return {classObject.IsDictionary.ToString().ToLower()};");
Write($"if (type == typeof({o.Value.ModuleSymbol.GetFullName().Replace("?", string.Empty)})) return true;");
}
Write("return false;");
UnIndent(); Write("}");
Expand All @@ -71,7 +77,15 @@ public override void Write(ClassSyntaxReceiver classSyntaxReceiver)
foreach (var o in classSyntaxReceiver.Classes)
{
var classObject = o.Value;
Write($"if (type == typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)})) return {classObject.IsArray.ToString().ToLower()};");
if (o.Value.IsArray)
{
Write($"if (type == typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)})) return true;");
}
else
{
//always support an array of the type
Write($"if (type == typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)}[])) return true;");
}
}
Write("return false;");
UnIndent(); Write("}");
Expand All @@ -81,7 +95,15 @@ public override void Write(ClassSyntaxReceiver classSyntaxReceiver)
foreach (var o in classSyntaxReceiver.Classes)
{
var classObject = o.Value;
Write($"if (type == typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)})) return {classObject.IsList.ToString().ToLower()};");
if (classObject.IsList)
{
Write($"if (type == typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)})) return true;");
}
else
{
//always support a list of the type
Write($"if (type == typeof(System.Collections.Generic.List<{classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)}>)) return true;");
}
}
Write("return false;");
UnIndent(); Write("}");
Expand Down Expand Up @@ -121,22 +143,28 @@ public override void Write(ClassSyntaxReceiver classSyntaxReceiver)
string valueType;
if (classObject.IsDictionary)
{
//we're a dictionary
valueType = ((INamedTypeSymbol)classObject.ModuleSymbol).TypeArguments[1].GetFullName().Replace("?", string.Empty);
}
else if (classObject.IsList)
{
//we're a list
valueType = ((INamedTypeSymbol)classObject.ModuleSymbol).TypeArguments[0].GetFullName().Replace("?", string.Empty);
}
else
{
//we're an array
valueType = ((IArrayTypeSymbol)classObject.ModuleSymbol).ElementType.GetFullName().Replace("?", string.Empty);
valueType = ((IArrayTypeSymbol)(classObject.ModuleSymbol)).ElementType.GetFullName().Replace("?", string.Empty);
}

Write($"if (type == typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)})) return typeof({valueType});");
}

//always support array and list of all types
foreach (var o in classSyntaxReceiver.Classes)
{
var classObject = o.Value;
Write($"if (type == typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)}[])) return typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)});");
Write($"if (type == typeof(System.Collections.Generic.List<{classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)}>)) return typeof({classObject.ModuleSymbol.GetFullName().Replace("?", string.Empty)});");
}

Write("throw new ArgumentOutOfRangeException(\"Unknown type: \" + type.ToString());");
UnIndent(); Write("}");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public override void Write(ClassSyntaxReceiver classSyntaxReceiver)
Write($"var accessor = new {classObject.SanitizedClassName}_{classObject.GuidSuffix}();");
foreach (var field in classObject.FieldSymbols)
{
Write($"if (name == \"{field.Name}\") return ", false);
Write($"if (name == \"{field.Name}\") return ");
WritePropertyDescriptor(field.Name, field.Type, field.IsReadOnly, field.GetAttributes(), ';');
}
foreach (var property in classObject.PropertySymbols)
Expand Down
49 changes: 33 additions & 16 deletions YamlDotNet.Analyzers.StaticGenerator/TypeFactoryGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

using System;
using System.Text;
using System.Xml;
using Microsoft.CodeAnalysis;

namespace YamlDotNet.Analyzers.StaticGenerator
Expand Down Expand Up @@ -78,27 +79,43 @@ private string GenerateSource(ClassSyntaxReceiver classSyntaxReceiver)
}
});

write("#pragma warning disable CS8767 // Nullability of reference types", true);
write("#pragma warning disable CS8767 // Nullability of reference types", true);
write("#pragma warning disable CS8603 // Possible null reference return", true);
write("#pragma warning disable CS8604 // Possible null reference argument", true);
write("#pragma warning disable CS8766 // Nullability of reference types", true);
try
{
write("#pragma warning disable CS8767 // Nullability of reference types", true);
write("#pragma warning disable CS8767 // Nullability of reference types", true);
write("#pragma warning disable CS8603 // Possible null reference return", true);
write("#pragma warning disable CS8604 // Possible null reference argument", true);
write("#pragma warning disable CS8766 // Nullability of reference types", true);

write("using System;", true);
write("using System.Collections.Generic;", true);
write("using System;", true);
write("using System.Collections.Generic;", true);

var namespaceName = classSyntaxReceiver.YamlStaticContextType?.ContainingNamespace.ContainingNamespace;
var namespaceName = classSyntaxReceiver.YamlStaticContextType?.ContainingNamespace.ContainingNamespace;

write($"namespace {classSyntaxReceiver.YamlStaticContextType?.GetNamespace() ?? "YamlDotNet.Static"}", true);
write("{", true); indent();
write($"namespace {classSyntaxReceiver.YamlStaticContextType?.GetNamespace() ?? "YamlDotNet.Static"}", true);
write("{", true); indent();

new StaticContextFile(write, indent, unindent, _context).Write(classSyntaxReceiver);
new StaticObjectFactoryFile(write, indent, unindent, _context).Write(classSyntaxReceiver);
new StaticPropertyDescriptorFile(write, indent, unindent, _context).Write(classSyntaxReceiver);
new StaticTypeInspectorFile(write, indent, unindent, _context).Write(classSyntaxReceiver);
new ObjectAccessorFileGenerator(write, indent, unindent, _context).Write(classSyntaxReceiver);
new StaticContextFile(write, indent, unindent, _context).Write(classSyntaxReceiver);
new StaticObjectFactoryFile(write, indent, unindent, _context).Write(classSyntaxReceiver);
new StaticPropertyDescriptorFile(write, indent, unindent, _context).Write(classSyntaxReceiver);
new StaticTypeInspectorFile(write, indent, unindent, _context).Write(classSyntaxReceiver);
new ObjectAccessorFileGenerator(write, indent, unindent, _context).Write(classSyntaxReceiver);

unindent(); write("}", true);
unindent(); write("}", true);
}
catch (Exception exception)
{
write("/*", true);
var e = exception;
while (e != null)
{
write(exception.Message, true);
write(exception.StackTrace, true);
write("======", true);
e = exception.InnerException;
}
write("*/", true);
}
return result.ToString();
}
}
Expand Down
25 changes: 23 additions & 2 deletions YamlDotNet.Core7AoTCompileTest/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
MyUInt64: {ulong.MaxValue}
Inner:
Text: yay
InnerArray:
- Text: hello
- Text: world
MyArray:
myArray:
- 1
Expand All @@ -57,8 +60,8 @@
x: y
a: b
MyList:
- a
- b
- a
- b
";

var input = new StringReader(yaml);
Expand All @@ -85,6 +88,10 @@
Console.WriteLine("MyUInt64: <{0}>", x.MyUInt64);
Console.WriteLine("Inner == null: <{0}>", x.Inner == null);
Console.WriteLine("Inner.Text: <{0}>", x.Inner?.Text);
foreach (var inner in x.InnerArray)
{
Console.WriteLine("InnerArray.Text: <{0}>", inner.Text);
}
Console.WriteLine("MyArray == null: <{0}>", x.MyArray == null);
Console.WriteLine("MyArray.myArray == null: <{0}>", x.MyArray?.myArray == null);

Expand Down Expand Up @@ -120,6 +127,19 @@
var output = serializer.Serialize(x);
Console.WriteLine(output);

yaml = @"- myArray:
- 1
- 2
- myArray:
- 3
- 4
";

var o = deserializer.Deserialize<MyArray[]>(yaml);
Console.WriteLine("Length: <{0}>", o.Length);
Console.WriteLine("Items[0]: <{0}>", string.Join(',', o[0].myArray));
Console.WriteLine("Items[1]: <{0}>", string.Join(',', o[1].myArray));

[YamlSerializable]
public class MyArray
{
Expand Down Expand Up @@ -157,6 +177,7 @@ public class PrimitiveTypes
public uint MyUInt32 { get; set; }
public ulong MyUInt64 { get; set; }
public Inner? Inner { get; set; }
public Inner[]? InnerArray { get; set; }
public MyArray? MyArray { get; set; }
public Dictionary<string, string>? MyDictionary { get; set; }
public List<string>? MyList { get; set; }
Expand Down

0 comments on commit 61573a9

Please sign in to comment.