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]); } ///