diff --git a/ICSharpCode.Decompiler/DebugInfo/DebugInfoGenerator.cs b/ICSharpCode.Decompiler/DebugInfo/DebugInfoGenerator.cs index 5a65476bd..32a45f9ab 100644 --- a/ICSharpCode.Decompiler/DebugInfo/DebugInfoGenerator.cs +++ b/ICSharpCode.Decompiler/DebugInfo/DebugInfoGenerator.cs @@ -48,7 +48,7 @@ namespace ICSharpCode.Decompiler.DebugInfo readonly ImportScopeInfo globalImportScope = new ImportScopeInfo(); ImportScopeInfo currentImportScope; List importScopes = new List(); - List<(MethodDefinitionHandle Method, ImportScopeInfo Import, int Offset, int Length, HashSet Locals)> localScopes = new List<(MethodDefinitionHandle Method, ImportScopeInfo Import, int Offset, int Length, HashSet Locals)>(); + internal List<(MethodDefinitionHandle Method, ImportScopeInfo Import, int Offset, int Length, HashSet Locals)> LocalScopes { get; } = new List<(MethodDefinitionHandle Method, ImportScopeInfo Import, int Offset, int Length, HashSet Locals)>(); List functions = new List(); /// @@ -64,25 +64,12 @@ namespace ICSharpCode.Decompiler.DebugInfo this.currentImportScope = globalImportScope; } - public void Generate(MetadataBuilder metadata, ImportScopeHandle globalImportScope) + public void GenerateImportScopes(MetadataBuilder metadata, ImportScopeHandle globalImportScope) { foreach (var scope in importScopes) { var blob = EncodeImports(metadata, scope); scope.Handle = metadata.AddImportScope(scope.Parent == null ? globalImportScope : scope.Parent.Handle, blob); } - - foreach (var localScope in localScopes) { - int nextRow = metadata.GetRowCount(TableIndex.LocalVariable) + 1; - var firstLocalVariable = MetadataTokens.LocalVariableHandle(nextRow); - - foreach (var local in localScope.Locals.OrderBy(l => l.Index)) { - var name = local.Name != null ? metadata.GetOrAddString(local.Name) : default; - metadata.AddLocalVariable(LocalVariableAttributes.None, local.Index.Value, name); - } - - metadata.AddLocalScope(localScope.Method, localScope.Import.Handle, firstLocalVariable, - default, localScope.Offset, localScope.Length); - } } static BlobHandle EncodeImports(MetadataBuilder metadata, ImportScopeInfo scope) @@ -185,7 +172,7 @@ namespace ICSharpCode.Decompiler.DebugInfo } } - localScopes.Add(((MethodDefinitionHandle)method.MetadataToken, currentImportScope, + LocalScopes.Add(((MethodDefinitionHandle)method.MetadataToken, currentImportScope, 0, methodBody.GetCodeSize(), localVariables)); } } diff --git a/ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs b/ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs index 4aee9bcb3..d898d8313 100644 --- a/ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs +++ b/ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs @@ -63,6 +63,7 @@ namespace ICSharpCode.Decompiler.DebugInfo var sequencePointBlobs = new Dictionary(); var emptyList = new List(); + var localScopes = new List<(MethodDefinitionHandle Method, ImportScopeInfo Import, int Offset, int Length, HashSet Locals)>(); var stateMachineMethods = new List<(MethodDefinitionHandle MoveNextMethod, MethodDefinitionHandle KickoffMethod)>(); var customDocumentDebugInfo = new List<(DocumentHandle Parent, GuidHandle Guid, BlobHandle Blob)>(); var customMethodDebugInfo = new List<(MethodDefinitionHandle Parent, GuidHandle Guid, BlobHandle Blob)>(); @@ -103,7 +104,9 @@ namespace ICSharpCode.Decompiler.DebugInfo metadata.GetOrAddGuid(DebugInfoEmbeddedSource), sourceBlob)); - debugInfoGen.Generate(metadata, globalImportScope); + debugInfoGen.GenerateImportScopes(metadata, globalImportScope); + + localScopes.AddRange(debugInfoGen.LocalScopes); foreach (var function in debugInfoGen.Functions) { var method = function.MoveNextMethod ?? function.Method; @@ -135,6 +138,28 @@ namespace ICSharpCode.Decompiler.DebugInfo } } + localScopes.Sort((x, y) => { + if (x.Method != y.Method) { + return MetadataTokens.GetRowNumber(x.Method) - MetadataTokens.GetRowNumber(y.Method); + } + if (x.Offset != y.Offset) { + return x.Offset - y.Offset; + } + return y.Length - x.Length; + }); + foreach (var localScope in localScopes) { + int nextRow = metadata.GetRowCount(TableIndex.LocalVariable) + 1; + var firstLocalVariable = MetadataTokens.LocalVariableHandle(nextRow); + + foreach (var local in localScope.Locals.OrderBy(l => l.Index)) { + var localVarName = local.Name != null ? metadata.GetOrAddString(local.Name) : default; + metadata.AddLocalVariable(LocalVariableAttributes.None, local.Index.Value, localVarName); + } + + metadata.AddLocalScope(localScope.Method, localScope.Import.Handle, firstLocalVariable, + default, localScope.Offset, localScope.Length); + } + stateMachineMethods.SortBy(row => MetadataTokens.GetRowNumber(row.MoveNextMethod)); foreach (var row in stateMachineMethods) { metadata.AddStateMachineMethod(row.MoveNextMethod, row.KickoffMethod);