Skip to content

Commit

Permalink
publish nino to nuget
Browse files Browse the repository at this point in the history
  • Loading branch information
JasonXuDeveloper committed Jul 2, 2024
1 parent 69f3e92 commit dcdf4fd
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 225 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Definite useful and high performance serialisation library for C# projects, espe

## 功能列表

[使用教程](Docs/Serialization.md) [![nino.serialization.nuget](https://img.shields.io/nuget/v/Nino.Serialization?label=Nino.Serialization)](https://www.nuget.org/packages/Nino.Serialization)
[使用教程](Docs/Serialization.md) [![nino.nuget](https://img.shields.io/nuget/v/Nino?label=Nino)](https://www.nuget.org/packages/Nino)

> Protobuf-net/MsgPack/BinaryFormatter/Bson/JSON等序列化库的平替方案,优势是更小体积,更高性能,支持多线程,支持多态
>
Expand Down Expand Up @@ -79,8 +79,8 @@ Definite useful and high performance serialisation library for C# projects, espe

- 使用NuGet

NuGet里搜```Nino.Serialization```
NuGet里搜```Nino```

```bash
PM> Install-Package Nino.Serialization -Version 2.0.0
PM> Install-Package Nino -Version 2.0.0.2
```
14 changes: 14 additions & 0 deletions src/Nino.Core/Nino.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>net5.0;net6.0;net7.0;net8.0;netcoreapp3.1;netstandard2.0;net48</TargetFrameworks>
<LangVersion>9</LangVersion>
<PackageId>Nino.Serialization</PackageId>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>2.0.0.2</Version>
<Title>Nino.Serialization</Title>
<Authors>JasonXuDeveloper</Authors>
<Description>High performance and low size binary serialization solution, especially for Unity.</Description>
<Copyright>JasonXuDeveloper</Copyright>
<RepositoryUrl>https://github.com/JasonXuDeveloper/Nino</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>Nino;Serialization;Binary</PackageTags>
<PackageReleaseNotes>Nino.Serialization v2.0.0
- [Optimisation] More efficient code generated via Source Generator
- [Feature] Polymorphism Solution for Collections Serialization</PackageReleaseNotes>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>

<ItemGroup>
Expand Down
241 changes: 125 additions & 116 deletions src/Nino.Generator/DeserializerGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,144 +106,153 @@ int GetId(string typeFullName)

foreach (var model in models)
{
string typeFullName = model.GetTypeFullName();

//only generate for top nino types
if (!topNinoTypes.Contains(typeFullName))
try
{
var topType = topNinoTypes.FirstOrDefault(t =>
subTypeMap.ContainsKey(t) && subTypeMap[t].Contains(typeFullName));
if (topType == null)
throw new Exception("topType is null");
string typeFullName = model.GetTypeFullName();

continue;
}
//only generate for top nino types
if (!topNinoTypes.Contains(typeFullName))
{
var topType = topNinoTypes.FirstOrDefault(t =>
subTypeMap.ContainsKey(t) && subTypeMap[t].Contains(typeFullName));
if (topType == null)
throw new Exception("topType is null");

sb.GenerateClassDeserializeMethods(typeFullName);
continue;
}

// only applicable for reference types
bool isReferenceType = model is ClassDeclarationSyntax;
if (isReferenceType)
{
sb.AppendLine($$"""
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
private static void Deserialize(out {{typeFullName}} value, ref Reader reader)
{
value = null;
reader.Read(out ushort typeId);
if (typeId == TypeCollector.NullTypeId)
sb.GenerateClassDeserializeMethods(typeFullName);

// only applicable for reference types
bool isReferenceType = model is ClassDeclarationSyntax;
if (isReferenceType)
{
sb.AppendLine($$"""
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
private static void Deserialize(out {{typeFullName}} value, ref Reader reader)
{
return;
}

""");
}
else
{
var structSymbol = compilation.GetTypeByMetadataName(typeFullName);
if (structSymbol == null)
value = null;
reader.Read(out ushort typeId);
if (typeId == TypeCollector.NullTypeId)
{
return;
}

""");
}
else
{
//check if is a nested type
TypeDeclarationSyntax? typeDeclarationSyntax = models.FirstOrDefault(m =>
string.Equals(m.GetTypeFullName(), typeFullName, StringComparison.Ordinal));
if (typeDeclarationSyntax == null)
throw new Exception("typeDeclarationSyntax is null");

var typeFullName2 = typeDeclarationSyntax.GetTypeFullName("+");
structSymbol = compilation.GetTypeByMetadataName(typeFullName2);
var structSymbol = compilation.GetTypeByMetadataName(typeFullName);
if (structSymbol == null)
throw new Exception("structSymbol is null");
}
{
//check if is a nested type
TypeDeclarationSyntax? typeDeclarationSyntax = models.FirstOrDefault(m =>
string.Equals(m.GetTypeFullName(), typeFullName, StringComparison.Ordinal));
if (typeDeclarationSyntax == null)
throw new Exception("typeDeclarationSyntax is null");

var typeFullName2 = typeDeclarationSyntax.GetTypeFullName("+");
structSymbol = compilation.GetTypeByMetadataName(typeFullName2);
if (structSymbol == null)
throw new Exception("structSymbol is null");
}

// check if struct is unmanged
if (structSymbol.IsUnmanagedType)
{
continue;
}
// check if struct is unmanged
if (structSymbol.IsUnmanagedType)
{
continue;
}

sb.AppendLine($$"""
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
private static void Deserialize(out {{typeFullName}} value, ref Reader reader)
{
value = default;
reader.Read(out ushort typeId);

""");
}
sb.AppendLine($$"""
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
private static void Deserialize(out {{typeFullName}} value, ref Reader reader)
{
value = default;
reader.Read(out ushort typeId);
""");
}

void WriteMembers(List<MemberDeclarationSyntax> members, string valName)
{
foreach (var memberDeclarationSyntax in members)
void WriteMembers(List<MemberDeclarationSyntax> members, string valName)
{
var name = memberDeclarationSyntax.GetMemberName();
// see if declaredType is a NinoType
var declaredType = memberDeclarationSyntax.GetDeclaredTypeFullName(compilation);
//check if declaredType is a NinoType
if (declaredType == null)
throw new Exception("declaredType is null");

if (memberDeclarationSyntax is FieldDeclarationSyntax)
sb.AppendLine($" Deserialize(out {valName}.{name}, ref reader);");
else
foreach (var memberDeclarationSyntax in members)
{
var tempName = $"temp_{name}";
sb.AppendLine(
$" Deserialize(out {declaredType.ToDisplayString()} {tempName}, ref reader);");
sb.AppendLine($" {valName}.{name} = {tempName};");
var name = memberDeclarationSyntax.GetMemberName();
// see if declaredType is a NinoType
var declaredType = memberDeclarationSyntax.GetDeclaredTypeFullName(compilation);
//check if declaredType is a NinoType
if (declaredType == null)
throw new Exception("declaredType is null");

if (memberDeclarationSyntax is FieldDeclarationSyntax)
sb.AppendLine($" Deserialize(out {valName}.{name}, ref reader);");
else
{
var tempName = $"temp_{name}";
sb.AppendLine(
$" Deserialize(out {declaredType.ToDisplayString()} {tempName}, ref reader);");
sb.AppendLine($" {valName}.{name} = {tempName};");
}
}
}
}

if (!subTypeMap.TryGetValue(typeFullName, out var lst))
{
lst = new List<string>();
}
if (!subTypeMap.TryGetValue(typeFullName, out var lst))
{
lst = new List<string>();
}

//sort lst by how deep the inheritance is (i.e. how many levels of inheritance), the deepest first
lst.Sort((a, b) =>
{
int aCount = inheritanceMap[a].Count;
int bCount = inheritanceMap[b].Count;
return bCount.CompareTo(aCount);
});
//sort lst by how deep the inheritance is (i.e. how many levels of inheritance), the deepest first
lst.Sort((a, b) =>
{
int aCount = inheritanceMap[a].Count;
int bCount = inheritanceMap[b].Count;
return bCount.CompareTo(aCount);
});


sb.AppendLine($" switch (typeId)");
sb.AppendLine(" {");
sb.AppendLine($" switch (typeId)");
sb.AppendLine(" {");

foreach (var subType in lst)
{
subTypes.AppendLine(subType.GeneratePublicDeserializeMethodBodyForSubType(typeFullName, " "));
string valName = subType.Replace(".", "_").ToLower();
int id = GetId(subType);
sb.AppendLine($" case {id}:");
sb.AppendLine($" {subType} {valName} = new {subType}();");


List<TypeDeclarationSyntax> subTypeModels =
models.Where(m => inheritanceMap[subType]
.Contains(m.GetTypeFullName())).ToList();

var members = models.First(m => m.GetTypeFullName() == subType).GetNinoTypeMembers(subTypeModels);
//get distinct members
members = members.Distinct().ToList();
WriteMembers(members, valName);
sb.AppendLine($" value = {valName};");
sb.AppendLine(" break;");
}
foreach (var subType in lst)
{
subTypes.AppendLine(
subType.GeneratePublicDeserializeMethodBodyForSubType(typeFullName, " "));
string valName = subType.Replace(".", "_").ToLower();
int id = GetId(subType);
sb.AppendLine($" case {id}:");
sb.AppendLine($" {subType} {valName} = new {subType}();");


List<TypeDeclarationSyntax> subTypeModels =
models.Where(m => inheritanceMap[subType]
.Contains(m.GetTypeFullName())).ToList();

var members = models.First(m => m.GetTypeFullName() == subType).GetNinoTypeMembers(subTypeModels);
//get distinct members
members = members.Distinct().ToList();
WriteMembers(members, valName);
sb.AppendLine($" value = {valName};");
sb.AppendLine(" break;");
}

sb.AppendLine($" case {GetId(typeFullName)}:");
sb.AppendLine($" value = new {typeFullName}();");
var defaultMembers = model.GetNinoTypeMembers(null);
WriteMembers(defaultMembers, "value");
sb.AppendLine(" break;");
sb.AppendLine($" case {GetId(typeFullName)}:");
sb.AppendLine($" value = new {typeFullName}();");
var defaultMembers = model.GetNinoTypeMembers(null);
WriteMembers(defaultMembers, "value");
sb.AppendLine(" break;");

sb.AppendLine(" default:");
sb.AppendLine(" throw new InvalidOperationException($\"Invalid type id {typeId}\");");
sb.AppendLine(" default:");
sb.AppendLine(
" throw new InvalidOperationException($\"Invalid type id {typeId}\");");

sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine();
}
catch (Exception e)
{
sb.AppendLine($"// Error: {e.Message} for type {model.GetTypeFullName()}: {e.StackTrace}");
}
}

// generate code
Expand Down
14 changes: 9 additions & 5 deletions src/Nino.Generator/Nino.Generator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
<IsRoslynComponent>true</IsRoslynComponent>

<RootNamespace>Nino.Generator</RootNamespace>
<PackageId>Nino.Serialization</PackageId>
<PackageId>Nino.Generator</PackageId>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>2.0.0</Version>
<Title>Nino.Serialization</Title>
<Version>2.0.0.2</Version>
<Title>Nino.Generator</Title>
<Authors>JasonXuDeveloper</Authors>
<Description>High performance and low size binary serialization solution, especially for Unity.</Description>
<Description>Source Generator for the high performance and low size binary serialization solution, especially for Unity.</Description>
<Copyright>JasonXuDeveloper</Copyright>
<RepositoryUrl>https://github.com/JasonXuDeveloper/Nino</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>Nino;Serialization;Binary</PackageTags>
<PackageTags>Nino;Serialization;Binary;Generator</PackageTags>
<PackageReleaseNotes>Nino.Serialization v2.0.0
- [Optimisation] More efficient code generated via Source Generator
- [Feature] Polymorphism Solution for Collections Serialization</PackageReleaseNotes>
Expand All @@ -39,5 +39,9 @@
<ProjectReference Include="..\Nino.Core\Nino.Core.csproj" />
</ItemGroup>

<ItemGroup>
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>


</Project>
9 changes: 8 additions & 1 deletion src/Nino.Generator/NinoTypeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,15 @@ public static string GetTypeFullName(this TypeDeclarationSyntax typeDeclarationS
private static string GetNamespace(SyntaxNode node)
{
//namespace XXX { ... }
var namespaceDeclaration = node.Ancestors().OfType<NamespaceDeclarationSyntax>().FirstOrDefault();
return namespaceDeclaration?.Name.ToString() ?? string.Empty;
//file-scoped namespace i.e. namespace XXX;
if (namespaceDeclaration == null)
{
var fileScopedNamespace = node.Ancestors().OfType<FileScopedNamespaceDeclarationSyntax>().FirstOrDefault();
return fileScopedNamespace?.Name.ToString() ?? string.Empty;
}
return namespaceDeclaration.Name.ToString();
}
private static string GetFullTypeName(TypeDeclarationSyntax typeDeclaration, string separator = ".")
Expand Down
Loading

0 comments on commit dcdf4fd

Please sign in to comment.