From 080d7595fca22a0f41ff4ede45204ae7735ae561 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Wed, 29 May 2024 22:24:51 +0200 Subject: [PATCH] Sort `ExportedType` table when writing to comply with new ECMA Augments --- src/DotNet/Writer/Metadata.cs | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 28e874ae3..9b474e6f3 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -1811,9 +1811,39 @@ void InitializeVTableFixups() { void AddExportedTypes() { using var _ = errorContext.SetSource("exported types"); var exportedTypes = module.ExportedTypes; - int count = exportedTypes.Count; + + var nestedTypeDict = new Dictionary>(); + for (var i = 0; i < exportedTypes.Count; i++) { + var exportedType = exportedTypes[i]; + if (exportedType.Implementation is not ExportedType decl) + continue; + if (!nestedTypeDict.TryGetValue(decl, out var nestedTypes)) + nestedTypes = nestedTypeDict[decl] = new List(); + nestedTypes.Add(exportedType); + } + + var sortedTypes = new List(exportedTypes.Count); + var visited = new Dictionary(); + var stack = new Stack>(); + stack.Push(exportedTypes.GetEnumerator()); + while (stack.Count > 0) { + var enumerator = stack.Pop(); + while (enumerator.MoveNext()) { + var type = enumerator.Current; + if (visited.ContainsKey(type)) + continue; + visited[type] = true; + sortedTypes.Add(type); + if (nestedTypeDict.TryGetValue(type, out var nested) && nested.Count > 0) { + stack.Push(enumerator); + enumerator = nested.GetEnumerator(); + } + } + } + + int count = sortedTypes.Count; for (int i = 0; i < count; i++) - AddExportedType(exportedTypes[i]); + AddExportedType(sortedTypes[i]); } ///