Skip to content

Commit ffe5ebe

Browse files
nino v2.0.5
Nino.Serialization v2.0.5 - [Fix] Fix compilation error for abstract class - [Optimisation] Optimise struct performance
1 parent ee02d69 commit ffe5ebe

File tree

7 files changed

+161
-100
lines changed

7 files changed

+161
-100
lines changed

src/Nino.Core/Nino.Core.csproj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@
77
<LangVersion>9</LangVersion>
88
<PackageId>Nino.Serialization</PackageId>
99
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
10-
<Version>2.0.4</Version>
10+
<Version>2.0.5</Version>
1111
<Title>Nino.Serialization</Title>
1212
<Authors>JasonXuDeveloper</Authors>
1313
<Description>High performance and low size binary serialization solution, especially for Unity.</Description>
1414
<Copyright>JasonXuDeveloper</Copyright>
1515
<RepositoryUrl>https://github.com/JasonXuDeveloper/Nino</RepositoryUrl>
1616
<RepositoryType>git</RepositoryType>
1717
<PackageTags>Nino;Serialization;Binary</PackageTags>
18-
<PackageReleaseNotes>Nino.Serialization v2.0.4
19-
- [Fix] Fix complilation error for subclasses having members with identical names</PackageReleaseNotes>
18+
<PackageReleaseNotes>Nino.Serialization v2.0.5
19+
- [Fix] Fix complilation error for abstract class
20+
- [Optimisation] Optimise struct performance</PackageReleaseNotes>
2021
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2122
<PackageProjectUrl>https://nino.xgamedev.net/</PackageProjectUrl>
2223
</PropertyGroup>

src/Nino.Generator/DeserializerGenerator.cs

Lines changed: 57 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -121,20 +121,7 @@ int GetId(string typeFullName)
121121
continue;
122122
}
123123

124-
var typeSymbol = compilation.GetTypeByMetadataName(typeFullName);
125-
if (typeSymbol == null)
126-
{
127-
//check if is a nested type
128-
TypeDeclarationSyntax? typeDeclarationSyntax = models.FirstOrDefault(m =>
129-
string.Equals(m.GetTypeFullName(), typeFullName, StringComparison.Ordinal));
130-
if (typeDeclarationSyntax == null)
131-
throw new Exception("typeDeclarationSyntax is null");
132-
133-
var typeFullName2 = typeDeclarationSyntax.GetTypeFullName("+");
134-
typeSymbol = compilation.GetTypeByMetadataName(typeFullName2);
135-
if (typeSymbol == null)
136-
throw new Exception("structSymbol is null");
137-
}
124+
var typeSymbol = compilation.GetTypeSymbol(typeFullName, models);
138125

139126
// check if struct is unmanged
140127
if (typeSymbol.IsUnmanagedType)
@@ -148,10 +135,14 @@ int GetId(string typeFullName)
148135
[MethodImpl(MethodImplOptions.AggressiveInlining)]
149136
private static void Deserialize(out {{typeFullName}} value, ref Reader reader)
150137
{
151-
reader.Read(out ushort typeId);
152-
153138
""");
154139

140+
if (!typeSymbol.IsValueType)
141+
{
142+
sb.AppendLine(" reader.Read(out ushort typeId);");
143+
sb.AppendLine();
144+
}
145+
155146
void WriteMembers(List<MemberDeclarationSyntax> members, string valName)
156147
{
157148
foreach (var memberDeclarationSyntax in members)
@@ -190,14 +181,12 @@ void WriteMembers(List<MemberDeclarationSyntax> members, string valName)
190181
return bCount.CompareTo(aCount);
191182
});
192183

193-
194-
sb.AppendLine($" switch (typeId)");
195-
sb.AppendLine(" {");
196-
197184
// only applicable for reference types
198-
bool isReferenceType = model is ClassDeclarationSyntax;
185+
bool isReferenceType = typeSymbol.IsReferenceType;
199186
if (isReferenceType)
200187
{
188+
sb.AppendLine(" switch (typeId)");
189+
sb.AppendLine(" {");
201190
sb.AppendLine("""
202191
case TypeCollector.NullTypeId:
203192
value = null;
@@ -207,41 +196,57 @@ void WriteMembers(List<MemberDeclarationSyntax> members, string valName)
207196

208197
foreach (var subType in lst)
209198
{
210-
subTypes.AppendLine(
211-
subType.GeneratePublicDeserializeMethodBodyForSubType(typeFullName, " "));
212-
string valName = subType.Replace(".", "_").ToLower();
213-
int id = GetId(subType);
214-
sb.AppendLine($" case {id}:");
215-
sb.AppendLine(" {");
216-
sb.AppendLine($" {subType} {valName} = new {subType}();");
217-
218-
219-
List<TypeDeclarationSyntax> subTypeModels =
220-
models.Where(m => inheritanceMap[subType]
221-
.Contains(m.GetTypeFullName())).ToList();
222-
223-
var members = models.First(m => m.GetTypeFullName() == subType).GetNinoTypeMembers(subTypeModels);
224-
//get distinct members
225-
members = members.Distinct().ToList();
226-
WriteMembers(members, valName);
227-
sb.AppendLine($" value = {valName};");
228-
sb.AppendLine(" return;");
229-
sb.AppendLine(" }");
199+
var subTypeSymbol = compilation.GetTypeSymbol(subType, models);
200+
if (!subTypeSymbol.IsAbstract)
201+
{
202+
subTypes.AppendLine(
203+
subType.GeneratePublicDeserializeMethodBodyForSubType(typeFullName, " "));
204+
string valName = subType.Replace(".", "_").ToLower();
205+
int id = GetId(subType);
206+
sb.AppendLine($" case {id}:");
207+
sb.AppendLine(" {");
208+
sb.AppendLine($" {subType} {valName} = new {subType}();");
209+
210+
211+
List<TypeDeclarationSyntax> subTypeModels =
212+
models.Where(m => inheritanceMap[subType]
213+
.Contains(m.GetTypeFullName())).ToList();
214+
215+
var members = models.First(m => m.GetTypeFullName() == subType).GetNinoTypeMembers(subTypeModels);
216+
//get distinct members
217+
members = members.Distinct().ToList();
218+
WriteMembers(members, valName);
219+
sb.AppendLine($" value = {valName};");
220+
sb.AppendLine(" return;");
221+
sb.AppendLine(" }");
222+
}
230223
}
231224

232-
sb.AppendLine($" case {GetId(typeFullName)}:");
233-
sb.AppendLine(" {");
234-
sb.AppendLine($" value = new {typeFullName}();");
235-
var defaultMembers = model.GetNinoTypeMembers(null);
236-
WriteMembers(defaultMembers, "value");
237-
sb.AppendLine(" return;");
238-
sb.AppendLine(" }");
225+
if (!typeSymbol.IsAbstract)
226+
{
227+
if (isReferenceType)
228+
{
229+
sb.AppendLine($" case {GetId(typeFullName)}:");
230+
sb.AppendLine(" {");
231+
}
232+
sb.AppendLine($" value = new {typeFullName}();");
233+
var defaultMembers = model.GetNinoTypeMembers(null);
234+
WriteMembers(defaultMembers, "value");
235+
if (isReferenceType)
236+
{
237+
sb.AppendLine(" return;");
238+
sb.AppendLine(" }");
239+
}
240+
}
239241

240-
sb.AppendLine(" default:");
241-
sb.AppendLine(
242-
" throw new InvalidOperationException($\"Invalid type id {typeId}\");");
242+
if (isReferenceType)
243+
{
244+
sb.AppendLine(" default:");
245+
sb.AppendLine(
246+
" throw new InvalidOperationException($\"Invalid type id {typeId}\");");
247+
sb.AppendLine(" }");
248+
}
243249

244-
sb.AppendLine(" }");
245250
sb.AppendLine(" }");
246251
sb.AppendLine();
247252
}

src/Nino.Generator/Nino.Generator.csproj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@
1010
<RootNamespace>Nino.Generator</RootNamespace>
1111
<PackageId>Nino.Generator</PackageId>
1212
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
13-
<Version>2.0.4</Version>
13+
<Version>2.0.5</Version>
1414
<Title>Nino.Generator</Title>
1515
<Authors>JasonXuDeveloper</Authors>
1616
<Description>Source Generator for the high performance and low size binary serialization solution, especially for Unity.</Description>
1717
<Copyright>JasonXuDeveloper</Copyright>
1818
<RepositoryUrl>https://github.com/JasonXuDeveloper/Nino</RepositoryUrl>
1919
<RepositoryType>git</RepositoryType>
2020
<PackageTags>Nino;Serialization;Binary;Generator</PackageTags>
21-
<PackageReleaseNotes>Nino.Serialization v2.0.4
22-
- [Fix] Fix complilation error for subclasses having members with identical names</PackageReleaseNotes>
21+
<PackageReleaseNotes>Nino.Serialization v2.0.5
22+
- [Fix] Fix complilation error for abstract class
23+
- [Optimisation] Optimise struct performance</PackageReleaseNotes>
2324
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2425
<AnalyzerLanguage>cs</AnalyzerLanguage>
2526
<IncludeBuildOutput>false</IncludeBuildOutput>

src/Nino.Generator/NinoTypeHelper.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Collections.Immutable;
34
using System.Linq;
45
using System.Text;
56
using Microsoft.CodeAnalysis;
@@ -29,6 +30,26 @@ public static bool IsNinoType(this ITypeSymbol typeSymbol)
2930
return typeSymbol.GetAttributes().Any(static a => a.AttributeClass?.Name == "NinoTypeAttribute");
3031
}
3132

33+
public static INamedTypeSymbol GetTypeSymbol(this Compilation compilation, string typeFullName, ImmutableArray<TypeDeclarationSyntax> models)
34+
{
35+
var typeSymbol = compilation.GetTypeByMetadataName(typeFullName);
36+
if (typeSymbol == null)
37+
{
38+
//check if is a nested type
39+
TypeDeclarationSyntax? typeDeclarationSyntax = models.FirstOrDefault(m =>
40+
string.Equals(m.GetTypeFullName(), typeFullName, StringComparison.Ordinal));
41+
if (typeDeclarationSyntax == null)
42+
throw new Exception("typeDeclarationSyntax is null");
43+
44+
var typeFullName2 = typeDeclarationSyntax.GetTypeFullName("+");
45+
typeSymbol = compilation.GetTypeByMetadataName(typeFullName2);
46+
if (typeSymbol == null)
47+
throw new Exception("structSymbol is null");
48+
}
49+
50+
return typeSymbol;
51+
}
52+
3253
public static void GenerateClassSerializeMethods(this StringBuilder sb, string typeFullName, string typeParam = "",
3354
string genericConstraint = "")
3455
{

src/Nino.Generator/SerializerGenerator.cs

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -119,21 +119,8 @@ int GetId(string typeFullName)
119119

120120
continue;
121121
}
122-
123-
var typeSymbol = compilation.GetTypeByMetadataName(typeFullName);
124-
if (typeSymbol == null)
125-
{
126-
//check if is a nested type
127-
TypeDeclarationSyntax? typeDeclarationSyntax = models.FirstOrDefault(m =>
128-
string.Equals(m.GetTypeFullName(), typeFullName, StringComparison.Ordinal));
129-
if (typeDeclarationSyntax == null)
130-
throw new Exception("typeDeclarationSyntax is null");
131-
132-
var typeFullName2 = typeDeclarationSyntax.GetTypeFullName("+");
133-
typeSymbol = compilation.GetTypeByMetadataName(typeFullName2);
134-
if (typeSymbol == null)
135-
throw new Exception("structSymbol is null");
136-
}
122+
123+
var typeSymbol = compilation.GetTypeSymbol(typeFullName, models);
137124

138125
// check if struct is unmanged
139126
if (typeSymbol.IsUnmanagedType)
@@ -153,7 +140,7 @@ int GetId(string typeFullName)
153140
{
154141
sb.AppendLine(" if (value == null)");
155142
sb.AppendLine(" {");
156-
sb.AppendLine($" writer.Write(TypeCollector.NullTypeId);");
143+
sb.AppendLine(" writer.Write(TypeCollector.NullTypeId);");
157144
sb.AppendLine(" return;");
158145
sb.AppendLine(" }");
159146
sb.AppendLine();
@@ -190,33 +177,45 @@ void WriteMembers(List<MemberDeclarationSyntax> members, string valName)
190177

191178
foreach (var subType in lst)
192179
{
193-
string valName = subType.Replace(".", "_").ToLower();
194-
sb.AppendLine($" case {subType} {valName}:");
195-
sb.AppendLine($" writer.Write((ushort){GetId(subType)});");
196-
197-
198-
List<TypeDeclarationSyntax> subTypeModels =
199-
models.Where(m => inheritanceMap[subType]
200-
.Contains(m.GetTypeFullName())).ToList();
180+
var subTypeSymbol = compilation.GetTypeSymbol(subType, models);
181+
if (!subTypeSymbol.IsAbstract)
182+
{
183+
string valName = subType.Replace(".", "_").ToLower();
184+
sb.AppendLine($" case {subType} {valName}:");
185+
sb.AppendLine($" writer.Write((ushort){GetId(subType)});");
186+
187+
188+
List<TypeDeclarationSyntax> subTypeModels =
189+
models.Where(m => inheritanceMap[subType]
190+
.Contains(m.GetTypeFullName())).ToList();
191+
192+
var members = models.First(m => m.GetTypeFullName() == subType)
193+
.GetNinoTypeMembers(subTypeModels);
194+
//get distinct members
195+
members = members.Distinct().ToList();
196+
WriteMembers(members, valName);
197+
sb.AppendLine(" return;");
198+
}
199+
}
201200

202-
var members = models.First(m => m.GetTypeFullName() == subType)
203-
.GetNinoTypeMembers(subTypeModels);
204-
//get distinct members
205-
members = members.Distinct().ToList();
206-
WriteMembers(members, valName);
201+
if (!typeSymbol.IsAbstract)
202+
{
203+
sb.AppendLine(" default:");
204+
sb.AppendLine($" writer.Write((ushort){GetId(typeFullName)});");
205+
var defaultMembers = model.GetNinoTypeMembers(null);
206+
WriteMembers(defaultMembers, "value");
207207
sb.AppendLine(" return;");
208208
}
209209

210-
sb.AppendLine(" default:");
211-
sb.AppendLine($" writer.Write((ushort){GetId(typeFullName)});");
212-
var defaultMembers = model.GetNinoTypeMembers(null);
213-
WriteMembers(defaultMembers, "value");
214-
sb.AppendLine(" return;");
215210
sb.AppendLine(" }");
216211
}
217-
else
212+
else if (!typeSymbol.IsAbstract)
218213
{
219-
sb.AppendLine($" writer.Write((ushort){GetId(typeFullName)});");
214+
if (!typeSymbol.IsValueType)
215+
{
216+
sb.AppendLine($" writer.Write((ushort){GetId(typeFullName)});");
217+
}
218+
220219
var members = model.GetNinoTypeMembers(null);
221220
WriteMembers(members, "value");
222221
}
@@ -238,7 +237,7 @@ void WriteMembers(List<MemberDeclarationSyntax> members, string valName)
238237
//replace special characters with _
239238
curNamespace = new string(curNamespace.Select(c => char.IsLetterOrDigit(c) ? c : '_').ToArray());
240239
curNamespace += "Nino";
241-
240+
242241
// generate code
243242
var code = $$"""
244243
// <auto-generated/>
@@ -357,7 +356,7 @@ public static void Serialize(this bool value, IBufferWriter<byte> bufferWriter)
357356
}
358357
359358
{{GeneratePrivateSerializeImplMethodBody("T", " ", "<T>", "where T : unmanaged")}}
360-
359+
361360
{{GeneratePrivateSerializeImplMethodBody("T[]", " ", "<T>", "where T : unmanaged")}}
362361
363362
{{GeneratePrivateSerializeImplMethodBody("List<T>", " ", "<T>", "where T : unmanaged")}}
@@ -367,7 +366,7 @@ public static void Serialize(this bool value, IBufferWriter<byte> bufferWriter)
367366
{{GeneratePrivateSerializeImplMethodBody("ICollection<T>", " ", "<T>", "where T : unmanaged")}}
368367
369368
{{GeneratePrivateSerializeImplMethodBody("T?", " ", "<T>", "where T : unmanaged")}}
370-
369+
371370
{{GeneratePrivateSerializeImplMethodBody("List<T?>", " ", "<T>", "where T : unmanaged")}}
372371
373372
{{GeneratePrivateSerializeImplMethodBody("ICollection<T?>", " ", "<T>", "where T : unmanaged")}}

src/Nino.UnitTests/TestClass.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,39 @@
44

55
namespace Nino.UnitTests
66
{
7+
[NinoType]
8+
public abstract class Base
9+
{
10+
public int A;
11+
}
12+
13+
[NinoType]
14+
public class Sub1 : Base
15+
{
16+
public int B;
17+
}
18+
19+
public class Nested
20+
{
21+
[NinoType]
22+
public abstract class Sub2 : Base
23+
{
24+
public int C;
25+
}
26+
27+
[NinoType]
28+
public class Sub2Impl : Sub2
29+
{
30+
public int D;
31+
}
32+
}
33+
34+
[NinoType]
35+
public class Sub3 : Nested.Sub2Impl
36+
{
37+
public int E;
38+
}
39+
740
[NinoType(false)]
841
public class TestClass
942
{

0 commit comments

Comments
 (0)