Exemplo n.º 1
0
        private static void GenerateRegular(Workspace ws, string outFolder, IJsonGenerator jsonGen)
        {
            using var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(RegularArchiveName);
            Debug.Assert(resource != null);

            using var reader = TarReader.Open(resource);

            while (reader.MoveToNextEntry())
            {
                if (reader.Entry.IsDirectory)
                {
                    continue;
                }

                var path = Path.Combine(outFolder, reader.Entry.Key);
                Directory.CreateDirectory(Path.GetDirectoryName(path));

                using var outFile = File.OpenWrite(path);
                using var entry   = reader.OpenEntryStream();

                if (reader.Entry.Key == "index.html")
                {
                    ProcessHtmlEntrypoint(entry, outFile, false);
                }
                else
                {
                    entry.CopyTo(outFile);
                }
            }

            using var dataOut = File.OpenWrite(Path.Combine(outFolder, "js/data.js"));
            jsonGen.Generate(ws, dataOut);
        }
Exemplo n.º 2
0
        private static void GenerateSingleFile(Workspace ws, string outFolder, IJsonGenerator jsonGen)
        {
            using var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(SingleFileName);
            Debug.Assert(resource != null);

            using var htmlOut = File.OpenWrite(Path.Combine(outFolder, "index.html"));

            string json;

            using (var jsonMem = new MemoryStream())
                using (var reader = new StreamReader(jsonMem))
                {
                    jsonGen.Generate(ws, jsonMem);

                    jsonMem.Position = 0;

                    json = reader.ReadToEnd();
                }

            ProcessHtmlEntrypoint(resource, htmlOut, true, json);
        }
Exemplo n.º 3
0
        public void Generate(GeneratorExecutionContext context)
        {
            // retreive the populated receiver
            if (context.SyntaxReceiver is not JsonSyntaxReceiver receiver)
            {
                return;
            }

            Compilation compilation = context.Compilation;

            compilation = GenerateFromResource("GenerationOutputFolderAttribute.cs", context, compilation, null);

            GenerationFolder = GetGenerationOutputFolder(receiver.CandidateAttributes, compilation);
            if (!Directory.Exists(GenerationFolder))
            {
                GenerationFolder = null;
            }
            if (!string.IsNullOrEmpty(GenerationFolder))
            {
                if (File.Exists(Path.Combine(GenerationFolder, "output.log")))
                {
                    File.Delete(Path.Combine(GenerationFolder, "output.log"));
                }
            }

            compilation = GenerateFromResource("InvalidJsonException.cs", context, compilation, GenerationFolder);
            compilation = GenerateFromResource("JsonArrayAttribute.cs", context, compilation, GenerationFolder);
            compilation = GenerateFromResource("JsonValueAttribute.cs", context, compilation, GenerationFolder);
            compilation = GenerateFromResource("JsonAttribute.cs", context, compilation, GenerationFolder);
            compilation = GenerateFromResource("JsonIgnoreNullAttribute.cs", context, compilation, GenerationFolder);
            compilation = GenerateFromResource("JsonDictionaryAttribute.cs", context, compilation, GenerationFolder);
            compilation = GenerateFromResource("JsonIgnoreAttribute.cs", context, compilation, GenerationFolder);
            compilation = GenerateFromResource("JsonOptionalAttribute.cs", context, compilation, GenerationFolder);
            compilation = GenerateFromResource("JsonListAttribute.cs", context, compilation, GenerationFolder);
            compilation = GenerateFromResource("JsonNameAttribute.cs", context, compilation, GenerationFolder);
            compilation = GenerateFromResource("JsonSpanExtensions.cs", context, compilation, GenerationFolder);
            compilation = GenerateFromResource("ICustomConverter.cs", context, compilation, GenerationFolder);
            compilation = GenerateFromResource("CustomConverterAttribute.cs", context, compilation, GenerationFolder);

            var classBuilder = new CodeBuilder();

            classBuilder.Append(@"
using System;
using System.Text;
using System.Collections.Generic;


namespace JsonSrcGen
{
#nullable enable
    public class JsonConverter
    {
        [ThreadStatic]
        JsonStringBuilder? Builder;
");
            var classes = GetJsonClassInfo(receiver.Targets, compilation);

            var generators = new IJsonGenerator[]
            {
                new DateTimeGenerator(),
                new DateTimeOffsetGenerator(),
                new NullableDateTimeGenerator(),
                new NullalbeDateTimeOffsetGenerator(),
                new GuidGenerator(),
                new NullableGuidGenerator(),
                new AppendReadGenerator("Int32"),
                new AppendReadGenerator("UInt32"),
                new AppendReadGenerator("UInt64"),
                new AppendReadGenerator("Int64"),
                new AppendReadGenerator("Int16"),
                new AppendReadGenerator("UInt16"),
                new AppendReadGenerator("Byte"),
                new AppendReadGenerator("Double"),
                new AppendReadGenerator("Decimal"),
                new AppendReadGenerator("Single")
                {
                    ReadType = "Double"
                },
                new NullableAppendReadGenerator("UInt64?"),
                new NullableAppendReadGenerator("UInt32?"),
                new NullableAppendReadGenerator("UInt16?")
                {
                    ReadType = "UInt32?"
                },
                new NullableAppendReadGenerator("Byte?")
                {
                    ReadType = "UInt32?"
                },
                new NullableAppendReadGenerator("Int32?"),
                new NullableAppendReadGenerator("Int16?")
                {
                    ReadType = "Int32?"
                },
                new NullableAppendReadGenerator("Int64?"),
                new NullableAppendReadGenerator("Double?"),
                new NullableAppendReadGenerator("Decimal?"),
                new NullableAppendReadGenerator("Single?")
                {
                    ReadType = "Double?"
                },
                new BoolGenerator(),
                new NullableBoolGenerator(),
                new StringGenerator(),
                new ListGenerator(type => GetGeneratorForType(type)),
                new ArrayGenerator(type => GetGeneratorForType(type), new CodeBuilder()),
                new DictionaryGenerator(type => GetGeneratorForType(type)),
                new CharGenerator()
            };

            _generators = new Dictionary <string, IJsonGenerator>();
            foreach (var generator in generators)
            {
                _generators.Add(generator.GeneratorId, generator);
            }

            foreach (var customClass in classes)
            {
                _generators.Add(customClass.FullName, new CustomTypeGenerator(customClass.FullName));
            }

            var customTypeConverters = GetCustomTypeConverters(receiver.Targets, compilation);

            foreach (var customTypeConverter in customTypeConverters)
            {
                LogLine($"Adding customTypeConverter GeneratorId: {customTypeConverter.GeneratorId}");

                if (_generators.ContainsKey(customTypeConverter.GeneratorId))
                {
                    LogLine($"overriding existing");
                    _generators[customTypeConverter.GeneratorId] = customTypeConverter;
                }
                else
                {
                    LogLine($"new generator");
                    _generators.Add(customTypeConverter.GeneratorId, customTypeConverter);
                }
            }

            var toJsonGenerator   = new ToJsonGenerator(GetGeneratorForType);
            var fromJsonGenerator = new FromJsonGenerator(GetGeneratorForType);

            var listTypes = GetListAttributesInfo(receiver.CandidateAttributes, compilation);

            foreach (var listType in listTypes)
            {
                toJsonGenerator.GenerateList(listType, classBuilder);
                fromJsonGenerator.GenerateList(listType, classBuilder);
            }

            var arrayTypes = GetArrayAttributesInfo(receiver.CandidateAttributes, compilation);

            foreach (var arrayType in arrayTypes)
            {
                toJsonGenerator.GenerateArray(arrayType, classBuilder);
                fromJsonGenerator.GenerateArray(arrayType, classBuilder);
            }

            var dictionaryTypes = GetDictionaryAttributesInfo(receiver.CandidateAttributes, compilation);

            foreach (var dictionaryType in dictionaryTypes)
            {
                toJsonGenerator.GenerateDictionary(dictionaryType.Item1, dictionaryType.Item2, classBuilder);
                fromJsonGenerator.GenerateDictionary(dictionaryType.Item1, dictionaryType.Item2, classBuilder);
            }

            //generate to string classes
            foreach (var jsonClass in classes)
            {
                toJsonGenerator.Generate(jsonClass, classBuilder);
                fromJsonGenerator.Generate(jsonClass, classBuilder);
            }

            var valueTypes = GetValueAttributesInfo(receiver.CandidateAttributes, compilation);

            foreach (var valueType in valueTypes)
            {
                toJsonGenerator.GenerateValue(valueType, classBuilder);
                fromJsonGenerator.GenerateValue(valueType, classBuilder);
            }

            foreach (var generator in _generators)
            {
                var codeBuilder = generator.Value.ClassLevelBuilder;
                if (codeBuilder != null)
                {
                    classBuilder.Append(codeBuilder.ToString());
                }
            }

            classBuilder.AppendLine(1, "}");
            classBuilder.AppendLine(0, "}");
            classBuilder.AppendLine(0, "#nullable restore");


            if (GenerationFolder != null)
            {
                try
                {
                    File.WriteAllText(Path.Combine(GenerationFolder, "Generated.cs"), classBuilder.ToString());
                }
                catch (DirectoryNotFoundException)
                {
                    //Don't fail the generation as this makes the CI Unit Tests fail
                }
            }

            context.AddSource("JsonConverter", SourceText.From(classBuilder.ToString(), Encoding.UTF8));
        }
Exemplo n.º 4
0
        public void Generate(GeneratorExecutionContext context)
        {
            // retreive the populated receiver
            if (!(context.SyntaxReceiver is SyntaxReceiver receiver))
            {
                return;
            }

            Compilation compilation = context.Compilation;

            compilation = GenerateFromResource("GenerationOutputFolderAttribute.cs", context, compilation, null);

            var generationFolder = GetGenerationOutputFolder(receiver.CandidateAttributes, compilation);

            compilation = GenerateFromResource("InvalidJsonException.cs", context, compilation, generationFolder);
            compilation = GenerateFromResource("JsonArrayAttribute.cs", context, compilation, generationFolder);
            compilation = GenerateFromResource("JsonAttribute.cs", context, compilation, generationFolder);
            compilation = GenerateFromResource("JsonDictionaryAttribute.cs", context, compilation, generationFolder);
            compilation = GenerateFromResource("JsonIgnoreAttribute.cs", context, compilation, generationFolder);
            compilation = GenerateFromResource("JsonListAttribute.cs", context, compilation, generationFolder);
            compilation = GenerateFromResource("JsonNameAttribute.cs", context, compilation, generationFolder);
            compilation = GenerateFromResource("JsonSpanExtensions.cs", context, compilation, generationFolder);
            compilation = GenerateFromResource("StringBuilderExtension.cs", context, compilation, generationFolder);

            var classBuilder = new CodeBuilder();

            classBuilder.Append(@"
using System;
using System.Text;
using System.Collections.Generic;

namespace JsonSrcGen
{
    public class JsonSrcGenConvert
    {
        [ThreadStatic]
        StringBuilder Builder;
");

            var classes = GetJsonClassInfo(receiver.CandidateClasses, compilation);

            var generators = new IJsonGenerator[]
            {
                new DateTimeGenerator(),
                new NullableDateTimeGenerator(),
                new GuidGenerator(),
                new NullableGuidGenerator(),
                new AppendReadGenerator("Int32"),
                new AppendReadGenerator("UInt32"),
                new AppendReadGenerator("UInt64"),
                new AppendReadGenerator("Int64"),
                new AppendReadGenerator("Int16"),
                new AppendReadGenerator("UInt16"),
                new AppendReadGenerator("Byte"),
                new AppendReadGenerator("Double"),
                new AppendReadGenerator("Single")
                {
                    ReadType = "Double"
                },
                new NullableAppendReadGenerator("UInt64?"),
                new NullableAppendReadGenerator("UInt32?"),
                new NullableAppendReadGenerator("UInt16?")
                {
                    ReadType = "UInt32?"
                },
                new NullableAppendReadGenerator("Byte?")
                {
                    ReadType = "UInt32?"
                },
                new NullableAppendReadGenerator("Int32?"),
                new NullableAppendReadGenerator("Int16?")
                {
                    ReadType = "Int32?"
                },
                new NullableAppendReadGenerator("Int64?"),
                new NullableAppendReadGenerator("Double?"),
                new NullableAppendReadGenerator("Single?")
                {
                    ReadType = "Double?"
                },
                new BoolGenerator(),
                new NullableBoolGenerator(),
                new StringGenerator(),
                new ListGenerator(type => GetGeneratorForType(type)),
                new ArrayGenerator(type => GetGeneratorForType(type), new CodeBuilder()),
                new CustomTypeGenerator(),
                new DictionaryGenerator(type => GetGeneratorForType(type))
            };

            _generators = new Dictionary <string, IJsonGenerator>();
            foreach (var generator in generators)
            {
                _generators.Add(generator.TypeName, generator);
            }

            var toJsonGenerator   = new ToJsonGenerator(GetGeneratorForType);
            var fromJsonGenerator = new FromJsonGenerator(GetGeneratorForType);

            var listTypes = GetListAttributesInfo(receiver.CandidateAttributes, compilation);

            foreach (var listType in listTypes)
            {
                toJsonGenerator.GenerateList(listType, classBuilder);
                fromJsonGenerator.GenerateList(listType, classBuilder);
            }

            var arrayTypes = GetArrayAttributesInfo(receiver.CandidateAttributes, compilation);

            foreach (var arrayType in arrayTypes)
            {
                toJsonGenerator.GenerateArray(arrayType, classBuilder);
                fromJsonGenerator.GenerateArray(arrayType, classBuilder);
            }

            var dictionaryTypes = GetDictionaryAttributesInfo(receiver.CandidateAttributes, compilation);

            foreach (var dictionaryType in dictionaryTypes)
            {
                toJsonGenerator.GenerateDictionary(dictionaryType.Item1, dictionaryType.Item2, classBuilder);
                fromJsonGenerator.GenerateDictionary(dictionaryType.Item1, dictionaryType.Item2, classBuilder);
            }

            foreach (var jsonClass in classes)
            {
                toJsonGenerator.Generate(jsonClass, classBuilder);
                fromJsonGenerator.Generate(jsonClass, classBuilder);
            }

            foreach (var generator in _generators)
            {
                var codeBuilder = generator.Value.ClassLevelBuilder;
                if (codeBuilder != null)
                {
                    classBuilder.Append(codeBuilder.ToString());
                }
            }

            classBuilder.AppendLine(1, "}");
            classBuilder.AppendLine(0, "}");

            if (generationFolder != null)
            {
                try
                {
                    File.WriteAllText(Path.Combine(generationFolder, "Generated.cs"), classBuilder.ToString());
                }
                catch (DirectoryNotFoundException)
                {
                    //Don't fail the generation as this makes the CI Unit Tests fail
                }
            }

            context.AddSource("JsonSrcGenConvert", SourceText.From(classBuilder.ToString(), Encoding.UTF8));
        }