feat(codegen): Adds AfterDeserialization support (#615)

Added the ability to execute arbitrary code after deserialization.

Example, let's say you want to delete an item after you deserialize it:
```cs
        [AfterDeserialization]
        private void OnAfterDeserialization()
        {
            Delete();
        }
```

Generates this:
```cs
        public override void Deserialize(IGenericReader reader)
        {
            base.Deserialize(reader);

            var version = reader.ReadEncodedInt();

            Timer.DelayCall(OnAfterDeserialization);
        }
```
This commit is contained in:
Kamron Batman 2021-05-24 22:30:13 -07:00 • committed by GitHub
parent c3f414f04f
commit b20f3df595
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 0 deletions

View file

@ -236,6 +236,7 @@ namespace SerializationGenerator
// Deserialize Method // Deserialize Method
source.GenerateDeserializeMethod( source.GenerateDeserializeMethod(
compilation, compilation,
classSymbol,
isOverride, isOverride,
version, version,
encodedVersion, encodedVersion,

View file

@ -15,6 +15,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq;
using System.Text; using System.Text;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
@ -25,6 +26,7 @@ namespace SerializationGenerator
public static void GenerateDeserializeMethod( public static void GenerateDeserializeMethod(
this StringBuilder source, this StringBuilder source,
Compilation compilation, Compilation compilation,
INamedTypeSymbol classSymbol,
bool isOverride, bool isOverride,
int version, int version,
bool encodedVersion, bool encodedVersion,
@ -47,6 +49,7 @@ namespace SerializationGenerator
if (isOverride) if (isOverride)
{ {
source.AppendLine($"{indent}base.Deserialize(reader);"); source.AppendLine($"{indent}base.Deserialize(reader);");
source.AppendLine();
} }
// Version // Version
@ -95,6 +98,29 @@ namespace SerializationGenerator
); );
} }
var afterDeserialization = classSymbol
.GetMembers()
.OfType<IMethodSymbol>()
.FirstOrDefault(
m =>
m.ReturnsVoid &&
m.Parameters.Length == 0 &&
m.GetAttributes()
.OfType<AttributeData>()
.Any(
attr => attr.AttributeClass?.Equals(
compilation.GetTypeByMetadataName(AFTERDESERIALIZATION_ATTRIBUTE),
SymbolEqualityComparer.Default
) ?? false
)
);
if (afterDeserialization != null)
{
source.AppendLine();
source.AppendLine($"{indent}Timer.DelayCall({afterDeserialization.Name});");
}
source.GenerateMethodEnd(); source.GenerateMethodEnd();
} }
} }

View file

@ -26,6 +26,7 @@ namespace SerializationGenerator
public const string IPADDRESS_CLASS = "System.Net.IPAddress"; public const string IPADDRESS_CLASS = "System.Net.IPAddress";
public const string KEYVALUEPAIR_STRUCT = "System.Collections.Generic.KeyValuePair"; public const string KEYVALUEPAIR_STRUCT = "System.Collections.Generic.KeyValuePair";
public const string AFTERDESERIALIZATION_ATTRIBUTE = "Server.AfterDeserializationAttribute";
public const string SERIALIZABLE_ATTRIBUTE = "Server.SerializableAttribute"; public const string SERIALIZABLE_ATTRIBUTE = "Server.SerializableAttribute";
public const string SERIALIZABLE_FIELD_ATTRIBUTE = "Server.SerializableFieldAttribute"; public const string SERIALIZABLE_FIELD_ATTRIBUTE = "Server.SerializableFieldAttribute";
public const string SERIALIZABLE_FIELD_ATTR_ATTRIBUTE = "Server.SerializableFieldAttrAttribute"; public const string SERIALIZABLE_FIELD_ATTR_ATTRIBUTE = "Server.SerializableFieldAttrAttribute";

View file

@ -0,0 +1,28 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: AfterDeserialization.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;
namespace Server
{
/// <summary>
/// Hints to the source generator that this method should be executed after deserializing the object.
/// Method must have no parameters and return void.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class AfterDeserializationAttribute : Attribute
{
}
}