fix(codegen): Creates multiple steps for serialization source generator (#628)

Roslyn Source generators are not supposed to access I/O. To get around this we have to use `AdditionalFiles` to give the analyzer access to read/load the schema files.
To write the schema files we have to use a separate program altogether.

- [X] Adds SerializationSchemaGenerator
- [X] Splits out the SerializationGenerator code
This commit is contained in:
Kamron Batman 2021-05-31 11:54:59 -07:00 committed by GitHub
parent f2d44e0283
commit b6779a7c09
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 641 additions and 297 deletions

View file

@ -14,11 +14,10 @@
*************************************************************************/
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using SerializableMigration;
namespace SerializationGenerator
{
@ -27,12 +26,6 @@ namespace SerializationGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
context.RegisterForPostInitialization(i =>
{
SerializerSyntaxReceiver.AttributeTypes.Add("Server.SerializableAttribute");
SerializerSyntaxReceiver.AttributeTypes.Add("Server.SerializableFieldAttribute");
});
context.RegisterForSyntaxNotifications(() => new SerializerSyntaxReceiver());
}
@ -43,29 +36,28 @@ namespace SerializationGenerator
return;
}
var migrationPath = SerializableMigration.GetMigrationPath(context);
var jsonOptions = SerializableMigration.GetJsonSerializerOptions(context.Compilation);
var jsonOptions = SerializableMigrationSchema.GetJsonSerializerOptions();
// List of types that _will_ become ISerializable
var serializableList = receiver
.ClassAndFields
.Select(g => g.Key)
.Where(t => t.WillBeSerializable(context))
.ToImmutableArray();
var serializableList = receiver.SerializableList;
foreach (var kvp in receiver.ClassAndFields)
foreach (var (classSymbol, (serializableAttr, fieldsList)) in receiver.ClassAndFields)
{
string classSource = SerializableEntityGeneration.GenerateSerializationPartialClass(
kvp.Key,
kvp.Value.ToImmutableArray(),
context,
migrationPath,
if (serializableAttr == null)
{
continue;
}
string classSource = context.GenerateSerializationPartialClass(
classSymbol,
serializableAttr,
fieldsList.ToImmutableArray(),
jsonOptions,
serializableList
);
if (classSource != null)
{
context.AddSource($"{kvp.Key.ToDisplayString()}.Serialization.cs", SourceText.From(classSource, Encoding.UTF8));
context.AddSource($"{classSymbol.ToDisplayString()}.Serialization.cs", SourceText.From(classSource, Encoding.UTF8));
}
}
}