fix(codegen): Fixes various code gen issues. Adds better embedded serialization support (#688)
* Adds save flag support (see `ElvenGlasses` for an example) * Updates AOSAttributes so they are code genned * Fixes embedded object support by adding an `IRawSerializable` * Fixes various inconsistencies in serializing with codegen
This commit is contained in:
parent
69af652a18
commit
2c8097f707
54 changed files with 787 additions and 507 deletions
|
|
@ -36,7 +36,8 @@ namespace SerializableMigration
|
|||
void GenerateDeserializationMethod(
|
||||
StringBuilder source,
|
||||
string indent,
|
||||
SerializableProperty property
|
||||
SerializableProperty property,
|
||||
string? parentReference
|
||||
);
|
||||
|
||||
void GenerateSerializationMethod(
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ namespace SerializableMigration
|
|||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var length = serializableArrayType.RuleArguments.Length;
|
||||
|
|
@ -60,7 +61,7 @@ namespace SerializableMigration
|
|||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
|
|
@ -74,7 +75,7 @@ namespace SerializableMigration
|
|||
Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2);
|
||||
|
||||
var propertyIndex = $"{property.Name}Index";
|
||||
source.AppendLine($"{indent}{property.Name} = new {ruleArguments[0]}[reader.ReadInt()];");
|
||||
source.AppendLine($"{indent}{property.Name} = new {ruleArguments[0]}[reader.ReadEncodedInt()];");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {property.Name}.Length; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
||||
|
|
@ -86,7 +87,7 @@ namespace SerializableMigration
|
|||
RuleArguments = arrayElementRuleArguments
|
||||
};
|
||||
|
||||
arrayElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableArrayElement);
|
||||
arrayElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableArrayElement, parentReference);
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
}
|
||||
|
|
@ -110,7 +111,7 @@ namespace SerializableMigration
|
|||
var propertyIndex = $"{propertyVarPrefix}Index";
|
||||
var propertyLength = $"{propertyVarPrefix}Length";
|
||||
source.AppendLine($"{indent}var {propertyLength} = {property.Name}?.Length ?? 0;");
|
||||
source.AppendLine($"{indent}writer.Write({propertyLength});");
|
||||
source.AppendLine($"{indent}writer.WriteEncodedInt({propertyLength});");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyLength}; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace SerializableMigration
|
|||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ namespace SerializableMigration
|
|||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var extraOptions = "";
|
||||
|
|
@ -71,7 +72,7 @@ namespace SerializableMigration
|
|||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
|
|
@ -95,7 +96,7 @@ namespace SerializableMigration
|
|||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};");
|
||||
source.AppendLine($"{indent}var {propertyCount} = reader.ReadInt();");
|
||||
source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
|
||||
source.AppendLine($"{indent}{property.Name} = new System.Collections.Generic.HashSet<{ruleArguments[argumentsOffset]}>({propertyCount});");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; i < {propertyCount}; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
|
@ -108,7 +109,7 @@ namespace SerializableMigration
|
|||
RuleArguments = setElementRuleArguments
|
||||
};
|
||||
|
||||
setElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableSetElement);
|
||||
setElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableSetElement, parentReference);
|
||||
source.AppendLine($"{indent} {property.Name}.Add({propertyEntry});");
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
|
|
@ -142,7 +143,7 @@ namespace SerializableMigration
|
|||
source.AppendLine($"{indent}{property.Name}?.Tidy();");
|
||||
}
|
||||
source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
|
||||
source.AppendLine($"{indent}writer.Write({propertyCount});");
|
||||
source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
|
||||
source.AppendLine($"{indent}if ({propertyCount} > 0)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)");
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ namespace SerializableMigration
|
|||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var valueSerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
|
|
@ -62,7 +63,8 @@ namespace SerializableMigration
|
|||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
// Key
|
||||
|
|
@ -81,7 +83,7 @@ namespace SerializableMigration
|
|||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
|
|
@ -107,7 +109,8 @@ namespace SerializableMigration
|
|||
keyRule.GenerateDeserializationMethod(
|
||||
source,
|
||||
indent,
|
||||
serializableKeyProperty
|
||||
serializableKeyProperty,
|
||||
parentReference
|
||||
);
|
||||
|
||||
var valueIndex = 3 + keyRuleArguments.Length;
|
||||
|
|
@ -127,7 +130,8 @@ namespace SerializableMigration
|
|||
keyRule.GenerateDeserializationMethod(
|
||||
source,
|
||||
indent,
|
||||
serializableValueProperty
|
||||
serializableValueProperty,
|
||||
parentReference
|
||||
);
|
||||
|
||||
source.AppendLine(
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ namespace SerializableMigration
|
|||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var extraOptions = "";
|
||||
|
|
@ -71,7 +72,7 @@ namespace SerializableMigration
|
|||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
|
|
@ -96,7 +97,7 @@ namespace SerializableMigration
|
|||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};");
|
||||
source.AppendLine($"{indent}var {propertyCount} = reader.ReadInt();");
|
||||
source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
|
||||
source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.List<{ruleArguments[argumentsOffset]}>({propertyCount});");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
|
@ -109,7 +110,7 @@ namespace SerializableMigration
|
|||
RuleArguments = listElementRuleArguments
|
||||
};
|
||||
|
||||
listElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableListElement);
|
||||
listElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableListElement, parentReference);
|
||||
source.AppendLine($"{indent} {propertyName}.Add({propertyEntry});");
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
|
|
@ -143,7 +144,7 @@ namespace SerializableMigration
|
|||
source.AppendLine($"{indent}{property.Name}?.Tidy();");
|
||||
}
|
||||
source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
|
||||
source.AppendLine($"{indent}writer.Write({propertyCount});");
|
||||
source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
|
||||
source.AppendLine($"{indent}if ({propertyCount} > 0)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)");
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ namespace SerializableMigration
|
|||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace SerializableMigration
|
|||
return ruleArguments != null;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* ModernUO *
|
||||
* Copyright 2019-2021 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: EmbeddedSerializableMigrationRule.cs *
|
||||
* File: RawSerializableMigrationRule.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
|
|
@ -21,9 +21,9 @@ using SerializationGenerator;
|
|||
|
||||
namespace SerializableMigration
|
||||
{
|
||||
public class EmbeddedSerializableMigrationRule : ISerializableMigrationRule
|
||||
public class RawSerializableMigrationRule : ISerializableMigrationRule
|
||||
{
|
||||
public string RuleName => nameof(EmbeddedSerializableMigrationRule);
|
||||
public string RuleName => nameof(RawSerializableMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
|
|
@ -35,13 +35,13 @@ namespace SerializableMigration
|
|||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol)
|
||||
if (symbol is not ITypeSymbol typeSymbol)
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!embeddedSerializableTypes.Contains(namedTypeSymbol))
|
||||
if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes))
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
|
|
@ -51,7 +51,7 @@ namespace SerializableMigration
|
|||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
|
|
@ -61,7 +61,7 @@ namespace SerializableMigration
|
|||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName} = new {property.Type}(this);");
|
||||
source.AppendLine($"{indent}{propertyName} = new {property.Type}({parentReference ?? "this"});");
|
||||
source.AppendLine($"{indent}{propertyName}.Deserialize(reader);");
|
||||
}
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ namespace SerializableMigration
|
|||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ namespace SerializableMigration
|
|||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace SerializableMigration
|
|||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace SerializableMigration
|
||||
{
|
||||
public class SerializableFieldFlagComparer : IComparer<(IMethodSymbol, int)>
|
||||
{
|
||||
public int Compare((IMethodSymbol, int) x, (IMethodSymbol, int) y)
|
||||
{
|
||||
var (methodSymbolX, orderX) = x;
|
||||
var (methodSymbolY, orderY) = y;
|
||||
|
||||
if (ReferenceEquals(methodSymbolX, methodSymbolY))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(null, methodSymbolY))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(null, methodSymbolX))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return orderX.CompareTo(orderY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -38,7 +38,7 @@ namespace SerializableMigration
|
|||
new PrimitiveUOTypeMigrationRule(),
|
||||
new SerializableInterfaceMigrationRule(),
|
||||
new SerializationMethodSignatureMigrationRule(),
|
||||
new EmbeddedSerializableMigrationRule(),
|
||||
new RawSerializableMigrationRule(),
|
||||
new TimerMigrationRule()
|
||||
};
|
||||
|
||||
|
|
@ -55,7 +55,8 @@ namespace SerializableMigration
|
|||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol = default
|
||||
ISymbol? parentSymbol,
|
||||
IMethodSymbol? serializablePropertyFlagGetter
|
||||
)
|
||||
{
|
||||
string propertyName;
|
||||
|
|
@ -84,7 +85,8 @@ namespace SerializableMigration
|
|||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol
|
||||
parentSymbol,
|
||||
serializablePropertyFlagGetter
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +98,8 @@ namespace SerializableMigration
|
|||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol = default
|
||||
ISymbol? parentSymbol,
|
||||
IMethodSymbol? serializablePropertyFlagGetter
|
||||
)
|
||||
{
|
||||
foreach (var rule in Rules.Values)
|
||||
|
|
@ -116,6 +119,7 @@ namespace SerializableMigration
|
|||
Name = propertyName,
|
||||
Type = propertyType.ToDisplayString(),
|
||||
Order = order,
|
||||
UsesSaveFlag = serializablePropertyFlagGetter != null ? true : null,
|
||||
Rule = rule.RuleName,
|
||||
RuleArguments = ruleArguments
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ namespace SerializableMigration
|
|||
[JsonPropertyName("type")]
|
||||
public string Type { get; init; }
|
||||
|
||||
[JsonPropertyName("usesSaveFlag")]
|
||||
public bool? UsesSaveFlag { get; init; }
|
||||
|
||||
[JsonPropertyName("rule")]
|
||||
public string Rule { get; init; }
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue