diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml
index ccd2c2280..62b080225 100644
--- a/.github/workflows/update-docs.yml
+++ b/.github/workflows/update-docs.yml
@@ -3,6 +3,7 @@ name: Updates Docs
on:
repository_dispatch:
types: [docs]
+ workflow_dispatch:
jobs:
update-docs:
diff --git a/Directory.Build.props b/Directory.Build.props
index be723978b..d0e008643 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -11,7 +11,7 @@
true
true
NU1603
- win-x64;debian.10-x64;debian.11-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;fedora.32-x64;fedora.33-x64;fedora.34-x64;rhel.7-x64;rhel.8-x64;osx-x64
+ win-x64;debian.10-x64;debian.11-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;fedora.32-x64;fedora.33-x64;fedora.34-x64;rhel.7-x64;rhel.8-x64;linuxmint.17-x64;linuxmint.18-x64;linuxmint.19-x64;osx-x64
Debug;Release;Analyze
false
true
diff --git a/Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs
new file mode 100644
index 000000000..4c47b7189
--- /dev/null
+++ b/Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs
@@ -0,0 +1,665 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+using Server;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Benchmarks
+{
+ [SimpleJob(RuntimeMoniker.NetCoreApp50)]
+ public class MapSelectors
+ {
+ static readonly Sector sector = new Sector();
+ static Server.Rectangle2D bounds = new Server.Rectangle2D(0, 0, 100, 100);
+
+ public static void Init()
+ {
+ for (int i = 0; i < 50; ++i)
+ {
+ sector.Multis.Add(new BaseMulti());
+ }
+ for (int i = 0; i < 1000; ++i)
+ {
+ sector.BItems.Add(new BItem());
+ }
+ for (int i = 0; i < 1000; ++i)
+ {
+ sector.Mobiles.Add(new Mobile());
+ }
+ }
+
+ #region MultiTiles
+ [Benchmark]
+ public void SelectMultiTilesNew()
+ {
+ foreach(StaticTile[] tiles in SelectMultiTiles(sector, bounds))
+ {
+ for(int i = 0; i < tiles.Length; ++i)
+ {
+ int id = tiles[i].ID;
+ }
+ }
+ }
+
+ [Benchmark]
+ public void SelectMultiTilesLinq()
+ {
+ foreach(StaticTile[] tiles in SelectMultiTilesLinq(sector, bounds))
+ {
+ for(int i = 0; i < tiles.Length; ++i)
+ {
+ int id = tiles[i].ID;
+ }
+ }
+ }
+
+ public IEnumerable SelectMultiTilesLinq(Sector s, Server.Rectangle2D bounds)
+ {
+ foreach (var o in s.Multis.Where(o => o != null && !o.Deleted))
+ {
+ var c = o.Components;
+
+ int x, y, xo, yo;
+ StaticTile[] t, r;
+
+ for (x = bounds.Start.X; x < bounds.End.X; x++)
+ {
+ xo = x - (o.X + c.Min.X);
+
+ if (xo < 0 || xo >= c.Width)
+ {
+ continue;
+ }
+
+ for (y = bounds.Start.Y; y < bounds.End.Y; y++)
+ {
+ yo = y - (o.Y + c.Min.Y);
+
+ if (yo < 0 || yo >= c.Height)
+ {
+ continue;
+ }
+
+ t = c.Tiles[xo][yo];
+
+ if (t.Length <= 0)
+ {
+ continue;
+ }
+
+ r = new StaticTile[t.Length];
+
+ for (var i = 0; i < t.Length; i++)
+ {
+ r[i] = t[i];
+ r[i].Z += o.Z;
+ }
+
+ yield return r;
+ }
+ }
+ }
+ }
+
+ public IEnumerable SelectMultiTiles(Sector s, Server.Rectangle2D bounds)
+ {
+ for (int l = s.Multis.Count - 1; l >= 0; --l)
+ {
+ BaseMulti o = s.Multis[l];
+ if (o != null && !o.Deleted)
+ {
+ MultiComponentList c = o.Components;
+
+ int x, y, xo, yo;
+ StaticTile[] t, r;
+
+ for (x = bounds.Start.X; x < bounds.End.X; x++)
+ {
+ xo = x - (o.X + c.Min.X);
+
+ if (xo < 0 || xo >= c.Width)
+ {
+ continue;
+ }
+
+ for (y = bounds.Start.Y; y < bounds.End.Y; y++)
+ {
+ yo = y - (o.Y + c.Min.Y);
+
+ if (yo < 0 || yo >= c.Height)
+ {
+ continue;
+ }
+
+ t = c.Tiles[xo][yo];
+
+ if (t.Length <= 0)
+ {
+ continue;
+ }
+
+ r = new StaticTile[t.Length];
+
+ for (var i = 0; i < t.Length; i++)
+ {
+ r[i] = t[i];
+ r[i].Z += o.Z;
+ }
+
+ yield return r;
+ }
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ #region Multis
+ [Benchmark]
+ public void SelectMultisNew()
+ {
+ SelectMultis(sector, bounds);
+ }
+
+ [Benchmark]
+ public void SelectMultisLinq()
+ {
+ SelectMultisLinq(sector, bounds);
+ }
+
+ public IEnumerable SelectMultisLinq(Sector s, Server.Rectangle2D bounds)
+ {
+ return s.Multis.Where(o => o != null && !o.Deleted && bounds.Contains(o.Location));
+ }
+
+ public IEnumerable SelectMultis(Sector s, Server.Rectangle2D bounds)
+ {
+ List entities = new List(s.Multis.Count);
+ for (int i = s.Multis.Count - 1; i >= 0; --i)
+ {
+ BaseMulti BItem = s.Multis[i];
+ if (BItem != null && !BItem.Deleted && bounds.Contains(BItem.Location))
+ entities.Add(BItem);
+ }
+ return entities;
+ }
+ #endregion
+
+ #region BItems
+ [Benchmark]
+ public void SelectBItemsNew()
+ {
+ SelectBItems(sector, bounds);
+ }
+
+ [Benchmark]
+ public void SelectBItemsLinq()
+ {
+ SelectBItemsLinq(sector, bounds);
+ }
+
+ public IEnumerable SelectBItemsLinq(Sector s, Server.Rectangle2D bounds) where T : BItem
+ {
+ return s.BItems.OfType().Where(o => o != null && !o.Deleted && o.Parent == null && bounds.Contains(o.Location));
+ }
+
+ public IEnumerable SelectBItems(Sector s, Server.Rectangle2D bounds) where T : BItem
+ {
+ List entities = new List(s.BItems.Count);
+ Type type = typeof(T);
+ for (int i = s.BItems.Count - 1; i >= 0; --i)
+ {
+ BItem BItem = s.BItems[i];
+ if (BItem != null && !BItem.Deleted && BItem.Parent == null && bounds.Contains(BItem.Location) && type.IsAssignableFrom(BItem.GetType()))
+ entities.Add(BItem as T);
+ }
+ return entities;
+ }
+ #endregion
+
+ #region Mobiles
+ [Benchmark]
+ public void SelectMobilesNew()
+ {
+ SelectMobiles(sector, bounds);
+ }
+
+ [Benchmark]
+ public void SelectMobilesLinq()
+ {
+ SelectMobilesLinq(sector, bounds);
+ }
+
+ public IEnumerable SelectMobilesLinq(Sector s, Server.Rectangle2D bounds) where T : Mobile
+ {
+ return s.Mobiles.OfType().Where(o => o != null && !o.Deleted && bounds.Contains(o.Location));
+ }
+
+ public IEnumerable SelectMobiles(Sector s, Server.Rectangle2D bounds) where T : Mobile
+ {
+ List entities = new List(s.Mobiles.Count);
+ Type type = typeof(T);
+ for (int i = s.Mobiles.Count - 1; i >= 0; --i)
+ {
+ Mobile mob = s.Mobiles[i];
+ if (mob != null && !mob.Deleted && bounds.Contains(mob.Location) && type.IsAssignableFrom(mob.GetType()))
+ entities.Add(mob as T);
+ }
+ return entities;
+ }
+ #endregion
+
+ #region Entities
+ [Benchmark]
+ public void SelectEntitiesNew()
+ {
+ SelectEntities(sector, bounds);
+ }
+
+ [Benchmark]
+ public void SelectEntitiesLinq()
+ {
+ SelectEntitiesLinq(sector, bounds);
+ }
+
+ public IEnumerable SelectEntitiesLinq(Sector s, Server.Rectangle2D bounds)
+ {
+ return Enumerable.Empty()
+ .Union(s.Mobiles.Where(o => o != null && !o.Deleted))
+ .Union(s.BItems.Where(o => o != null && !o.Deleted && o.Parent == null))
+ .Where(o => bounds.Contains(o.Location));
+ }
+
+ private readonly List entities = new (10);
+ public IEnumerable SelectEntities(Sector s, Server.Rectangle2D bounds)
+ {
+ entities.Clear();
+ entities.Capacity = s.Mobiles.Count + s.BItems.Count;
+ for (int i = s.Mobiles.Count - 1, j = s.BItems.Count - 1; i >= 0 || j >= 0; --i, --j)
+ {
+ if (j >= 0)
+ {
+ BItem BItem = s.BItems[j];
+ if (BItem != null && !BItem.Deleted && BItem.Parent == null && bounds.Contains(BItem.Location))
+ entities.Add(BItem);
+ }
+ if (i >= 0)
+ {
+ Mobile mob = s.Mobiles[i];
+ if (mob != null && !mob.Deleted && bounds.Contains(mob.Location))
+ entities.Add(mob);
+ }
+ }
+ return entities;
+ }
+ #endregion
+ }
+ public class BItem : Server.IPoint3D, IEntity
+ {
+ public object Parent { get; set; } = null;
+
+ public bool Deleted { get; set; } = false;
+
+ public int Z { get; set; } = 1;
+
+ public int X { get; set; } = 1;
+
+ public int Y { get; set; } = 1;
+
+ public Serial Serial => throw new System.NotImplementedException();
+
+ public Point3D Location { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
+ public Map Map { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
+
+ public Region Region => throw new System.NotImplementedException();
+
+ public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
+ public int Hue { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
+ public Direction Direction { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
+ public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public int TypeRef => throw new NotImplementedException();
+
+ Point3D IEntity.Location => throw new NotImplementedException();
+
+ Map IEntity.Map => throw new NotImplementedException();
+
+ int IPoint3D.Z => throw new NotImplementedException();
+
+ int IPoint2D.X => throw new NotImplementedException();
+
+ int IPoint2D.Y => throw new NotImplementedException();
+
+ DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ int ISerializable.TypeRef => throw new NotImplementedException();
+
+ Serial ISerializable.Serial => throw new NotImplementedException();
+
+ bool ISerializable.Deleted => throw new NotImplementedException();
+
+ public BItem()
+ {
+
+ }
+
+ public void Delete()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void ProcessDelta()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void OnStatsQuery(Server.Mobile m)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void InvalidateProperties()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public int CompareTo(object obj)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public int CompareTo(IEntity other)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void MoveToWorld(Point3D location, Map map)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point2D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point3D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveBItem(BItem BItem)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ void IEntity.MoveToWorld(Point3D location, Map map)
+ {
+ throw new NotImplementedException();
+ }
+
+ void IEntity.ProcessDelta()
+ {
+ throw new NotImplementedException();
+ }
+
+ bool IEntity.InRange(Point2D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ bool IEntity.InRange(Point3D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveItem(Item item)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public class Mobile : Server.IPoint3D, IEntity
+ {
+ public bool Deleted { get; set; } = false;
+
+ public int Z { get; set; } = 1;
+
+ public int X { get; set; } = 1;
+
+ public int Y { get; set; } = 1;
+
+ public Serial Serial => throw new System.NotImplementedException();
+
+ public Point3D Location { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
+ public Map Map { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
+
+ public Region Region => throw new System.NotImplementedException();
+
+ public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
+ public int Hue { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
+ public Direction Direction { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
+ public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public int TypeRef => throw new NotImplementedException();
+
+ Point3D IEntity.Location => throw new NotImplementedException();
+
+ Map IEntity.Map => throw new NotImplementedException();
+
+ int IPoint3D.Z => throw new NotImplementedException();
+
+ int IPoint2D.X => throw new NotImplementedException();
+
+ int IPoint2D.Y => throw new NotImplementedException();
+
+ DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ int ISerializable.TypeRef => throw new NotImplementedException();
+
+ Serial ISerializable.Serial => throw new NotImplementedException();
+
+ bool ISerializable.Deleted => throw new NotImplementedException();
+
+ public Mobile()
+ {
+
+ }
+
+ public void Delete()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void ProcessDelta()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void OnStatsQuery(Server.Mobile m)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void InvalidateProperties()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public int CompareTo(object obj)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public int CompareTo(IEntity other)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void MoveToWorld(Point3D location, Map map)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point2D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point3D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveBItem(BItem BItem)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ void IEntity.MoveToWorld(Point3D location, Map map)
+ {
+ throw new NotImplementedException();
+ }
+
+ void IEntity.ProcessDelta()
+ {
+ throw new NotImplementedException();
+ }
+
+ bool IEntity.InRange(Point2D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ bool IEntity.InRange(Point3D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveItem(Item item)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public class BaseMulti : BItem
+ {
+ public MultiComponentList Components = MultiComponentList.Empty;
+
+ public BaseMulti()
+ {
+ for (int i = 0; i < 20; ++i)
+ for (int j = 0; j < 20; ++j)
+ for (int z = 0; z < 20; ++z)
+ Components.Add(123, i, j, z);
+ }
+
+ }
+
+ public class Sector
+ {
+ public List BItems { get; set; } = new List();
+ public List Mobiles { get; set; } = new List();
+ public List Multis { get; set; } = new List();
+ }
+}
diff --git a/Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs b/Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs
new file mode 100644
index 000000000..53b079cb5
--- /dev/null
+++ b/Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs
@@ -0,0 +1,28 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+using Server.Random;
+
+namespace Benchmarks.Benchmarks.Rng
+{
+ [MemoryDiagnoser]
+ [SimpleJob(RuntimeMoniker.Net60)]
+ public class BenchmarkDoubleVsFixed
+ {
+ private Xoshiro256PlusPlus _xoshiro256PlusPlus;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _xoshiro256PlusPlus = new Xoshiro256PlusPlus();
+ }
+
+ [Benchmark]
+ public bool NextDouble() => 50.1 < _xoshiro256PlusPlus.NextDouble() * 100;
+
+ [Benchmark]
+ public bool NextFixedInt() => 501 < _xoshiro256PlusPlus.Next(1000);
+
+ [Benchmark]
+ public bool NextHighResDouble() => 50.1 < _xoshiro256PlusPlus.NextDoubleHighRes() * 100;
+ }
+}
diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs
index 845354d56..bfdadb1bc 100644
--- a/Projects/Benchmarks/Program.cs
+++ b/Projects/Benchmarks/Program.cs
@@ -15,7 +15,10 @@ namespace Benchmarks
// var textEncoding = BenchmarkRunner.Run();
// var logging = BenchmarkRunner.Run();
// var gumpPacket = BenchmarkRunner.Run();
- var rngTest = BenchmarkRunner.Run();
+ // MapSelectors.Init();
+ // var mapSelectors = BenchmarkRunner.Run();
+ // var rngTest = BenchmarkRunner.Run();
+ var doubleRngText = BenchmarkRunner.Run();
}
}
}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs
index 7e664920e..56544ed60 100644
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs
+++ b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs
@@ -37,12 +37,9 @@ namespace SerializationGenerator
foreach (var serializableProperty in properties)
{
- 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};");
+ SerializableMigrationRulesEngine.Rules[serializableProperty.Rule].GenerateMigrationProperty(
+ source, compilation, $"{indent} ", serializableProperty
+ );
}
var innerIndent = $"{indent} ";
@@ -100,7 +97,8 @@ namespace SerializationGenerator
source,
$"{innerIndent} ",
property,
- "entity"
+ "entity",
+ true
);
source.AppendLine($"{innerIndent}}}\n{innerIndent}else\n{innerIndent}{{");
@@ -114,7 +112,8 @@ namespace SerializationGenerator
source,
innerIndent,
property,
- "entity"
+ "entity",
+ true
);
}
}
diff --git a/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs
index 1f944c4fa..a64453e33 100644
--- a/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs
@@ -23,6 +23,13 @@ namespace SerializableMigration
{
string RuleName { get; }
+ void GenerateMigrationProperty(
+ StringBuilder source,
+ Compilation compilation,
+ string indent,
+ SerializableProperty serializableProperty
+ );
+
bool GenerateRuleState(
Compilation compilation,
ISymbol symbol,
@@ -37,7 +44,8 @@ namespace SerializableMigration
StringBuilder source,
string indent,
SerializableProperty property,
- string? parentReference
+ string? parentReference,
+ bool isMigration = false
);
void GenerateSerializationMethod(
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs
index 54b63cc1c..99a1e911e 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs
@@ -18,117 +18,118 @@ using System.Collections.Immutable;
using System.Text;
using Microsoft.CodeAnalysis;
-namespace SerializableMigration
+namespace SerializableMigration;
+
+public class ArrayMigrationRule : MigrationRule
{
- public class ArrayMigrationRule : ISerializableMigrationRule
+ 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
+ )
{
- public string RuleName => nameof(ArrayMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
+ if (symbol is not IArrayTypeSymbol arrayTypeSymbol)
{
- 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;
+ ruleArguments = null;
+ return false;
}
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
+ 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)
{
- 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}}}");
+ Array.Copy(serializableArrayType.RuleArguments!, 0, ruleArguments, 2, length);
}
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
+ 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)
{
- 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}}}");
+ 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
index 309e4c461..caf0d1dc8 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs
@@ -20,230 +20,231 @@ using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
-namespace SerializableMigration
+namespace SerializableMigration;
+
+public class DictionaryMigrationRule : MigrationRule
{
- public class DictionaryMigrationRule : ISerializableMigrationRule
+ 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
+ )
{
- public string RuleName => nameof(DictionaryMigrationRule);
-
- public 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))
{
- 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;
+ ruleArguments = null;
+ return false;
}
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
+ 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)))
{
- 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}}}");
+ extraOptions += "@Tidy";
}
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
+ 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)
{
- 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}}}");
+ 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
index 18ebc3678..5e8d7fd45 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs
@@ -19,54 +19,55 @@ using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
-namespace SerializableMigration
+namespace SerializableMigration;
+
+public class EnumMigrationRule : MigrationRule
{
- public class EnumMigrationRule : ISerializableMigrationRule
+ 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
+ )
{
- public string RuleName => nameof(EnumMigrationRule);
-
- public 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())
{
- if (symbol is not ITypeSymbol typeSymbol || !typeSymbol.IsEnum())
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = Array.Empty();
- return true;
+ ruleArguments = null;
+ return false;
}
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
+ ruleArguments = Array.Empty();
+ return true;
+ }
- source.AppendLine($"{indent}{property.Name} = reader.ReadEnum<{property.Type}>();");
+ 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}.");
}
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
+ source.AppendLine($"{indent}{property.Name} = reader.ReadEnum<{property.Type}>();");
+ }
- source.AppendLine($"{indent}writer.WriteEnum<{property.Type}>({property.Name});");
+ 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
index d670ae01f..20fe03d08 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs
@@ -20,151 +20,152 @@ using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
-namespace SerializableMigration
+namespace SerializableMigration;
+
+public class HashSetMigrationRule : MigrationRule
{
- public class HashSetMigrationRule : ISerializableMigrationRule
+ 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
+ )
{
- public string RuleName => nameof(HashSetMigrationRule);
-
- public 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))
{
- 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;
+ ruleArguments = null;
+ return false;
}
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
+ 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)))
{
- 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}}}");
+ extraOptions += "@Tidy";
}
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
+ 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)
{
- 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}}}");
+ 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
index 1797764c1..5b7c4fbef 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs
@@ -19,206 +19,207 @@ using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
-namespace SerializableMigration
+namespace SerializableMigration;
+
+public class KeyValuePairMigrationRule : MigrationRule
{
- public class KeyValuePairMigrationRule : ISerializableMigrationRule
+ 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
+ )
{
- public string RuleName => nameof(KeyValuePairMigrationRule);
-
- public 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))
{
- 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;
+ ruleArguments = null;
+ return false;
}
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
+ 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)
{
- 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);"
- );
+ Array.Copy(keySerializedProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength);
+ index += keyArgumentsLength;
}
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
+ // Value
+ ruleArguments[index++] = valueSymbolType.ToDisplayString();
+ ruleArguments[index++] = valueSerializedProperty.Rule;
+
+ if (valueArgumentsLength > 0)
{
- 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
- );
+ 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
index f11e3f369..53d2d2c44 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs
@@ -20,152 +20,153 @@ using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
-namespace SerializableMigration
+namespace SerializableMigration;
+
+public class ListMigrationRule : MigrationRule
{
- public class ListMigrationRule : ISerializableMigrationRule
+ 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
+ )
{
- public string RuleName => nameof(ListMigrationRule);
-
- public 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))
{
- 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;
+ ruleArguments = null;
+ return false;
}
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
+ 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)))
{
- 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}}}");
+ extraOptions += "@Tidy";
}
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
+ 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)
{
- 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}}}");
+ 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
new file mode 100644
index 000000000..848812b54
--- /dev/null
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs
@@ -0,0 +1,36 @@
+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
index f3d8135bd..70b34ce06 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs
@@ -20,129 +20,130 @@ using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
-namespace SerializableMigration
+namespace SerializableMigration;
+
+public class PrimitiveTypeMigrationRule : MigrationRule
{
- public class PrimitiveTypeMigrationRule : ISerializableMigrationRule
+ 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
+ )
{
- public string RuleName => nameof(PrimitiveTypeMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
+ if (symbol.IsIpAddress(compilation) || symbol.IsTimeSpan(compilation))
{
- 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[] { "" }
- };
-
+ ruleArguments = Array.Empty();
return true;
}
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
+ 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
+ )
{
- 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});");
+ ruleArguments = null;
+ return false;
}
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
+ ruleArguments = typeSymbol.SpecialType switch
{
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
+ 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[] { "" }
+ };
- var propertyName = property.Name;
- var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null;
+ return true;
+ }
- var writeMethod = property.Type switch
- {
- "System.DateTime" when argument == "DeltaTime" => "WriteDeltaTime",
- "int" when argument == "EncodedInt" => "WriteEncodedInt",
- _ => "Write"
- };
-
- source.AppendLine($"{indent}writer.{writeMethod}({propertyName});");
+ 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
index 9d60ca27e..ec2ea15d3 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs
@@ -19,61 +19,62 @@ using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
-namespace SerializableMigration
+namespace SerializableMigration;
+
+public class PrimitiveUOTypeMigrationRule : MigrationRule
{
- public class PrimitiveUOTypeMigrationRule : ISerializableMigrationRule
+ 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
+ )
{
- public string RuleName => nameof(PrimitiveUOTypeMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
+ ruleArguments = symbol switch
{
- 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
- };
+ _ 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;
+ 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}.");
}
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- 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] ?? ""}();");
+ }
- 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}.");
}
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}writer.Write({propertyName});");
- }
+ 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
index e5ee8c725..8f0944f1d 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs
@@ -19,63 +19,64 @@ using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
-namespace SerializableMigration
+namespace SerializableMigration;
+
+public class RawSerializableMigrationRule : MigrationRule
{
- public class RawSerializableMigrationRule : ISerializableMigrationRule
+ 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
+ )
{
- public string RuleName => nameof(RawSerializableMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
+ if (symbol is not ITypeSymbol typeSymbol)
{
- if (symbol is not ITypeSymbol typeSymbol)
- {
- ruleArguments = null;
- return false;
- }
-
- if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes))
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = new[] { "" };
- return true;
+ ruleArguments = null;
+ return false;
}
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
+ if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes))
{
- 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);");
+ ruleArguments = null;
+ return false;
}
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
+ ruleArguments = new[] { "" };
+ return true;
+ }
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
+ 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
index 3cc932c80..2326af110 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs
@@ -19,56 +19,57 @@ using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
-namespace SerializableMigration
+namespace SerializableMigration;
+
+public class SerializableInterfaceMigrationRule : MigrationRule
{
- public class SerializableInterfaceMigrationRule : ISerializableMigrationRule
+ 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
+ )
{
- public string RuleName => nameof(SerializableInterfaceMigrationRule);
-
- public 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))
{
- if (symbol is ITypeSymbol typeSymbol && typeSymbol.HasSerializableInterface(compilation, serializableTypes))
- {
- ruleArguments = Array.Empty();
- return true;
- }
-
- ruleArguments = null;
- return false;
+ ruleArguments = Array.Empty();
+ return true;
}
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
+ ruleArguments = null;
+ return false;
+ }
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName} = reader.ReadEntity<{property.Type}>();");
+ 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}.");
}
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
+ var propertyName = property.Name;
+ source.AppendLine($"{indent}{propertyName} = reader.ReadEntity<{property.Type}>();");
+ }
- var propertyName = property.Name;
- source.AppendLine($"{indent}writer.Write({propertyName});");
+ 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
index 1cd17971b..4e9859170 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs
@@ -19,66 +19,67 @@ using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
-namespace SerializableMigration
+namespace SerializableMigration;
+
+public class SerializationMethodSignatureMigrationRule : MigrationRule
{
- public class SerializationMethodSignatureMigrationRule : ISerializableMigrationRule
+ 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
+ )
{
- public string RuleName => nameof(SerializationMethodSignatureMigrationRule);
-
- public 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)
{
- 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;
+ ruleArguments = null;
+ return false;
}
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
+ if (symbol is not INamedTypeSymbol namedTypeSymbol ||
+ !namedTypeSymbol.HasGenericReaderCtor(compilation, parentSymbol, out var requiresParent))
{
- 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});");
+ ruleArguments = null;
+ return false;
}
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
+ ruleArguments = new[] { requiresParent ? "DeserializationRequiresParent" : "" };
+ return true;
+ }
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
+ 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
index 9fba1913a..7d97dfd6e 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs
@@ -20,107 +20,117 @@ using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
-namespace SerializableMigration
+namespace SerializableMigration;
+
+public class TimerMigrationRule : MigrationRule, IPostDeserializeMethod
{
- public class TimerMigrationRule : ISerializableMigrationRule, 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
+ )
{
- public string RuleName => nameof(TimerMigrationRule);
-
- public 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)))
{
- if (!(symbol is ITypeSymbol typeSymbol && typeSymbol.IsTimer(compilation)))
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = attributes.Any(a => a.IsTimerDrift(compilation))
- ? new[] { "@TimerDrift" }
- : new[] { "" };
-
- return true;
+ ruleArguments = null;
+ return false;
}
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
+ 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)
{
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- var ruleArguments = property.RuleArguments;
- var driftTimer = ruleArguments![0].Contains("@TimerDrift");
-
- var readTimer = driftTimer ? "reader.ReadDeltaTime()" : "reader.ReadDateTime()";
- source.AppendLine($"{indent}var {propertyName}Next = {readTimer};");
- source.AppendLine($"{indent}var {propertyName}Delay = {propertyName}Next == System.DateTime.MinValue ? System.TimeSpan.MinValue : {propertyName}Next - Core.Now;");
+ throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
}
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
+ 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)
{
- 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);");
+ throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
}
- public void PostDeserializeMethod(
- StringBuilder source, string indent, SerializableProperty property, Compilation compilation, INamedTypeSymbol classSymbol
- )
- {
- var deserializeTimerMethod = classSymbol
- .GetMembers()
- .OfType()
- .FirstOrDefault(
- m =>
+ 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))
{
- if (!m.ReturnsVoid || m.Parameters.Length != 1 || !m.Parameters[0].Type.IsTimeSpan(compilation))
- {
- return false;
- }
+ return false;
+ }
- return m.GetAttributes()
- .FirstOrDefault(
- attr =>
- {
- if (!SymbolEqualityComparer.Default.Equals(
+ 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;
+ {
+ return false;
}
- ) != 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);");
- }
+ 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/Server.Tests/Server.Tests.csproj b/Projects/Server.Tests/Server.Tests.csproj
index 6536e8cab..b33bf4c7d 100644
--- a/Projects/Server.Tests/Server.Tests.csproj
+++ b/Projects/Server.Tests/Server.Tests.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/Projects/Server/Commands.cs b/Projects/Server/Commands.cs
index 503b24814..6c5de7deb 100644
--- a/Projects/Server/Commands.cs
+++ b/Projects/Server/Commands.cs
@@ -26,65 +26,20 @@ namespace Server
public int Length => Arguments.Length;
- public string GetString(int index)
- {
- if (index < 0 || index >= Arguments.Length)
- {
- return "";
- }
+ public string GetString(int index) => index < 0 || index >= Arguments.Length ? "" : Arguments[index];
- return Arguments[index];
- }
+ public int GetInt32(int index) => index < 0 || index >= Arguments.Length ? 0 : Utility.ToInt32(Arguments[index]);
- public int GetInt32(int index)
- {
- if (index < 0 || index >= Arguments.Length)
- {
- return 0;
- }
+ public uint GetUInt32(int index) =>
+ index < 0 || index >= Arguments.Length ? 0 : Utility.ToUInt32(Arguments[index]);
- return Utility.ToInt32(Arguments[index]);
- }
+ public bool GetBoolean(int index) => index >= 0 && index < Arguments.Length && Utility.ToBoolean(Arguments[index]);
- public uint GetUInt32(int index)
- {
- if (index < 0 || index >= Arguments.Length)
- {
- return 0;
- }
+ public double GetDouble(int index) =>
+ index < 0 || index >= Arguments.Length ? 0.0 : Utility.ToDouble(Arguments[index]);
- return Utility.ToUInt32(Arguments[index]);
- }
-
- public bool GetBoolean(int index)
- {
- if (index < 0 || index >= Arguments.Length)
- {
- return false;
- }
-
- return Utility.ToBoolean(Arguments[index]);
- }
-
- public double GetDouble(int index)
- {
- if (index < 0 || index >= Arguments.Length)
- {
- return 0.0;
- }
-
- return Utility.ToDouble(Arguments[index]);
- }
-
- public TimeSpan GetTimeSpan(int index)
- {
- if (index < 0 || index >= Arguments.Length)
- {
- return TimeSpan.Zero;
- }
-
- return Utility.ToTimeSpan(Arguments[index]);
- }
+ public TimeSpan GetTimeSpan(int index) =>
+ index < 0 || index >= Arguments.Length ? TimeSpan.Zero : Utility.ToTimeSpan(Arguments[index]);
}
public static partial class EventSink
@@ -137,27 +92,7 @@ namespace Server
}
}
- public record CommandInfo
- {
- public CommandInfo(AccessLevel accessLevel, string name, string[] aliases, string usage, string description)
- {
- AccessLevel = accessLevel;
- Name = name;
- Aliases = aliases;
- Usage = usage;
- Description = description;
- }
-
- public AccessLevel AccessLevel { get; }
-
- public string Name { get; }
-
- public string[] Aliases { get; }
-
- public string Usage { get; }
-
- public string Description { get; }
- }
+ public record CommandInfo(AccessLevel AccessLevel, string Name, string[] Aliases, string Usage, string Description);
public class CommandInfoSorter : IComparer
{
diff --git a/Projects/Server/Items/SecureTradeContainer.cs b/Projects/Server/Items/SecureTradeContainer.cs
index 2cc4f39c9..3c28e8089 100644
--- a/Projects/Server/Items/SecureTradeContainer.cs
+++ b/Projects/Server/Items/SecureTradeContainer.cs
@@ -93,7 +93,7 @@ namespace Server.Items
public override bool IsChildVisibleTo(Mobile m, Item child) =>
child is VirtualCheck
- ? !AccountGold.Enabled || m.NetState?.NewSecureTrading != true
+ ? AccountGold.Enabled && m.NetState is not { NewSecureTrading: true }
: base.IsChildVisibleTo(m, child);
public override void Serialize(IGenericWriter writer)
diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs
index 5593ee918..7f5e87d1f 100644
--- a/Projects/Server/Maps/Map.cs
+++ b/Projects/Server/Maps/Map.cs
@@ -1,4 +1,5 @@
using System;
+using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
@@ -54,49 +55,97 @@ namespace Server
public static IEnumerable SelectClients(Sector s, Rectangle2D bounds)
{
- return s.Clients.Where(o => o?.Mobile?.Deleted == false && bounds.Contains(o.Mobile.Location));
+ var clients = new List(s.Clients.Count);
+ foreach (var client in s.Clients)
+ {
+ var m = client.Mobile;
+
+ if (m?.Deleted == false && bounds.Contains(m.Location))
+ {
+ clients.Add(client);
+ }
+ }
+
+ return clients;
}
- public static IEnumerable SelectEntities(Sector s, Rectangle2D bounds) =>
- SelectEntities(s, true, true, bounds);
-
- public static IEnumerable SelectEntities(Sector s, bool items, bool mobiles, Rectangle2D bounds)
+ public static IEnumerable SelectEntities(Sector s, Rectangle2D bounds)
{
- var eable = Enumerable.Empty();
- if (mobiles)
+ var entities = new List(s.Mobiles.Count + s.Items.Count);
+ for (int i = s.Mobiles.Count - 1, j = s.Items.Count - 1; i >= 0 || j >= 0; --i, --j)
{
- eable = eable.Union(s.Mobiles.Where(o => o?.Deleted == false));
- }
+ if (j >= 0)
+ {
+ Item item = s.Items[j];
+ if (item is { Deleted: false, Parent: null } && bounds.Contains(item.Location))
+ {
+ entities.Add(item);
+ }
+ }
- if (items)
- {
- eable = eable.Union(s.Items.Where(o => o?.Deleted == false && o.Parent == null));
+ if (i >= 0)
+ {
+ Mobile mob = s.Mobiles[i];
+ if (mob is { Deleted: false } && bounds.Contains(mob.Location))
+ {
+ entities.Add(mob);
+ }
+ }
}
-
- return eable.Where(o => bounds.Contains(o.Location));
+ return entities;
}
public static IEnumerable SelectMobiles(Sector s, Rectangle2D bounds) where T : Mobile
{
- return s.Mobiles.OfType().Where(o => !o.Deleted && bounds.Contains(o.Location));
+ var entities = new List(s.Mobiles.Count);
+ for (int i = s.Mobiles.Count - 1; i >= 0; --i)
+ {
+ if (s.Mobiles[i] is T { Deleted: false } mob && bounds.Contains(mob.Location))
+ {
+ entities.Add(mob);
+ }
+ }
+ return entities;
}
public static IEnumerable SelectItems(Sector s, Rectangle2D bounds) where T : Item
{
- return s.Items.OfType()
- .Where(o => o.Deleted == false && o.Parent == null && bounds.Contains(o.Location));
+ var entities = new List(s.Items.Count);
+ for (int i = s.Items.Count - 1; i >= 0; --i)
+ {
+ if (s.Items[i] is T { Deleted: false, Parent: null } item && bounds.Contains(item.Location))
+ {
+ entities.Add(item);
+ }
+ }
+ return entities;
}
public static IEnumerable SelectMultis(Sector s, Rectangle2D bounds)
{
- return s.Multis.Where(o => o?.Deleted == false && bounds.Contains(o.Location));
+ var entities = new List(s.Multis.Count);
+ for (int i = s.Multis.Count - 1; i >= 0; --i)
+ {
+ BaseMulti multi = s.Multis[i];
+ if (multi is { Deleted: false } && bounds.Contains(multi.Location))
+ {
+ entities.Add(multi);
+ }
+ }
+ return entities;
}
public static IEnumerable SelectMultiTiles(Sector s, Rectangle2D bounds)
{
- foreach (var o in s.Multis.Where(o => o?.Deleted == false))
+ for (int l = s.Multis.Count - 1; l >= 0; --l)
{
- var c = o.Components;
+ BaseMulti o = s.Multis[l];
+ if (o?.Deleted != false)
+ {
+ continue;
+ }
+
+ MultiComponentList c = o.Components;
int x, y, xo, yo;
StaticTile[] t, r;
@@ -143,10 +192,8 @@ namespace Server
public static Map.PooledEnumerable GetClients(Map map, Rectangle2D bounds) =>
Map.PooledEnumerable.Instantiate(map, bounds, ClientSelector ?? SelectClients);
- public static Map.PooledEnumerable GetEntities(
- Map map, Rectangle2D bounds, bool items = true,
- bool mobiles = true
- ) => Map.PooledEnumerable.Instantiate(map, bounds, EntitySelector ?? SelectEntities);
+ public static Map.PooledEnumerable GetEntities(Map map, Rectangle2D bounds) =>
+ Map.PooledEnumerable.Instantiate(map, bounds, EntitySelector ?? SelectEntities);
public static Map.PooledEnumerable GetMobiles(Map map, Rectangle2D bounds) =>
GetMobiles(map, bounds);
@@ -272,9 +319,6 @@ namespace Server
public const int SectorShift = 4;
public const int SectorActiveRange = 2;
- private static readonly Queue> m_FixPool = new(128);
- private static readonly List- m_EmptyFixItems = new();
-
private static ILogger _logger;
private static ILogger Logger => _logger ??= LogFactory.GetLogger(typeof(Map));
@@ -389,9 +433,55 @@ namespace Server
public int CompareTo(Map other) => other == null ? -1 : MapID.CompareTo(other.MapID);
- public static string[] GetMapNames() => Maps.Where(m => m != null).Select(m => m.Name).ToArray();
+ public static string[] GetMapNames()
+ {
+ var mapCount = 0;
+ for (var i = 0; i < Maps.Length; i++)
+ {
+ var map = Maps[i];
+ if (map != null)
+ {
+ mapCount++;
+ }
+ }
- public static Map[] GetMapValues() => Maps.Where(m => m != null).ToArray();
+ var mapNames = new string[mapCount];
+ for (int i = 0, mIndex = 0; i < Maps.Length; i++)
+ {
+ var map = Maps[i];
+ if (map != null)
+ {
+ mapNames[mIndex++] = map.Name;
+ }
+ }
+
+ return mapNames;
+ }
+
+ public static Map[] GetMapValues()
+ {
+ var mapCount = 0;
+ for (var i = 0; i < Maps.Length; i++)
+ {
+ var map = Maps[i];
+ if (map != null)
+ {
+ mapCount++;
+ }
+ }
+
+ var mapValues = new Map[mapCount];
+ for (int i = 0, mIndex = 0; i < Maps.Length; i++)
+ {
+ var map = Maps[i];
+ if (map != null)
+ {
+ mapValues[mIndex++] = map;
+ }
+ }
+
+ return mapValues;
+ }
public static Map Parse(string value)
{
@@ -498,54 +588,31 @@ namespace Server
public IPooledEnumerable GetMultiTilesAt(int x, int y) =>
PooledEnumeration.GetMultiTiles(this, new Rectangle2D(x, y, 1, 1));
- private static List
- AcquireFixItems(Map map, int x, int y)
+ private static void AcquireFixItems(Map map, int x, int y, Item[] pool, out int length)
{
+ length = 0;
if (map == null || map == Internal || x < 0 || x > map.Width || y < 0 || y > map.Height)
- {
- return m_EmptyFixItems;
- }
-
- List
- pool = null;
-
- lock (m_FixPool)
- {
- if (m_FixPool.Count > 0)
- {
- pool = m_FixPool.Dequeue();
- }
- }
-
- pool ??= new List
- (128); // Arbitrary limit
-
- var eable = map.GetItemsInRange(new Point3D(x, y, 0), 0);
-
- pool.AddRange(
- eable.Where(item => item.ItemID <= TileData.MaxItemValue && item is not BaseMulti)
- .OrderBy(item => item.Z)
- .Take(pool.Capacity)
- );
-
- eable.Free();
-
- return pool;
- }
-
- private static void FreeFixItems(List
- pool)
- {
- if (pool == m_EmptyFixItems)
{
return;
}
- pool.Clear();
-
- lock (m_FixPool)
+ var eable = map.GetItemsInRange(new Point3D(x, y, 0), 0);
+ foreach (var item in eable)
{
- if (m_FixPool.Count < 128)
+ if (item is not BaseMulti && item.ItemID <= TileData.MaxItemValue)
{
- m_FixPool.Enqueue(pool);
+ if (length == 128)
+ {
+ break;
+ }
+
+ pool[length++] = item;
}
}
+
+ eable.Free();
+
+ Array.Sort(pool, 0, length, ZComparer.Default);
}
public void FixColumn(int x, int y)
@@ -555,9 +622,10 @@ namespace Server
GetAverageZ(x, y, out _, out var landAvg, out _);
- var items = AcquireFixItems(this, x, y);
+ var items = ArrayPool
- .Shared.Rent(128);
+ AcquireFixItems(this, x, y, items, out var length);
- for (var i = 0; i < items.Count; i++)
+ for (var i = 0; i < length; i++)
{
var toFix = items[i];
@@ -592,7 +660,7 @@ namespace Server
}
}
- for (var j = 0; j < items.Count; ++j)
+ for (var j = 0; j < length; ++j)
{
if (j == i)
{
@@ -622,7 +690,7 @@ namespace Server
}
}
- FreeFixItems(items);
+ ArrayPool
- .Shared.Return(items);
}
/* This could probably be re-implemented if necessary (perhaps via an ITile interface?).
@@ -1031,15 +1099,11 @@ namespace Server
public IPooledEnumerable GetObjectsInRange(Point3D p) => GetObjectsInRange(p, Core.GlobalMaxUpdateRange);
- public IPooledEnumerable GetObjectsInRange(Point3D p, int range, bool items = true, bool mobiles = true) =>
- GetObjectsInBounds(
- new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1),
- items,
- mobiles
- );
+ public IPooledEnumerable GetObjectsInRange(Point3D p, int range) =>
+ GetObjectsInBounds(new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1));
- public IPooledEnumerable GetObjectsInBounds(Rectangle2D bounds, bool items = true, bool mobiles = true) =>
- PooledEnumeration.GetEntities(this, bounds, items, mobiles);
+ public IPooledEnumerable GetObjectsInBounds(Rectangle2D bounds) =>
+ PooledEnumeration.GetEntities(this, bounds);
public IPooledEnumerable GetClientsInRange(Point3D p) => GetClientsInRange(p, Core.GlobalMaxUpdateRange);
@@ -1188,6 +1252,13 @@ namespace Server
public bool CanSpawnMobile(int x, int y, int z) =>
Region.Find(new Point3D(x, y, z), this).AllowSpawn() && CanFit(x, y, z, 16);
+ private class ZComparer : IComparer
-
+ {
+ public static readonly ZComparer Default = new();
+
+ public int Compare(Item x, Item y) => x!.Z.CompareTo(y!.Z);
+ }
+
public Sector GetSector(Point3D p) => InternalGetSector(p.m_X >> SectorShift, p.m_Y >> SectorShift);
public Sector GetSector(Point2D p) => InternalGetSector(p.m_X >> SectorShift, p.m_Y >> SectorShift);
@@ -1529,9 +1600,7 @@ namespace Server
{
public static readonly NullEnumerable Instance = new();
- private readonly IEnumerable m_Empty;
-
- private NullEnumerable() => m_Empty = Enumerable.Empty();
+ private readonly IEnumerable m_Empty = Enumerable.Empty();
IEnumerator IEnumerable.GetEnumerator() => m_Empty.GetEnumerator();
diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj
index 392fccc6f..5293d55e6 100755
--- a/Projects/Server/Server.csproj
+++ b/Projects/Server/Server.csproj
@@ -36,7 +36,7 @@
-
+
diff --git a/Projects/UOContent/Commands/Batch.cs b/Projects/UOContent/Commands/Batch.cs
index 84aeca315..8e7ce6b73 100644
--- a/Projects/UOContent/Commands/Batch.cs
+++ b/Projects/UOContent/Commands/Batch.cs
@@ -177,7 +177,8 @@ namespace Server.Commands
CommandSystem.Register("Batch", AccessLevel.Counselor, Batch_OnCommand);
}
- [Usage("Batch"), Description("Allows multiple commands to be run at the same time.")]
+ [Usage("Batch")]
+ [Description("Allows multiple commands to be run at the same time.")]
public static void Batch_OnCommand(CommandEventArgs e)
{
e.Mobile.SendGump(new BatchGump(e.Mobile, new Batch()));
diff --git a/Projects/UOContent/Commands/DragEffects.cs b/Projects/UOContent/Commands/DragEffects.cs
index d9ef33a38..d67d0d393 100644
--- a/Projects/UOContent/Commands/DragEffects.cs
+++ b/Projects/UOContent/Commands/DragEffects.cs
@@ -7,7 +7,8 @@ namespace Server.Commands
CommandSystem.Register("DragEffects", AccessLevel.Developer, DragEffects_OnCommand);
}
- [Usage("DragEffects [enable=false]"), Description("Enables or disables the item drag and drop effects.")]
+ [Usage("DragEffects [enable=false]")]
+ [Description("Enables or disables the item drag and drop effects.")]
public static void DragEffects_OnCommand(CommandEventArgs e)
{
if (e.Length == 0)
diff --git a/Projects/UOContent/Commands/Dupe.cs b/Projects/UOContent/Commands/Dupe.cs
index db7bfdbde..3cbf9de10 100644
--- a/Projects/UOContent/Commands/Dupe.cs
+++ b/Projects/UOContent/Commands/Dupe.cs
@@ -13,7 +13,8 @@ namespace Server.Commands
CommandSystem.Register("DupeInBag", AccessLevel.GameMaster, DupeInBag_OnCommand);
}
- [Usage("Dupe [amount]"), Description("Dupes a targeted item.")]
+ [Usage("Dupe [amount]")]
+ [Description("Dupes a targeted item.")]
private static void Dupe_OnCommand(CommandEventArgs e)
{
var amount = 1;
@@ -26,7 +27,8 @@ namespace Server.Commands
e.Mobile.SendMessage("What do you wish to dupe?");
}
- [Usage("DupeInBag "), Description("Dupes an item at it's current location (count) number of times.")]
+ [Usage("DupeInBag ")]
+ [Description("Dupes an item at it's current location (count) number of times.")]
private static void DupeInBag_OnCommand(CommandEventArgs e)
{
var amount = 1;
diff --git a/Projects/UOContent/Commands/Generic/Implementors/AreaCommandImplementor.cs b/Projects/UOContent/Commands/Generic/Implementors/AreaCommandImplementor.cs
index 12a3694a1..e203e988a 100644
--- a/Projects/UOContent/Commands/Generic/Implementors/AreaCommandImplementor.cs
+++ b/Projects/UOContent/Commands/Generic/Implementors/AreaCommandImplementor.cs
@@ -43,13 +43,18 @@ namespace Server.Commands.Generic
return;
}
- var eable = map.GetObjectsInBounds(rect, items, mobiles);
+ var eable = map.GetObjectsInBounds(rect);
var objs = new List
diff --git a/README.md b/README.md
index 1ee0cb293..0983a8826 100644
--- a/README.md
+++ b/README.md
@@ -19,16 +19,17 @@ ModernUO [
[](https://www.debian.org/distrib/)
[](https://ubuntu.com/download/server)
+[](https://linuxmint.com/download.php)
[](https://www.centos.org/download/)
-[](https://getfedora.org/en/server/download/)
+[](https://getfedora.org/en/server/download/)
[](https://access.redhat.com/downloads)
#### Running the server
-[](https://dotnet.microsoft.com/download/dotnet/6.0)
+[](https://dotnet.microsoft.com/download/dotnet/6.0)
#### Development
[](https://git-scm.com/downloads)
-[](https://dotnet.microsoft.com/download/dotnet/6.0)
+[](https://dotnet.microsoft.com/download/dotnet/6.0)
#### Supported IDEs
@@ -51,11 +52,12 @@ Rider 2021.3+ &
- `win` - Windows 10/11/2016/2019/2022
- `osx` - MacOS 10.15/11.0+/12.0+ (Catalina, Big Sur, Monterey)
- `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04` - Ubuntu LTS
+ - `linuxmint.17`, `linuxmint.18`, `linuxmint.19` - Linux Mint
- `debian.10`, `debian.11` - Debian
- `centos.7`, `centos.8` - CentOS
- `fedora.32`, `fedora.33`, `fedora.34` - Fedora
- `rhel.7`, `rhel.8` - Redhat
- - If blank, the operating system running the build is used
+ - If blank, the operating system running the build is used. Linux Mint 20 is not supported directly yet, so build explicitly against `ubuntu.20.04` instead.
**Note:** Building in Visual Studio (or Rider) will not run the schema migration. The schema migration ensures future changes
to the code will be backward compatible.
@@ -64,6 +66,9 @@ to the code will be backward compatible.
- Follow the [publish](https://github.com/modernuo/ModernUO#publishing-builds) instructions
- Run `ModernUO.exe` or `dotnet ModernUO.dll` from the `Distribution` directory on the server
+**Note:** If you are running a version of linux that isn't listed above, then you may have to install the following using a package manager:
+ * `libargon2-dev`, `libz-dev`, and `zstd`
+
## Thanks
- RunUO Team & Community
- ServUO Team & Community
diff --git a/docs/assets/stylesheets/extra.css b/docs/assets/stylesheets/extra.css
index 361f284ce..dfe2e4d38 100644
--- a/docs/assets/stylesheets/extra.css
+++ b/docs/assets/stylesheets/extra.css
@@ -82,14 +82,26 @@ html .md-footer-meta.md-typeset a:hover {
color: #e95420;
}
+.linuxmint {
+ color: #87cF3e;
+}
+
.debian {
color: #d70a53;
}
+.fedora {
+ color: #3c6eb4;
+}
+
.centos {
color: #212078;
}
+.redhat {
+ color: #be0000;
+}
+
.codehilitetable .linenodiv pre, .highlighttable .linenodiv pre {
color: var(--md-default-bg-color);
}
diff --git a/docs/building-server.md b/docs/building-server.md
index b167e1c6a..9e2e63b71 100644
--- a/docs/building-server.md
+++ b/docs/building-server.md
@@ -23,6 +23,9 @@ The operating system to build the server against. If not specified then the serv
:fontawesome-brands-windows:{: .windows } `win`
:fontawesome-brands-apple:{: .apple } `osx`
-:fontawesome-brands-ubuntu:{: .ubuntu } `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04`
+:fontawesome-brands-ubuntu:{: .ubuntu } `ubuntu.14.04` `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04`
+:brands-linuxmint:{: .linuxmint } `linuxmint.17` `linuxmint.18`, `linuxmint.19`, `ubuntu.20.04` for v20
:brands-debian:{: .debian } `debian.9`, `debian.10`
-:fontawesome-brands-centos:{: .centos } `centos.7`, `centos.8`
+:fontawesome-brands-fedora:{: .fedora } `fedora.32`, `fedora.33`, `fedora.34`
+:fontawesome-brands-centos:{: .centos } `centos.7`, `centos.8`
+:fontawesome-brands-redhat:{: .redhat } `redhat.7`, `redhat.8`
diff --git a/docs/installation.md b/docs/installation.md
index a6bd079ec..edf4c673b 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -6,7 +6,7 @@ title: Installation
=== "Windows"
### Prerequisites
- 1. Download and install the latest [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0)
+ 1. Download and install the latest [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0)
1. Download and install from [here](https://git-scm.com/download/win)
!!! Tip
@@ -21,14 +21,14 @@ title: Installation
```
=== "OSX"
- Prerequisites
- 1. Download and install the latest [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0)
+ ### Prerequisites
+ 1. Download and install the latest [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0).
1. Using _terminal_, install [homebrew](https://brew.sh) and git:
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
brew install git
```
- Install ModernUO
+ ### Install ModernUO
1. Using _terminal_, navigate to the folder where you want to install ModernUO and run:
```bash
git clone https://github.com/modernuo/modernuo
@@ -36,8 +36,8 @@ title: Installation
```
=== "Linux"
- Prerequisites
- 1. Download and install the latest [.NET Core SDK](instructions [here](https://docs.microsoft.com/en-us/dotnet/core/install/linux))
+ ### Prerequisites
+ 1. Download and install the latest [.NET 6 SDK](https://docs.microsoft.com/en-us/dotnet/core/install/linux).
1. Using _bash_, install git:
```bash
sudo apt update && sudo apt install git
@@ -46,7 +46,7 @@ title: Installation
!!! Note
The command to install git might be different for your flavor of linux. Consult your local Google search for answers.
- Install ModernUO
+ ### Install ModernUO
1. Using _bash_, navigate to the folder where you want to install ModernUO and run:
```bash
git clone https://github.com/modernuo/modernuo
diff --git a/docs/overrides/.icons/brands/linuxmint.svg b/docs/overrides/.icons/brands/linuxmint.svg
new file mode 100644
index 000000000..a9dcf1131
--- /dev/null
+++ b/docs/overrides/.icons/brands/linuxmint.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/quick-start.md b/docs/quick-start.md
deleted file mode 100644
index 189b4841e..000000000
--- a/docs/quick-start.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: Quick Start
----
-
-# Quick Start
-
-If you are familiar with RunUO, then follow these steps to get your ModernUO server running in less than 10 minutes:
-
-=== "Windows"
- 1. Download and install the [.NET 5 Runtime](https://dotnet.microsoft.com/download/dotnet/5.0)
- 1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder.
- 1. Navigate to the _Distribution_ folder.
- 1. Run `ModernUO.exe`
-
-=== "OSX"
- 1. Download and install the [.NET 5 Runtime](https://dotnet.microsoft.com/download/dotnet/5.0)
- 1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder.
- 1. Using _terminal_, navigate to the _Distribution_ folder.
- 1. Run `dotnet ModernUO.dll`
-
-=== "Linux"
- 1. Download and install the [.NET 5 Runtime](instructions [here](https://docs.microsoft.com/en-us/dotnet/core/install/linux))
- 1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder.
- 1. Using _bash_, navigate to the _Distribution_ folder.
- 1. Run `dotnet ModernUO.dll`
-
-!!! Note
- Follow the rest of the [Get Started](../installation) guide to learn how to connect, configure, and customize, your server.
diff --git a/mkdocs.yml b/mkdocs.yml
index d0dbbf9f4..dcb2d826d 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -3,6 +3,7 @@
site_name: ModernUO
site_author: Kamron Batman
site_url: https://modernuo.com
+edit_uri: edit/main/docs/
# Repository
repo_name: modernuo/modernuo
@@ -41,14 +42,16 @@ markdown_extensions:
- admonition
- footnotes
- meta
- - markdown.extensions.toc:
+ - toc:
+ toc_depth: "1-1"
permalink: true
- attr_list
- pymdownx.highlight
- pymdownx.inlinehilite
- pymdownx.superfences
- pymdownx.snippets
- - pymdownx.tabbed
+ - pymdownx.tabbed:
+ alternate_style: true
- pymdownx.caret
- pymdownx.mark
- pymdownx.tilde
@@ -67,6 +70,5 @@ markdown_extensions:
nav:
- Home: 'index.md'
- 'Get Started':
- - 'quick-start.md'
- 'installation.md'
- 'building-server.md'
diff --git a/publish.cmd b/publish.cmd
index e0f9fe6df..0490b16a8 100755
--- a/publish.cmd
+++ b/publish.cmd
@@ -12,7 +12,7 @@ elif [[ $(uname) = "Darwin" ]]; then
os="-r osx-x64"
elif [[ -f /etc/os-release ]]; then
. /etc/os-release
- NAME="$(tr '[:upper:]' '[:lower:]' <<< $NAME)"
+ NAME="$(tr '[:upper:]' '[:lower:]' <<< $NAME | tr -d [:blank:])"
os="-r $NAME.$VERSION_ID-x64"
fi
@@ -32,8 +32,11 @@ 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 publish ${config} ${os} --framework net6.0 --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj
-dotnet publish ${config} ${os} --framework net6.0 --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj
+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
@@ -65,8 +68,11 @@ 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 publish %config% %os% --framework net6.0 --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
-dotnet publish %config% %os% --framework net6.0 --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
+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