fix(codegen): Adds access modifiers to serializable fields (#633)
- [X] Adds options for SerializableField. Example: ```cs [SerializableField(0, getter: "protected", setter: "protected", isVritual: true)] private int _someField; ``` Defaults: `getter: "public", setter: "public", isVirtual: false`
This commit is contained in:
parent
72d3966541
commit
803b4a33cb
33 changed files with 183 additions and 164 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SourceGeneration;
|
using SerializationGenerator;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace SerializationGeneratorTests
|
namespace SerializationGeneratorTests
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SerializableMigration;
|
using SerializableMigration;
|
||||||
using SourceGeneration;
|
|
||||||
|
|
||||||
namespace SerializationGenerator
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
|
|
@ -128,7 +127,7 @@ namespace SerializationGenerator
|
||||||
const string indent = " ";
|
const string indent = " ";
|
||||||
|
|
||||||
source.GenerateClassField(
|
source.GenerateClassField(
|
||||||
AccessModifier.Private,
|
Accessibility.Private,
|
||||||
InstanceModifier.Const,
|
InstanceModifier.Const,
|
||||||
"int",
|
"int",
|
||||||
"_version",
|
"_version",
|
||||||
|
|
@ -154,8 +153,6 @@ namespace SerializationGenerator
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var order = (int)serializableFieldAttr.ConstructorArguments[0].Value!;
|
|
||||||
|
|
||||||
foreach (var attr in allAttributes)
|
foreach (var attr in allAttributes)
|
||||||
{
|
{
|
||||||
if (!SymbolEqualityComparer.Default.Equals(attr.AttributeClass, serializableFieldAttrAttribute))
|
if (!SymbolEqualityComparer.Default.Equals(attr.AttributeClass, serializableFieldAttrAttribute))
|
||||||
|
|
@ -182,9 +179,22 @@ namespace SerializationGenerator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
if (fieldOrPropertySymbol is IFieldSymbol fieldSymbol)
|
||||||
{
|
{
|
||||||
source.GenerateSerializableProperty(fieldSymbol, compilation);
|
source.GenerateSerializableProperty(
|
||||||
|
compilation,
|
||||||
|
fieldSymbol,
|
||||||
|
getterAccessor,
|
||||||
|
setterAccessor,
|
||||||
|
virtualProperty
|
||||||
|
);
|
||||||
source.AppendLine();
|
source.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -206,22 +216,22 @@ namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
// long ISerializable.SavePosition { get; set; } = -1;
|
// long ISerializable.SavePosition { get; set; } = -1;
|
||||||
source.GenerateAutoProperty(
|
source.GenerateAutoProperty(
|
||||||
AccessModifier.None,
|
Accessibility.NotApplicable,
|
||||||
"long",
|
"long",
|
||||||
"ISerializable.SavePosition",
|
"ISerializable.SavePosition",
|
||||||
AccessModifier.None,
|
Accessibility.NotApplicable,
|
||||||
AccessModifier.None,
|
Accessibility.NotApplicable,
|
||||||
indent,
|
indent,
|
||||||
defaultValue: "-1"
|
defaultValue: "-1"
|
||||||
);
|
);
|
||||||
|
|
||||||
// BufferWriter ISerializable.SaveBuffer { get; set; }
|
// BufferWriter ISerializable.SaveBuffer { get; set; }
|
||||||
source.GenerateAutoProperty(
|
source.GenerateAutoProperty(
|
||||||
AccessModifier.None,
|
Accessibility.NotApplicable,
|
||||||
"BufferWriter",
|
"BufferWriter",
|
||||||
"ISerializable.SaveBuffer",
|
"ISerializable.SaveBuffer",
|
||||||
AccessModifier.None,
|
Accessibility.NotApplicable,
|
||||||
AccessModifier.None,
|
Accessibility.NotApplicable,
|
||||||
indent
|
indent
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SerializableMigration;
|
using SerializableMigration;
|
||||||
using SourceGeneration;
|
|
||||||
|
|
||||||
namespace SerializationGenerator
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +38,7 @@ namespace SerializationGenerator
|
||||||
|
|
||||||
source.GenerateMethodStart(
|
source.GenerateMethodStart(
|
||||||
"Deserialize",
|
"Deserialize",
|
||||||
AccessModifier.Public,
|
Accessibility.Public,
|
||||||
isOverride,
|
isOverride,
|
||||||
"void",
|
"void",
|
||||||
ImmutableArray.Create<(ITypeSymbol, string)>((genericReaderInterface, "reader"))
|
ImmutableArray.Create<(ITypeSymbol, string)>((genericReaderInterface, "reader"))
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SourceGeneration;
|
|
||||||
|
|
||||||
namespace SerializationGenerator
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
|
|
@ -24,8 +23,11 @@ namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
public static void GenerateSerializableProperty(
|
public static void GenerateSerializableProperty(
|
||||||
this StringBuilder source,
|
this StringBuilder source,
|
||||||
|
Compilation compilation,
|
||||||
IFieldSymbol fieldSymbol,
|
IFieldSymbol fieldSymbol,
|
||||||
Compilation compilation
|
Accessibility getter,
|
||||||
|
Accessibility? setter,
|
||||||
|
bool isVirtual
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var fieldName = fieldSymbol.Name;
|
var fieldName = fieldSymbol.Name;
|
||||||
|
|
@ -40,27 +42,38 @@ namespace SerializationGenerator
|
||||||
) ?? false
|
) ?? false
|
||||||
);
|
);
|
||||||
|
|
||||||
source.GeneratePropertyStart(AccessModifier.Public, fieldSymbol);
|
const string indent = " ";
|
||||||
|
const string propertyIndent = " ";
|
||||||
|
|
||||||
|
var propertyAccessor = setter > getter ? setter : getter;
|
||||||
|
var getterAccessor = getter == propertyAccessor ? Accessibility.NotApplicable : getter;
|
||||||
|
|
||||||
|
source.GeneratePropertyStart(indent, propertyAccessor.Value, isVirtual, fieldSymbol);
|
||||||
|
|
||||||
// Getter
|
// Getter
|
||||||
source.GeneratePropertyGetterReturnsField(fieldSymbol);
|
source.GeneratePropertyGetterReturnsField(propertyIndent, fieldSymbol, getterAccessor);
|
||||||
|
|
||||||
// Setter
|
if (setter != null)
|
||||||
source.GeneratePropertySetterStart(false);
|
|
||||||
const string indent = " ";
|
|
||||||
source.AppendLine($"{indent}if (value != {fieldName})");
|
|
||||||
source.AppendLine($"{indent}{{");
|
|
||||||
source.AppendLine($"{indent} {fieldName} = value;");
|
|
||||||
source.AppendLine($"{indent} ((ISerializable)this).MarkDirty();");
|
|
||||||
|
|
||||||
if (invalidatePropertiesAttribute != null)
|
|
||||||
{
|
{
|
||||||
source.AppendLine($"{indent} InvalidateProperties();");
|
var setterAccessor = setter == propertyAccessor ? Accessibility.NotApplicable : setter;
|
||||||
}
|
|
||||||
source.AppendLine($"{indent}}}");
|
|
||||||
source.GeneratePropertyGetSetEnd(false);
|
|
||||||
|
|
||||||
source.GeneratePropertyEnd();
|
// Setter
|
||||||
|
source.GeneratePropertySetterStart(propertyIndent, false, setterAccessor.Value);
|
||||||
|
const string innerIndent = " ";
|
||||||
|
source.AppendLine($"{innerIndent}if (value != {fieldName})");
|
||||||
|
source.AppendLine($"{innerIndent}{{");
|
||||||
|
source.AppendLine($"{innerIndent} {fieldName} = value;");
|
||||||
|
source.AppendLine($"{innerIndent} ((ISerializable)this).MarkDirty();");
|
||||||
|
|
||||||
|
if (invalidatePropertiesAttribute != null)
|
||||||
|
{
|
||||||
|
source.AppendLine($"{innerIndent} InvalidateProperties();");
|
||||||
|
}
|
||||||
|
source.AppendLine($"{innerIndent}}}");
|
||||||
|
source.GeneratePropertyGetSetEnd(propertyIndent, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
source.GeneratePropertyEnd(indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SourceGeneration;
|
|
||||||
|
|
||||||
namespace SerializationGenerator
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
|
|
@ -34,7 +33,7 @@ namespace SerializationGenerator
|
||||||
|
|
||||||
source.GenerateConstructorStart(
|
source.GenerateConstructorStart(
|
||||||
className,
|
className,
|
||||||
AccessModifier.Public,
|
Accessibility.Public,
|
||||||
new []{ (serialType, "serial") }.ToImmutableArray(),
|
new []{ (serialType, "serial") }.ToImmutableArray(),
|
||||||
isOverride ? _baseParameters : ImmutableArray<string>.Empty
|
isOverride ? _baseParameters : ImmutableArray<string>.Empty
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SerializableMigration;
|
using SerializableMigration;
|
||||||
using SourceGeneration;
|
|
||||||
|
|
||||||
namespace SerializationGenerator
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
|
|
@ -35,7 +34,7 @@ namespace SerializationGenerator
|
||||||
|
|
||||||
source.GenerateMethodStart(
|
source.GenerateMethodStart(
|
||||||
"Serialize",
|
"Serialize",
|
||||||
AccessModifier.Public,
|
Accessibility.Public,
|
||||||
isOverride,
|
isOverride,
|
||||||
"void",
|
"void",
|
||||||
ImmutableArray.Create<(ITypeSymbol, string)>((genericWriterInterface, "writer"))
|
ImmutableArray.Create<(ITypeSymbol, string)>((genericWriterInterface, "writer"))
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ using System;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SourceGeneration;
|
using SerializationGenerator;
|
||||||
|
|
||||||
namespace SerializableMigration
|
namespace SerializableMigration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ using System;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SourceGeneration;
|
using SerializationGenerator;
|
||||||
|
|
||||||
namespace SerializableMigration
|
namespace SerializableMigration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ using System;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SourceGeneration;
|
using SerializationGenerator;
|
||||||
|
|
||||||
namespace SerializableMigration
|
namespace SerializableMigration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ using System;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SourceGeneration;
|
using SerializationGenerator;
|
||||||
|
|
||||||
namespace SerializableMigration
|
namespace SerializableMigration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SourceGeneration;
|
using SerializationGenerator;
|
||||||
|
|
||||||
namespace SerializableMigration
|
namespace SerializableMigration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ using System;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SourceGeneration;
|
using SerializationGenerator;
|
||||||
|
|
||||||
namespace SerializableMigration
|
namespace SerializableMigration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ using System;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SourceGeneration;
|
using SerializationGenerator;
|
||||||
|
|
||||||
namespace SerializableMigration
|
namespace SerializableMigration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ using System;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SourceGeneration;
|
using SerializationGenerator;
|
||||||
|
|
||||||
namespace SerializableMigration
|
namespace SerializableMigration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SourceGeneration;
|
using SerializationGenerator;
|
||||||
|
|
||||||
namespace SerializableMigration
|
namespace SerializableMigration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -58,6 +57,7 @@ namespace SerializableMigration
|
||||||
{
|
{
|
||||||
var text = File.ReadAllText(file, Encoding.UTF8);
|
var text = File.ReadAllText(file, Encoding.UTF8);
|
||||||
migration = JsonSerializer.Deserialize<SerializableMetadata>(text, options);
|
migration = JsonSerializer.Deserialize<SerializableMetadata>(text, options);
|
||||||
|
_cache[fi.Name] = migration;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeName == migration!.Type && version > migration.Version)
|
if (typeName == migration!.Type && version > migration.Version)
|
||||||
|
|
@ -96,6 +96,7 @@ namespace SerializableMigration
|
||||||
}
|
}
|
||||||
|
|
||||||
migration = JsonSerializer.Deserialize<SerializableMetadata>(text, options);
|
migration = JsonSerializer.Deserialize<SerializableMetadata>(text, options);
|
||||||
|
_cache[fi.Name] = migration;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeName == migration!.Type && version > migration.Version)
|
if (typeName == migration!.Type && version > migration.Version)
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,10 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using SourceGeneration;
|
|
||||||
|
|
||||||
namespace SerializationGenerator
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,9 @@ using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
|
||||||
namespace SourceGeneration
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
public static class Helpers
|
public static class Helpers
|
||||||
{
|
{
|
||||||
|
|
@ -40,5 +41,19 @@ namespace SourceGeneration
|
||||||
|
|
||||||
return list.ToImmutableArray();
|
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
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
/*************************************************************************
|
|
||||||
* ModernUO *
|
|
||||||
* Copyright (C) 2019-2021 - ModernUO Development Team *
|
|
||||||
* Email: hi@modernuo.com *
|
|
||||||
* File: SourceGeneration.AccessModifier.cs *
|
|
||||||
* *
|
|
||||||
* This program is free software: you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU General Public License *
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
|
||||||
*************************************************************************/
|
|
||||||
|
|
||||||
namespace SourceGeneration
|
|
||||||
{
|
|
||||||
public enum AccessModifier
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Public,
|
|
||||||
Private,
|
|
||||||
Protected,
|
|
||||||
Internal,
|
|
||||||
ProtectedInternal,
|
|
||||||
PrivateProtected
|
|
||||||
}
|
|
||||||
|
|
||||||
public static partial class SourceGeneration
|
|
||||||
{
|
|
||||||
public static string ToFriendlyString(this AccessModifier modifier) =>
|
|
||||||
modifier switch
|
|
||||||
{
|
|
||||||
AccessModifier.Public => "public",
|
|
||||||
AccessModifier.Private => "private",
|
|
||||||
AccessModifier.Protected => "protected",
|
|
||||||
AccessModifier.Internal => "internal",
|
|
||||||
AccessModifier.ProtectedInternal => "protected internal",
|
|
||||||
AccessModifier.PrivateProtected => "private protected",
|
|
||||||
_ => ""
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -18,7 +18,7 @@ using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
namespace SourceGeneration
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
public static partial class SourceGeneration
|
public static partial class SourceGeneration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
namespace SourceGeneration
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
public static partial class SourceGeneration
|
public static partial class SourceGeneration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
namespace SourceGeneration
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
public static partial class SourceGeneration
|
public static partial class SourceGeneration
|
||||||
{
|
{
|
||||||
|
|
@ -49,7 +49,7 @@ namespace SourceGeneration
|
||||||
// TODO: Generalize this to any field using dynamic indentation
|
// TODO: Generalize this to any field using dynamic indentation
|
||||||
public static void GenerateClassField(
|
public static void GenerateClassField(
|
||||||
this StringBuilder source,
|
this StringBuilder source,
|
||||||
AccessModifier accessors,
|
Accessibility accessors,
|
||||||
InstanceModifier instance,
|
InstanceModifier instance,
|
||||||
string type,
|
string type,
|
||||||
string variableName,
|
string variableName,
|
||||||
|
|
@ -63,7 +63,7 @@ namespace SourceGeneration
|
||||||
}
|
}
|
||||||
|
|
||||||
var instanceStr = instance == InstanceModifier.None ? "" : $"{instance.ToFriendlyString()} ";
|
var instanceStr = instance == InstanceModifier.None ? "" : $"{instance.ToFriendlyString()} ";
|
||||||
var accessorStr = accessors == AccessModifier.None ? "" : $"{accessors.ToFriendlyString()} ";
|
var accessorStr = accessors == Accessibility.NotApplicable ? "" : $"{accessors.ToFriendlyString()} ";
|
||||||
var valueStr = value == null ? "" : $" = {value}";
|
var valueStr = value == null ? "" : $" = {value}";
|
||||||
source.AppendLine($" {accessorStr}{instanceStr}{type} {variableName}{valueStr};");
|
source.AppendLine($" {accessorStr}{instanceStr}{type} {variableName}{valueStr};");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
namespace SourceGeneration
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
public enum InstanceModifier
|
public enum InstanceModifier
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,11 @@ using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
namespace SourceGeneration
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
public static partial class SourceGeneration
|
public static partial class SourceGeneration
|
||||||
{
|
{
|
||||||
public static void GenerateMethodStart(this StringBuilder source, string methodName, AccessModifier accessors, bool isOverride, string returnType, ImmutableArray<(ITypeSymbol, string)> parameters)
|
public static void GenerateMethodStart(this StringBuilder source, string methodName, Accessibility accessors, bool isOverride, string returnType, ImmutableArray<(ITypeSymbol, string)> parameters)
|
||||||
{
|
{
|
||||||
source.Append($" {accessors.ToFriendlyString()}{(isOverride ? " override" : "")} {returnType} {methodName}(");
|
source.Append($" {accessors.ToFriendlyString()}{(isOverride ? " override" : "")} {returnType} {methodName}(");
|
||||||
source.GenerateSignatureArguments(parameters);
|
source.GenerateSignatureArguments(parameters);
|
||||||
|
|
@ -32,7 +32,7 @@ namespace SourceGeneration
|
||||||
public static void GenerateMethodEnd(this StringBuilder source) => source.AppendLine(@" }");
|
public static void GenerateMethodEnd(this StringBuilder source) => source.AppendLine(@" }");
|
||||||
|
|
||||||
public static void GenerateConstructorStart(
|
public static void GenerateConstructorStart(
|
||||||
this StringBuilder source, string className, AccessModifier accessors, ImmutableArray<(ITypeSymbol, string)> parameters,
|
this StringBuilder source, string className, Accessibility accessors, ImmutableArray<(ITypeSymbol, string)> parameters,
|
||||||
ImmutableArray<string> baseParameters, bool isOverload = false
|
ImmutableArray<string> baseParameters, bool isOverload = false
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace SourceGeneration
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
public static partial class SourceGeneration
|
public static partial class SourceGeneration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ using System.Text;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
namespace SourceGeneration
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
public static partial class SourceGeneration
|
public static partial class SourceGeneration
|
||||||
{
|
{
|
||||||
|
|
@ -42,23 +42,26 @@ namespace SourceGeneration
|
||||||
|
|
||||||
public static void GeneratePropertyStart(
|
public static void GeneratePropertyStart(
|
||||||
this StringBuilder source,
|
this StringBuilder source,
|
||||||
AccessModifier accessors,
|
string indent,
|
||||||
|
Accessibility accessors,
|
||||||
|
bool isVirtual,
|
||||||
IFieldSymbol fieldSymbol
|
IFieldSymbol fieldSymbol
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var propertyName = fieldSymbol.GetPropertyName();
|
var propertyName = fieldSymbol.GetPropertyName();
|
||||||
|
var virt = isVirtual ? "virtual " : "";
|
||||||
|
|
||||||
source.AppendLine($@" {accessors.ToFriendlyString()} {fieldSymbol.Type} {propertyName}
|
source.AppendLine($"{indent}{accessors.ToFriendlyString()} {virt}{fieldSymbol.Type} {propertyName}");
|
||||||
{{");
|
source.AppendLine($"{indent}{{");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GenerateAutoProperty(
|
public static void GenerateAutoProperty(
|
||||||
this StringBuilder source,
|
this StringBuilder source,
|
||||||
AccessModifier accessors,
|
Accessibility accessors,
|
||||||
string type,
|
string type,
|
||||||
string propertyName,
|
string propertyName,
|
||||||
AccessModifier? getAccessor,
|
Accessibility? getAccessor,
|
||||||
AccessModifier? setAccessor,
|
Accessibility? setAccessor,
|
||||||
string indent,
|
string indent,
|
||||||
bool useInit = false,
|
bool useInit = false,
|
||||||
string defaultValue = null,
|
string defaultValue = null,
|
||||||
|
|
@ -72,18 +75,18 @@ namespace SourceGeneration
|
||||||
|
|
||||||
var getter = getAccessor == null ?
|
var getter = getAccessor == null ?
|
||||||
"" :
|
"" :
|
||||||
$"{(getAccessor != AccessModifier.None ? $"{getAccessor.Value.ToFriendlyString()} " : "")}get;";
|
$"{(getAccessor != Accessibility.NotApplicable ? $"{getAccessor.Value.ToFriendlyString()} " : "")}get;";
|
||||||
|
|
||||||
var getterSpace = getAccessor != null ? " " : "";
|
var getterSpace = getAccessor != null ? " " : "";
|
||||||
var setOrInit = useInit ? "init;" : "set;";
|
var setOrInit = useInit ? "init;" : "set;";
|
||||||
|
|
||||||
var setterAccessor = setAccessor is null or AccessModifier.None
|
var setterAccessor = setAccessor is null or Accessibility.NotApplicable
|
||||||
? ""
|
? ""
|
||||||
: $"{setAccessor.Value.ToFriendlyString() ?? ""} ";
|
: $"{setAccessor.Value.ToFriendlyString() ?? ""} ";
|
||||||
|
|
||||||
var setter = setAccessor == null ? "" : $"{getterSpace}{setterAccessor}{setOrInit}";
|
var setter = setAccessor == null ? "" : $"{getterSpace}{setterAccessor}{setOrInit}";
|
||||||
|
|
||||||
var propertyAccessor = accessors == AccessModifier.None ? "" : $"{accessors.ToFriendlyString()} ";
|
var propertyAccessor = accessors == Accessibility.NotApplicable ? "" : $"{accessors.ToFriendlyString()} ";
|
||||||
var printOverride = isOverride ? "override " : "";
|
var printOverride = isOverride ? "override " : "";
|
||||||
var printDefaultValue = defaultValue != null ? $"{(setAccessor != null ? " =" : "")} {defaultValue};" : "";
|
var printDefaultValue = defaultValue != null ? $"{(setAccessor != null ? " =" : "")} {defaultValue};" : "";
|
||||||
var printGetterSetter = setAccessor == null ? "=>" : $"{{ {getter}{setter} }}";
|
var printGetterSetter = setAccessor == null ? "=>" : $"{{ {getter}{setter} }}";
|
||||||
|
|
@ -91,26 +94,51 @@ namespace SourceGeneration
|
||||||
source.AppendLine($"{indent}{propertyAccessor}{printOverride}{type} {propertyName} {printGetterSetter}{printDefaultValue}");
|
source.AppendLine($"{indent}{propertyAccessor}{printOverride}{type} {propertyName} {printGetterSetter}{printDefaultValue}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GeneratePropertyEnd(this StringBuilder source) => source.AppendLine(" }");
|
public static void GeneratePropertyEnd(this StringBuilder source, string indent) => source.AppendLine($"{indent}}}");
|
||||||
|
|
||||||
public static void GeneratePropertyGetterReturnsField(this StringBuilder source, IFieldSymbol fieldSymbol) =>
|
public static void GeneratePropertyGetterReturnsField(
|
||||||
source.AppendLine($" get => {fieldSymbol.Name};");
|
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, bool useExpression) =>
|
public static void GeneratePropertyGetterStart(
|
||||||
source.AppendLine($" get{(useExpression ? " => " : "\n {")}");
|
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, bool useExpression)
|
public static void GeneratePropertyGetSetEnd(this StringBuilder source, string indent, bool useExpression)
|
||||||
{
|
{
|
||||||
if (!useExpression)
|
if (!useExpression)
|
||||||
{
|
{
|
||||||
source.AppendLine(" }");
|
source.AppendLine($"{indent}}}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GeneratePropertySetterSetsValue(this StringBuilder source, IFieldSymbol fieldSymbol) =>
|
public static void GeneratePropertySetterStart(
|
||||||
source.AppendLine($" set => {fieldSymbol.Name} = value;");
|
this StringBuilder source,
|
||||||
|
string indent,
|
||||||
public static void GeneratePropertySetterStart(this StringBuilder source, bool useExpression, bool useInit = false) =>
|
bool useExpression,
|
||||||
source.AppendLine($" {(useInit ? "init" : "set")}{(useExpression ? " => " : "\n {")}");
|
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}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
namespace SourceGeneration
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
public static partial class SymbolMetadata
|
public static partial class SymbolMetadata
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,11 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
namespace SourceGeneration
|
namespace SerializationGenerator
|
||||||
{
|
{
|
||||||
public static partial class SymbolMetadata
|
public static partial class SymbolMetadata
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ using System.Linq;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using SerializableMigration;
|
using SerializableMigration;
|
||||||
using SourceGeneration;
|
using SerializationGenerator;
|
||||||
|
|
||||||
namespace SerializationSchemaGenerator
|
namespace SerializationSchemaGenerator
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,21 @@ namespace Server
|
||||||
public sealed class SerializableFieldAttribute : Attribute
|
public sealed class SerializableFieldAttribute : Attribute
|
||||||
{
|
{
|
||||||
public int Order { get; }
|
public int Order { get; }
|
||||||
|
public string PropertyGetter { get; }
|
||||||
|
public string? PropertySetter { get; }
|
||||||
|
public bool IsVirtual { get; }
|
||||||
|
|
||||||
public SerializableFieldAttribute(int order) => Order = order;
|
public SerializableFieldAttribute(
|
||||||
|
int order,
|
||||||
|
string getter = "public",
|
||||||
|
string setter = "public",
|
||||||
|
bool isVirtual = false
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Order = order;
|
||||||
|
PropertyGetter = getter;
|
||||||
|
PropertySetter = setter;
|
||||||
|
IsVirtual = isVirtual;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,4 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AdditionalFiles Include="Migrations/*.v*.json" />
|
<AdditionalFiles Include="Migrations/*.v*.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<AdditionalFiles Include="Migrations/*.v*.json" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -173,19 +173,18 @@ namespace Server.Engines.Events
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ZombieSkeleton : BaseCreature
|
[Serializable(0, false)]
|
||||||
|
public partial class ZombieSkeleton : BaseCreature
|
||||||
{
|
{
|
||||||
private const string _name = "Zombie Skeleton";
|
[SerializableField(0, "private", "private")]
|
||||||
|
private PlayerMobile _deadPlayer;
|
||||||
|
|
||||||
// TODO: Requires private modifier
|
public override string DefaultName => _deadPlayer != null ? $"{_deadPlayer.Name}'s Zombie Skeleton" : "Zombie Skeleton";
|
||||||
private PlayerMobile m_DeadPlayer;
|
|
||||||
|
|
||||||
public ZombieSkeleton(PlayerMobile player = null)
|
public ZombieSkeleton(PlayerMobile player = null)
|
||||||
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||||
{
|
{
|
||||||
m_DeadPlayer = player;
|
_deadPlayer = player;
|
||||||
|
|
||||||
Name = player != null ? $"{player.Name}'s {_name}" : _name;
|
|
||||||
|
|
||||||
Body = 0x93;
|
Body = 0x93;
|
||||||
BaseSoundID = 0x1c3;
|
BaseSoundID = 0x1c3;
|
||||||
|
|
@ -219,11 +218,6 @@ namespace Server.Engines.Events
|
||||||
VirtualArmor = 18;
|
VirtualArmor = 18;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ZombieSkeleton(Serial serial)
|
|
||||||
: base(serial)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string CorpseName => "a rotting corpse";
|
public override string CorpseName => "a rotting corpse";
|
||||||
|
|
||||||
public override bool BleedImmune => true;
|
public override bool BleedImmune => true;
|
||||||
|
|
@ -232,7 +226,7 @@ namespace Server.Engines.Events
|
||||||
|
|
||||||
public override void GenerateLoot()
|
public override void GenerateLoot()
|
||||||
{
|
{
|
||||||
var deadPlayerExists = m_DeadPlayer?.Deleted == false;
|
var deadPlayerExists = _deadPlayer?.Deleted == false;
|
||||||
|
|
||||||
PackItem(
|
PackItem(
|
||||||
Utility.Random(deadPlayerExists ? 8 : 10) switch
|
Utility.Random(deadPlayerExists ? 8 : 10) switch
|
||||||
|
|
@ -242,7 +236,7 @@ namespace Server.Engines.Events
|
||||||
2 => new Torso(),
|
2 => new Torso(),
|
||||||
3 => new Bone(),
|
3 => new Bone(),
|
||||||
4 => new RibCage(),
|
4 => new RibCage(),
|
||||||
9 => deadPlayerExists ? new PlayerBones(m_DeadPlayer.Name) : null,
|
9 => deadPlayerExists ? new PlayerBones(_deadPlayer.Name) : null,
|
||||||
_ => null // 5-8, 10 (50%)
|
_ => null // 5-8, 10 (50%)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -252,26 +246,10 @@ namespace Server.Engines.Events
|
||||||
|
|
||||||
public override void OnDelete()
|
public override void OnDelete()
|
||||||
{
|
{
|
||||||
if (m_DeadPlayer?.Deleted == false)
|
if (_deadPlayer?.Deleted == false)
|
||||||
{
|
{
|
||||||
HalloweenHauntings.ReAnimated?.Remove(m_DeadPlayer);
|
HalloweenHauntings.ReAnimated?.Remove(_deadPlayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
writer.Write(0);
|
|
||||||
|
|
||||||
writer.Write(m_DeadPlayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
|
|
||||||
m_DeadPlayer = reader.ReadEntity<PlayerMobile>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Engines.Events.ZombieSkeleton",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"name": "DeadPlayer",
|
||||||
|
"type": "Server.Mobiles.PlayerMobile",
|
||||||
|
"rule": "SerializableInterfaceMigrationRule",
|
||||||
|
"ruleArguments": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue