SymbolScopeImpl ReadScope(uint methodRid, GenericParamContext gpContext) { var scopesRidList = pdbMetadata.GetLocalScopeRidList(methodRid); SymbolScopeImpl rootScopeOrNull = null; if (scopesRidList.Count != 0) { var custInfos = ListCache <PdbCustomDebugInfo> .AllocList(); var stack = ListCache <SymbolScopeImpl> .AllocList(); var importScopeBlobReader = new ImportScopeBlobReader(module, pdbMetadata.BlobStream); for (int i = 0; i < scopesRidList.Count; i++) { var rid = scopesRidList[i]; int token = new MDToken(Table.LocalScope, rid).ToInt32(); bool b = pdbMetadata.TablesStream.TryReadLocalScopeRow(rid, out var row); Debug.Assert(b); uint startOffset = row.StartOffset; uint endOffset = startOffset + row.Length; SymbolScopeImpl parent = null; while (stack.Count > 0) { var nextParent = stack[stack.Count - 1]; if (startOffset >= nextParent.StartOffset && endOffset <= nextParent.EndOffset) { parent = nextParent; break; } stack.RemoveAt(stack.Count - 1); } Debug.Assert(parent != null || rootScopeOrNull == null); custInfos.Clear(); GetCustomDebugInfos(token, gpContext, custInfos); var customDebugInfos = custInfos.Count == 0 ? Array2.Empty <PdbCustomDebugInfo>() : custInfos.ToArray(); var scope = new SymbolScopeImpl(this, parent, (int)startOffset, (int)endOffset, customDebugInfos); if (rootScopeOrNull == null) { rootScopeOrNull = scope; } stack.Add(scope); if (parent != null) { parent.childrenList.Add(scope); } scope.importScope = ReadPdbImportScope(ref importScopeBlobReader, row.ImportScope, gpContext); GetEndOfLists(rid, out uint variableListEnd, out uint constantListEnd); ReadVariables(scope, gpContext, row.VariableList, variableListEnd); ReadConstants(scope, row.ConstantList, constantListEnd); } ListCache <SymbolScopeImpl> .Free(ref stack); ListCache <PdbCustomDebugInfo> .Free(ref custInfos); } return(rootScopeOrNull ?? new SymbolScopeImpl(this, null, 0, int.MaxValue, Array2.Empty <PdbCustomDebugInfo>())); }
PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReader, uint importScope, GenericParamContext gpContext) { if (importScope == 0) { return(null); } const int MAX = 1000; PdbImportScope result = null; PdbImportScope prevScope = null; for (int i = 0; importScope != 0; i++) { Debug.Assert(i < MAX); if (i >= MAX) { return(null); } int token = new MDToken(Table.ImportScope, importScope).ToInt32(); if (!pdbMetadata.TablesStream.TryReadImportScopeRow(importScope, out var row)) { return(null); } var scope = new PdbImportScope(); GetCustomDebugInfos(token, gpContext, scope.CustomDebugInfos); if (result == null) { result = scope; } if (prevScope != null) { prevScope.Parent = scope; } importScopeBlobReader.Read(row.Imports, scope.Imports); prevScope = scope; importScope = row.Parent; } return(result); }