fix(codegen): Adds codegen for embedded objects and timer fields (#686)
* Adds code genning for embedded objects. See `AquariumState` as an example. * Adds code genning for fields that are `Timer`. See `Aquarium` as an example. * Codegens aquariums * Fixes missing option for most primitive field types.
This commit is contained in:
parent
4c265562bb
commit
1323162628
126 changed files with 1287 additions and 1129 deletions
|
|
@ -39,6 +39,7 @@ namespace SerializationGenerator
|
|||
var jsonOptions = SerializableMigrationSchema.GetJsonSerializerOptions();
|
||||
// List of types that _will_ become ISerializable
|
||||
var serializableList = receiver.SerializableList;
|
||||
var embeddedSerializableList = receiver.EmbeddedSerializableList;
|
||||
|
||||
foreach (var (classSymbol, (serializableAttr, fieldsList)) in receiver.ClassAndFields)
|
||||
{
|
||||
|
|
@ -50,9 +51,34 @@ namespace SerializationGenerator
|
|||
string classSource = context.GenerateSerializationPartialClass(
|
||||
classSymbol,
|
||||
serializableAttr,
|
||||
false,
|
||||
fieldsList.ToImmutableArray(),
|
||||
jsonOptions,
|
||||
serializableList
|
||||
serializableList,
|
||||
embeddedSerializableList
|
||||
);
|
||||
|
||||
if (classSource != null)
|
||||
{
|
||||
context.AddSource($"{classSymbol.ToDisplayString()}.Serialization.cs", SourceText.From(classSource, Encoding.UTF8));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var (classSymbol, (embeddedSerializableAttr, fieldsList)) in receiver.EmbeddedClassAndFields)
|
||||
{
|
||||
if (embeddedSerializableAttr == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string classSource = context.GenerateSerializationPartialClass(
|
||||
classSymbol,
|
||||
embeddedSerializableAttr,
|
||||
true,
|
||||
fieldsList.ToImmutableArray(),
|
||||
jsonOptions,
|
||||
serializableList,
|
||||
embeddedSerializableList
|
||||
);
|
||||
|
||||
if (classSource != null)
|
||||
|
|
|
|||
|
|
@ -30,9 +30,11 @@ namespace SerializationGenerator
|
|||
this GeneratorExecutionContext context,
|
||||
INamedTypeSymbol classSymbol,
|
||||
AttributeData serializableAttr,
|
||||
bool embedded,
|
||||
ImmutableArray<ISymbol> fieldsAndProperties,
|
||||
JsonSerializerOptions jsonSerializerOptions,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes
|
||||
)
|
||||
{
|
||||
var version = (int)serializableAttr.ConstructorArguments[0].Value!;
|
||||
|
|
@ -47,10 +49,12 @@ namespace SerializationGenerator
|
|||
classSymbol,
|
||||
serializableAttr,
|
||||
null, // Do not generate schema
|
||||
embedded,
|
||||
null,
|
||||
migrations.ToImmutableArray(),
|
||||
fieldsAndProperties,
|
||||
serializableTypes
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -59,9 +63,11 @@ namespace SerializationGenerator
|
|||
INamedTypeSymbol classSymbol,
|
||||
AttributeData serializableAttr,
|
||||
string? migrationPath,
|
||||
bool embedded,
|
||||
JsonSerializerOptions? jsonSerializerOptions,
|
||||
ImmutableArray<ISymbol> fieldsAndProperties,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes
|
||||
)
|
||||
{
|
||||
var version = (int)serializableAttr.ConstructorArguments[0].Value!;
|
||||
|
|
@ -77,10 +83,12 @@ namespace SerializationGenerator
|
|||
classSymbol,
|
||||
serializableAttr,
|
||||
migrationPath,
|
||||
embedded,
|
||||
jsonSerializerOptions,
|
||||
migrations.ToImmutableArray(),
|
||||
fieldsAndProperties,
|
||||
serializableTypes
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -89,22 +97,27 @@ namespace SerializationGenerator
|
|||
INamedTypeSymbol classSymbol,
|
||||
AttributeData serializableAttr,
|
||||
string? migrationPath,
|
||||
bool embedded,
|
||||
JsonSerializerOptions? jsonSerializerOptions,
|
||||
ImmutableArray<SerializableMetadata> migrations,
|
||||
ImmutableArray<ISymbol> fieldsAndProperties,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes
|
||||
)
|
||||
{
|
||||
var serializableFieldAttribute =
|
||||
compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTRIBUTE);
|
||||
var serializableFieldAttrAttribute =
|
||||
compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTR_ATTRIBUTE);
|
||||
var serializableInterface = compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_INTERFACE);
|
||||
var serializableInterface =
|
||||
compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_INTERFACE);
|
||||
var parentSerializableAttribute =
|
||||
compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_PARENT_ATTRIBUTE);
|
||||
|
||||
// If we have a parent that is or derives from ISerializable, then we are in override
|
||||
var isOverride = classSymbol.BaseType.ContainsInterface(serializableInterface);
|
||||
|
||||
if (!isOverride && !classSymbol.ContainsInterface(serializableInterface))
|
||||
if (!(embedded || isOverride || classSymbol.ContainsInterface(serializableInterface)))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
|
@ -120,10 +133,7 @@ namespace SerializationGenerator
|
|||
source.AppendLine("#pragma warning disable\n");
|
||||
source.GenerateNamespaceStart(namespaceName);
|
||||
|
||||
source.GenerateClassStart(
|
||||
className,
|
||||
ImmutableArray<ITypeSymbol>.Empty
|
||||
);
|
||||
source.GenerateClassStart(className, ImmutableArray<ITypeSymbol>.Empty);
|
||||
|
||||
const string indent = " ";
|
||||
|
||||
|
|
@ -136,6 +146,14 @@ namespace SerializationGenerator
|
|||
);
|
||||
source.AppendLine();
|
||||
|
||||
var parentFieldOrProperty = embedded ? fieldsAndProperties.FirstOrDefault(
|
||||
fieldOrPropertySymbol => fieldOrPropertySymbol.GetAttributes()
|
||||
.FirstOrDefault(
|
||||
attr =>
|
||||
SymbolEqualityComparer.Default.Equals(attr.AttributeClass, parentSerializableAttribute)
|
||||
) != null
|
||||
) : null;
|
||||
|
||||
var serializablePropertySet = new SortedSet<SerializableProperty>(new SerializablePropertyComparer());
|
||||
|
||||
foreach (var fieldOrPropertySymbol in fieldsAndProperties)
|
||||
|
|
@ -193,7 +211,8 @@ namespace SerializationGenerator
|
|||
fieldSymbol,
|
||||
getterAccessor,
|
||||
setterAccessor,
|
||||
virtualProperty
|
||||
virtualProperty,
|
||||
parentFieldOrProperty
|
||||
);
|
||||
source.AppendLine();
|
||||
}
|
||||
|
|
@ -204,6 +223,7 @@ namespace SerializationGenerator
|
|||
order,
|
||||
allAttributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
classSymbol
|
||||
);
|
||||
|
||||
|
|
@ -213,7 +233,7 @@ namespace SerializationGenerator
|
|||
var serializableProperties = serializablePropertySet.ToImmutableArray();
|
||||
|
||||
// If we are not inheriting ISerializable, then we need to define some stuff
|
||||
if (!isOverride)
|
||||
if (!(isOverride || embedded))
|
||||
{
|
||||
// long ISerializable.SavePosition { get; set; } = -1;
|
||||
source.GenerateAutoProperty(
|
||||
|
|
@ -237,9 +257,12 @@ namespace SerializationGenerator
|
|||
);
|
||||
}
|
||||
|
||||
// Serial constructor
|
||||
source.GenerateSerialCtor(compilation, className, isOverride);
|
||||
source.AppendLine();
|
||||
if (!embedded)
|
||||
{
|
||||
// Serial constructor
|
||||
source.GenerateSerialCtor(compilation, className, isOverride);
|
||||
source.AppendLine();
|
||||
}
|
||||
|
||||
if (version > 0)
|
||||
{
|
||||
|
|
@ -271,7 +294,8 @@ namespace SerializationGenerator
|
|||
version,
|
||||
encodedVersion,
|
||||
migrations,
|
||||
serializableProperties
|
||||
serializableProperties,
|
||||
parentFieldOrProperty
|
||||
);
|
||||
|
||||
source.GenerateClassEnd();
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ namespace SerializationGenerator
|
|||
int version,
|
||||
bool encodedVersion,
|
||||
ImmutableArray<SerializableMetadata> migrations,
|
||||
ImmutableArray<SerializableProperty> properties
|
||||
ImmutableArray<SerializableProperty> properties,
|
||||
ISymbol parentFieldOrProperty
|
||||
)
|
||||
{
|
||||
var genericReaderInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_READER_INTERFACE);
|
||||
|
|
@ -74,6 +75,7 @@ namespace SerializationGenerator
|
|||
|
||||
if (version > 0)
|
||||
{
|
||||
var parent = parentFieldOrProperty?.Name ?? "this";
|
||||
var nextVersion = 0;
|
||||
|
||||
for (var i = 0; i < migrations.Length; i++)
|
||||
|
|
@ -88,7 +90,7 @@ namespace SerializationGenerator
|
|||
source.AppendLine($"{indent}if (version == {migrationVersion})");
|
||||
source.AppendLine($"{indent}{{");
|
||||
source.AppendLine($"{indent} MigrateFrom(new V{migrationVersion}Content(reader));");
|
||||
source.AppendLine($"{indent} ((Server.ISerializable)this).MarkDirty();");
|
||||
source.AppendLine($"{indent} {parent}.MarkDirty();");
|
||||
if (afterDeserialization != null)
|
||||
{
|
||||
source.AppendLine($"{indent} Timer.DelayCall({afterDeserialization.Name});");
|
||||
|
|
@ -103,7 +105,7 @@ namespace SerializationGenerator
|
|||
source.AppendLine($"{indent}if (version < _version)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
source.AppendLine($"{indent} Deserialize(reader, version);");
|
||||
source.AppendLine($"{indent} ((Server.ISerializable)this).MarkDirty();");
|
||||
source.AppendLine($"{indent} {parent}.MarkDirty();");
|
||||
if (afterDeserialization != null)
|
||||
{
|
||||
source.AppendLine($"{indent} Timer.DelayCall({afterDeserialization.Name});");
|
||||
|
|
@ -116,11 +118,14 @@ namespace SerializationGenerator
|
|||
foreach (var property in properties)
|
||||
{
|
||||
source.AppendLine();
|
||||
SerializableMigrationRulesEngine.Rules[property.Rule].GenerateDeserializationMethod(
|
||||
var rule = SerializableMigrationRulesEngine.Rules[property.Rule];
|
||||
rule.GenerateDeserializationMethod(
|
||||
source,
|
||||
indent,
|
||||
property
|
||||
);
|
||||
|
||||
(rule as IPostDeserializeMethod)?.PostDeserializeMethod(source, indent, property, compilation, classSymbol);
|
||||
}
|
||||
|
||||
if (afterDeserialization != null)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ namespace SerializationGenerator
|
|||
IFieldSymbol fieldSymbol,
|
||||
Accessibility getter,
|
||||
Accessibility? setter,
|
||||
bool isVirtual
|
||||
bool isVirtual,
|
||||
ISymbol? parentFieldOrProperty = null
|
||||
)
|
||||
{
|
||||
var fieldName = fieldSymbol.Name;
|
||||
|
|
@ -54,16 +55,18 @@ namespace SerializationGenerator
|
|||
// Getter
|
||||
source.GeneratePropertyGetterReturnsField(propertyIndent, fieldSymbol, getterAccessor);
|
||||
|
||||
if (setter != null)
|
||||
if (setter != null && setter != Accessibility.NotApplicable)
|
||||
{
|
||||
var setterAccessor = setter == propertyAccessor ? Accessibility.NotApplicable : setter;
|
||||
|
||||
var parentSymbol = parentFieldOrProperty?.Name ?? "this";
|
||||
|
||||
// Setter
|
||||
source.GeneratePropertySetterStart(propertyIndent, false, setterAccessor.Value);
|
||||
source.AppendLine($"{innerIndent}if (value != {fieldName})");
|
||||
source.AppendLine($"{innerIndent}{{");
|
||||
source.AppendLine($"{innerIndent} {fieldName} = value;");
|
||||
source.AppendLine($"{innerIndent} ((ISerializable)this).MarkDirty();");
|
||||
source.AppendLine($"{innerIndent} {parentSymbol}.MarkDirty();");
|
||||
|
||||
if (invalidatePropertiesAttribute != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2021 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: IPostDeserializeMethod.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.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace SerializableMigration
|
||||
{
|
||||
public interface IPostDeserializeMethod
|
||||
{
|
||||
public void PostDeserializeMethod(
|
||||
StringBuilder source,
|
||||
string indent,
|
||||
SerializableProperty property,
|
||||
Compilation compilation,
|
||||
INamedTypeSymbol classSymbol
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -28,6 +28,7 @@ namespace SerializableMigration
|
|||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace SerializableMigration
|
|||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
|
|
@ -46,6 +47,7 @@ namespace SerializableMigration
|
|||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol
|
||||
);
|
||||
|
||||
|
|
@ -60,7 +62,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(ArrayMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
@ -91,7 +93,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(ArrayMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2021 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: EmbeddedSerializableMigrationRule.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;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
{
|
||||
public class EmbeddedSerializableMigrationRule : ISerializableMigrationRule
|
||||
{
|
||||
public string RuleName => nameof(EmbeddedSerializableMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol)
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!embeddedSerializableTypes.Contains(namedTypeSymbol))
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ruleArguments = new[] { "" };
|
||||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName} = new {property.Type}(this);");
|
||||
source.AppendLine($"{indent}{propertyName}.Deserialize(reader);");
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,6 +30,7 @@ namespace SerializableMigration
|
|||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
|
|
@ -46,7 +47,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(EnumMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
@ -58,7 +59,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(EnumMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ namespace SerializableMigration
|
|||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
|
|
@ -50,6 +51,7 @@ namespace SerializableMigration
|
|||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol
|
||||
);
|
||||
|
||||
|
|
@ -71,7 +73,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(HashSetMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
@ -114,7 +116,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(HashSetMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace SerializableMigration
|
|||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
|
|
@ -49,6 +50,7 @@ namespace SerializableMigration
|
|||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol
|
||||
);
|
||||
|
||||
|
|
@ -59,6 +61,7 @@ namespace SerializableMigration
|
|||
1,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol
|
||||
);
|
||||
|
||||
|
|
@ -80,7 +83,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(KeyValuePairMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
@ -134,7 +137,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(KeyValuePairMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ namespace SerializableMigration
|
|||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
|
|
@ -50,6 +51,7 @@ namespace SerializableMigration
|
|||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol
|
||||
);
|
||||
|
||||
|
|
@ -71,7 +73,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(ListMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
@ -115,7 +117,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(ListMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ namespace SerializableMigration
|
|||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
|
|
@ -73,7 +74,7 @@ namespace SerializableMigration
|
|||
new[] { "DeltaTime" },
|
||||
SpecialType.System_String when attributes.Any(a => a.IsInternString(compilation)) =>
|
||||
new[] { "InternString" },
|
||||
_ => Array.Empty<string>()
|
||||
_ => new[] { "" }
|
||||
};
|
||||
|
||||
return true;
|
||||
|
|
@ -81,7 +82,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(PrimitiveTypeMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
@ -124,7 +125,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(PrimitiveTypeMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace SerializableMigration
|
|||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
|
|
@ -50,7 +51,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(PrimitiveUOTypeMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
@ -63,7 +64,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(PrimitiveUOTypeMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace SerializableMigration
|
|||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
|
|
@ -46,7 +47,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(SerializableInterfaceMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
@ -59,7 +60,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(SerializableInterfaceMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace SerializableMigration
|
|||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
|
|
@ -53,7 +54,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(SerializationMethodSignatureMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
@ -69,7 +70,7 @@ namespace SerializableMigration
|
|||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
const string expectedRule = nameof(SerializationMethodSignatureMigrationRule);
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2021 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: TimerMigrationRule.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.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
{
|
||||
public class TimerMigrationRule : ISerializableMigrationRule, IPostDeserializeMethod
|
||||
{
|
||||
public string RuleName => nameof(TimerMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
if (!(symbol is ITypeSymbol typeSymbol && typeSymbol.IsTimer(compilation)))
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ruleArguments = attributes.Any(a => a.IsTimerDrift(compilation))
|
||||
? new[] { "@TimerDrift" }
|
||||
: new[] { "" };
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var driftTimer = ruleArguments[0].Contains("@TimerDrift");
|
||||
|
||||
var readTimer = driftTimer ? "reader.ReadDeltaTime()" : "reader.ReadDateTime()";
|
||||
source.AppendLine($"{indent}var {propertyName}Delay = {readTimer} - Core.Now;");
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var driftTimer = ruleArguments[0].Contains("@TimerDrift");
|
||||
|
||||
var writerMethod = driftTimer ? "WriteDeltaTime" : "Write";
|
||||
source.AppendLine($"{indent}writer.{writerMethod}({propertyName}.Next);");
|
||||
}
|
||||
|
||||
public void PostDeserializeMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, Compilation compilation, INamedTypeSymbol classSymbol
|
||||
)
|
||||
{
|
||||
var deserializeTimerMethod = classSymbol
|
||||
.GetMembers()
|
||||
.OfType<IMethodSymbol>()
|
||||
.FirstOrDefault(
|
||||
m =>
|
||||
{
|
||||
if (!m.ReturnsVoid || m.Parameters.Length != 1 || !m.Parameters[0].Type.IsTimeSpan(compilation))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m.GetAttributes()
|
||||
.FirstOrDefault(
|
||||
attr =>
|
||||
{
|
||||
if (!SymbolEqualityComparer.Default.Equals(
|
||||
attr.AttributeClass,
|
||||
compilation.GetTypeByMetadataName(
|
||||
SymbolMetadata.DESERIALIZE_TIMER_FIELD_ATTRIBUTE
|
||||
)
|
||||
))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var order = (int)attr.ConstructorArguments[0].Value!;
|
||||
return order == property.Order;
|
||||
}
|
||||
) != null;
|
||||
}
|
||||
) ?? throw new Exception("Serializing a timer requires a method with the DeserializeTimerField attribute to handle creating the timer itself.");
|
||||
|
||||
source.AppendLine($"{indent}{deserializeTimerMethod.Name}({property.Name}Delay);");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -38,6 +38,8 @@ namespace SerializableMigration
|
|||
new PrimitiveUOTypeMigrationRule(),
|
||||
new SerializableInterfaceMigrationRule(),
|
||||
new SerializationMethodSignatureMigrationRule(),
|
||||
new EmbeddedSerializableMigrationRule(),
|
||||
new TimerMigrationRule()
|
||||
};
|
||||
|
||||
foreach (var rule in rules)
|
||||
|
|
@ -52,6 +54,7 @@ namespace SerializableMigration
|
|||
int order,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol = default
|
||||
)
|
||||
{
|
||||
|
|
@ -80,6 +83,7 @@ namespace SerializableMigration
|
|||
order,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol
|
||||
);
|
||||
}
|
||||
|
|
@ -91,6 +95,7 @@ namespace SerializableMigration
|
|||
int order,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol = default
|
||||
)
|
||||
{
|
||||
|
|
@ -101,6 +106,7 @@ namespace SerializableMigration
|
|||
propertyType,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
out var ruleArguments
|
||||
))
|
||||
|
|
|
|||
|
|
@ -24,10 +24,13 @@ namespace SerializationGenerator
|
|||
{
|
||||
#pragma warning disable RS1024
|
||||
public Dictionary<INamedTypeSymbol, (AttributeData?, List<ISymbol>)> ClassAndFields { get; } = new(SymbolEqualityComparer.Default);
|
||||
public Dictionary<INamedTypeSymbol, (AttributeData?, List<ISymbol>)> EmbeddedClassAndFields { get; } = new(SymbolEqualityComparer.Default);
|
||||
#pragma warning restore RS1024
|
||||
|
||||
public ImmutableArray<INamedTypeSymbol> SerializableList => ClassAndFields.Keys.ToImmutableArray();
|
||||
|
||||
public ImmutableArray<INamedTypeSymbol> EmbeddedSerializableList => EmbeddedClassAndFields.Keys.ToImmutableArray();
|
||||
|
||||
public void OnVisitSyntaxNode(SyntaxNode node, SemanticModel semanticModel)
|
||||
{
|
||||
var compilation = semanticModel.Compilation;
|
||||
|
|
@ -39,7 +42,19 @@ namespace SerializationGenerator
|
|||
return;
|
||||
}
|
||||
|
||||
if (classSymbol.WillBeSerializable(compilation, out var attrData))
|
||||
if (classSymbol.IsEmbeddedSerializable(compilation, out var attrData))
|
||||
{
|
||||
if (EmbeddedClassAndFields.TryGetValue(classSymbol, out var value))
|
||||
{
|
||||
var (_, fieldsList) = value;
|
||||
EmbeddedClassAndFields[classSymbol] = (attrData, fieldsList);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmbeddedClassAndFields.Add(classSymbol, (attrData, new List<ISymbol>()));
|
||||
}
|
||||
}
|
||||
else if (classSymbol.WillBeSerializable(compilation, out attrData))
|
||||
{
|
||||
if (ClassAndFields.TryGetValue(classSymbol, out var value))
|
||||
{
|
||||
|
|
@ -64,8 +79,11 @@ namespace SerializationGenerator
|
|||
AddFieldOrProperty(fieldSymbol, compilation);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (node is PropertyDeclarationSyntax { AttributeLists: { Count: > 0 } } propertyDeclarationSyntax)
|
||||
|
||||
if (node is PropertyDeclarationSyntax { AttributeLists: { Count: > 0 } } propertyDeclarationSyntax)
|
||||
{
|
||||
if (semanticModel.GetDeclaredSymbol(propertyDeclarationSyntax) is IPropertySymbol propertySymbol)
|
||||
{
|
||||
|
|
@ -80,8 +98,9 @@ namespace SerializationGenerator
|
|||
private void AddFieldOrProperty(ISymbol symbol, Compilation compilation)
|
||||
{
|
||||
var serializableFieldAttr = compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTRIBUTE);
|
||||
var parentAttr = compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_PARENT_ATTRIBUTE);
|
||||
|
||||
if (symbol.GetAttribute(serializableFieldAttr) == null)
|
||||
if (symbol.GetAttribute(serializableFieldAttr) == null && symbol.GetAttribute(parentAttr) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -94,10 +113,21 @@ namespace SerializationGenerator
|
|||
return;
|
||||
}
|
||||
|
||||
if (EmbeddedClassAndFields.TryGetValue(classSymbol, out value))
|
||||
{
|
||||
var (_, fieldsList) = value;
|
||||
fieldsList.Add(symbol);
|
||||
return;
|
||||
}
|
||||
|
||||
if (classSymbol.WillBeSerializable(compilation, out var attrData))
|
||||
{
|
||||
ClassAndFields.Add(classSymbol, (attrData, new List<ISymbol> { symbol }));
|
||||
}
|
||||
else if (classSymbol.IsEmbeddedSerializable(compilation, out attrData))
|
||||
{
|
||||
EmbeddedClassAndFields.Add(classSymbol, (attrData, new List<ISymbol> { symbol }));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,5 +55,11 @@ namespace SerializationGenerator
|
|||
"private protected" => Accessibility.ProtectedAndInternal,
|
||||
_ => Accessibility.NotApplicable
|
||||
};
|
||||
|
||||
public static bool CanBeConstructedFrom(this ITypeSymbol? symbol, ISymbol classSymbol) =>
|
||||
symbol is INamedTypeSymbol namedTypeSymbol && namedTypeSymbol.ConstructedFrom.Equals(
|
||||
classSymbol,
|
||||
SymbolEqualityComparer.Default
|
||||
) || symbol != null && CanBeConstructedFrom(symbol.BaseType, classSymbol);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ namespace SerializationGenerator
|
|||
public const string INVALIDATEPROPERTIES_ATTRIBUTE = "Server.InvalidatePropertiesAttribute";
|
||||
public const string AFTERDESERIALIZATION_ATTRIBUTE = "Server.AfterDeserializationAttribute";
|
||||
public const string SERIALIZABLE_ATTRIBUTE = "Server.SerializableAttribute";
|
||||
public const string EMBEDDED_SERIALIZABLE_ATTRIBUTE = "Server.EmbeddedSerializableAttribute";
|
||||
public const string SERIALIZABLE_PARENT_ATTRIBUTE = "Server.SerializableParentAttribute";
|
||||
public const string SERIALIZABLE_FIELD_ATTRIBUTE = "Server.SerializableFieldAttribute";
|
||||
public const string SERIALIZABLE_FIELD_ATTR_ATTRIBUTE = "Server.SerializableFieldAttrAttribute";
|
||||
public const string SERIALIZABLE_INTERFACE = "Server.ISerializable";
|
||||
|
|
@ -39,6 +41,15 @@ namespace SerializationGenerator
|
|||
public const string RECTANGLE3D_STRUCT = "Server.Rectangle3D";
|
||||
public const string RACE_CLASS = "Server.Race";
|
||||
public const string MAP_CLASS = "Server.Map";
|
||||
public const string TIMER_CLASS = "Server.Timer";
|
||||
public const string TIMER_DRIFT_ATTRIBUTE = "Server.TimerDriftAttribute";
|
||||
public const string DESERIALIZE_TIMER_FIELD_ATTRIBUTE = "Server.DeserializeTimerFieldAttribute";
|
||||
|
||||
public static bool IsTimerDrift(this AttributeData attr, Compilation compilation) =>
|
||||
attr?.IsAttribute(compilation.GetTypeByMetadataName(TIMER_DRIFT_ATTRIBUTE)) == true;
|
||||
|
||||
public static bool IsTimer(this ITypeSymbol symbol, Compilation compilation) =>
|
||||
symbol.CanBeConstructedFrom(compilation.GetTypeByMetadataName(TIMER_CLASS));
|
||||
|
||||
public static bool IsEncodedInt(this AttributeData attr, Compilation compilation) =>
|
||||
attr?.IsAttribute(compilation.GetTypeByMetadataName(ENCODED_INT_ATTRIBUTE)) == true;
|
||||
|
|
@ -112,6 +123,29 @@ namespace SerializationGenerator
|
|||
);
|
||||
}
|
||||
|
||||
public static bool HasPublicDeserializeMethod(
|
||||
this ITypeSymbol symbol,
|
||||
Compilation compilation,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes
|
||||
)
|
||||
{
|
||||
if (symbol.HasSerializableInterface(compilation, serializableTypes))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var genericReaderInterface = compilation.GetTypeByMetadataName(GENERIC_READER_INTERFACE);
|
||||
|
||||
return symbol.GetAllMethods("Deserialize")
|
||||
.Any(
|
||||
m => !m.IsStatic &&
|
||||
m.ReturnsVoid &&
|
||||
m.Parameters.Length == 1 &&
|
||||
SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, genericReaderInterface) &&
|
||||
m.DeclaredAccessibility == Accessibility.Public
|
||||
);
|
||||
}
|
||||
|
||||
public static bool IsPoint2D(this ISymbol symbol, Compilation compilation) =>
|
||||
symbol.Equals(
|
||||
compilation.GetTypeByMetadataName(POINT2D_STRUCT),
|
||||
|
|
@ -171,5 +205,14 @@ namespace SerializationGenerator
|
|||
attributeData = classSymbol.GetAttribute(serializableEntityAttribute);
|
||||
return attributeData != null;
|
||||
}
|
||||
|
||||
public static bool IsEmbeddedSerializable(this INamedTypeSymbol classSymbol, Compilation compilation, out AttributeData? attributeData)
|
||||
{
|
||||
var embeddedSerializableEntityAttribute =
|
||||
compilation.GetTypeByMetadataName(EMBEDDED_SERIALIZABLE_ATTRIBUTE);
|
||||
|
||||
attributeData = classSymbol.GetAttribute(embeddedSerializableEntityAttribute);
|
||||
return attributeData != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue