Skip to content

Commit ed32806

Browse files
Merge pull request #174 from HuangUan/main
修改CSharpParser的AddMembers 修复多类或继承类新增对象不兼容反系列化问题
2 parents 5a1e961 + 623f9eb commit ed32806

2 files changed

Lines changed: 17 additions & 8 deletions

File tree

src/Nino.Generator/Parser/CSharpParser.cs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ protected override HashSet<NinoType> ParseTypes(Compilation compilation)
2929

3030
if (!isNinoType) continue;
3131
}
32-
32+
3333
// inaccessible types
3434
if (ninoSymbol.DeclaredAccessibility != Accessibility.Public)
3535
{
@@ -99,6 +99,21 @@ bool IsNinoType(ITypeSymbol ts)
9999

100100
void AddMembers(NinoType type)
101101
{
102+
// FIX: Collect parent members FIRST (depth-first, root-to-leaf order).
103+
// Previously this added the current type's entry before recursing into parents,
104+
// which produced [child, parent, grandparent] order. That meant:
105+
// 1. In an inheritance chain (A : B) the child's own fields were serialized
106+
// before the base-class fields, so any new field appended to the child
107+
// class would shift the base-class fields and break deserialization.
108+
// 2. When a type contains multiple NinoType members (B then C), the members
109+
// of B were interleaved with the outer type's own fields in an unexpected
110+
// way, making it impossible to safely append fields to B.
111+
// The correct order is [grandparent, parent, child] – i.e. base types first.
112+
foreach (var parent in type.Parents)
113+
{
114+
AddMembers(parent);
115+
}
116+
102117
var entry = (new HashSet<ISymbol>(SymbolEqualityComparer.Default), new List<IParameterSymbol>());
103118
hierarchicalMembers.Add(entry);
104119
var (members, primaryConstructorParams) = entry;
@@ -154,7 +169,7 @@ void AddMembers(NinoType type)
154169
p.Name.Equals(parameter.Name, StringComparison.OrdinalIgnoreCase)
155170
&& !p.IsStatic);
156171

157-
// If any parameter does not have a matching readonly property, its likely not a primary constructor
172+
// If any parameter does not have a matching readonly property, it's likely not a primary constructor
158173
if (matchingProperty == null || !matchingProperty.IsReadOnly)
159174
{
160175
break;
@@ -166,12 +181,6 @@ void AddMembers(NinoType type)
166181
break;
167182
}
168183
}
169-
170-
// Parent members
171-
foreach (var parent in type.Parents)
172-
{
173-
AddMembers(parent);
174-
}
175184
}
176185

177186
AddMembers(ninoType);
Binary file not shown.

0 commit comments

Comments
 (0)