fix: Fixes codegenning nested classes (#738)
This commit is contained in:
parent
408a343e0c
commit
862e868cf0
6 changed files with 107 additions and 63 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue