Skip to content

Commit c11380a

Browse files
committed
fix(TrP): correct abstract model inheritance chain construction
1 parent c2dfabf commit c11380a

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

src/TrProtocol.SerializerGenerator/Internal/Extensions/SyntaxExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public static void GetNamespace(this TypeDeclarationSyntax type, out string[] ty
1616
names.Insert(0, classParent.Identifier.Text);
1717
parent = classParent.Parent;
1818
}
19-
typeParentsNames = names.ToArray();
19+
typeParentsNames = [.. names];
2020
fullNameSpce = null;
2121
while (parent is NamespaceDeclarationSyntax @namespace) {
2222
if (fullNameSpce is null) {
@@ -75,13 +75,13 @@ public static bool AttributeMatch<TAttribute>(this AttributeSyntax attribute) wh
7575
}
7676
public static ExpressionSyntax[] ExtractAttributeParams(this AttributeSyntax attribute) {
7777
if (attribute.ArgumentList == null) {
78-
return Array.Empty<ExpressionSyntax>();
78+
return [];
7979
}
8080
if (attribute.ArgumentList.Arguments.Count == 1 && attribute.ArgumentList.Arguments.First().Expression is InitializerExpressionSyntax init) {
81-
return init.Expressions.ToArray();
81+
return [.. init.Expressions];
8282
}
8383
else {
84-
return attribute.ArgumentList.Arguments.Select(a => a.Expression).ToArray();
84+
return [.. attribute.ArgumentList.Arguments.Select(a => a.Expression)];
8585
}
8686
}
8787
public static string GetTypeSymbolName(this TypeSyntax type) {

src/TrProtocol.SerializerGenerator/SerializeGenerator.cs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ private static ProtocolTypeInfo Transform(TypeDeclarationSyntax typeDeclaration)
8585

8686
// TODO: Split the serialization code generation process into more smaller SyntaxTemplates
8787
private static void Execute(SourceProductionContext context, (Compilation compilation, ImmutableArray<ProtocolTypeInfo> infos) data) {
88+
#if DEBUG
8889
// if (!Debugger.IsAttached) Debugger.Launch();
90+
#endif
8991

9092
#region Init global info
9193
Compilation.LoadCompilation(data.compilation);
@@ -189,7 +191,7 @@ static void CheckMemberSymbol(INamedTypeSymbol typeSym, SerializationExpandConte
189191

190192
#region Add type constructors and special behavior
191193

192-
List<(string memberName, string memberType)> externalMembers = model.DefSyntax.Members
194+
List<(string memberName, string memberType)> externalMembers = [.. model.DefSyntax.Members
193195
.Where(m => m.AttributeLists
194196
.SelectMany(a => a.Attributes)
195197
.Any(a => a.AttributeMatch<ExternalMemberAttribute>()))
@@ -205,7 +207,7 @@ static void CheckMemberSymbol(INamedTypeSymbol typeSym, SerializationExpandConte
205207
}
206208
return list;
207209
}
208-
}).SelectMany(m => m).ToList();
210+
}).SelectMany(m => m)];
209211

210212
string externalMemberParams;
211213
if (externalMembers.Count == 0) {
@@ -233,7 +235,7 @@ static void CheckMemberSymbol(INamedTypeSymbol typeSym, SerializationExpandConte
233235

234236
if (model.IsLengthAware) {
235237
if (model.HasExtraData) {
236-
classNode.WriteLine($"public byte[] {nameof(IExtraData.ExtraData)} {{ get; set; }} = Array.Empty<byte>();");
238+
classNode.WriteLine($"public byte[] {nameof(IExtraData.ExtraData)} {{ get; set; }} = [];");
237239
}
238240
classNode.Write($"public {model.TypeName}(ref void* ptr, void* ptr_end{(model.IsSideSpecific ? ", bool isServerSide" : "")}{externalMemberParams})");
239241
classNode.BlockWrite((source) => {
@@ -1503,10 +1505,12 @@ object GetArraySize(ExpressionSyntax indexExp, int i) {
15031505

15041506
writeNode.WriteLine("var ptr_current = ptr;");
15051507
writeNode.WriteLine();
1508+
15061509
if (model.IsConcreteImpl) {
15071510
INamedTypeSymbol[] ExtractAbstractModelInheritance(INamedTypeSymbol type) {
15081511
var abstractModelAncestors = type.GetFullInheritanceTree()
15091512
.Where(t => t.HasAbstractModelAttribute())
1513+
.OfType<INamedTypeSymbol>()
15101514
.ToList();
15111515

15121516
var graph = new Dictionary<INamedTypeSymbol, List<INamedTypeSymbol>>(SymbolEqualityComparer.Default);
@@ -1522,30 +1526,39 @@ INamedTypeSymbol[] ExtractAbstractModelInheritance(INamedTypeSymbol type) {
15221526
var roots = graph.Where(kvp => !kvp.Value.Any()).Select(kvp => kvp.Key).ToList();
15231527
if (roots.Count > 1) {
15241528
throw new InvalidOperationException(
1525-
$"类型 {type.Name} 从多个独立的AbstractModelAttribute标记类型继承: " +
1529+
$"Type {type.Name} inherits from multiple independent AbstractModelAttribute marked types: " +
15261530
string.Join(", ", roots.Select(r => r.Name)));
15271531
}
1532+
15281533
foreach (var kvp in graph) {
15291534
if (kvp.Value.Count > 1) {
15301535
throw new InvalidOperationException(
1531-
$"类型 {type.Name} 的祖先 {kvp.Key.Name} 同时从多个AbstractModelAttribute标记类型继承: " +
1536+
$"Type {type.Name} ancestor {kvp.Key.Name} inherits from multiple AbstractModelAttribute marked types: " +
15321537
string.Join(", ", kvp.Value.Select(p => p.Name)));
15331538
}
15341539
}
1540+
15351541
if (roots.Count == 1) {
1542+
// find the closest abstract ancestor (leaf) that does not appear in any other node's parents
1543+
var leaf = graph.Keys
1544+
.FirstOrDefault(k => !graph.Values.SelectMany(v => v).Contains(k, SymbolEqualityComparer.Default));
1545+
15361546
var chain = new List<INamedTypeSymbol>();
1537-
var current = roots[0];
1547+
var current = leaf;
15381548

1549+
// follow the parent pointer up (child -> parent), and then reverse the chain to get from root to leaf
15391550
while (current != null) {
15401551
chain.Add(current);
1541-
var next = graph[current].FirstOrDefault();
1542-
current = next;
1552+
1553+
var parent = graph[current].FirstOrDefault(); // safe: graph has entry for current
1554+
current = parent;
15431555
}
15441556

1545-
return chain.ToArray();
1557+
chain.Reverse();
1558+
return [];
15461559
}
15471560

1548-
return Array.Empty<INamedTypeSymbol>();
1561+
return [];
15491562
}
15501563

15511564
foreach (var inherit in ExtractAbstractModelInheritance(modelSym)) {
@@ -1689,7 +1702,7 @@ param[0].Type is PointerTypeSyntax pointerType &&
16891702

16901703
if (polymorphicBase is not null) {
16911704
polymorphicBase.DefSyntax.GetNamespace(out var classes, out var fullNamespace, out var unit);
1692-
var usings = unit?.Usings.Select(u => u.Name?.ToString() ?? "").Where(u => u is not "").ToArray() ?? Array.Empty<string>();
1705+
var usings = unit?.Usings.Select(u => u.Name?.ToString() ?? "").Where(u => u is not "").ToArray() ?? [];
16931706

16941707
var source = new SourceCodeWriter(1024 * 4);
16951708
source.WriteLine();

0 commit comments

Comments
 (0)