Ejemplo n.º 1
0
            public static ImmutableDictionary <TypeName, JsonType> GetJsonTypes(ImmutableArray <SyntaxTree> nodes, Compilation compilation)
            {
                var walker = new JsonAttributeScanningWalker(compilation);

                foreach (var tinyType in TinyTypeScanningWalker.GetTinyTypes(compilation, nodes))
                {
                    walker.VisitTinyType(tinyType);
                }

                foreach (var node in nodes)
                {
                    walker.Visit(node.GetRoot());
                }

                return(walker.JsonTypes.ToImmutable());
            }
Ejemplo n.º 2
0
        public static string Generate(string outputPath, ImmutableArray <SyntaxTree> syntaxTrees, CSharpCompilation compilation)
        {
            using (var outputFile = new FileStream(Path.Combine(outputPath, "Converters.cs"), FileMode.Create, FileAccess.Write))
                using (var writer = new StreamWriter(outputFile, leaveOpen: true))
                {
                    writer.WriteLine("using System;");
                    writer.WriteLine("using System.Text.Json;");
                    writer.WriteLine("using System.Text.Json.Serialization;");
                    writer.WriteLine("using System.Collections.Immutable;");

                    writer.WriteLine();

                    writer.WriteLine("#pragma warning disable CA1801 // Unused parameter");

                    writer.WriteLine();

                    writer.WriteLine("namespace DNSMadeEasy.Json");
                    writer.WriteLine("{");

                    writer.WriteLine("partial class CustomJsonConverterFactory");
                    writer.WriteLine("{");

                    var jsonTypes      = JsonAttributeScanningWalker.GetJsonTypes(syntaxTrees, compilation);
                    var anonymousTypes = JsonAnonymousTypeWithValueScanningWalker.GetAnonymousTypes(syntaxTrees, compilation);

                    writer.WriteLine($"private static ImmutableDictionary<Type, JsonConverter> CreateConverters()");
                    writer.WriteLine("{");
                    writer.WriteLine("var builder = ImmutableDictionary.CreateBuilder<Type, JsonConverter>();");
                    foreach (var type in jsonTypes.Values.Where(t => t.ConverterName != null))
                    {
                        writer.WriteLine($"builder.Add(typeof({type.Type}), new {type.ConverterName}());");
                    }

                    foreach (var(type, _, prototype) in anonymousTypes)
                    {
                        writer.WriteLine("{");
                        writer.WriteLine($@"var type = GetAnonymousType(false ? {prototype} : null);");
                        writer.WriteLine($"builder.Add(type, new ValueConverter(type));");
                        writer.WriteLine("}");
                    }

                    writer.WriteLine("return builder.ToImmutable();");
                    writer.WriteLine("}");

                    foreach (var type in jsonTypes.Values.Where(t => t.ConverterName != null))
                    {
                        writer.WriteLine();
                        writer.WriteLine($"private sealed class {type.ConverterName} : JsonConverter<{type.Type}>");
                        writer.WriteLine("{");

                        writer.WriteLine($"public override {type.Type} Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => ReadInternal(ref reader, options);");
                        writer.WriteLine($"public override void Write(Utf8JsonWriter writer, {type.Type} value, JsonSerializerOptions options) => WriteInternal(writer, value, options);");

                        writer.WriteLine($"internal static {type.Type} ReadInternal(ref Utf8JsonReader reader, JsonSerializerOptions options)");
                        writer.WriteLine("{");
                        if (type.ConstructionMember is ConstructorDeclarationSyntax)
                        {
                            GenerateConstructorReader(type, writer, jsonTypes, compilation);
                        }
                        else if (type.ConstructionMember is MethodDeclarationSyntax)
                        {
                            GenerateParseReader(type, writer, jsonTypes, compilation);
                        }
                        else if (type.TinyType != null)
                        {
                            GenerateTinyTypeReader(type, writer, jsonTypes);
                        }
                        else if (type.ConstructionMember != null || type.TinyType != null)
                        {
                            throw new InvalidOperationException("Unknown declaration type");
                        }

                        writer.WriteLine("}");
                        writer.WriteLine();
                        writer.WriteLine($"internal static void WriteInternal(Utf8JsonWriter writer, {type.Type} value, JsonSerializerOptions options)");
                        writer.WriteLine("{");

                        if (type.ConstructionMember is ConstructorDeclarationSyntax)
                        {
                            writer.WriteLine("throw new NotImplementedException();");                     //GenerateConstructorWriter(type, writer, jsonTypes);
                        }
                        else if (type.ConstructionMember is MethodDeclarationSyntax)
                        {
                            GenerateParseWriter(type, writer, jsonTypes, compilation);
                        }
                        else if (type.TinyType != null)
                        {
                            GenerateTinyTypeWriter(type, writer, jsonTypes);
                        }
                        else if (type.ConstructionMember != null || type.TinyType != null)
                        {
                            throw new InvalidOperationException("Unknown declaration type");
                        }

                        writer.WriteLine("}");

                        writer.WriteLine("}");
                    }

                    writer.WriteLine($"partial class ValueConverter");
                    writer.WriteLine("{");
                    writer.WriteLine("private static ImmutableDictionary<Type, Action<Utf8JsonWriter, object, JsonSerializerOptions>> CreateDelegates()");
                    writer.WriteLine("{");
                    writer.WriteLine("var builder = ImmutableDictionary.CreateBuilder<Type, Action<Utf8JsonWriter, object, JsonSerializerOptions>>();");
                    foreach (var(type, methodName, prototype) in anonymousTypes)
                    {
                        writer.WriteLine($@"builder.Add(GetAnonymousType(false ? {prototype} : null), {methodName});");
                    }

                    writer.WriteLine("return builder.ToImmutable();");
                    writer.WriteLine("}");

                    foreach (var(type, methodName, prototype) in anonymousTypes)
                    {
                        GenerateAnonymousTypeMethod(type, methodName, prototype, writer, jsonTypes, compilation);
                    }

                    writer.WriteLine("}");

                    writer.WriteLine("}");
                    writer.WriteLine("}");

                    return(outputFile.Name);
                }
        }