diff --git a/YamlDotNet.Analyzers.StaticGenerator/StaticObjectFactoryFile.cs b/YamlDotNet.Analyzers.StaticGenerator/StaticObjectFactoryFile.cs index 9c6571742..50edbebdc 100644 --- a/YamlDotNet.Analyzers.StaticGenerator/StaticObjectFactoryFile.cs +++ b/YamlDotNet.Analyzers.StaticGenerator/StaticObjectFactoryFile.cs @@ -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("}"); @@ -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("}"); @@ -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("}"); @@ -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("}"); diff --git a/YamlDotNet.Analyzers.StaticGenerator/StaticTypeInspectorFile.cs b/YamlDotNet.Analyzers.StaticGenerator/StaticTypeInspectorFile.cs index 59e2fd537..410ba1d24 100644 --- a/YamlDotNet.Analyzers.StaticGenerator/StaticTypeInspectorFile.cs +++ b/YamlDotNet.Analyzers.StaticGenerator/StaticTypeInspectorFile.cs @@ -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) diff --git a/YamlDotNet.Analyzers.StaticGenerator/TypeFactoryGenerator.cs b/YamlDotNet.Analyzers.StaticGenerator/TypeFactoryGenerator.cs index 3af8ce0d4..0a95a7963 100644 --- a/YamlDotNet.Analyzers.StaticGenerator/TypeFactoryGenerator.cs +++ b/YamlDotNet.Analyzers.StaticGenerator/TypeFactoryGenerator.cs @@ -21,6 +21,7 @@ using System; using System.Text; +using System.Xml; using Microsoft.CodeAnalysis; namespace YamlDotNet.Analyzers.StaticGenerator @@ -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(); } } diff --git a/YamlDotNet.Core7AoTCompileTest/Program.cs b/YamlDotNet.Core7AoTCompileTest/Program.cs index d61bf5134..7b54f95da 100644 --- a/YamlDotNet.Core7AoTCompileTest/Program.cs +++ b/YamlDotNet.Core7AoTCompileTest/Program.cs @@ -48,6 +48,9 @@ MyUInt64: {ulong.MaxValue} Inner: Text: yay +InnerArray: + - Text: hello + - Text: world MyArray: myArray: - 1 @@ -57,8 +60,8 @@ x: y a: b MyList: - - a - - b +- a +- b "; var input = new StringReader(yaml); @@ -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); @@ -120,6 +127,19 @@ var output = serializer.Serialize(x); Console.WriteLine(output); +yaml = @"- myArray: + - 1 + - 2 +- myArray: + - 3 + - 4 +"; + +var o = deserializer.Deserialize(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 { @@ -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? MyDictionary { get; set; } public List? MyList { get; set; }