Skip to content

Commit 6067e27

Browse files
refactor(generator): transform to pure incremental source generator with DTO-based pipeline
Complete architectural transformation of Nino.Generator from hybrid incremental generator to pure incremental source generator using only value-based DTOs. This eliminates all ITypeSymbol dependencies in the code generation phase and implements proper multi-stage incremental caching following Roslyn best practices. Key Changes: Architecture: - Implemented 7-stage incremental pipeline with optimal caching at each stage - Created single symbol bridge pattern in SymbolDataExtractor.cs - Converted all metadata types to readonly record structs for value-based equality - Replaced ITypeSymbol comparisons with TypeId-based lookups New Infrastructure (Pipeline): - Pipeline/SymbolDataExtractor.cs - Centralized ITypeSymbol extraction (THE ONLY symbol bridge) - Pipeline/NinoGraphBuilder.cs - Pure DTO-based graph construction - Metadata/CircularTypeDetector.cs - Circular reference detection using graph traversal New Metadata DTOs: - Metadata/TypeInfoDto.cs - Complete type information DTO - Metadata/TypeInfoDtoExtensions.cs - Type analysis extension methods - Metadata/TypeInfoDtoEnums.cs - Enum mappings (TypeKindDto, SpecialTypeDto, etc.) - Metadata/ConstructorInfoDto.cs - Constructor metadata for deserialization - Metadata/EquatableArray.cs - Value-based array wrapper for caching - Metadata/CompilationMetadata.cs - Compilation-level metadata Utilities: - NinoConstants.cs - Constants (WeakVersionToleranceSymbol) - Common/StringExtensions.cs - String utilities for code generation - Common/CodeGeneratorExtensions.cs - Code generation helper methods Converted to readonly record struct: - Metadata/NinoMember.cs - Member metadata - Metadata/NinoType.cs - Type metadata with members and constructors - Metadata/NinoGraph.cs - Type hierarchy graph Updated Generators (25 files): - GlobalGenerator.cs - Completely rewritten with 7-stage pipeline - All 5 common generators (Serializer, Deserializer, TypeConst, UnsafeAccessor, PartialClass) - All 15 built-in type generators (Array, List, Dictionary, HashSet, Queue, Stack, etc.) - All 3 base generator classes (NinoGenerator, NinoCommonGenerator, NinoBuiltInTypeGenerator) Removed: - Parser/CSharpParser.cs - Replaced by SymbolDataExtractor - Parser/NinoTypeParser.cs - Replaced by NinoGraphBuilder - DTOs/CompilationMetadataDto.cs - Renamed to CompilationMetadata.cs - DTOs/TypeTransformations.cs - Logic moved to SymbolDataExtractor Enhanced Features: - Full constructor reflection support in DTO pipeline - Intelligent constructor selection (NinoConstructor attribute, primary constructor, etc.) - Pre-computed display names and instance variable names - Support for custom serializers from external assemblies Build Status: 0 errors, 0 warnings Impact: - Optimal incremental caching (only changed types trigger regeneration) - Zero ITypeSymbol retention after extraction phase - Value-based equality for all metadata types - Type-safe DTO-based code generation - Proper separation between symbol extraction and code generation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
1 parent e632cda commit 6067e27

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3610
-2011
lines changed

src/Nino.Generator/BuiltInType/ArrayGenerator.cs

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -32,38 +32,39 @@
3232
namespace Nino.Generator.BuiltInType;
3333

3434
public class ArrayGenerator(
35+
Dictionary<int, TypeInfoDto> typeInfoCache,
36+
string assemblyNamespace,
3537
NinoGraph ninoGraph,
36-
HashSet<ITypeSymbol> potentialTypes,
37-
HashSet<ITypeSymbol> selectedTypes,
38-
Compilation compilation) : NinoBuiltInTypeGenerator(ninoGraph, potentialTypes, selectedTypes, compilation)
38+
HashSet<int> potentialTypeIds,
39+
HashSet<int> selectedTypeIds,
40+
bool isUnityAssembly = false) : NinoBuiltInTypeGenerator(typeInfoCache, assemblyNamespace, ninoGraph, potentialTypeIds, selectedTypeIds, isUnityAssembly)
3941
{
4042
protected override string OutputFileName => "NinoArrayTypeGenerator";
4143

42-
public override bool Filter(ITypeSymbol typeSymbol)
44+
public override bool Filter(TypeInfoDto typeInfo)
4345
{
44-
if (typeSymbol is not IArrayTypeSymbol arraySymbol) return false;
45-
var elementType = arraySymbol.ElementType;
46-
return elementType.GetKind(NinoGraph, GeneratedTypes) != NinoTypeHelper.NinoTypeKind.Invalid;
46+
if (typeInfo.ArrayRank == 0) return false;
47+
if (!typeInfo.ArrayElementType.HasValue) return false;
48+
var elementType = typeInfo.ArrayElementType.Value;
49+
return TypeInfoDtoExtensions.GetKind(elementType, NinoGraph, GeneratedTypeIds) != NinoTypeKind.Invalid;
4750
}
4851

49-
protected override void GenerateSerializer(ITypeSymbol typeSymbol, Writer writer)
52+
protected override void GenerateSerializer(TypeInfoDto typeInfo, Writer writer)
5053
{
51-
var arraySymbol = (IArrayTypeSymbol)typeSymbol;
52-
var elementType = arraySymbol.ElementType;
53-
elementType.GetDisplayString();
54-
var rank = arraySymbol.Rank;
55-
var typeName = typeSymbol.GetDisplayString();
54+
var elementType = typeInfo.ArrayElementType!.Value;
55+
var rank = typeInfo.ArrayRank;
56+
var typeName = typeInfo.DisplayName;
5657

5758
// Check if we can use the fast unmanaged write path
5859
// Element must be unmanaged AND cannot be polymorphic
5960
// Fast path only works for 1D arrays
60-
bool canUseFastPath = rank == 1 && elementType.GetKind(NinoGraph, GeneratedTypes) == NinoTypeHelper.NinoTypeKind.Unmanaged;
61+
bool canUseFastPath = rank == 1 && TypeInfoDtoExtensions.GetKind(elementType, NinoGraph, GeneratedTypeIds) == NinoTypeKind.Unmanaged;
6162

6263
// Check if we can use monomorphic fast path (sealed/struct NinoType)
6364
// This allows us to cache the serializer delegate once instead of lookup per element
6465
bool canUseMonomorphicPath = rank == 1 &&
65-
elementType.GetKind(NinoGraph, GeneratedTypes) == NinoTypeHelper.NinoTypeKind.NinoType &&
66-
elementType.IsSealedOrStruct();
66+
TypeInfoDtoExtensions.GetKind(elementType, NinoGraph, GeneratedTypeIds) == NinoTypeKind.NinoType &&
67+
TypeInfoDtoExtensions.IsSealedOrStruct(elementType);
6768

6869
WriteAggressiveInlining(writer);
6970
writer.Append("public static void Serialize(this ");
@@ -105,20 +106,20 @@ protected override void GenerateSerializer(ITypeSymbol typeSymbol, Writer writer
105106
writer.AppendLine();
106107
writer.AppendLine(" do");
107108
writer.AppendLine(" {");
108-
IfDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
109+
IfDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
109110
w => { w.AppendLine(" var pos = writer.Advance(4);"); });
110111

111112
if (canUseMonomorphicPath)
112113
{
113114
// Monomorphic fast path: direct call to avoid delegate allocation
114-
writer.AppendLine($" CachedSerializer<{elementType.GetDisplayString()}>.SerializePolymorphic(cur, ref writer);");
115+
writer.AppendLine($" CachedSerializer<{elementType.DisplayName}>.SerializePolymorphic(cur, ref writer);");
115116
}
116117
else
117118
{
118119
writer.Append(" ");
119120
writer.AppendLine(GetSerializeString(elementType, "cur"));
120121
}
121-
IfDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
122+
IfDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
122123
w => { w.AppendLine(" writer.PutLength(pos);"); });
123124
writer.AppendLine(" cur = ref System.Runtime.CompilerServices.Unsafe.Add(ref cur, 1);");
124125
writer.AppendLine(" }");
@@ -174,11 +175,11 @@ protected override void GenerateSerializer(ITypeSymbol typeSymbol, Writer writer
174175
var indices = string.Join(", ", Enumerable.Range(0, rank).Select(i => $"i{i}"));
175176

176177
// Only use WEAK_VERSION_TOLERANCE for non-unmanaged types
177-
bool isUnmanaged = elementType.GetKind(NinoGraph, GeneratedTypes) == NinoTypeHelper.NinoTypeKind.Unmanaged;
178+
bool isUnmanaged = TypeInfoDtoExtensions.GetKind(elementType, NinoGraph, GeneratedTypeIds) == NinoTypeKind.Unmanaged;
178179

179180
if (!isUnmanaged)
180181
{
181-
IfDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
182+
IfDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
182183
w => { w.AppendLine($"{innerIndent}var pos = writer.Advance(4);"); });
183184
}
184185

@@ -187,7 +188,7 @@ protected override void GenerateSerializer(ITypeSymbol typeSymbol, Writer writer
187188

188189
if (!isUnmanaged)
189190
{
190-
IfDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
191+
IfDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
191192
w => { w.AppendLine($"{innerIndent}writer.PutLength(pos);"); });
192193
}
193194

@@ -201,24 +202,23 @@ protected override void GenerateSerializer(ITypeSymbol typeSymbol, Writer writer
201202
writer.AppendLine("}");
202203
}
203204

204-
protected override void GenerateDeserializer(ITypeSymbol typeSymbol, Writer writer)
205+
protected override void GenerateDeserializer(TypeInfoDto typeInfo, Writer writer)
205206
{
206-
var arraySymbol = (IArrayTypeSymbol)typeSymbol;
207-
var elementType = arraySymbol.ElementType;
208-
var elemType = elementType.GetDisplayString();
209-
var rank = arraySymbol.Rank;
210-
var typeName = typeSymbol.GetDisplayString();
207+
var elementType = typeInfo.ArrayElementType!.Value;
208+
var elemType = elementType.DisplayName;
209+
var rank = typeInfo.ArrayRank;
210+
var typeName = typeInfo.DisplayName;
211211

212212
// Check if we can use the fast unmanaged read path
213213
// Element must be unmanaged AND cannot be polymorphic
214214
// Fast path only works for 1D arrays
215-
bool canUseFastPath = rank == 1 && elementType.GetKind(NinoGraph, GeneratedTypes) == NinoTypeHelper.NinoTypeKind.Unmanaged;
215+
bool canUseFastPath = rank == 1 && TypeInfoDtoExtensions.GetKind(elementType, NinoGraph, GeneratedTypeIds) == NinoTypeKind.Unmanaged;
216216

217217
// Check if we can use monomorphic fast path (sealed/struct NinoType)
218218
// This allows us to cache the deserializer delegate once instead of lookup per element
219219
bool canUseMonomorphicPath = rank == 1 &&
220-
elementType.GetKind(NinoGraph, GeneratedTypes) == NinoTypeHelper.NinoTypeKind.NinoType &&
221-
elementType.IsSealedOrStruct();
220+
TypeInfoDtoExtensions.GetKind(elementType, NinoGraph, GeneratedTypeIds) == NinoTypeKind.NinoType &&
221+
TypeInfoDtoExtensions.IsSealedOrStruct(elementType);
222222

223223
// Out overload
224224
WriteAggressiveInlining(writer);
@@ -242,7 +242,7 @@ protected override void GenerateDeserializer(ITypeSymbol typeSymbol, Writer writ
242242
writer.AppendLine(" }");
243243
writer.AppendLine();
244244
// Optimized array deserialization - reduce reader slicing overhead
245-
IfDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
245+
IfDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
246246
w => { w.AppendLine(" Reader eleReader;"); });
247247
writer.AppendLine();
248248
writer.Append(" value = new ");
@@ -256,20 +256,20 @@ protected override void GenerateDeserializer(ITypeSymbol typeSymbol, Writer writ
256256
if (canUseMonomorphicPath)
257257
{
258258
// Monomorphic fast path: direct call to avoid delegate allocation
259-
IfElseDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
259+
IfElseDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
260260
w =>
261261
{
262262
w.AppendLine(" eleReader = reader.Slice();");
263-
w.AppendLine($" CachedDeserializer<{elementType.GetDisplayString()}>.Deserialize(out span[i], ref eleReader);");
263+
w.AppendLine($" CachedDeserializer<{elementType.DisplayName}>.Deserialize(out span[i], ref eleReader);");
264264
},
265265
w =>
266266
{
267-
w.AppendLine($" CachedDeserializer<{elementType.GetDisplayString()}>.Deserialize(out span[i], ref reader);");
267+
w.AppendLine($" CachedDeserializer<{elementType.DisplayName}>.Deserialize(out span[i], ref reader);");
268268
});
269269
}
270270
else
271271
{
272-
IfElseDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
272+
IfElseDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
273273
w =>
274274
{
275275
w.AppendLine(" eleReader = reader.Slice();");
@@ -314,11 +314,11 @@ protected override void GenerateDeserializer(ITypeSymbol typeSymbol, Writer writ
314314
writer.AppendLine();
315315

316316
// Only use WEAK_VERSION_TOLERANCE reader for non-unmanaged types
317-
bool isUnmanaged = elementType.GetKind(NinoGraph, GeneratedTypes) == NinoTypeHelper.NinoTypeKind.Unmanaged;
317+
bool isUnmanaged = TypeInfoDtoExtensions.GetKind(elementType, NinoGraph, GeneratedTypeIds) == NinoTypeKind.Unmanaged;
318318

319319
if (!isUnmanaged)
320320
{
321-
IfDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
321+
IfDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
322322
w => { w.AppendLine(" Reader eleReader;"); });
323323
}
324324
writer.AppendLine();
@@ -344,7 +344,7 @@ protected override void GenerateDeserializer(ITypeSymbol typeSymbol, Writer writ
344344

345345
if (!isUnmanaged)
346346
{
347-
IfElseDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
347+
IfElseDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
348348
w =>
349349
{
350350
w.AppendLine($"{innerIndent}eleReader = reader.Slice();");
@@ -397,7 +397,7 @@ protected override void GenerateDeserializer(ITypeSymbol typeSymbol, Writer writ
397397
writer.AppendLine(" }");
398398
writer.AppendLine();
399399

400-
IfDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
400+
IfDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
401401
w => { w.AppendLine(" Reader eleReader;"); });
402402
writer.AppendLine();
403403

@@ -421,20 +421,20 @@ protected override void GenerateDeserializer(ITypeSymbol typeSymbol, Writer writ
421421
if (canUseMonomorphicPath)
422422
{
423423
// Monomorphic fast path: direct call to avoid delegate allocation
424-
IfElseDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
424+
IfElseDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
425425
w =>
426426
{
427427
w.AppendLine(" eleReader = reader.Slice();");
428-
w.AppendLine($" CachedDeserializer<{elementType.GetDisplayString()}>.DeserializeRef(ref span[i], ref eleReader);");
428+
w.AppendLine($" CachedDeserializer<{elementType.DisplayName}>.DeserializeRef(ref span[i], ref eleReader);");
429429
},
430430
w =>
431431
{
432-
w.AppendLine($" CachedDeserializer<{elementType.GetDisplayString()}>.DeserializeRef(ref span[i], ref reader);");
432+
w.AppendLine($" CachedDeserializer<{elementType.DisplayName}>.DeserializeRef(ref span[i], ref reader);");
433433
});
434434
}
435435
else
436436
{
437-
IfElseDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
437+
IfElseDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
438438
w =>
439439
{
440440
w.AppendLine(" eleReader = reader.Slice();");
@@ -478,11 +478,11 @@ protected override void GenerateDeserializer(ITypeSymbol typeSymbol, Writer writ
478478
writer.AppendLine();
479479

480480
// Only use WEAK_VERSION_TOLERANCE reader for non-unmanaged types
481-
bool isUnmanagedRef = elementType.GetKind(NinoGraph, GeneratedTypes) == NinoTypeHelper.NinoTypeKind.Unmanaged;
481+
bool isUnmanagedRef = TypeInfoDtoExtensions.GetKind(elementType, NinoGraph, GeneratedTypeIds) == NinoTypeKind.Unmanaged;
482482

483483
if (!isUnmanagedRef)
484484
{
485-
IfDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
485+
IfDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
486486
w => { w.AppendLine(" Reader eleReader;"); });
487487
}
488488
writer.AppendLine();
@@ -519,7 +519,7 @@ protected override void GenerateDeserializer(ITypeSymbol typeSymbol, Writer writ
519519

520520
if (!isUnmanagedRef)
521521
{
522-
IfElseDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
522+
IfElseDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
523523
w =>
524524
{
525525
w.AppendLine($"{innerIndent}eleReader = reader.Slice();");

src/Nino.Generator/BuiltInType/ArraySegmentGenerator.cs

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,40 +31,42 @@
3131
namespace Nino.Generator.BuiltInType;
3232

3333
public class ArraySegmentGenerator(
34+
Dictionary<int, TypeInfoDto> typeInfoCache,
35+
string assemblyNamespace,
3436
NinoGraph ninoGraph,
35-
HashSet<ITypeSymbol> potentialTypes,
36-
HashSet<ITypeSymbol> selectedTypes,
37-
Compilation compilation) : NinoBuiltInTypeGenerator(ninoGraph, potentialTypes, selectedTypes, compilation)
37+
HashSet<int> potentialTypeIds,
38+
HashSet<int> selectedTypeIds,
39+
bool isUnityAssembly = false) : NinoBuiltInTypeGenerator(typeInfoCache, assemblyNamespace, ninoGraph, potentialTypeIds, selectedTypeIds, isUnityAssembly)
3840
{
3941
protected override string OutputFileName => "NinoArraySegmentTypeGenerator";
4042

41-
public override bool Filter(ITypeSymbol typeSymbol)
43+
public override bool Filter(TypeInfoDto typeInfo)
4244
{
43-
if (typeSymbol is not INamedTypeSymbol namedType) return false;
45+
if (!typeInfo.IsGenericType) return false;
46+
if (typeInfo.TypeArguments.Length != 1) return false;
4447

4548
// Only accept ArraySegment<T>
46-
var originalDef = namedType.OriginalDefinition.ToDisplayString();
49+
var originalDef = typeInfo.GenericOriginalDefinition;
4750
if (originalDef != "System.ArraySegment<T>")
4851
return false;
4952

50-
var elementType = namedType.TypeArguments[0];
53+
var elementType = typeInfo.TypeArguments[0];
5154

5255
// Element type must be valid
53-
if (elementType.GetKind(NinoGraph, GeneratedTypes) == NinoTypeHelper.NinoTypeKind.Invalid)
56+
if (TypeInfoDtoExtensions.GetKind(elementType, NinoGraph, GeneratedTypeIds) == NinoTypeKind.Invalid)
5457
return false;
5558

5659
return true;
5760
}
5861

59-
protected override void GenerateSerializer(ITypeSymbol typeSymbol, Writer writer)
62+
protected override void GenerateSerializer(TypeInfoDto typeInfo, Writer writer)
6063
{
61-
var namedType = (INamedTypeSymbol)typeSymbol;
62-
var elementType = namedType.TypeArguments[0];
64+
var elementType = typeInfo.TypeArguments[0];
6365

64-
var typeName = typeSymbol.GetDisplayString();
66+
var typeName = typeInfo.DisplayName;
6567

6668
// Check if element type is unmanaged for fast path
67-
bool canUseFastPath = elementType.GetKind(NinoGraph, GeneratedTypes) == NinoTypeHelper.NinoTypeKind.Unmanaged;
69+
bool canUseFastPath = TypeInfoDtoExtensions.GetKind(elementType, NinoGraph, GeneratedTypeIds) == NinoTypeKind.Unmanaged;
6870

6971
WriteAggressiveInlining(writer);
7072
writer.Append("public static void Serialize(this ");
@@ -96,28 +98,27 @@ protected override void GenerateSerializer(ITypeSymbol typeSymbol, Writer writer
9698
// For managed element types, serialize element by element
9799
writer.AppendLine(" for (int i = 0; i < cnt; i++)");
98100
writer.AppendLine(" {");
99-
IfDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
101+
IfDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
100102
w => { w.AppendLine(" var pos = writer.Advance(4);"); });
101103

102104
writer.Append(" ");
103105
writer.AppendLine(GetSerializeString(elementType, "value[i]"));
104-
IfDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
106+
IfDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
105107
w => { w.AppendLine(" writer.PutLength(pos);"); });
106108
writer.AppendLine(" }");
107109
}
108110

109111
writer.AppendLine("}");
110112
}
111113

112-
protected override void GenerateDeserializer(ITypeSymbol typeSymbol, Writer writer)
114+
protected override void GenerateDeserializer(TypeInfoDto typeInfo, Writer writer)
113115
{
114-
var namedType = (INamedTypeSymbol)typeSymbol;
115-
var elementType = namedType.TypeArguments[0];
116-
var elemType = elementType.GetDisplayString();
117-
var typeName = typeSymbol.GetDisplayString();
116+
var elementType = typeInfo.TypeArguments[0];
117+
var elemType = elementType.DisplayName;
118+
var typeName = typeInfo.DisplayName;
118119

119120
// Check if element type is unmanaged for fast path
120-
bool canUseFastPath = elementType.GetKind(NinoGraph, GeneratedTypes) == NinoTypeHelper.NinoTypeKind.Unmanaged;
121+
bool canUseFastPath = TypeInfoDtoExtensions.GetKind(elementType, NinoGraph, GeneratedTypeIds) == NinoTypeKind.Unmanaged;
121122

122123
// Out overload
123124
WriteAggressiveInlining(writer);
@@ -148,7 +149,7 @@ protected override void GenerateDeserializer(ITypeSymbol typeSymbol, Writer writ
148149
writer.AppendLine();
149150

150151
// For managed element types, deserialize element by element
151-
IfDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
152+
IfDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
152153
w => { w.AppendLine(" Reader eleReader;"); });
153154
writer.AppendLine();
154155

@@ -158,7 +159,7 @@ protected override void GenerateDeserializer(ITypeSymbol typeSymbol, Writer writ
158159
writer.AppendLine(" for (int i = 0; i < length; i++)");
159160
writer.AppendLine(" {");
160161

161-
IfElseDirective(NinoTypeHelper.WeakVersionToleranceSymbol, writer,
162+
IfElseDirective(NinoConstants.WeakVersionToleranceSymbol, writer,
162163
w =>
163164
{
164165
w.AppendLine(" eleReader = reader.Slice();");

0 commit comments

Comments
 (0)