diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 000000000..e0dbc85fc --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "modernuoschemagenerator": { + "version": "1.0.2", + "commands": [ + "ModernUOSchemaGenerator" + ] + } + } +} diff --git a/Directory.Build.props b/Directory.Build.props index 500f44bb9..4a52a9154 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -59,7 +59,7 @@ - 3.4.244 + 3.4.255 all diff --git a/ModernUO.sln b/ModernUO.sln index 75eb761a4..3251fb4a4 100644 --- a/ModernUO.sln +++ b/ModernUO.sln @@ -12,9 +12,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UOContent.Tests", "Projects EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Projects\Benchmarks\Benchmarks.csproj", "{38B7E4A1-FDDD-486C-98EE-BA7B13712528}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerializationGenerator", "Projects\SerializationGenerator\SerializationGenerator.csproj", "{07DDB8CF-F926-44F4-A584-FF2997D2C9D0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerializationSchemaGenerator", "Projects\SerializationSchemaGenerator\SerializationSchemaGenerator.csproj", "{A30150A3-796C-4C6D-B3E4-B7BEB0021701}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Run Schema Migrations", "Projects\Schema Migrations\Run Schema Migrations.csproj", "{75256276-FEAB-416C-9DB8-533FE816A0EF}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -53,18 +51,12 @@ Global {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Debug|x64.Build.0 = Debug|x64 {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Release|x64.ActiveCfg = Release|x64 {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Release|x64.Build.0 = Release|x64 - {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Analyze|x64.ActiveCfg = Analyze|x64 - {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Analyze|x64.Build.0 = Analyze|x64 - {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Debug|x64.ActiveCfg = Debug|x64 - {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Debug|x64.Build.0 = Debug|x64 - {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Release|x64.ActiveCfg = Release|x64 - {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Release|x64.Build.0 = Release|x64 - {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Analyze|x64.ActiveCfg = Analyze|x64 - {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Analyze|x64.Build.0 = Analyze|x64 - {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Debug|x64.ActiveCfg = Debug|x64 - {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Debug|x64.Build.0 = Debug|x64 - {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Release|x64.ActiveCfg = Release|x64 - {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Release|x64.Build.0 = Release|x64 + {75256276-FEAB-416C-9DB8-533FE816A0EF}.Analyze|x64.ActiveCfg = Analyze|x64 + {75256276-FEAB-416C-9DB8-533FE816A0EF}.Analyze|x64.Build.0 = Analyze|x64 + {75256276-FEAB-416C-9DB8-533FE816A0EF}.Debug|x64.ActiveCfg = Debug|x64 + {75256276-FEAB-416C-9DB8-533FE816A0EF}.Debug|x64.Build.0 = Debug|x64 + {75256276-FEAB-416C-9DB8-533FE816A0EF}.Release|x64.ActiveCfg = Release|x64 + {75256276-FEAB-416C-9DB8-533FE816A0EF}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Projects/Schema Migrations/Run Schema Migrations.csproj b/Projects/Schema Migrations/Run Schema Migrations.csproj new file mode 100644 index 000000000..39947e2f9 --- /dev/null +++ b/Projects/Schema Migrations/Run Schema Migrations.csproj @@ -0,0 +1,13 @@ + + + Schema_Migrations + + + + + + + + + + diff --git a/Projects/SerializationGenerator/EntitySerializationGenerator.cs b/Projects/SerializationGenerator/EntitySerializationGenerator.cs deleted file mode 100755 index e5b1e0f0d..000000000 --- a/Projects/SerializationGenerator/EntitySerializationGenerator.cs +++ /dev/null @@ -1,91 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: EntityJsonGenerator.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 . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Text; -using SerializableMigration; - -namespace SerializationGenerator -{ - [Generator] - public class EntitySerializationGenerator : ISourceGenerator - { - public void Initialize(GeneratorInitializationContext context) - { - context.RegisterForSyntaxNotifications(() => new SerializerSyntaxReceiver()); - } - - public void Execute(GeneratorExecutionContext context) - { - if (context.SyntaxContextReceiver is not SerializerSyntaxReceiver receiver) - { - return; - } - - 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) - { - if (serializableAttr == null) - { - continue; - } - - string classSource = context.GenerateSerializationPartialClass( - classSymbol, - serializableAttr, - false, - fieldsList.ToImmutableArray(), - jsonOptions, - 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) - { - context.AddSource($"{classSymbol.ToDisplayString()}.Serialization.cs", SourceText.From(classSource, Encoding.UTF8)); - } - } - } - } -} diff --git a/Projects/SerializationGenerator/IsExternalInit.cs b/Projects/SerializationGenerator/IsExternalInit.cs deleted file mode 100644 index eb2da113f..000000000 --- a/Projects/SerializationGenerator/IsExternalInit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace System.Runtime.CompilerServices -{ - internal static class IsExternalInit {} -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs deleted file mode 100644 index 7611d5799..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs +++ /dev/null @@ -1,436 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableEntityGeneration.Class.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 . * - *************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.Json; -using Microsoft.CodeAnalysis; -using SerializableMigration; - -namespace SerializationGenerator -{ - public static partial class SerializableEntityGeneration - { - public static string GenerateSerializationPartialClass( - this GeneratorExecutionContext context, - INamedTypeSymbol classSymbol, - AttributeData serializableAttr, - bool embedded, - ImmutableArray fieldsAndProperties, - JsonSerializerOptions jsonSerializerOptions, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes - ) - { - var version = (int)serializableAttr.ConstructorArguments[0].Value!; - - var migrations = context.GetMigrationsByAnalyzerConfig( - classSymbol, - version, - jsonSerializerOptions - ); - - return context.Compilation.GenerateSerializationPartialClass( - classSymbol, - serializableAttr, - null, // Do not generate schema - embedded, - null, - migrations.ToImmutableArray(), - fieldsAndProperties, - serializableTypes, - embeddedSerializableTypes - ); - } - - public static string GenerateSerializationPartialClass( - this Compilation compilation, - INamedTypeSymbol classSymbol, - AttributeData serializableAttr, - string? migrationPath, - bool embedded, - JsonSerializerOptions? jsonSerializerOptions, - ImmutableArray fieldsAndProperties, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes - ) - { - var version = (int)serializableAttr.ConstructorArguments[0].Value!; - - var migrations = SerializableMigrationSchema.GetMigrations( - classSymbol, - version, - migrationPath, - jsonSerializerOptions - ); - - return compilation.GenerateSerializationPartialClass( - classSymbol, - serializableAttr, - migrationPath, - embedded, - jsonSerializerOptions, - migrations.ToImmutableArray(), - fieldsAndProperties, - serializableTypes, - embeddedSerializableTypes - ); - } - - public static string GenerateSerializationPartialClass( - this Compilation compilation, - INamedTypeSymbol classSymbol, - AttributeData serializableAttr, - string? migrationPath, - bool embedded, - JsonSerializerOptions? jsonSerializerOptions, - ImmutableArray migrations, - ImmutableArray fieldsAndProperties, - ImmutableArray serializableTypes, - ImmutableArray 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 parentSerializableAttribute = - compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_PARENT_ATTRIBUTE); - var serializableFieldSaveFlagAttribute = - compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_SAVE_FLAG_ATTRIBUTE); - var serializableFieldDefaultAttribute = - compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_DEFAULT_ATTRIBUTE); - - // If we have a parent that is or derives from ISerializable, then we are in override - var isOverride = classSymbol.BaseType.ContainsInterface(serializableInterface); - - if (!(embedded || isOverride || classSymbol.ContainsInterface(serializableInterface))) - { - return null; - } - - var isRawSerializable = classSymbol.HasRawSerializableInterface(compilation, ImmutableArray.Empty); - - var version = (int)serializableAttr.ConstructorArguments[0].Value!; - var encodedVersion = (bool)serializableAttr.ConstructorArguments[1].Value!; - - // Let's find out if we need to do serialization flags - var serializableFieldSaveFlags = new SortedDictionary(); - foreach (var m in classSymbol.GetMembers().OfType()) - { - var getSaveFlagAttribute = m.GetAttribute(serializableFieldSaveFlagAttribute); - var getDefaultValueAttribute = m.GetAttribute(serializableFieldDefaultAttribute); - - if (getSaveFlagAttribute == null && getDefaultValueAttribute == null) - { - continue; - } - - var attrCtorArgs = getSaveFlagAttribute?.ConstructorArguments ?? getDefaultValueAttribute.ConstructorArguments; - var order = (int)attrCtorArgs[0].Value!; - - serializableFieldSaveFlags.TryGetValue(order, out var saveFlagMethods); - - serializableFieldSaveFlags[order] = new SerializableFieldSaveFlagMethods - { - DetermineFieldShouldSerialize = getSaveFlagAttribute != null ? m : saveFlagMethods?.DetermineFieldShouldSerialize, - GetFieldDefaultValue = getDefaultValueAttribute != null ? m : saveFlagMethods?.GetFieldDefaultValue - }; - } - - var namespaceName = classSymbol.ContainingNamespace.ToDisplayString(); - var className = classSymbol.Name; - - StringBuilder source = new StringBuilder(); - - source.AppendLine("#pragma warning disable\n"); - source.GenerateNamespaceStart(namespaceName); - - var interfaces = !embedded || isRawSerializable - ? Array.Empty() - : new ITypeSymbol[] { compilation.GetTypeByMetadataName(SymbolMetadata.RAW_SERIALIZABLE_INTERFACE) }; - - var indent = " "; - - source.RecursiveGenerateClassStart(classSymbol, interfaces.ToImmutableArray(), ref indent); - - source.GenerateClassField( - indent, - Accessibility.Private, - InstanceModifier.Const, - "int", - "_version", - version.ToString() - ); - source.AppendLine(); - - var parentFieldOrProperty = embedded ? fieldsAndProperties.FirstOrDefault( - fieldOrPropertySymbol => fieldOrPropertySymbol.GetAttributes() - .FirstOrDefault( - attr => - SymbolEqualityComparer.Default.Equals(attr.AttributeClass, parentSerializableAttribute) - ) != null - ) : null; - - var serializablePropertySet = new SortedDictionary(new SerializablePropertyComparer()); - - foreach (var fieldOrPropertySymbol in fieldsAndProperties) - { - var allAttributes = fieldOrPropertySymbol.GetAttributes(); - - var serializableFieldAttr = allAttributes - .FirstOrDefault( - attr => - SymbolEqualityComparer.Default.Equals(attr.AttributeClass, serializableFieldAttribute) - ); - - if (serializableFieldAttr == null) - { - continue; - } - - foreach (var attr in allAttributes) - { - if (!SymbolEqualityComparer.Default.Equals(attr.AttributeClass, serializableFieldAttrAttribute)) - { - continue; - } - - if (attr.AttributeClass == null) - { - continue; - } - - var ctorArgs = attr.ConstructorArguments; - var attrTypeArg = ctorArgs[0]; - - if (attrTypeArg.Kind == TypedConstantKind.Primitive && attrTypeArg.Value is string attrStr) - { - source.AppendLine($"{indent}{attrStr}"); - } - else - { - var attrType = (ITypeSymbol)attrTypeArg.Value; - source.GenerateAttribute(indent, attrType?.Name, ctorArgs[1].Values); - } - } - - var attrCtorArgs = serializableFieldAttr.ConstructorArguments; - - var order = (int)attrCtorArgs[0].Value!; - var getterAccessor = Helpers.GetAccessibility(attrCtorArgs[1].Value?.ToString()); - var setterAccessor = Helpers.GetAccessibility(attrCtorArgs[2].Value?.ToString()); - var virtualProperty = (bool)attrCtorArgs[3].Value!; - - if (fieldOrPropertySymbol is IFieldSymbol fieldSymbol) - { - source.GenerateSerializableProperty( - compilation, - indent, - fieldSymbol, - getterAccessor, - setterAccessor, - virtualProperty, - parentFieldOrProperty - ); - source.AppendLine(); - } - - serializableFieldSaveFlags.TryGetValue(order, out var serializableFieldSaveFlagMethods); - - var serializableProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - fieldOrPropertySymbol, - order, - allAttributes, - serializableTypes, - embeddedSerializableTypes, - classSymbol, - serializableFieldSaveFlagMethods - ); - - serializablePropertySet.Add(serializableProperty, fieldOrPropertySymbol); - } - - var serializableFields = serializablePropertySet.Keys.ToImmutableArray(); - var serializableProperties = serializablePropertySet.Select( - kvp => kvp.Key with - { - Name = (kvp.Value as IFieldSymbol)?.GetPropertyName() ?? ((IPropertySymbol)kvp.Value).Name - } - ).ToImmutableArray(); - - // If we are not inheriting ISerializable, then we need to define some stuff - if (!(isOverride || embedded)) - { - // long ISerializable.SavePosition { get; set; } = -1; - source.GenerateAutoProperty( - Accessibility.NotApplicable, - "long", - "ISerializable.SavePosition", - Accessibility.NotApplicable, - Accessibility.NotApplicable, - indent, - defaultValue: "-1" - ); - - // BufferWriter ISerializable.SaveBuffer { get; set; } - source.GenerateAutoProperty( - Accessibility.NotApplicable, - "BufferWriter", - "ISerializable.SaveBuffer", - Accessibility.NotApplicable, - Accessibility.NotApplicable, - indent - ); - } - - if (!embedded) - { - // Serial constructor - source.GenerateSerialCtor(compilation, className, indent, isOverride); - source.AppendLine(); - } - - if (version > 0) - { - for (var i = 0; i < migrations.Length; i++) - { - var migration = migrations[i]; - if (migration.Version < version) - { - source.GenerateMigrationContentStruct(compilation, indent, migration, classSymbol); - source.AppendLine(); - } - } - } - - // Serialize Method - source.GenerateSerializeMethod( - compilation, - indent, - isOverride, - encodedVersion, - serializableFields, - serializableProperties, - serializableFieldSaveFlags - ); - source.AppendLine(); - - // Deserialize Method - source.GenerateDeserializeMethod( - compilation, - classSymbol, - indent, - isOverride, - version, - encodedVersion, - migrations, - serializableFields, - serializableProperties, - parentFieldOrProperty, - serializableFieldSaveFlags - ); - - // Serialize SaveFlag enum class - if (serializableFieldSaveFlags.Count > 0) - { - source.AppendLine(); - source.GenerateEnumStart( - "SaveFlag", - $"{indent} ", - true, - Accessibility.Private - ); - - source.GenerateEnumValue($"{indent} ", true, "None", -1); - int index = 0; - foreach (var (order, _) in serializableFieldSaveFlags) - { - source.GenerateEnumValue($"{indent} ", true, serializableProperties[order].Name, index++); - } - - source.GenerateEnumEnd($"{indent} "); - } - - source.RecursiveGenerateClassEnd(classSymbol, ref indent); - source.GenerateNamespaceEnd(); - - if (migrationPath != null) - { - // Write the migration file - var newMigration = new SerializableMetadata - { - Version = version, - Type = classSymbol.ToDisplayString(), - Properties = serializableProperties.Length > 0 ? serializableProperties : null - }; - - WriteMigration(migrationPath, newMigration, jsonSerializerOptions); - } - - return source.ToString(); - } - - private static void WriteMigration(string migrationPath, SerializableMetadata metadata, JsonSerializerOptions options) - { - Directory.CreateDirectory(migrationPath); - 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 interfaces, - ref string indent - ) - { - var containingSymbolList = new List(); - - 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.Empty); - indent += " "; - } - } - - private static void RecursiveGenerateClassEnd(this StringBuilder source, INamedTypeSymbol classSymbol, ref string indent) - { - do - { - indent = indent.Substring(0, indent.Length - 4); - source.GenerateClassEnd(indent); - - classSymbol = classSymbol.ContainingSymbol as INamedTypeSymbol; - } while (classSymbol != null); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs deleted file mode 100644 index 59048a125..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs +++ /dev/null @@ -1,213 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableEntityGeneration.DeserializeMethod.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 . * - *************************************************************************/ - -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializableMigration; - -namespace SerializationGenerator -{ - public static partial class SerializableEntityGeneration - { - public static void GenerateDeserializeMethod( - this StringBuilder source, - Compilation compilation, - INamedTypeSymbol classSymbol, - string indent, - bool isOverride, - int version, - bool encodedVersion, - ImmutableArray migrations, - ImmutableArray fields, - ImmutableArray properties, - ISymbol parentFieldOrProperty, - SortedDictionary serializableFieldSaveFlagMethodsDictionary - ) - { - var genericReaderInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_READER_INTERFACE); - - source.GenerateMethodStart( - indent, - "Deserialize", - Accessibility.Public, - isOverride, - "void", - ImmutableArray.Create<(ITypeSymbol, string)>((genericReaderInterface, "reader")) - ); - - var bodyIndent = $"{indent} "; - var innerIndent = $"{bodyIndent} "; - - if (isOverride) - { - source.AppendLine($"{bodyIndent}base.Deserialize(reader);"); - source.AppendLine(); - } - - var afterDeserialization = classSymbol - .GetMembers() - .OfType() - .Select( - m => - { - if (!m.ReturnsVoid || m.Parameters.Length != 0) - { - return (m, null); - } - - return (m, m.GetAttributes() - .FirstOrDefault( - attr => SymbolEqualityComparer.Default.Equals( - attr.AttributeClass, - compilation.GetTypeByMetadataName(SymbolMetadata.AFTERDESERIALIZATION_ATTRIBUTE) - ) - )); - } - ).Where(m => m.Item2 != null).ToList(); - - // Version - source.AppendLine($"{bodyIndent}var version = reader.{(encodedVersion ? "ReadEncodedInt" : "ReadInt")}();"); - - if (version > 0) - { - var parent = parentFieldOrProperty?.Name ?? "this"; - var nextVersion = 0; - - for (var i = 0; i < migrations.Length; i++) - { - var migrationVersion = migrations[i].Version; - if (migrationVersion == nextVersion) - { - nextVersion++; - } - - source.AppendLine(); - 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($"{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($"{bodyIndent}var saveFlags = reader.ReadEnum();"); - } - - for (var i = 0; i < properties.Length; i++) - { - var field = fields[i]; - var property = properties[i]; - var rule = SerializableMigrationRulesEngine.Rules[property.Rule]; - - if (serializableFieldSaveFlagMethodsDictionary.TryGetValue( - property.Order, - out var serializableFieldSaveFlagMethods - )) - { - source.AppendLine(); - // Special case - if (property.Type == "bool") - { - source.AppendLine($"{bodyIndent}{field.Name} = (saveFlags & SaveFlag.{property.Name}) != 0;"); - } - else - { - source.AppendLine($"{bodyIndent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{bodyIndent}{{"); - rule.GenerateDeserializationMethod( - source, - innerIndent, - field, - parentFieldOrProperty?.Name ?? "this" - ); - (rule as IPostDeserializeMethod)?.PostDeserializeMethod( - source, - innerIndent, - field, - compilation, - classSymbol - ); - - if (serializableFieldSaveFlagMethods.GetFieldDefaultValue != null) - { - source.AppendLine($"{bodyIndent}}}\n{bodyIndent}else\n{bodyIndent}{{"); - source.AppendLine( - $"{bodyIndent} {field.Name} = {serializableFieldSaveFlagMethods.GetFieldDefaultValue.Name}();" - ); - } - - source.AppendLine($"{bodyIndent}}}"); - } - } - else - { - source.AppendLine(); - rule.GenerateDeserializationMethod( - source, - bodyIndent, - field, - parentFieldOrProperty?.Name ?? "this" - ); - (rule as IPostDeserializeMethod)?.PostDeserializeMethod( - source, - bodyIndent, - field, - compilation, - classSymbol - ); - } - } - - source.GenerateAfterDeserialization($"{bodyIndent}", afterDeserialization); - source.GenerateMethodEnd(indent); - } - - private static void GenerateAfterDeserialization( - this StringBuilder source, string indent, IList<(IMethodSymbol, AttributeData?)> afterDeserialization - ) - { - foreach (var (method, attr) in afterDeserialization) - { - if ((bool)attr.ConstructorArguments[0].Value!) - { - source.AppendLine($"{indent}{method.Name}();"); - } - else - { - source.AppendLine($"{indent}Timer.DelayCall({method.Name});"); - } - } - } - } -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs deleted file mode 100644 index d2457bb90..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableEntityGeneration.Property.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 . * - *************************************************************************/ - -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SerializableEntityGeneration - { - public static void GenerateSerializableProperty( - this StringBuilder source, - Compilation compilation, - string indent, - IFieldSymbol fieldSymbol, - Accessibility getter, - Accessibility? setter, - bool isVirtual, - ISymbol? parentFieldOrProperty - ) - { - var fieldName = fieldSymbol.Name; - - var invalidatePropertiesAttribute = fieldSymbol - .GetAttributes() - .OfType() - .FirstOrDefault( - attr => attr.AttributeClass?.Equals( - compilation.GetTypeByMetadataName(SymbolMetadata.INVALIDATEPROPERTIES_ATTRIBUTE), - SymbolEqualityComparer.Default - ) ?? false - ); - - var propertyIndent = $"{indent} "; - var innerIndent = $"{propertyIndent} "; - - var propertyAccessor = setter > getter ? setter : getter; - var getterAccessor = getter == propertyAccessor ? Accessibility.NotApplicable : getter; - - source.GeneratePropertyStart(indent, propertyAccessor.Value, isVirtual, fieldSymbol); - - // Getter - source.GeneratePropertyGetterReturnsField(propertyIndent, fieldSymbol, getterAccessor); - - 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} {parentSymbol}.MarkDirty();"); - - if (invalidatePropertiesAttribute != null) - { - source.AppendLine($"{innerIndent} InvalidateProperties();"); - } - source.AppendLine($"{innerIndent}}}"); - source.GeneratePropertyGetSetEnd(propertyIndent, false); - } - - source.GeneratePropertyEnd(indent); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs deleted file mode 100644 index 7b7ebcb7f..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableEntityGeneration.SerialCtor.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 . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SerializableEntityGeneration - { - private static readonly ImmutableArray _baseParameters = new[] { "serial" }.ToImmutableArray(); - public static void GenerateSerialCtor( - 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(), - isOverride ? _baseParameters : ImmutableArray.Empty - ); - - if (!isOverride) - { - source.AppendLine($"{indent} Serial = serial;"); - source.AppendLine($"{indent} SetTypeRef(typeof({className}));"); - } - - source.GenerateMethodEnd(indent); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs deleted file mode 100644 index 6aff93f5e..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableEntityGeneration.SerializeMethod.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 . * - *************************************************************************/ - -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializableMigration; - -namespace SerializationGenerator -{ - public static partial class SerializableEntityGeneration - { - public static void GenerateSerializeMethod( - this StringBuilder source, - Compilation compilation, - string indent, - bool isOverride, - bool encodedVersion, - ImmutableArray fields, - ImmutableArray properties, - SortedDictionary serializableFieldSaveFlagMethodsDictionary - ) - { - var genericWriterInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_WRITER_INTERFACE); - - source.GenerateMethodStart( - indent, - "Serialize", - Accessibility.Public, - isOverride, - "void", - ImmutableArray.Create<(ITypeSymbol, string)>((genericWriterInterface, "writer")) - ); - - var bodyIndent = $"{indent} "; - var innerIndent = $"{bodyIndent} "; - - if (isOverride) - { - source.AppendLine($"{bodyIndent}base.Serialize(writer);"); - source.AppendLine(); - } - - // Version - source.AppendLine($"{bodyIndent}writer.{(encodedVersion ? "WriteEncodedInt" : "Write")}(_version);"); - - // Let's collect the flags - if (serializableFieldSaveFlagMethodsDictionary.Count > 0) - { - source.AppendLine($"\n{bodyIndent}var saveFlags = SaveFlag.None;"); - - foreach (var (order, saveFlagMethods) in serializableFieldSaveFlagMethodsDictionary) - { - source.AppendLine($"{bodyIndent}if ({saveFlagMethods.DetermineFieldShouldSerialize!.Name}())\n{bodyIndent}{{"); - - var propertyName = properties[order].Name; - source.AppendLine($"{innerIndent}saveFlags |= SaveFlag.{propertyName};"); - - source.AppendLine($"{bodyIndent}}}"); - } - - source.AppendLine($"{bodyIndent}writer.WriteEnum(saveFlags);"); - } - - for (var i = 0; i < properties.Length; i++) - { - var field = fields[i]; - var property = properties[i]; - if (serializableFieldSaveFlagMethodsDictionary.ContainsKey(property.Order)) - { - // Special case - if (property.Type != "bool") - { - source.AppendLine($"\n{bodyIndent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{bodyIndent}{{"); - SerializableMigrationRulesEngine.Rules[property.Rule] - .GenerateSerializationMethod( - source, - innerIndent, - field - ); - source.AppendLine($"{bodyIndent}}}"); - } - } - else - { - source.AppendLine(); - SerializableMigrationRulesEngine.Rules[property.Rule] - .GenerateSerializationMethod( - source, - bodyIndent, - field - ); - } - } - - source.GenerateMethodEnd(indent); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs deleted file mode 100644 index 55a087914..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public record SerializableFieldSaveFlagMethods - { - public IMethodSymbol? DetermineFieldShouldSerialize { get; init; } - - public IMethodSymbol? GetFieldDefaultValue { get; init; } - } -} diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs deleted file mode 100644 index 56544ed60..000000000 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs +++ /dev/null @@ -1,127 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializationEntityGeneration.ContentStruct.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 . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializableMigration; - -namespace SerializationGenerator -{ - public static partial class SerializableEntityGeneration - { - public static void GenerateMigrationContentStruct( - this StringBuilder source, - Compilation compilation, - string indent, - SerializableMetadata migration, - INamedTypeSymbol classSymbol - ) - { - source.AppendLine($"{indent}ref struct V{migration.Version}Content"); - source.AppendLine($"{indent}{{"); - var properties = migration.Properties ?? ImmutableArray.Empty; - - foreach (var serializableProperty in properties) - { - SerializableMigrationRulesEngine.Rules[serializableProperty.Rule].GenerateMigrationProperty( - source, compilation, $"{indent} ", serializableProperty - ); - } - - var innerIndent = $"{indent} "; - - var usesSaveFlags = properties.Any(p => p.UsesSaveFlag == true); - - if (usesSaveFlags) - { - source.AppendLine(); - source.GenerateEnumStart( - $"V{migration.Version}SaveFlag", - $"{indent} ", - true, - Accessibility.Private - ); - - source.GenerateEnumValue(innerIndent, true, "None", -1); - int index = 0; - foreach (var property in properties) - { - if (property.UsesSaveFlag == true) - { - source.GenerateEnumValue(innerIndent, true, property.Name, index++); - } - } - - source.GenerateEnumEnd($"{indent} "); - } - - source.AppendLine($"{indent} internal V{migration.Version}Content(IGenericReader reader, {classSymbol.ToDisplayString()} entity)"); - source.AppendLine($"{indent} {{"); - - if (usesSaveFlags) - { - source.AppendLine($"{innerIndent}var saveFlags = reader.ReadEnum();"); - } - - if (properties.Length > 0) - { - foreach (var property in properties) - { - if (property.UsesSaveFlag == true) - { - source.AppendLine(); - // Special case - if (property.Type == "bool") - { - source.AppendLine($"{innerIndent}{property.Name} = (saveFlags & V{migration.Version}SaveFlag.{property.Name}) != 0;"); - } - else - { - source.AppendLine($"{innerIndent}if ((saveFlags & V{migration.Version}SaveFlag.{property.Name}) != 0)\n{innerIndent}{{"); - - SerializableMigrationRulesEngine.Rules[property.Rule].GenerateDeserializationMethod( - source, - $"{innerIndent} ", - property, - "entity", - true - ); - - source.AppendLine($"{innerIndent}}}\n{innerIndent}else\n{innerIndent}{{"); - source.AppendLine($"{innerIndent} {property.Name} = default;"); - source.AppendLine($"{innerIndent}}}"); - } - } - else - { - SerializableMigrationRulesEngine.Rules[property.Rule].GenerateDeserializationMethod( - source, - innerIndent, - property, - "entity", - true - ); - } - } - } - - source.AppendLine($"{indent} }}"); - - source.AppendLine($"{indent}}}"); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs b/Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs deleted file mode 100644 index 0a48c0117..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************************* - * 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 . * - *************************************************************************/ - -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializableMigration -{ - public interface IPostDeserializeMethod - { - public void PostDeserializeMethod( - StringBuilder source, - string indent, - SerializableProperty property, - Compilation compilation, - INamedTypeSymbol classSymbol - ); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs deleted file mode 100644 index a64453e33..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableMigrationRule.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 . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializableMigration -{ - public interface ISerializableMigrationRule - { - string RuleName { get; } - - void GenerateMigrationProperty( - StringBuilder source, - Compilation compilation, - string indent, - SerializableProperty serializableProperty - ); - - bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ); - - void GenerateDeserializationMethod( - StringBuilder source, - string indent, - SerializableProperty property, - string? parentReference, - bool isMigration = false - ); - - void GenerateSerializationMethod( - StringBuilder source, - string indent, - SerializableProperty property - ); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs deleted file mode 100644 index 99a1e911e..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs +++ /dev/null @@ -1,135 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: ArrayMigrationRule.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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializableMigration; - -public class ArrayMigrationRule : MigrationRule -{ - public override string RuleName => nameof(ArrayMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not IArrayTypeSymbol arrayTypeSymbol) - { - ruleArguments = null; - return false; - } - - var serializableArrayType = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "ArrayEntry", - arrayTypeSymbol.ElementType, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var length = serializableArrayType.RuleArguments?.Length?? 0; - ruleArguments = new string[length + 2]; - ruleArguments[0] = arrayTypeSymbol.ElementType.ToDisplayString(); - ruleArguments[1] = serializableArrayType.Rule; - if (length > 0) - { - Array.Copy(serializableArrayType.RuleArguments!, 0, ruleArguments, 2, length); - } - - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - 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 ruleArguments = property.RuleArguments; - var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]]; - var arrayElementRuleArguments = new string[ruleArguments.Length - 2]; - Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2); - - var propertyIndex = $"{property.Name}Index"; - 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}{{"); - - var serializableArrayElement = new SerializableProperty - { - Name = $"{property.Name}[{propertyIndex}]", - Type = ruleArguments[0], - Rule = arrayElementRule.RuleName, - RuleArguments = arrayElementRuleArguments - }; - - arrayElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableArrayElement, parentReference); - - source.AppendLine($"{indent}}}"); - } - - public override 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 ruleArguments = property.RuleArguments; - var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]]; - var arrayElementRuleArguments = new string[ruleArguments.Length - 2]; - Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyIndex = $"{propertyVarPrefix}Index"; - var propertyLength = $"{propertyVarPrefix}Length"; - source.AppendLine($"{indent}var {propertyLength} = {property.Name}?.Length ?? 0;"); - source.AppendLine($"{indent}writer.WriteEncodedInt({propertyLength});"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyLength}; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableArrayElement = new SerializableProperty - { - Name = $"{property.Name}![{propertyIndex}]", - Type = ruleArguments[0], - Rule = arrayElementRule.RuleName, - RuleArguments = arrayElementRuleArguments - }; - - arrayElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableArrayElement); - - source.AppendLine($"{indent}}}"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs deleted file mode 100644 index caf0d1dc8..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs +++ /dev/null @@ -1,250 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: DictionaryMigrationRule.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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class DictionaryMigrationRule : MigrationRule -{ - public override string RuleName => nameof(DictionaryMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsDictionary(compilation)) - { - ruleArguments = null; - return false; - } - - var keySymbolType = namedTypeSymbol.TypeArguments[0]; - - var serializableKeyProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "KeyEntry", - keySymbolType, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var valueSymbolType = namedTypeSymbol.TypeArguments[1]; - - var serializableValueProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "ValueEntry", - valueSymbolType, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var extraOptions = ""; - if (attributes.Any(a => a.IsTidy(compilation))) - { - extraOptions += "@Tidy"; - } - - var keyArgumentsLength = serializableKeyProperty.RuleArguments?.Length ?? 0; - var valueArgumentsLength = serializableValueProperty.RuleArguments?.Length ?? 0; - var index = 0; - - ruleArguments = new string[7 + keyArgumentsLength + valueArgumentsLength]; - ruleArguments[index++] = extraOptions; - ruleArguments[index++] = keySymbolType.ToDisplayString(); - ruleArguments[index++] = serializableKeyProperty.Rule; - ruleArguments[index++] = keyArgumentsLength.ToString(); - - if (keyArgumentsLength > 0) - { - Array.Copy(serializableKeyProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength); - index += keyArgumentsLength; - } - - ruleArguments[index++] = valueSymbolType.ToDisplayString(); - ruleArguments[index++] = serializableValueProperty.Rule; - ruleArguments[index++] = valueArgumentsLength.ToString(); - - if (valueArgumentsLength > 0) - { - Array.Copy(serializableValueProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength); - } - - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - 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 ruleArguments = property.RuleArguments; - var index = 1; - var keyType = ruleArguments![index++]; - - var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (keyRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); - index += keyRuleArguments.Length; - } - - var valueType = ruleArguments[index++]; - var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (valueRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); - } - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyIndex = $"{propertyVarPrefix}Index"; - var propertyKeyEntry = $"{propertyVarPrefix}Key"; - var propertyValueEntry = $"{propertyVarPrefix}Value"; - var propertyCount = $"{propertyVarPrefix}Count"; - - source.AppendLine($"{indent}{ruleArguments[1]} {propertyKeyEntry};"); - source.AppendLine($"{indent}{valueType} {propertyValueEntry};"); - source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();"); - source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.Dictionary<{keyType}, {valueType}>({propertyCount});"); - source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableKeyElement = new SerializableProperty - { - Name = propertyKeyEntry, - Type = keyType, - Rule = keyElementRule.RuleName, - RuleArguments = keyRuleArguments - }; - - keyElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableKeyElement, parentReference); - - var serializableValueElement = new SerializableProperty - { - Name = propertyValueEntry, - Type = valueType, - Rule = valueElementRule.RuleName, - RuleArguments = valueRuleArguments - }; - - valueElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableValueElement, parentReference); - source.AppendLine($"{indent} {propertyName}.Add({propertyKeyEntry}, {propertyValueEntry});"); - - source.AppendLine($"{indent}}}"); - } - - public override 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 ruleArguments = property.RuleArguments; - var index = 0; - var shouldTidy = ruleArguments![index++].Contains("@Tidy"); - var keyType = ruleArguments![index++]; - - var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![index++]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (keyRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); - index += keyRuleArguments.Length; - } - - var valueType = ruleArguments[index++]; - var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (valueRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); - } - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyKeyEntry = $"{propertyVarPrefix}Key"; - var propertyValueEntry = $"{propertyVarPrefix}Value"; - var propertyCount = $"{propertyVarPrefix}Count"; - - if (shouldTidy) - { - source.AppendLine($"{indent}{property.Name}?.Tidy();"); - } - source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); - source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); - source.AppendLine($"{indent}if ({propertyCount} > 0)"); - source.AppendLine($"{indent}{{"); - source.AppendLine($"{indent} foreach (var ({propertyKeyEntry}, {propertyValueEntry}) in {property.Name}!)"); - source.AppendLine($"{indent} {{"); - - var serializableKeyElement = new SerializableProperty - { - Name = propertyKeyEntry, - Type = keyType, - Rule = keyElementRule.RuleName, - RuleArguments = keyRuleArguments - }; - - keyElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableKeyElement); - - var serializableValueElement = new SerializableProperty - { - Name = propertyValueEntry, - Type = valueType, - Rule = valueElementRule.RuleName, - RuleArguments = valueRuleArguments - }; - - valueElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableValueElement); - - source.AppendLine($"{indent} }}"); - source.AppendLine($"{indent}}}"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs deleted file mode 100644 index 5e8d7fd45..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************* - * 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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class EnumMigrationRule : MigrationRule -{ - public override string RuleName => nameof(EnumMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not ITypeSymbol typeSymbol || !typeSymbol.IsEnum()) - { - ruleArguments = null; - return false; - } - - ruleArguments = Array.Empty(); - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - var expectedRule = RuleName; - 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 override 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}."); - } - - source.AppendLine($"{indent}writer.WriteEnum<{property.Type}>({property.Name});"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs deleted file mode 100644 index 20fe03d08..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs +++ /dev/null @@ -1,171 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: HashSetMigrationRule.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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class HashSetMigrationRule : MigrationRule -{ - public override string RuleName => nameof(HashSetMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsHashSet(compilation)) - { - ruleArguments = null; - return false; - } - - var setTypeSymbol = namedTypeSymbol.TypeArguments[0]; - - var serializableSetType = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "SetEntry", - setTypeSymbol, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var extraOptions = ""; - if (attributes.Any(a => a.IsTidy(compilation))) - { - extraOptions += "@Tidy"; - } - - var length = serializableSetType.RuleArguments?.Length ?? 0; - ruleArguments = new string[length + 3]; - ruleArguments[0] = extraOptions; - ruleArguments[1] = setTypeSymbol.ToDisplayString(); - ruleArguments[2] = serializableSetType.Rule; - - if (length > 0) - { - Array.Copy(serializableSetType.RuleArguments, 0, ruleArguments, 3, length); - } - - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - 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 ruleArguments = property.RuleArguments; - var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); - var argumentsOffset = hasExtraOptions ? 1 : 0; - - var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]]; - var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; - Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyIndex = $"{propertyVarPrefix}Index"; - var propertyEntry = $"{propertyVarPrefix}Entry"; - var propertyCount = $"{propertyVarPrefix}Count"; - - source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};"); - 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; {propertyIndex} < {propertyCount}; {propertyIndex}++)"); - source.AppendLine($"{indent}{{"); - - var serializableSetElement = new SerializableProperty - { - Name = propertyEntry, - Type = ruleArguments[argumentsOffset], - Rule = setElementRule.RuleName, - RuleArguments = setElementRuleArguments - }; - - setElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableSetElement, parentReference); - source.AppendLine($"{indent} {property.Name}.Add({propertyEntry});"); - - source.AppendLine($"{indent}}}"); - } - - public override 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 ruleArguments = property.RuleArguments; - var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); - var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy"); - var argumentsOffset = hasExtraOptions ? 1 : 0; - - var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]]; - var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; - Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyEntry = $"{propertyVarPrefix}Entry"; - var propertyCount = $"{propertyVarPrefix}Count"; - - if (shouldTidy) - { - source.AppendLine($"{indent}{property.Name}?.Tidy();"); - } - source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); - source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); - source.AppendLine($"{indent}if ({propertyCount} > 0)"); - source.AppendLine($"{indent}{{"); - source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)"); - source.AppendLine($"{indent} {{"); - - var serializableSetElement = new SerializableProperty - { - Name = propertyEntry, - Type = ruleArguments[argumentsOffset], - Rule = setElementRule.RuleName, - RuleArguments = setElementRuleArguments - }; - - setElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableSetElement); - - source.AppendLine($"{indent} }}"); - source.AppendLine($"{indent}}}"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs deleted file mode 100644 index 5b7c4fbef..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs +++ /dev/null @@ -1,225 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: KeyValuePairMigrationRule.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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class KeyValuePairMigrationRule : MigrationRule -{ - public override string RuleName => nameof(KeyValuePairMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsKeyValuePair(compilation)) - { - ruleArguments = null; - return false; - } - - var keySymbolType = namedTypeSymbol.TypeArguments[0]; - - var keySerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "key", - keySymbolType, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var valueSymbolType = namedTypeSymbol.TypeArguments[1]; - - var valueSerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "value", - valueSymbolType, - 1, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var keyArgumentsLength = keySerializedProperty.RuleArguments?.Length ?? 0; - var valueArgumentsLength = valueSerializedProperty.RuleArguments?.Length ?? 0; - var index = 0; - - // Key - ruleArguments = new string[6 + keyArgumentsLength + valueArgumentsLength]; - ruleArguments[index++] = ""; // Extra options - ruleArguments[index++] = keySymbolType.ToDisplayString(); - ruleArguments[index++] = keySerializedProperty.Rule; - ruleArguments[index++] = keyArgumentsLength.ToString(); - if (keyArgumentsLength > 0) - { - Array.Copy(keySerializedProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength); - index += keyArgumentsLength; - } - - // Value - ruleArguments[index++] = valueSymbolType.ToDisplayString(); - ruleArguments[index++] = valueSerializedProperty.Rule; - - if (valueArgumentsLength > 0) - { - Array.Copy(valueSerializedProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength); - } - - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - 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 ruleArguments = property.RuleArguments; - var index = 1; // skip extra options - var keyType = ruleArguments![index++]; - var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (keyRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); - index += keyRuleArguments.Length; - } - - var serializableKeyProperty = new SerializableProperty - { - Name = "key", - Type = keyType, - Rule = keyRule.RuleName, - RuleArguments = keyRuleArguments - }; - - keyRule.GenerateDeserializationMethod( - source, - indent, - serializableKeyProperty, - parentReference - ); - - var valueType = ruleArguments[index++]; - var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (valueRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); - } - - var serializableValueProperty = new SerializableProperty - { - Name = "value", - Type = valueType, - Rule = valueRule.RuleName, - RuleArguments = valueRuleArguments - }; - - valueRule.GenerateDeserializationMethod( - source, - indent, - serializableValueProperty, - parentReference - ); - - source.AppendLine( - $"{indent}{property.Name} = new {SymbolMetadata.KEYVALUEPAIR_STRUCT}<{keyType}, {valueType}>(key, value);" - ); - } - - public override 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 ruleArguments = property.RuleArguments; - var index = 1; // skip extra options - var keyType = ruleArguments![index++]; - var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var keyRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (keyRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length); - index += keyRuleArguments.Length; - } - - var serializableKeyProperty = new SerializableProperty - { - Name = $"{property.Name}.Key", - Type = keyType, - Rule = keyRule.RuleName, - RuleArguments = keyRuleArguments - }; - - keyRule.GenerateSerializationMethod( - source, - indent, - serializableKeyProperty - ); - - var valueType = ruleArguments[index++]; - var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]]; - var valueRuleArguments = new string[int.Parse(ruleArguments[index++])]; - - if (valueRuleArguments.Length > 0) - { - Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length); - } - - var serializableValueProperty = new SerializableProperty - { - Name = $"{property.Name}.Value", - Type = valueType, - Rule = valueRule.RuleName, - RuleArguments = valueRuleArguments - }; - - valueRule.GenerateSerializationMethod( - source, - indent, - serializableValueProperty - ); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs deleted file mode 100644 index 53d2d2c44..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs +++ /dev/null @@ -1,172 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: ListMigrationRule.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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class ListMigrationRule : MigrationRule -{ - public override string RuleName => nameof(ListMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsList(compilation)) - { - ruleArguments = null; - return false; - } - - var listTypeSymbol = namedTypeSymbol.TypeArguments[0]; - - var serializableListType = SerializableMigrationRulesEngine.GenerateSerializableProperty( - compilation, - "ListEntry", - listTypeSymbol, - 0, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - null - ); - - var extraOptions = ""; - if (attributes.Any(a => a.IsTidy(compilation))) - { - extraOptions += "@Tidy"; - } - - var length = serializableListType.RuleArguments?.Length ?? 0; - ruleArguments = new string[length + 3]; - ruleArguments[0] = extraOptions; - ruleArguments[1] = listTypeSymbol.ToDisplayString(); - ruleArguments[2] = serializableListType.Rule; - - if (length > 0) - { - Array.Copy(serializableListType.RuleArguments!, 0, ruleArguments, 3, length); - } - - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - 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 ruleArguments = property.RuleArguments; - var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); - var argumentsOffset = hasExtraOptions ? 1 : 0; - - var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[argumentsOffset + 1]]; - - var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; - Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyIndex = $"{propertyVarPrefix}Index"; - var propertyEntry = $"{propertyVarPrefix}Entry"; - var propertyCount = $"{propertyVarPrefix}Count"; - - source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};"); - 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}{{"); - - var serializableListElement = new SerializableProperty - { - Name = propertyEntry, - Type = ruleArguments[argumentsOffset], - Rule = listElementRule.RuleName, - RuleArguments = listElementRuleArguments - }; - - listElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableListElement, parentReference); - source.AppendLine($"{indent} {propertyName}.Add({propertyEntry});"); - - source.AppendLine($"{indent}}}"); - } - - public override 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 ruleArguments = property.RuleArguments; - var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal); - var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy"); - var argumentsOffset = hasExtraOptions ? 1 : 0; - - var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]]; - var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset]; - Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset); - - var propertyName = property.Name; - var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}"; - var propertyEntry = $"{propertyVarPrefix}Entry"; - var propertyCount = $"{propertyVarPrefix}Count"; - - if (shouldTidy) - { - source.AppendLine($"{indent}{property.Name}?.Tidy();"); - } - source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;"); - source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});"); - source.AppendLine($"{indent}if ({propertyCount} > 0)"); - source.AppendLine($"{indent}{{"); - source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)"); - source.AppendLine($"{indent} {{"); - - var serializableListElement = new SerializableProperty - { - Name = propertyEntry, - Type = ruleArguments[argumentsOffset], - Rule = listElementRule.RuleName, - RuleArguments = listElementRuleArguments - }; - - listElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableListElement); - - source.AppendLine($"{indent} }}"); - source.AppendLine($"{indent}}}"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs deleted file mode 100644 index 848812b54..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public abstract class MigrationRule : ISerializableMigrationRule -{ - public abstract string RuleName { get; } - - public virtual void GenerateMigrationProperty( - StringBuilder source, Compilation compilation, string indent, SerializableProperty serializableProperty - ) - { - var propertyType = serializableProperty.Type; - var type = compilation.GetTypeByMetadataName(propertyType)?.IsValueType == true - || SymbolMetadata.IsPrimitiveFromTypeDisplayString(propertyType) && propertyType != "bool" - ? $"{propertyType}{(serializableProperty.UsesSaveFlag == true ? "?" : "")}" : propertyType; - - source.AppendLine($"{indent}internal readonly {type} {serializableProperty.Name};"); - } - - public abstract bool GenerateRuleState( - Compilation compilation, ISymbol symbol, ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, ISymbol? parentSymbol, out string[] ruleArguments - ); - - public abstract void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ); - - public abstract void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property); -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs deleted file mode 100644 index 70b34ce06..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs +++ /dev/null @@ -1,149 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: PrimitiveTypeMigrationRule.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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class PrimitiveTypeMigrationRule : MigrationRule -{ - public override string RuleName => nameof(PrimitiveTypeMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol.IsIpAddress(compilation) || symbol.IsTimeSpan(compilation)) - { - ruleArguments = Array.Empty(); - return true; - } - - if ( - symbol is not ITypeSymbol { - SpecialType: not (not - SpecialType.System_Boolean and not - SpecialType.System_SByte and not - SpecialType.System_Int16 and not - SpecialType.System_Int32 and not - SpecialType.System_Int64 and not - SpecialType.System_Byte and not - SpecialType.System_UInt16 and not - SpecialType.System_UInt32 and not - SpecialType.System_UInt64 and not - SpecialType.System_Single and not - SpecialType.System_Double and not - SpecialType.System_String and not - SpecialType.System_Decimal and not - SpecialType.System_DateTime) - } typeSymbol - ) - { - ruleArguments = null; - return false; - } - - ruleArguments = typeSymbol.SpecialType switch - { - 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" }, - _ => new[] { "" } - }; - - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - 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 argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null; - - const string ipAddress = SymbolMetadata.IPADDRESS_CLASS; - const string timeSpan = SymbolMetadata.TIMESPAN_STRUCT; - const string date = "System.DateTime"; - - var readMethod = property.Type switch - { - "bool" => "ReadBool", - "sbyte" => "ReadSByte", - "short" => "ReadShort", - "int" when argument == "EncodedInt" => "ReadEncodedInt", - "int" => "ReadInt", - "long" => "ReadLong", - "byte" => "ReadByte", - "ushort" => "ReadUShort", - "uint" => "ReadUInt", - "ulong" => "ReadULong", - "float" => "ReadFloat", - "double" => "ReadDouble", - "string" => "ReadString", - "decimal" => "ReadDecimal", - date when argument == "DeltaTime" => "ReadDeltaTime", - date => "ReadDateTime", - ipAddress => "ReadIPAddress", - timeSpan => "ReadTimeSpan" - }; - - var readArgument = readMethod == "ReadString" && argument == "InternString" ? "true" : ""; - - source.AppendLine($"{indent}{propertyName} = reader.{readMethod}({readArgument});"); - } - - public override 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 argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null; - - var writeMethod = property.Type switch - { - "System.DateTime" when argument == "DeltaTime" => "WriteDeltaTime", - "int" when argument == "EncodedInt" => "WriteEncodedInt", - _ => "Write" - }; - - source.AppendLine($"{indent}writer.{writeMethod}({propertyName});"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs deleted file mode 100644 index ec2ea15d3..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: PrimitiveUOTypeMigrationRule.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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class PrimitiveUOTypeMigrationRule : MigrationRule -{ - public override string RuleName => nameof(PrimitiveUOTypeMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - ruleArguments = symbol switch - { - _ when symbol.IsPoint2D(compilation) => new[] { "Point2D" }, - _ when symbol.IsPoint3D(compilation) => new[] { "Point3D" }, - _ when symbol.IsRectangle2D(compilation) => new[] { "Rect2D" }, - _ when symbol.IsRectangle3D(compilation) => new[] { "Rect3D" }, - _ when symbol.IsRace(compilation) => new[] { "Race" }, - _ when symbol.IsMap(compilation) => new[] { "Map" }, - _ when symbol.IsBitArray(compilation) => new[] { "BitArray" }, - _ => null - }; - - return ruleArguments != null; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - 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} = reader.Read{property.RuleArguments?[0] ?? ""}();"); - } - - public override 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}writer.Write({propertyName});"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs deleted file mode 100644 index 8f0944f1d..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * 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 * - * 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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class RawSerializableMigrationRule : MigrationRule -{ - public override string RuleName => nameof(RawSerializableMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is not ITypeSymbol typeSymbol) - { - ruleArguments = null; - return false; - } - - if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes)) - { - ruleArguments = null; - return false; - } - - ruleArguments = new[] { "" }; - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - 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}({parentReference ?? "this"});"); - source.AppendLine($"{indent}{propertyName}.Deserialize(reader);"); - } - - public override 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);"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs deleted file mode 100644 index 2326af110..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs +++ /dev/null @@ -1,75 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableInterfaceMigrationRule.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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class SerializableInterfaceMigrationRule : MigrationRule -{ - public override string RuleName => nameof(SerializableInterfaceMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if (symbol is ITypeSymbol typeSymbol && typeSymbol.HasSerializableInterface(compilation, serializableTypes)) - { - ruleArguments = Array.Empty(); - return true; - } - - ruleArguments = null; - return false; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - 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} = reader.ReadEntity<{property.Type}>();"); - } - - public override 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}writer.Write({propertyName});"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs deleted file mode 100644 index 4e9859170..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializationMethodSignatureMigrationRule.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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class SerializationMethodSignatureMigrationRule : MigrationRule -{ - public override string RuleName => nameof(SerializationMethodSignatureMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - out string[] ruleArguments - ) - { - if ((symbol as ITypeSymbol)?.HasPublicSerializeMethod(compilation, serializableTypes) != true) - { - ruleArguments = null; - return false; - } - - if (symbol is not INamedTypeSymbol namedTypeSymbol || - !namedTypeSymbol.HasGenericReaderCtor(compilation, parentSymbol, out var requiresParent)) - { - ruleArguments = null; - return false; - } - - ruleArguments = new[] { requiresParent ? "DeserializationRequiresParent" : "" }; - return true; - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - 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 argument = property.RuleArguments?.Length >= 1 && - property.RuleArguments[0] == "DeserializationRequiresParent" ? ", this" : ""; - - source.AppendLine($"{indent}{propertyName} = new {property.Type}(reader{argument});"); - } - - public override 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);"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs deleted file mode 100644 index 7d97dfd6e..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs +++ /dev/null @@ -1,136 +0,0 @@ -/************************************************************************* - * 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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration; - -public class TimerMigrationRule : MigrationRule, IPostDeserializeMethod -{ - public override string RuleName => nameof(TimerMigrationRule); - - public override bool GenerateRuleState( - Compilation compilation, - ISymbol symbol, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray 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 override void GenerateMigrationProperty( - StringBuilder source, Compilation compilation, string indent, SerializableProperty serializableProperty - ) - { - source.AppendLine($"{indent}internal readonly System.DateTime {serializableProperty.Name}Next;"); - source.AppendLine($"{indent}internal readonly System.TimeSpan {serializableProperty.Name}Delay;"); - } - - public override void GenerateDeserializationMethod( - StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false - ) - { - 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()"; - var useVar = isMigration ? "" : "var "; - source.AppendLine($"{indent}{useVar}{propertyName}Next = {readTimer};"); - source.AppendLine($"{indent}{useVar}{propertyName}Delay = {propertyName}Next == System.DateTime.MinValue ? System.TimeSpan.MinValue : {propertyName}Next - Core.Now;"); - } - - public override 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 ?? System.DateTime.MinValue);"); - } - - public void PostDeserializeMethod( - StringBuilder source, string indent, SerializableProperty property, Compilation compilation, INamedTypeSymbol classSymbol - ) - { - var deserializeTimerMethod = classSymbol - .GetMembers() - .OfType() - .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);"); - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadata.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMetadata.cs deleted file mode 100644 index a7a8a6b81..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadata.cs +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableMigration.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 . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text.Json.Serialization; - -namespace SerializableMigration -{ - public record SerializableMetadata - { - [JsonPropertyName("version")] - public int Version { get; init; } - - [JsonPropertyName("type")] - public string Type { get; init; } - - [JsonPropertyName("properties")] - public ImmutableArray? Properties { get; init; } - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs deleted file mode 100644 index 13fd600b2..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Collections.Generic; - -namespace SerializableMigration -{ - public class SerializableMetadataComparer : IComparer - { - public int Compare(SerializableMetadata x, SerializableMetadata y) - { - if (ReferenceEquals(x, y)) - { - return 0; - } - - if (ReferenceEquals(null, y)) - { - return 1; - } - - if (ReferenceEquals(null, x)) - { - return -1; - } - - return x.Version.CompareTo(y.Version); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs deleted file mode 100644 index 1fe3e32f5..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableMigrationRulesEngine.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 . * - *************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using Microsoft.CodeAnalysis; -using SerializationGenerator; - -namespace SerializableMigration -{ - public static class SerializableMigrationRulesEngine - { - public static readonly Dictionary Rules = new(); - - static SerializableMigrationRulesEngine() - { - var rules = new ISerializableMigrationRule[] - { - new EnumMigrationRule(), - new ListMigrationRule(), - new ArrayMigrationRule(), - new HashSetMigrationRule(), - new DictionaryMigrationRule(), - new KeyValuePairMigrationRule(), - new PrimitiveTypeMigrationRule(), - new PrimitiveUOTypeMigrationRule(), - new SerializableInterfaceMigrationRule(), - new SerializationMethodSignatureMigrationRule(), - new RawSerializableMigrationRule(), - new TimerMigrationRule() - }; - - foreach (var rule in rules) - { - Rules.Add(rule.RuleName, rule); - } - } - - public static SerializableProperty? GenerateSerializableProperty( - Compilation compilation, - ISymbol fieldOrPropertySymbol, - int order, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - SerializableFieldSaveFlagMethods? serializableFieldSaveFlagMethods - ) - { - string propertyName; - ITypeSymbol propertyType; - - if (fieldOrPropertySymbol is IFieldSymbol fieldSymbol) - { - propertyName = fieldSymbol.Name; - propertyType = fieldSymbol.Type; - } - else if (fieldOrPropertySymbol is IPropertySymbol propertySymbol) - { - propertyName = fieldOrPropertySymbol.Name; - propertyType = propertySymbol.Type; - } - else - { - return null; - } - - return GenerateSerializableProperty( - compilation, - propertyName, - propertyType, - order, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - serializableFieldSaveFlagMethods - ); - } - - public static SerializableProperty GenerateSerializableProperty( - Compilation compilation, - string propertyName, - ISymbol propertyType, - int order, - ImmutableArray attributes, - ImmutableArray serializableTypes, - ImmutableArray embeddedSerializableTypes, - ISymbol? parentSymbol, - SerializableFieldSaveFlagMethods? serializableFieldSaveFlagMethods - ) - { - foreach (var rule in Rules.Values) - { - if (rule.GenerateRuleState( - compilation, - propertyType, - attributes, - serializableTypes, - embeddedSerializableTypes, - parentSymbol, - out var ruleArguments - )) - { - return new SerializableProperty - { - Name = propertyName, - Type = propertyType.ToDisplayString(), - Order = order, - UsesSaveFlag = serializableFieldSaveFlagMethods?.DetermineFieldShouldSerialize != null ? true : null, - Rule = rule.RuleName, - RuleArguments = ruleArguments.Length > 0 ? ruleArguments : null - }; - } - } - - throw new Exception($"No rule found for property {propertyName} of type {propertyType} ({Rules.Count})"); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs deleted file mode 100644 index 2f8613456..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableMigrationSchema.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 . * - *************************************************************************/ - -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Text.RegularExpressions; -using Microsoft.CodeAnalysis; - -namespace SerializableMigration -{ - public static class SerializableMigrationSchema - { - public static JsonSerializerOptions GetJsonSerializerOptions() => - new() - { - WriteIndented = true, - AllowTrailingCommas = true, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, - ReadCommentHandling = JsonCommentHandling.Skip - }; - - private static Dictionary _cache = new(); - - private static readonly Regex _fileRegex = new(@"\S+\.v\d+\.json$"); - - public static List GetMigrations( - INamedTypeSymbol typeSymbol, - int version, - string migrationPath, - JsonSerializerOptions options - ) - { - var typeName = typeSymbol.ToDisplayString(); - var migrations = new SortedSet(new SerializableMetadataComparer()); - - var migrationFiles = Directory.GetFiles(migrationPath, $"{typeName}.v*.json"); - - foreach (var file in migrationFiles) - { - var fi = new FileInfo(file); - if (!_cache.TryGetValue(fi.Name, out var migration)) - { - var text = File.ReadAllText(file, Encoding.UTF8); - migration = JsonSerializer.Deserialize(text, options); - _cache[fi.Name] = migration; - } - - if (typeName == migration!.Type && version > migration.Version) - { - migrations.Add(migration); - } - } - - return migrations.ToList(); - } - - public static List GetMigrationsByAnalyzerConfig( - this GeneratorExecutionContext context, - INamedTypeSymbol typeSymbol, - int version, - JsonSerializerOptions options - ) - { - var typeName = typeSymbol.ToDisplayString(); - var migrations = new SortedSet(new SerializableMetadataComparer()); - - foreach (var additionalText in context.AdditionalFiles) - { - var fi = new FileInfo(additionalText.Path); - if (!_fileRegex.IsMatch(fi.Name)) - { - continue; - } - - if (!_cache.TryGetValue(fi.Name, out var migration)) - { - var text = additionalText.GetText(context.CancellationToken)?.ToString(); - if (text == null) - { - continue; - } - - migration = JsonSerializer.Deserialize(text, options); - _cache[fi.Name] = migration; - } - - if (typeName == migration!.Type && version > migration.Version) - { - migrations.Add(migration); - } - } - - return migrations.ToList(); - } - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs deleted file mode 100644 index 1f6f0c55e..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializableProperty.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 . * - *************************************************************************/ - -using System.Text.Json.Serialization; - -namespace SerializableMigration -{ - public record SerializableProperty - { - [JsonPropertyName("name")] - public string Name { get; init; } - - [JsonPropertyName("type")] - public string Type { get; init; } - - [JsonPropertyName("usesSaveFlag")] - public bool? UsesSaveFlag { get; init; } - - [JsonPropertyName("rule")] - public string Rule { get; init; } - - [JsonPropertyName("ruleArguments")] - public string[]? RuleArguments { get; init; } - - [JsonIgnore] - public int Order { get; init; } - } -} diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs b/Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs deleted file mode 100644 index d4b736978..000000000 --- a/Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SerializablePropertyComparer.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 . * - *************************************************************************/ - -using System.Collections.Generic; - -namespace SerializableMigration -{ - public class SerializablePropertyComparer : IComparer - { - public int Compare(SerializableProperty x, SerializableProperty y) - { - if (Equals(x, y)) - { - return 0; - } - - if (Equals(null, y)) - { - return 1; - } - - if (Equals(null, x)) - { - return -1; - } - - return x.Order.CompareTo(y.Order); - } - } -} diff --git a/Projects/SerializationGenerator/SerializationGenerator.csproj b/Projects/SerializationGenerator/SerializationGenerator.csproj deleted file mode 100755 index 10448f42f..000000000 --- a/Projects/SerializationGenerator/SerializationGenerator.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - netstandard2.0 - preview - analyzers - - - - - - - - - - - - - - $(GetTargetPathDependsOn);GetDependencyTargetPaths - - - - - - - - - - - - diff --git a/Projects/SerializationGenerator/SerializerSyntaxReceiver.cs b/Projects/SerializationGenerator/SerializerSyntaxReceiver.cs deleted file mode 100755 index fea02e69d..000000000 --- a/Projects/SerializationGenerator/SerializerSyntaxReceiver.cs +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SyntaxReceiver.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 . * - *************************************************************************/ - -using System.Collections.Generic; -using System.Collections.Immutable; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace SerializationGenerator -{ - public class SerializerSyntaxReceiver : ISyntaxContextReceiver - { -#pragma warning disable RS1024 - public Dictionary)> ClassAndFields { get; } = new(SymbolEqualityComparer.Default); - public Dictionary)> EmbeddedClassAndFields { get; } = new(SymbolEqualityComparer.Default); -#pragma warning restore RS1024 - - public ImmutableArray SerializableList => ClassAndFields.Keys.ToImmutableArray(); - - public ImmutableArray EmbeddedSerializableList => EmbeddedClassAndFields.Keys.ToImmutableArray(); - - public void OnVisitSyntaxNode(SyntaxNode node, SemanticModel semanticModel) - { - var compilation = semanticModel.Compilation; - - if (node is ClassDeclarationSyntax { AttributeLists: { Count: > 0 } } classDeclarationSyntax) - { - if (semanticModel.GetDeclaredSymbol(classDeclarationSyntax) is not INamedTypeSymbol classSymbol) - { - return; - } - - 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())); - } - } - else if (classSymbol.WillBeSerializable(compilation, out attrData)) - { - if (ClassAndFields.TryGetValue(classSymbol, out var value)) - { - var (_, fieldsList) = value; - ClassAndFields[classSymbol] = (attrData, fieldsList); - } - else - { - ClassAndFields.Add(classSymbol, (attrData, new List())); - } - } - - return; - } - - if (node is FieldDeclarationSyntax { AttributeLists: { Count: > 0 } } fieldDeclarationSyntax) - { - foreach (var variable in fieldDeclarationSyntax.Declaration.Variables) - { - if (semanticModel.GetDeclaredSymbol(variable) is IFieldSymbol fieldSymbol) - { - AddFieldOrProperty(fieldSymbol, compilation); - } - } - - return; - } - - if (node is PropertyDeclarationSyntax { AttributeLists: { Count: > 0 } } propertyDeclarationSyntax) - { - if (semanticModel.GetDeclaredSymbol(propertyDeclarationSyntax) is IPropertySymbol propertySymbol) - { - AddFieldOrProperty(propertySymbol, compilation); - } - } - } - - public void OnVisitSyntaxNode(GeneratorSyntaxContext context) => - OnVisitSyntaxNode(context.Node, context.SemanticModel); - - 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 && symbol.GetAttribute(parentAttr) == null) - { - return; - } - - var classSymbol = symbol.ContainingType; - if (ClassAndFields.TryGetValue(classSymbol, out var value)) - { - var (_, fieldsList) = value; - fieldsList.Add(symbol); - 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 { symbol })); - } - else if (classSymbol.IsEmbeddedSerializable(compilation, out attrData)) - { - EmbeddedClassAndFields.Add(classSymbol, (attrData, new List { symbol })); - } - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/Helpers.cs b/Projects/SerializationGenerator/SourceGeneration/Helpers.cs deleted file mode 100644 index f1a9a88e5..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/Helpers.cs +++ /dev/null @@ -1,65 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: Helpers.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 . * - *************************************************************************/ - -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; - -namespace SerializationGenerator -{ - public static class Helpers - { - public static bool ContainsInterface(this ITypeSymbol symbol, ISymbol interfaceSymbol) => - symbol.Interfaces.Any(i => i.ConstructedFrom.Equals(interfaceSymbol, SymbolEqualityComparer.Default)) || - symbol.AllInterfaces.Any(i => i.ConstructedFrom.Equals(interfaceSymbol, SymbolEqualityComparer.Default)); - - public static ImmutableArray GetAllMethods(this ITypeSymbol symbol, string name) - { - var methods = symbol.GetMembers(name).OfType().ToImmutableArray(); - if (symbol.ContainingSymbol is not ITypeSymbol typeSymbol) - { - return methods; - } - - var list = new List(); - list.AddRange(methods.ToList()); - list.AddRange(GetAllMethods(typeSymbol, name).ToList()); - - return list.ToImmutableArray(); - } - - public static string ToFriendlyString(this Accessibility accessibility) => SyntaxFacts.GetText(accessibility); - - public static Accessibility GetAccessibility(string? value) => - value switch - { - "private" => Accessibility.Private, - "protected" => Accessibility.Protected, - "internal" => Accessibility.Internal, - "public" => Accessibility.Public, - "protected internal" => Accessibility.ProtectedOrInternal, - "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); - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs deleted file mode 100644 index 53dc5823c..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Arguments.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 . * - *************************************************************************/ - -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static void GetTypesFromTypedConstant(TypedConstant arg, List list) - { - if (arg.Kind == TypedConstantKind.Type) - { - list.Add((ITypeSymbol)arg.Value); - } - else if (arg.Kind == TypedConstantKind.Array) - { - for (var i = 0; i < arg.Values.Length; i++) - { - GetTypesFromTypedConstant(arg.Values[i], list); - } - } - } - - public static void GenerateSignatureArguments(this StringBuilder source, ImmutableArray<(ITypeSymbol, string)> parameters) - { - for (var i = 0; i < parameters.Length; i++) - { - var (t, v) = parameters[i]; - source.AppendFormat("{0} {1}", t.ToDisplayString(), v); - if (i < parameters.Length - 1) - { - source.Append(", "); - } - } - } - - public static void GenerateNamedArgument(this StringBuilder source, KeyValuePair namedArg) - { - source.AppendFormat("{0} = ", namedArg.Key); - source.GenerateTypedConstant(namedArg.Value); - } - - public static void GenerateTypedConstants(this StringBuilder source, ImmutableArray args) - { - source.Append("new []{"); - for (var i = 0; i < args.Length; i++) - { - source.GenerateTypedConstant(args[i]); - if (i < args.Length - 1) - { - source.Append(", "); - } - } - source.Append('}'); - } - - public static void GenerateTypedConstant(this StringBuilder source, TypedConstant arg) - { - if (arg.IsNull) - { - source.Append("null"); - return; - } - - switch (arg.Kind) - { - default: - { - return; - } - case TypedConstantKind.Primitive: - { - - if (arg.Value is string str) - { - source.AppendFormat("\"{0}\"", str); - } - else - { - source.Append(arg.Value); - } - break; - } - case TypedConstantKind.Enum: - { - if (arg.Type == null || arg.Value == null) - { - source.Append("null"); - } - else - { - source.AppendFormat("({0}){1}", arg.Type.ToDisplayString(), arg.Value); - } - break; - } - case TypedConstantKind.Type: - { - source.AppendFormat("typeof({0})", ((ITypeSymbol)arg.Value)?.Name); - break; - } - case TypedConstantKind.Array: - { - source.GenerateTypedConstants(arg.Values); - break; - } - } - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Attribute.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Attribute.cs deleted file mode 100644 index eda4cf08c..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Attribute.cs +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Attribute.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 . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static void GenerateAttribute( - this StringBuilder source, - string indent, - string attrClassName, - ImmutableArray args - ) - { - source.Append($"{indent}[{attrClassName}"); - var hasArgs = args.Length > 0; - - if (hasArgs) - { - source.Append("("); - } - - for (var i = 0; i < args.Length; i++) - { - var arg = args[i]; - source.GenerateTypedConstant(arg); - if (i < args.Length - 1) - { - source.Append(", "); - } - } - - if (hasArgs) - { - source.Append(")"); - } - - source.AppendLine("]"); - } - - public static void GenerateAttribute(this StringBuilder source, AttributeData attr) - { - source.Append($" [{attr.AttributeClass?.Name}"); - var ctorArgs = attr.ConstructorArguments; - var namedArgs = attr.NamedArguments; - var hasArgs = ctorArgs.Length + namedArgs.Length > 0; - - if (hasArgs) - { - source.Append("("); - } - - for (var i = 0; i < ctorArgs.Length; i++) - { - var arg = ctorArgs[i]; - source.GenerateTypedConstant(arg); - if (i < ctorArgs.Length - 1) - { - source.Append(", "); - } - } - - for (var i = 0; i < namedArgs.Length; i++) - { - var arg = namedArgs[i]; - source.GenerateNamedArgument(arg); - if (i < namedArgs.Length - 1) - { - source.Append(", "); - } - } - - if (hasArgs) - { - source.Append(")"); - } - - source.AppendLine("]"); - } - - public static void AggressiveInline(this StringBuilder source, string indent) => - source.AppendLine( - $"{indent}[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]" - ); - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs deleted file mode 100644 index c25999cd8..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Class.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 . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static void GenerateClassStart( - this StringBuilder source, - INamedTypeSymbol classSymbol, - string indent, - ImmutableArray interfaces, - bool isPartial = true - ) - { - var accessor = classSymbol.DeclaredAccessibility; - source.Append($"{indent}{accessor.ToFriendlyString()} {(isPartial ? "partial " : "")}class {classSymbol.Name}"); - if (!interfaces.IsEmpty) - { - source.Append(" : "); - for (var i = 0; i < interfaces.Length; i++) - { - source.Append(interfaces[i].ToDisplayString()); - if (i < interfaces.Length - 1) - { - source.Append(", "); - } - } - } - - source.AppendLine($"\n{indent}{{"); - } - - public static void GenerateClassEnd(this StringBuilder source, string indent) - { - source.AppendLine($"{indent}}}"); - } - - // TODO: Generalize this to any field using dynamic indentation - public static void GenerateClassField( - this StringBuilder source, - string indent, - Accessibility accessors, - InstanceModifier instance, - string type, - string variableName, - string value - ) - { - var instanceStr = instance == InstanceModifier.None ? "" : $"{instance.ToFriendlyString()} "; - var accessorStr = accessors == Accessibility.NotApplicable ? "" : $"{accessors.ToFriendlyString()} "; - var valueStr = value == null ? "" : $" = {value}"; - source.AppendLine($"{indent}{accessorStr}{instanceStr}{type} {variableName}{valueStr};"); - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Enum.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Enum.cs deleted file mode 100644 index 6f8213561..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Enum.cs +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Enum.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 . * - *************************************************************************/ - -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static void GenerateEnumStart( - this StringBuilder source, - string enumName, - string indent, - bool useFlags, - Accessibility accessor = Accessibility.Public - ) - { - if (useFlags) - { - source.AppendLine($"{indent}[System.Flags]"); - } - source.AppendLine($"{indent}{accessor.ToFriendlyString()} enum {enumName}\n{indent}{{"); - } - - public static void GenerateEnumValue(this StringBuilder source, string indent, bool isFlag, string name, int value) - { - var number = value < 0 ? 0 : 1 << value; - var valueStr = isFlag ? $"0x{number:X8}" : value.ToString(); - source.AppendLine($"{indent}{name} = {valueStr},"); - } - - public static void GenerateEnumEnd(this StringBuilder source, string indent) - { - source.AppendLine($"{indent}}}"); - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.InstanceModifier.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.InstanceModifier.cs deleted file mode 100644 index 2fdfef6da..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.InstanceModifier.cs +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.InstanceModifier.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 . * - *************************************************************************/ - -namespace SerializationGenerator -{ - public enum InstanceModifier - { - None, - Const, - ReadOnly, - Static, - StaticReadOnly - } - - public static partial class SourceGeneration - { - public static string ToFriendlyString(this InstanceModifier modifier) => - modifier switch - { - InstanceModifier.Const => "const", - InstanceModifier.ReadOnly => "readonly", - InstanceModifier.Static => "static", - InstanceModifier.StaticReadOnly => "static readonly", - _ => "" - }; - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Method.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Method.cs deleted file mode 100644 index 407fd3e32..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Method.cs +++ /dev/null @@ -1,62 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Method.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 . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static void GenerateMethodStart( - this StringBuilder source, string indent, string methodName, Accessibility accessors, bool isOverride, - string returnType, ImmutableArray<(ITypeSymbol, string)> parameters - ) - { - source.Append($"{indent}{accessors.ToFriendlyString()}{(isOverride ? " override" : "")} {returnType} {methodName}("); - source.GenerateSignatureArguments(parameters); - source.AppendLine($")\n{indent}{{"); - } - - public static void GenerateMethodEnd(this StringBuilder source, string indent) => source.AppendLine($"{indent}}}"); - - public static void GenerateConstructorStart( - this StringBuilder source, string indent, string className, Accessibility accessors, ImmutableArray<(ITypeSymbol, string)> parameters, - ImmutableArray baseParameters, bool isOverload = false - ) - { - source.Append($"{indent}{accessors.ToFriendlyString()} {className}("); - source.GenerateSignatureArguments(parameters); - source.Append(')'); - bool hasBaseParams = baseParameters.Length > 0; - if (hasBaseParams) - { - source.AppendFormat(" : {0}(", isOverload ? "this" : "base"); - for (int i = 0; i < baseParameters.Length; i++) - { - source.Append(baseParameters[i]); - if (i < baseParameters.Length - 1) - { - source.Append(','); - } - } - source.Append(')'); - } - - source.AppendLine($"\n{indent}{{"); - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Namespace.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Namespace.cs deleted file mode 100644 index 24ced2544..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Namespace.cs +++ /dev/null @@ -1,33 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Namespace.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 . * - *************************************************************************/ - -using System.Text; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static void GenerateNamespaceStart(this StringBuilder source, string namespaceName) - { - source.AppendLine($@"namespace {namespaceName} -{{"); - } - - public static void GenerateNamespaceEnd(this StringBuilder source) - { - source.AppendLine("}"); - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Property.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Property.cs deleted file mode 100644 index fc66bc985..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Property.cs +++ /dev/null @@ -1,144 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceGeneration.Property.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 . * - *************************************************************************/ - -using System; -using System.Text; -using Humanizer; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SourceGeneration - { - public static string GetPropertyName(this IFieldSymbol fieldSymbol) - { - var fieldName = fieldSymbol.Name; - - var propertyName = fieldName; - - if (propertyName.StartsWith("m_", StringComparison.OrdinalIgnoreCase)) - { - propertyName = propertyName.Substring(2); - } - else if (propertyName.StartsWith("_", StringComparison.OrdinalIgnoreCase)) - { - propertyName = propertyName.Substring(1); - } - - return propertyName.Dehumanize(); - } - - public static void GeneratePropertyStart( - this StringBuilder source, - string indent, - Accessibility accessors, - bool isVirtual, - IFieldSymbol fieldSymbol - ) - { - var propertyName = fieldSymbol.GetPropertyName(); - var virt = isVirtual ? "virtual " : ""; - - source.AppendLine($"{indent}{accessors.ToFriendlyString()} {virt}{fieldSymbol.Type} {propertyName}"); - source.AppendLine($"{indent}{{"); - } - - public static void GenerateAutoProperty( - this StringBuilder source, - Accessibility accessors, - string type, - string propertyName, - Accessibility? getAccessor, - Accessibility? setAccessor, - string indent, - bool useInit = false, - string defaultValue = null, - bool isOverride = false - ) - { - if (getAccessor == null && setAccessor == null) - { - throw new ArgumentNullException($"Must specify a {nameof(getAccessor)} or {nameof(setAccessor)} parameter"); - } - - var getter = getAccessor == null ? - "" : - $"{(getAccessor != Accessibility.NotApplicable ? $"{getAccessor.Value.ToFriendlyString()} " : "")}get;"; - - var getterSpace = getAccessor != null ? " " : ""; - var setOrInit = useInit ? "init;" : "set;"; - - var setterAccessor = setAccessor is null or Accessibility.NotApplicable - ? "" - : $"{setAccessor.Value.ToFriendlyString() ?? ""} "; - - var setter = setAccessor == null ? "" : $"{getterSpace}{setterAccessor}{setOrInit}"; - - var propertyAccessor = accessors == Accessibility.NotApplicable ? "" : $"{accessors.ToFriendlyString()} "; - var printOverride = isOverride ? "override " : ""; - var printDefaultValue = defaultValue != null ? $"{(setAccessor != null ? " =" : "")} {defaultValue};" : ""; - var printGetterSetter = setAccessor == null ? "=>" : $"{{ {getter}{setter} }}"; - - source.AppendLine($"{indent}{propertyAccessor}{printOverride}{type} {propertyName} {printGetterSetter}{printDefaultValue}"); - } - - public static void GeneratePropertyEnd(this StringBuilder source, string indent) => source.AppendLine($"{indent}}}"); - - public static void GeneratePropertyGetterReturnsField( - this StringBuilder source, - string indent, - IFieldSymbol fieldSymbol, - Accessibility Accessibility - ) - { - var accessor = Accessibility != Accessibility.NotApplicable ? $"{Accessibility.ToFriendlyString()} " : ""; - source.AppendLine($"{indent}{accessor}get => {fieldSymbol.Name};"); - } - - public static void GeneratePropertyGetterStart( - this StringBuilder source, - string indent, - bool useExpression, - Accessibility Accessibility - ) - { - var accessor = Accessibility != Accessibility.NotApplicable ? $"{Accessibility.ToFriendlyString()} " : ""; - var expression = useExpression ? " => " : $"\n{indent}{{"; - source.AppendLine($"{indent}{accessor}get{expression}"); - } - - public static void GeneratePropertyGetSetEnd(this StringBuilder source, string indent, bool useExpression) - { - if (!useExpression) - { - source.AppendLine($"{indent}}}"); - } - } - - public static void GeneratePropertySetterStart( - this StringBuilder source, - string indent, - bool useExpression, - Accessibility Accessibility, - bool useInit = false - ) - { - var init = useInit ? "init" : "set"; - var expression = useExpression ? " => " : $"\n{indent}{{"; - var accessor = Accessibility != Accessibility.NotApplicable ? $"{Accessibility.ToFriendlyString()} " : ""; - source.AppendLine($"{indent}{accessor}{init}{expression}"); - } - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs b/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs deleted file mode 100644 index 28241d463..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs +++ /dev/null @@ -1,69 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SymbolMetadata.Builtin.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 . * - *************************************************************************/ - -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SymbolMetadata - { - public const string DICTIONARY_CLASS = "System.Collections.Generic.Dictionary`2"; - public const string LIST_CLASS = "System.Collections.Generic.List`1"; - public const string HASHSET_CLASS = "System.Collections.Generic.HashSet`1"; - public const string IPADDRESS_CLASS = "System.Net.IPAddress"; - public const string KEYVALUEPAIR_STRUCT = "System.Collections.Generic.KeyValuePair"; - public const string TIMESPAN_STRUCT = "System.TimeSpan"; - - public static bool IsTimeSpan(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(TIMESPAN_STRUCT), - SymbolEqualityComparer.Default - ); - - public static bool IsIpAddress(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(IPADDRESS_CLASS), - SymbolEqualityComparer.Default - ); - - public static bool IsKeyValuePair(this ISymbol symbol, Compilation compilation) => - (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals( - compilation.GetTypeByMetadataName(KEYVALUEPAIR_STRUCT), - SymbolEqualityComparer.Default - ) == true; - - public static bool IsDictionary(this ISymbol symbol, Compilation compilation) => - (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals( - compilation.GetTypeByMetadataName(DICTIONARY_CLASS), - SymbolEqualityComparer.Default - ) == true; - - public static bool IsHashSet(this ISymbol symbol, Compilation compilation) => - (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals( - compilation.GetTypeByMetadataName(HASHSET_CLASS), - SymbolEqualityComparer.Default - ) == true; - - public static bool IsList(this ISymbol symbol, Compilation compilation) => - (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals( - compilation.GetTypeByMetadataName(LIST_CLASS), - SymbolEqualityComparer.Default - ) == true; - - public static bool IsPrimitiveFromTypeDisplayString(string type) => - type is "bool" or "sbyte" or "short" or "int" or "long" or "byte" or "ushort" - or "uint" or "ulong" or "float" or "double" or "string" or "decimal"; - } -} diff --git a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs b/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs deleted file mode 100644 index 2fdf8793c..000000000 --- a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs +++ /dev/null @@ -1,228 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SymbolMetadata.UO.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 . * - *************************************************************************/ - -using System.Collections.Immutable; -using System.Linq; -using Microsoft.CodeAnalysis; - -namespace SerializationGenerator -{ - public static partial class SymbolMetadata - { - 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"; - public const string GENERIC_WRITER_INTERFACE = "Server.IGenericWriter"; - public const string GENERIC_READER_INTERFACE = "Server.IGenericReader"; - public const string DELTA_DATE_TIME_ATTRIBUTE = "Server.DeltaDateTimeAttribute"; - public const string INTERN_STRING_ATTRIBUTE = "Server.InternStringAttribute"; - public const string ENCODED_INT_ATTRIBUTE = "Server.EncodedIntAttribute"; - public const string TIDY_ATTRIBUTE = "Server.TidyAttribute"; - public const string POINT2D_STRUCT = "Server.Point2D"; - public const string POINT3D_STRUCT = "Server.Point3D"; - public const string RECTANGLE2D_STRUCT = "Server.Rectangle2D"; - 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 const string SERIALIZABLE_FIELD_SAVE_FLAG_ATTRIBUTE = "Server.SerializableFieldSaveFlagAttribute"; - public const string SERIALIZABLE_FIELD_DEFAULT_ATTRIBUTE = "Server.SerializableFieldDefaultAttribute"; - public const string RAW_SERIALIZABLE_INTERFACE = "Server.IRawSerializable"; - // ModernUO modified BitArray - public const string SERVER_BITARRAY_CLASS = "Server.Collections.BitArray"; - - 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; - - public static bool IsDeltaDateTime(this AttributeData attr, Compilation compilation) => - attr?.IsAttribute(compilation.GetTypeByMetadataName(DELTA_DATE_TIME_ATTRIBUTE)) == true; - - public static bool IsInternString(this AttributeData attr, Compilation compilation) => - attr?.IsAttribute(compilation.GetTypeByMetadataName(INTERN_STRING_ATTRIBUTE)) == true; - - public static bool IsTidy(this AttributeData attr, Compilation compilation) => - attr?.IsAttribute(compilation.GetTypeByMetadataName(TIDY_ATTRIBUTE)) == true; - - public static bool IsAttribute(this AttributeData attr, ISymbol symbol) => - attr?.AttributeClass?.Equals(symbol, SymbolEqualityComparer.Default) == true; - - public static bool IsEnum(this ITypeSymbol symbol) => - symbol.SpecialType == SpecialType.System_Enum || symbol.TypeKind == TypeKind.Enum; - - public static bool HasSerializableInterface( - this ITypeSymbol symbol, - Compilation compilation, - ImmutableArray serializableTypes - ) => - symbol.ContainsInterface(compilation.GetTypeByMetadataName(SERIALIZABLE_INTERFACE)) || - serializableTypes.Contains(symbol); - - public static bool HasRawSerializableInterface( - this ITypeSymbol symbol, - Compilation compilation, - ImmutableArray embeddedSerializableTypes - ) => - symbol.ContainsInterface(compilation.GetTypeByMetadataName(RAW_SERIALIZABLE_INTERFACE)) || - embeddedSerializableTypes.Contains(symbol); - - public static bool Contains(this ImmutableArray symbols, ITypeSymbol? symbol) => - symbol is INamedTypeSymbol namedSymbol && - symbols.Contains(namedSymbol, SymbolEqualityComparer.Default) || symbols.Contains(symbol?.BaseType); - - public static bool HasGenericReaderCtor( - this INamedTypeSymbol symbol, - Compilation compilation, - ISymbol? parentSymbol, - out bool requiresParent - ) - { - var genericReaderInterface = compilation.GetTypeByMetadataName(GENERIC_READER_INTERFACE); - var genericCtor = symbol.Constructors.FirstOrDefault( - m => !m.IsStatic && - m.MethodKind == MethodKind.Constructor && - m.Parameters.Length >= 1 && - m.Parameters.Length <= 2 && - SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, genericReaderInterface) - ); - - requiresParent = genericCtor?.Parameters.Length == 2 && SymbolEqualityComparer.Default.Equals(genericCtor.Parameters[1].Type, parentSymbol); - return genericCtor != null; - } - - public static bool HasPublicSerializeMethod( - this ITypeSymbol symbol, - Compilation compilation, - ImmutableArray serializableTypes - ) - { - var genericWriterInterface = compilation.GetTypeByMetadataName(GENERIC_WRITER_INTERFACE); - - return symbol.GetAllMethods("Serialize") - .Any( - m => !m.IsStatic && - m.ReturnsVoid && - m.Parameters.Length == 1 && - SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, genericWriterInterface) && - m.DeclaredAccessibility == Accessibility.Public - ); - } - - public static bool HasPublicDeserializeMethod( - this ITypeSymbol symbol, - Compilation compilation, - ImmutableArray serializableTypes - ) - { - 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), - SymbolEqualityComparer.Default - ); - - public static bool IsPoint3D(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(POINT3D_STRUCT), - SymbolEqualityComparer.Default - ); - - public static bool IsRectangle2D(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(RECTANGLE2D_STRUCT), - SymbolEqualityComparer.Default - ); - - public static bool IsRectangle3D(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(RECTANGLE3D_STRUCT), - SymbolEqualityComparer.Default - ); - - public static bool IsRace(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(RACE_CLASS), - SymbolEqualityComparer.Default - ); - - public static bool IsMap(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(MAP_CLASS), - SymbolEqualityComparer.Default - ); - - public static bool IsBitArray(this ISymbol symbol, Compilation compilation) => - symbol.Equals( - compilation.GetTypeByMetadataName(SERVER_BITARRAY_CLASS), - SymbolEqualityComparer.Default - ); - - public static AttributeData? GetAttribute(this ISymbol symbol, ISymbol attrSymbol) => - symbol - .GetAttributes() - .FirstOrDefault( - ad => ad.AttributeClass != null && SymbolEqualityComparer.Default.Equals(ad.AttributeClass, attrSymbol) - ); - - public static bool WillBeSerializable(this INamedTypeSymbol classSymbol, Compilation compilation, out AttributeData? attributeData) - { - var serializableInterface = compilation.GetTypeByMetadataName(SERIALIZABLE_INTERFACE); - - if (!classSymbol.ContainsInterface(serializableInterface)) - { - attributeData = null; - return false; - } - - var serializableEntityAttribute = - compilation.GetTypeByMetadataName(SERIALIZABLE_ATTRIBUTE); - - 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; - } - } -} diff --git a/Projects/SerializationGenerator/Utility.cs b/Projects/SerializationGenerator/Utility.cs deleted file mode 100644 index ad3f9c9c8..000000000 --- a/Projects/SerializationGenerator/Utility.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: Utility.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 . * - *************************************************************************/ - -using System.Collections.Generic; - -namespace SerializationGenerator -{ - public static class Utility - { - public static void Deconstruct(this KeyValuePair tuple, out T1 key, out T2 value) - { - key = tuple.Key; - value = tuple.Value; - } - } -} diff --git a/Projects/SerializationSchemaGenerator/.gitignore b/Projects/SerializationSchemaGenerator/.gitignore deleted file mode 100644 index 2fe317a80..000000000 --- a/Projects/SerializationSchemaGenerator/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Output/ diff --git a/Projects/SerializationSchemaGenerator/Application.cs b/Projects/SerializationSchemaGenerator/Application.cs deleted file mode 100644 index eb6946787..000000000 --- a/Projects/SerializationSchemaGenerator/Application.cs +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: Application.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 . * - *************************************************************************/ - -using System; -using System.Collections.Immutable; -using System.IO; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Threading.Tasks; -using SerializationGenerator; - -namespace SerializationSchemaGenerator -{ - public static class Application - { - public static void Main(string[] args) - { - if (args.Length < 1) - { - throw new ArgumentException("Usage: dotnet SerializationSchemaGenerator.dll "); - } - - var solutionPath = args[0]; - - Parallel.ForEach( - SourceCodeAnalysis.GetCompilation(solutionPath), - (projectCompilation) => - { - var (project, compilation) = projectCompilation; - if (project.Name.EndsWith(".Tests", StringComparison.Ordinal) || project.Name == "Benchmarks") - { - return; - } - - var projectFile = new FileInfo(project.FilePath!); - var projectPath = projectFile.Directory?.FullName; - var migrationPath = Path.Join(projectPath, "Migrations"); - Directory.CreateDirectory(migrationPath); - - var syntaxReceiver = new SerializerSyntaxReceiver(); - - foreach (var syntaxTree in compilation.SyntaxTrees) - { - var root = syntaxTree.GetRoot(); - var syntaxVisitor = new SyntaxVisitor(compilation.GetSemanticModel(syntaxTree), syntaxReceiver); - syntaxVisitor.Visit(root); - } - - var jsonOptions = new JsonSerializerOptions - { - WriteIndented = true, - AllowTrailingCommas = true, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, - ReadCommentHandling = JsonCommentHandling.Skip - }; - - var serializableTypes = syntaxReceiver.SerializableList; - var embeddedSerializableTypes = syntaxReceiver.EmbeddedSerializableList; - - foreach (var (classSymbol, (attributeData, fieldsList)) in syntaxReceiver.ClassAndFields) - { - var source = compilation.GenerateSerializationPartialClass( - classSymbol, - attributeData, - migrationPath, - false, - jsonOptions, - fieldsList.ToImmutableArray(), - serializableTypes, - embeddedSerializableTypes - ); - } - - foreach (var (classSymbol, (attributeData, fieldsList)) in syntaxReceiver.EmbeddedClassAndFields) - { - var source = compilation.GenerateSerializationPartialClass( - classSymbol, - attributeData, - migrationPath, - true, - jsonOptions, - fieldsList.ToImmutableArray(), - serializableTypes, - embeddedSerializableTypes - ); - } - } - ); - } - } -} diff --git a/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj b/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj deleted file mode 100755 index 1df2df68a..000000000 --- a/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - Exe - Output - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - diff --git a/Projects/SerializationSchemaGenerator/SourceCodeAnalysis.cs b/Projects/SerializationSchemaGenerator/SourceCodeAnalysis.cs deleted file mode 100644 index ac578b406..000000000 --- a/Projects/SerializationSchemaGenerator/SourceCodeAnalysis.cs +++ /dev/null @@ -1,49 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SourceCodeAnalysis.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 . * - *************************************************************************/ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.Build.Locator; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.MSBuild; - -namespace SerializationSchemaGenerator -{ - public static class SourceCodeAnalysis - { - public static List<(Project, Compilation)> GetCompilation(string solutionPath) - { - if (!File.Exists(solutionPath) || !solutionPath.EndsWith(".sln", StringComparison.Ordinal)) - { - throw new FileNotFoundException($"Could not open a valid solution at location {solutionPath}"); - } - - MSBuildLocator.RegisterDefaults(); - - var workspace = MSBuildWorkspace.Create(); - - var solutionToAnalyze = workspace.OpenSolutionAsync(solutionPath).Result; - - var results = solutionToAnalyze.Projects.AsParallel() - .Select((project) => (project, project?.GetCompilationAsync().Result)) - .Where((value) => value.Result != null) - .ToList(); - - return results; - } - } -} diff --git a/Projects/SerializationSchemaGenerator/SyntaxVisitor.cs b/Projects/SerializationSchemaGenerator/SyntaxVisitor.cs deleted file mode 100644 index 1e47733be..000000000 --- a/Projects/SerializationSchemaGenerator/SyntaxVisitor.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: SyntaxVisitor.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 . * - *************************************************************************/ - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using SerializationGenerator; - -namespace SerializationSchemaGenerator -{ - public class SyntaxVisitor : CSharpSyntaxWalker - { - private readonly SemanticModel _semanticModel; - private readonly SerializerSyntaxReceiver _syntaxReceiver; - - public SyntaxVisitor(SemanticModel semanticModel, SerializerSyntaxReceiver syntaxReceiver) - { - _semanticModel = semanticModel; - _syntaxReceiver = syntaxReceiver; - } - - public override void VisitClassDeclaration(ClassDeclarationSyntax node) - { - base.VisitClassDeclaration(node); - _syntaxReceiver.OnVisitSyntaxNode(node, _semanticModel); - } - - public override void VisitFieldDeclaration(FieldDeclarationSyntax node) - { - base.VisitFieldDeclaration(node); - _syntaxReceiver.OnVisitSyntaxNode(node, _semanticModel); - } - - public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node) - { - base.VisitPropertyDeclaration(node); - _syntaxReceiver.OnVisitSyntaxNode(node, _semanticModel); - } - } -} diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index 5293d55e6..5f4e998c5 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -37,14 +37,8 @@ - - - - TargetFramework=netstandard2.0 - Analyzer - false - all - + + diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index f260b9a4c..4981eed58 100755 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -38,20 +38,14 @@ false - + - - - - TargetFramework=netstandard2.0 - Analyzer - false - all - + + diff --git a/publish.cmd b/publish.cmd index 0490b16a8..ffe8c6039 100755 --- a/publish.cmd +++ b/publish.cmd @@ -27,21 +27,19 @@ if [[ $os == *'centos'* || $os == *'rhel'* ]]; then export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 fi +echo dotnet tool restore +dotnet tool restore + echo dotnet clean --verbosity quiet dotnet clean --verbosity quiet echo dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json -echo dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj -dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj - echo dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj -echo dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj -dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj -echo Generating serialization schemas -dotnet Projects/SerializationSchemaGenerator/Output/SerializationSchemaGenerator.dll ModernUO.sln +echo Generating serialization migration schema... +dotnet tool run ModernUOSchemaGenerator ModernUO.sln exit $? @@ -63,18 +61,16 @@ IF "%~2" == "" ( SET os=-r %~2-x64 ) +echo dotnet tool restore +dotnet tool restore + echo dotnet clean --verbosity quiet dotnet clean --verbosity quiet echo dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json -echo dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj -dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj - echo dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj -echo dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj -dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj -echo Generating serialization schemas -dotnet Projects/SerializationSchemaGenerator/Output/SerializationSchemaGenerator.dll ModernUO.sln +echo Generating serialization migration schema... +dotnet tool run ModernUOSchemaGenerator ModernUO.sln