@@ -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, it’ s 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 ) ;
0 commit comments