fix(codegen): Adds string intern, encoded int, enum and legacy version support (#613)

- [X] Adds Enum migration rule
- [X] Adds legacy version (writing full int for version field)
- [X] Adds encoded int attribute
- [X] Adds intern string attribute
- [X] Fixes missing base deserialize/serialize
This commit is contained in:
Kamron Batman 2021-05-24 01:01:56 -07:00 committed by GitHub
parent 7084c6c24f
commit ca5a06e9a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 182 additions and 43 deletions

View file

@ -0,0 +1,69 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: EnumMigrationRule.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 *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
using System.Collections.Immutable;
using System.Text;
using Microsoft.CodeAnalysis;
namespace SerializationGenerator
{
public class EnumMigrationRule : ISerializableMigrationRule
{
public string RuleName => nameof(EnumMigrationRule);
public bool GenerateRuleState(
Compilation compilation,
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
out string[] ruleArguments
)
{
if (symbol is not ITypeSymbol typeSymbol || !typeSymbol.IsEnum())
{
ruleArguments = null;
return false;
}
ruleArguments = Array.Empty<string>();
return true;
}
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(EnumMigrationRule);
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
}
source.AppendLine($"{indent}{property.Name} = reader.ReadEnum<{property.Type}>();");
}
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(EnumMigrationRule);
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
}
source.AppendLine($"{indent}{property.Name} = reader.WriteEnum<{property.Type}>({property.Name});");
}
}
}

View file

@ -63,14 +63,16 @@ namespace SerializationGenerator
return false;
}
if (typeSymbol.SpecialType == SpecialType.System_DateTime && attributes.Any(a => a.IsDeltaDateTime(compilation)))
ruleArguments = typeSymbol.SpecialType switch
{
ruleArguments = new[] { "DeltaTime" };
}
else
{
ruleArguments = Array.Empty<string>();
}
SpecialType.System_Int32 when attributes.Any(a => a.IsEncodedInt(compilation)) =>
new[] { "EncodedInt" },
SpecialType.System_DateTime when attributes.Any(a => a.IsDeltaDateTime(compilation)) =>
new[] { "DeltaTime" },
SpecialType.System_String when attributes.Any(a => a.IsInternString(compilation)) =>
new[] { "InternString" },
_ => Array.Empty<string>()
};
return true;
}
@ -85,11 +87,10 @@ namespace SerializationGenerator
}
var propertyName = property.Name;
string readMethod;
const string ipAddress = SerializableEntityGeneration.IPADDRESS_CLASS;
readMethod = property.Type switch
var readMethod = property.Type switch
{
"bool" => "ReadBool",
"sbyte" => "ReadSByte",
@ -100,7 +101,7 @@ namespace SerializationGenerator
"ushort" => "ReadUShort",
"uint" => "ReadUInt",
"ulong" => "ReadULong",
"float" => "ReadFloat",
"float" => "ReadFloat",
"double" => "ReadDouble",
"string" => "ReadString",
"decimal" => "ReadDecimal",
@ -111,7 +112,11 @@ namespace SerializationGenerator
"ReadDateTime"
};
source.AppendLine($"{indent}{propertyName} = reader.{readMethod}();");
var readArgument = readMethod == "ReadString" &&
property.RuleArguments.Length >= 1 &&
property.RuleArguments[0] == "InternString" ? "true" : "";
source.AppendLine($"{indent}{propertyName} = reader.{readMethod}({readArgument});");
}
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)

View file

@ -28,14 +28,15 @@ namespace SerializationGenerator
{
var rules = new ISerializableMigrationRule[]
{
new EnumMigrationRule(),
new ListMigrationRule(),
new ArrayMigrationRule(),
new HashSetMigrationRule(),
new KeyValuePairMigrationRule(),
new ListMigrationRule(),
new PrimitiveTypeMigrationRule(),
new PrimitiveUOTypeMigrationRule(),
new SerializableInterfaceMigrationRule(),
new SerializationMethodSignatureMigrationRule()
new SerializationMethodSignatureMigrationRule(),
};
foreach (var rule in rules)