fix: Fixes codegenning nested classes (#738)

This commit is contained in:
Kamron Batman 2021-08-27 19:08:04 -07:00 committed by GitHub
parent 408a343e0c
commit 862e868cf0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 107 additions and 63 deletions

View file

@ -168,11 +168,13 @@ namespace SerializationGenerator
? Array.Empty<ITypeSymbol>()
: new ITypeSymbol[] { compilation.GetTypeByMetadataName(SymbolMetadata.RAW_SERIALIZABLE_INTERFACE) };
source.GenerateClassStart(className, " ", interfaces.ToImmutableArray());
var indent = " ";
const string indent = " ";
source.RecursiveGenerateClassStart(classSymbol, interfaces.ToImmutableArray(), ref indent);
indent += " ";
source.GenerateClassField(
indent,
Accessibility.Private,
InstanceModifier.Const,
"int",
@ -223,7 +225,7 @@ namespace SerializationGenerator
if (attrTypeArg.Kind == TypedConstantKind.Primitive && attrTypeArg.Value is string attrStr)
{
source.AppendLine($" {attrStr}");
source.AppendLine($"{indent} {attrStr}");
}
else
{
@ -298,7 +300,7 @@ namespace SerializationGenerator
if (!embedded)
{
// Serial constructor
source.GenerateSerialCtor(compilation, className, isOverride);
source.GenerateSerialCtor(compilation, className, indent, isOverride);
source.AppendLine();
}
@ -309,7 +311,7 @@ namespace SerializationGenerator
var migration = migrations[i];
if (migration.Version < version)
{
source.GenerateMigrationContentStruct(compilation, migration, classSymbol);
source.GenerateMigrationContentStruct(compilation, indent, migration, classSymbol);
source.AppendLine();
}
}
@ -318,6 +320,7 @@ namespace SerializationGenerator
// Serialize Method
source.GenerateSerializeMethod(
compilation,
indent,
isOverride,
encodedVersion,
serializableProperties,
@ -329,6 +332,7 @@ namespace SerializationGenerator
source.GenerateDeserializeMethod(
compilation,
classSymbol,
indent,
isOverride,
version,
encodedVersion,
@ -344,22 +348,23 @@ namespace SerializationGenerator
source.AppendLine();
source.GenerateEnumStart(
"SaveFlag",
" ",
$"{indent} ",
true,
Accessibility.Private
);
source.GenerateEnumValue(" ", true, "None", -1);
source.GenerateEnumValue($"{indent} ", true, "None", -1);
int index = 0;
foreach (var (order, _) in serializableFieldSaveFlags)
{
source.GenerateEnumValue(" ", true, serializableProperties[order].Name, index++);
source.GenerateEnumValue($"{indent} ", true, serializableProperties[order].Name, index++);
}
source.GenerateEnumEnd(" ");
source.GenerateEnumEnd($"{indent} ");
}
source.GenerateClassEnd(" ");
indent = indent.Substring(0, indent.Length - 4);
source.RecursiveGenerateClassEnd(classSymbol, ref indent);
source.GenerateNamespaceEnd();
if (migrationPath != null)
@ -384,5 +389,41 @@ namespace SerializationGenerator
var filePath = Path.Combine(migrationPath, $"{metadata.Type}.v{metadata.Version}.json");
File.WriteAllText(filePath, JsonSerializer.Serialize(metadata, options));
}
private static void RecursiveGenerateClassStart(
this StringBuilder source,
INamedTypeSymbol classSymbol,
ImmutableArray<ITypeSymbol> interfaces,
ref string indent
)
{
var containingSymbolList = new List<INamedTypeSymbol>();
do
{
containingSymbolList.Add(classSymbol);
classSymbol = classSymbol.ContainingSymbol as INamedTypeSymbol;
} while (classSymbol != null);
containingSymbolList.Reverse();
for (var i = 0; i < containingSymbolList.Count; i++)
{
var symbol = containingSymbolList[i];
source.GenerateClassStart(symbol, indent, i == containingSymbolList.Count - 1 ? interfaces : ImmutableArray<ITypeSymbol>.Empty);
indent += " ";
}
}
private static void RecursiveGenerateClassEnd(this StringBuilder source, INamedTypeSymbol classSymbol, ref string indent)
{
do
{
source.GenerateClassEnd(indent);
indent = indent.Substring(0, indent.Length - 4);
classSymbol = classSymbol.ContainingSymbol as INamedTypeSymbol;
} while (classSymbol != null);
}
}
}

View file

@ -28,6 +28,7 @@ namespace SerializationGenerator
this StringBuilder source,
Compilation compilation,
INamedTypeSymbol classSymbol,
string indent,
bool isOverride,
int version,
bool encodedVersion,
@ -40,7 +41,7 @@ namespace SerializationGenerator
var genericReaderInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_READER_INTERFACE);
source.GenerateMethodStart(
" ",
indent,
"Deserialize",
Accessibility.Public,
isOverride,
@ -48,12 +49,12 @@ namespace SerializationGenerator
ImmutableArray.Create<(ITypeSymbol, string)>((genericReaderInterface, "reader"))
);
const string indent = " ";
const string innerIndent = $"{indent} ";
var bodyIndent = $"{indent} ";
var innerIndent = $"{bodyIndent} ";
if (isOverride)
{
source.AppendLine($"{indent}base.Deserialize(reader);");
source.AppendLine($"{bodyIndent}base.Deserialize(reader);");
source.AppendLine();
}
@ -79,7 +80,7 @@ namespace SerializationGenerator
).Where(m => m.Item2 != null).ToList();
// Version
source.AppendLine($"{indent}var version = reader.{(encodedVersion ? "ReadEncodedInt" : "ReadInt")}();");
source.AppendLine($"{bodyIndent}var version = reader.{(encodedVersion ? "ReadEncodedInt" : "ReadInt")}();");
if (version > 0)
{
@ -95,32 +96,32 @@ namespace SerializationGenerator
}
source.AppendLine();
source.AppendLine($"{indent}if (version == {migrationVersion})");
source.AppendLine($"{indent}{{");
source.AppendLine($"{indent} MigrateFrom(new V{migrationVersion}Content(reader, this));");
source.AppendLine($"{indent} {parent}.MarkDirty();");
source.GenerateAfterDeserialization($"{indent} ", afterDeserialization);
source.AppendLine($"{indent} return;");
source.AppendLine($"{indent}}}");
source.AppendLine($"{bodyIndent}if (version == {migrationVersion})");
source.AppendLine($"{bodyIndent}{{");
source.AppendLine($"{bodyIndent} MigrateFrom(new V{migrationVersion}Content(reader, this));");
source.AppendLine($"{bodyIndent} {parent}.MarkDirty();");
source.GenerateAfterDeserialization($"{bodyIndent} ", afterDeserialization);
source.AppendLine($"{bodyIndent} return;");
source.AppendLine($"{bodyIndent}}}");
}
if (nextVersion < version)
{
source.AppendLine();
source.AppendLine($"{indent}if (version < _version)");
source.AppendLine($"{indent}{{");
source.AppendLine($"{indent} Deserialize(reader, version);");
source.AppendLine($"{indent} {parent}.MarkDirty();");
source.GenerateAfterDeserialization($"{indent} ", afterDeserialization);
source.AppendLine($"{indent} return;");
source.AppendLine($"{indent}}}");
source.AppendLine($"{bodyIndent}if (version < _version)");
source.AppendLine($"{bodyIndent}{{");
source.AppendLine($"{bodyIndent} Deserialize(reader, version);");
source.AppendLine($"{bodyIndent} {parent}.MarkDirty();");
source.GenerateAfterDeserialization($"{bodyIndent} ", afterDeserialization);
source.AppendLine($"{bodyIndent} return;");
source.AppendLine($"{bodyIndent}}}");
}
}
if (serializableFieldSaveFlagMethodsDictionary.Count > 0)
{
source.AppendLine();
source.AppendLine($"{indent}var saveFlags = reader.ReadEnum<SaveFlag>();");
source.AppendLine($"{bodyIndent}var saveFlags = reader.ReadEnum<SaveFlag>();");
}
foreach (var property in properties)
@ -137,11 +138,11 @@ namespace SerializationGenerator
// Special case
if (property.Type == "bool")
{
source.AppendLine($"{indent}{property.Name} = (saveFlags & SaveFlag.{property.Name}) != 0;");
source.AppendLine($"{bodyIndent}{property.Name} = (saveFlags & SaveFlag.{property.Name}) != 0;");
}
else
{
source.AppendLine($"{indent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{indent}{{");
source.AppendLine($"{bodyIndent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{bodyIndent}{{");
rule.GenerateDeserializationMethod(
source,
innerIndent,
@ -152,13 +153,13 @@ namespace SerializationGenerator
if (serializableFieldSaveFlagMethods.GetFieldDefaultValue != null)
{
source.AppendLine($"{indent}}}\n{indent}else\n{indent}{{");
source.AppendLine($"{bodyIndent}}}\n{bodyIndent}else\n{bodyIndent}{{");
source.AppendLine(
$"{indent} {property.Name} = {serializableFieldSaveFlagMethods.GetFieldDefaultValue.Name}();"
$"{bodyIndent} {property.Name} = {serializableFieldSaveFlagMethods.GetFieldDefaultValue.Name}();"
);
}
source.AppendLine($"{indent}}}");
source.AppendLine($"{bodyIndent}}}");
}
}
else
@ -166,16 +167,16 @@ namespace SerializationGenerator
source.AppendLine();
rule.GenerateDeserializationMethod(
source,
indent,
bodyIndent,
property,
parentFieldOrProperty?.Name ?? "this"
);
(rule as IPostDeserializeMethod)?.PostDeserializeMethod(source, indent, property, compilation, classSymbol);
(rule as IPostDeserializeMethod)?.PostDeserializeMethod(source, bodyIndent, property, compilation, classSymbol);
}
}
source.GenerateAfterDeserialization($"{indent}", afterDeserialization);
source.GenerateMethodEnd(" ");
source.GenerateAfterDeserialization($"{bodyIndent}", afterDeserialization);
source.GenerateMethodEnd(indent);
}
private static void GenerateAfterDeserialization(

View file

@ -26,13 +26,14 @@ namespace SerializationGenerator
this StringBuilder source,
Compilation compilation,
string className,
string indent,
bool isOverride
)
{
var serialType = (ITypeSymbol)compilation.GetTypeByMetadataName("Server.Serial");
source.GenerateConstructorStart(
" ",
indent,
className,
Accessibility.Public,
new []{ (serialType, "serial") }.ToImmutableArray(),
@ -41,11 +42,11 @@ namespace SerializationGenerator
if (!isOverride)
{
source.AppendLine(@$" Serial = serial;
SetTypeRef(typeof({className}));");
source.AppendLine($"{indent} Serial = serial;");
source.AppendLine($"{indent} SetTypeRef(typeof({className}));");
}
source.GenerateMethodEnd(" ");
source.GenerateMethodEnd(indent);
}
}
}

View file

@ -27,6 +27,7 @@ namespace SerializationGenerator
public static void GenerateSerializeMethod(
this StringBuilder source,
Compilation compilation,
string indent,
bool isOverride,
bool encodedVersion,
ImmutableArray<SerializableProperty> properties,
@ -36,7 +37,7 @@ namespace SerializationGenerator
var genericWriterInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_WRITER_INTERFACE);
source.GenerateMethodStart(
" ",
indent,
"Serialize",
Accessibility.Public,
isOverride,
@ -44,34 +45,34 @@ namespace SerializationGenerator
ImmutableArray.Create<(ITypeSymbol, string)>((genericWriterInterface, "writer"))
);
const string indent = " ";
const string innerIndent = $"{indent} ";
var bodyIndent = $"{indent} ";
var innerIndent = $"{bodyIndent} ";
if (isOverride)
{
source.AppendLine($"{indent}base.Serialize(writer);");
source.AppendLine($"{bodyIndent}base.Serialize(writer);");
source.AppendLine();
}
// Version
source.AppendLine($"{indent}writer.{(encodedVersion ? "WriteEncodedInt" : "Write")}(_version);");
source.AppendLine($"{bodyIndent}writer.{(encodedVersion ? "WriteEncodedInt" : "Write")}(_version);");
// Let's collect the flags
if (serializableFieldSaveFlagMethodsDictionary.Count > 0)
{
source.AppendLine($"\n{indent}var saveFlags = SaveFlag.None;");
source.AppendLine($"\n{bodyIndent}var saveFlags = SaveFlag.None;");
foreach (var (order, saveFlagMethods) in serializableFieldSaveFlagMethodsDictionary)
{
source.AppendLine($"{indent}if ({saveFlagMethods.DetermineFieldShouldSerialize!.Name}())\n{indent}{{");
source.AppendLine($"{bodyIndent}if ({saveFlagMethods.DetermineFieldShouldSerialize!.Name}())\n{bodyIndent}{{");
var propertyName = properties[order].Name;
source.AppendLine($"{innerIndent}saveFlags |= SaveFlag.{propertyName};");
source.AppendLine($"{indent}}}");
source.AppendLine($"{bodyIndent}}}");
}
source.AppendLine($"{indent}writer.WriteEnum(saveFlags);");
source.AppendLine($"{bodyIndent}writer.WriteEnum(saveFlags);");
}
foreach (var property in properties)
@ -81,13 +82,13 @@ namespace SerializationGenerator
// Special case
if (property.Type != "bool")
{
source.AppendLine($"\n{indent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{indent}{{");
source.AppendLine($"\n{bodyIndent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{bodyIndent}{{");
SerializableMigrationRulesEngine.Rules[property.Rule].GenerateSerializationMethod(
source,
innerIndent,
property
);
source.AppendLine($"{indent}}}");
source.AppendLine($"{bodyIndent}}}");
}
}
else
@ -95,13 +96,13 @@ namespace SerializationGenerator
source.AppendLine();
SerializableMigrationRulesEngine.Rules[property.Rule].GenerateSerializationMethod(
source,
indent,
bodyIndent,
property
);
}
}
source.GenerateMethodEnd(" ");
source.GenerateMethodEnd(indent);
}
}
}

View file

@ -26,12 +26,11 @@ namespace SerializationGenerator
public static void GenerateMigrationContentStruct(
this StringBuilder source,
Compilation compilation,
string indent,
SerializableMetadata migration,
INamedTypeSymbol classSymbol
)
{
const string indent = " ";
source.AppendLine($"{indent}ref struct V{migration.Version}Content");
source.AppendLine($"{indent}{{");
var properties = migration.Properties ?? ImmutableArray<SerializableProperty>.Empty;
@ -46,7 +45,7 @@ namespace SerializationGenerator
source.AppendLine($"{indent} internal readonly {type} {serializableProperty.Name};");
}
const string innerIndent = $"{indent} ";
var innerIndent = $"{indent} ";
var usesSaveFlags = properties.Any(p => p.UsesSaveFlag == true);