// dnlib: See LICENSE.txt for more info
using System;
using System.Collections.Generic;
using System.Threading;
using dnlib.DotNet.Emit;
namespace dnlib.DotNet.Pdb {
///
/// Custom debug info kind
///
/// See CustomDebugInfoKind in Roslyn source code
public enum PdbCustomDebugInfoKind {
///
///
///
UsingGroups,
///
///
///
ForwardMethodInfo,
///
///
///
ForwardModuleInfo,
///
///
///
StateMachineHoistedLocalScopes,
///
///
///
StateMachineTypeName,
///
///
///
DynamicLocals,
///
///
///
EditAndContinueLocalSlotMap,
///
///
///
EditAndContinueLambdaMap,
///
///
///
TupleElementNames,
// Values 0x00-0xFF are reserved for Windows PDB CDIs.
///
/// Unknown
///
Unknown = int.MinValue,
///
///
///
TupleElementNames_PortablePdb,
///
///
///
DefaultNamespace,
///
///
///
DynamicLocalVariables,
///
///
///
EmbeddedSource,
///
///
///
SourceLink,
///
///
///
SourceServer,
///
///
///
AsyncMethod,
///
///
///
IteratorMethod,
///
///
///
CompilationMetadataReferences,
///
///
///
CompilationOptions,
///
///
///
TypeDefinitionDocuments,
///
///
///
EditAndContinueStateMachineStateMap,
///
///
///
PrimaryConstructorInformationBlob,
}
///
/// Base class of custom debug info added to the PDB file by the compiler
///
public abstract class PdbCustomDebugInfo {
///
/// Gets the custom debug info kind
///
public abstract PdbCustomDebugInfoKind Kind { get; }
///
/// Gets the custom debug info guid, see
///
public abstract Guid Guid { get; }
}
///
/// Unknown custom debug info. If you see an instance of this class, you're using an old dnlib version or
/// dnlib hasn't been updated to support this new custom debug info kind.
///
public sealed class PdbUnknownCustomDebugInfo : PdbCustomDebugInfo {
readonly PdbCustomDebugInfoKind kind;
readonly Guid guid;
readonly byte[] data;
///
/// Gets the custom debug info kind
///
public override PdbCustomDebugInfoKind Kind => kind;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => guid;
///
/// Gets the data
///
public byte[] Data => data;
///
/// Constructor
///
/// Custom debug info kind
/// Raw custom debug info data
public PdbUnknownCustomDebugInfo(PdbCustomDebugInfoKind kind, byte[] data) {
this.kind = kind;
this.data = data ?? throw new ArgumentNullException(nameof(data));
guid = Guid.Empty;
}
///
/// Constructor
///
/// Custom debug info guid
/// Raw custom debug info data
public PdbUnknownCustomDebugInfo(Guid guid, byte[] data) {
kind = PdbCustomDebugInfoKind.Unknown;
this.data = data ?? throw new ArgumentNullException(nameof(data));
this.guid = guid;
}
}
///
/// Contains sizes of using groups
///
public sealed class PdbUsingGroupsCustomDebugInfo : PdbCustomDebugInfo {
readonly IList usingCounts;
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.UsingGroups;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => Guid.Empty;
///
/// Gets the using counts
///
public IList UsingCounts => usingCounts;
///
/// Constructor
///
public PdbUsingGroupsCustomDebugInfo() => usingCounts = new List();
///
/// Constructor
///
/// Initial capacity of
public PdbUsingGroupsCustomDebugInfo(int capacity) => usingCounts = new List(capacity);
}
///
/// Contains a reference to another method that contains the import strings
///
public sealed class PdbForwardMethodInfoCustomDebugInfo : PdbCustomDebugInfo {
IMethodDefOrRef method;
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.ForwardMethodInfo;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => Guid.Empty;
///
/// Gets/sets the referenced method
///
public IMethodDefOrRef Method {
get => method;
set => method = value;
}
///
/// Constructor
///
public PdbForwardMethodInfoCustomDebugInfo() {
}
///
/// Constructor
///
/// The referenced method
public PdbForwardMethodInfoCustomDebugInfo(IMethodDefOrRef method) => this.method = method;
}
///
/// Contains a reference to another method that contains the per-module debug info (assembly reference aliases)
///
public sealed class PdbForwardModuleInfoCustomDebugInfo : PdbCustomDebugInfo {
IMethodDefOrRef method;
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.ForwardModuleInfo;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => Guid.Empty;
///
/// Gets/sets the referenced method
///
public IMethodDefOrRef Method {
get => method;
set => method = value;
}
///
/// Constructor
///
public PdbForwardModuleInfoCustomDebugInfo() {
}
///
/// Constructor
///
/// The referenced method
public PdbForwardModuleInfoCustomDebugInfo(IMethodDefOrRef method) => this.method = method;
}
///
/// State machine hosted local scope info
///
public struct StateMachineHoistedLocalScope {
///
/// true if it's a syntesized local ( and are both null)
///
public readonly bool IsSynthesizedLocal => Start is null && End is null;
///
/// The instruction of the first operation in the scope. Can be null if it's a synthesized local
///
public Instruction Start;
///
/// The instruction of the first operation outside of the scope or null if it ends at the last instruction in the body.
/// Can also be null if it's a synthesized local (in which case is also null, see )
///
public Instruction End;
///
/// Constructor
///
/// Start of the scope
/// First instruction after the end of the scope
public StateMachineHoistedLocalScope(Instruction start, Instruction end) {
Start = start;
End = end;
}
}
///
/// Contains local scopes for state machine hoisted local variables.
///
public sealed class PdbStateMachineHoistedLocalScopesCustomDebugInfo : PdbCustomDebugInfo {
readonly IList scopes;
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.StateMachineHoistedLocalScopes;
///
/// Gets the scopes
///
public IList Scopes => scopes;
///
/// Constructor
///
public PdbStateMachineHoistedLocalScopesCustomDebugInfo() => scopes = new List();
///
/// Constructor
///
/// Initial capacity of
public PdbStateMachineHoistedLocalScopesCustomDebugInfo(int capacity) => scopes = new List(capacity);
}
///
/// Contains the state machine type
///
public sealed class PdbStateMachineTypeNameCustomDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.StateMachineTypeName;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => Guid.Empty;
///
/// Gets/sets the state machine type
///
public TypeDef Type { get; set; }
///
/// Constructor
///
public PdbStateMachineTypeNameCustomDebugInfo() {
}
///
/// Constructor
///
/// State machine type
public PdbStateMachineTypeNameCustomDebugInfo(TypeDef type) => Type = type;
}
///
/// Contains dynamic flags for local variables and constants
///
public sealed class PdbDynamicLocalsCustomDebugInfo : PdbCustomDebugInfo {
readonly IList locals;
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.DynamicLocals;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => Guid.Empty;
///
/// Gets the dynamic locals
///
public IList Locals => locals;
///
/// Constructor
///
public PdbDynamicLocalsCustomDebugInfo() => locals = new List();
///
/// Constructor
///
/// Initial capacity of
public PdbDynamicLocalsCustomDebugInfo(int capacity) => locals = new List(capacity);
}
///
/// Dynamic local info
///
public sealed class PdbDynamicLocal {
readonly IList flags;
string name;
Local local;
///
/// Gets the dynamic flags
///
public IList Flags => flags;
///
/// Gets/sets the name of the local. The name must have at most 64 characters and no char can be NUL (0x0000).
/// If null is written, is returned instead.
///
public string Name {
get {
var n = name;
if (n is not null)
return n;
return local?.Name;
}
set => name = value;
}
///
/// true if it's a constant and not a variable ( is null)
///
public bool IsConstant => Local is null;
///
/// true if it's a variable ( is not null)
///
public bool IsVariable => Local is not null;
///
/// Gets/sets the local. Could be null if there's no local (it's a 'const' local).
///
public Local Local {
get => local;
set => local = value;
}
///
/// Constructor
///
public PdbDynamicLocal() => flags = new List();
///
/// Constructor
///
/// Initial capacity of
public PdbDynamicLocal(int capacity) => flags = new List(capacity);
}
///
/// Contains the EnC local variable slot map
///
public sealed class PdbEditAndContinueLocalSlotMapCustomDebugInfo : PdbCustomDebugInfo {
readonly byte[] data;
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.EncLocalSlotMap;
///
/// Gets the data. Spec: https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#EditAndContinueLocalSlotMap
///
public byte[] Data => data;
///
/// Constructor
///
/// Raw custom debug info data
public PdbEditAndContinueLocalSlotMapCustomDebugInfo(byte[] data) => this.data = data ?? throw new ArgumentNullException(nameof(data));
}
///
/// Contains the EnC lambda map
///
public sealed class PdbEditAndContinueLambdaMapCustomDebugInfo : PdbCustomDebugInfo {
readonly byte[] data;
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.EditAndContinueLambdaMap;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.EncLambdaAndClosureMap;
///
/// Gets the data. Spec: https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#EditAndContinueLambdaAndClosureMap
///
public byte[] Data => data;
///
/// Constructor
///
/// Raw custom debug info data
public PdbEditAndContinueLambdaMapCustomDebugInfo(byte[] data) => this.data = data ?? throw new ArgumentNullException(nameof(data));
}
///
/// Contains tuple element names for local variables and constants
///
public sealed class PdbTupleElementNamesCustomDebugInfo : PdbCustomDebugInfo {
readonly IList names;
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.TupleElementNames;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => Guid.Empty;
///
/// Gets the tuple element names
///
public IList Names => names;
///
/// Constructor
///
public PdbTupleElementNamesCustomDebugInfo() => names = new List();
///
/// Constructor
///
/// Initial capacity of
public PdbTupleElementNamesCustomDebugInfo(int capacity) => names = new List(capacity);
}
///
/// Tuple element name info
///
public sealed class PdbTupleElementNames {
readonly IList tupleElementNames;
string name;
Local local;
Instruction scopeStart, scopeEnd;
///
/// Gets/sets the name of the local. If null is written, is returned instead.
///
public string Name {
get {
var n = name;
if (n is not null)
return n;
return local?.Name;
}
set => name = value;
}
///
/// Gets/sets the local. It's null if it's a constant, and non-null if it's a variable
///
public Local Local {
get => local;
set => local = value;
}
///
/// true if it's a constant. Constants have a scope ( and )
///
public bool IsConstant => local is null;
///
/// true if it's a variable. Variables don't have a scope ( and )
///
public bool IsVariable => local is not null;
///
/// Gets/sets the start of the scope or null. Only constants have a scope.
///
public Instruction ScopeStart {
get => scopeStart;
set => scopeStart = value;
}
///
/// Gets/sets the end of the scope or null if it has no scope or if the scope ends at the end of the body. Only constants have a scope.
///
public Instruction ScopeEnd {
get => scopeEnd;
set => scopeEnd = value;
}
///
/// Gets the tuple element names
///
public IList TupleElementNames => tupleElementNames;
///
/// Constructor
///
public PdbTupleElementNames() => tupleElementNames = new List();
///
/// Constructor
///
/// Initial capacity of
public PdbTupleElementNames(int capacity) => tupleElementNames = new List(capacity);
}
///
/// Contains tuple element names for local variables and constants
///
public sealed class PortablePdbTupleElementNamesCustomDebugInfo : PdbCustomDebugInfo {
readonly IList names;
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.TupleElementNames_PortablePdb;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.TupleElementNames;
///
/// Gets the tuple element names
///
public IList Names => names;
///
/// Constructor
///
public PortablePdbTupleElementNamesCustomDebugInfo() => names = new List();
///
/// Constructor
///
/// Initial capacity of
public PortablePdbTupleElementNamesCustomDebugInfo(int capacity) => names = new List(capacity);
}
///
/// Async method stepping info
///
/// It's internal and translated to a
///
sealed class PdbAsyncMethodSteppingInformationCustomDebugInfo : PdbCustomDebugInfo {
readonly IList asyncStepInfos;
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.Unknown;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.AsyncMethodSteppingInformationBlob;
///
/// Gets the catch handler instruction or null
///
public Instruction CatchHandler { get; set; }
///
/// Gets all async step infos
///
public IList AsyncStepInfos => asyncStepInfos;
///
/// Constructor
///
public PdbAsyncMethodSteppingInformationCustomDebugInfo() => asyncStepInfos = new List();
}
///
/// Default namespace
///
public sealed class PdbDefaultNamespaceCustomDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.DefaultNamespace;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.DefaultNamespace;
///
/// Gets the default namespace
///
public string Namespace { get; set; }
///
/// Constructor
///
public PdbDefaultNamespaceCustomDebugInfo() {
}
///
/// Constructor
///
/// Default namespace
public PdbDefaultNamespaceCustomDebugInfo(string defaultNamespace) => Namespace = defaultNamespace;
}
///
/// Dynamic flags
///
public sealed class PdbDynamicLocalVariablesCustomDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.DynamicLocalVariables;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.DynamicLocalVariables;
///
/// Gets/sets the dynamic flags
///
public bool[] Flags { get; set; }
///
/// Constructor
///
public PdbDynamicLocalVariablesCustomDebugInfo() {
}
///
/// Constructor
///
/// Dynamic flags
public PdbDynamicLocalVariablesCustomDebugInfo(bool[] flags) => Flags = flags;
}
///
/// Contains the source code
///
public sealed class PdbEmbeddedSourceCustomDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.EmbeddedSource;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.EmbeddedSource;
///
/// Gets the source code blob.
///
/// It's not decompressed and converted to a string because the encoding isn't specified.
///
/// https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#embedded-source-c-and-vb-compilers
///
public byte[] SourceCodeBlob { get; set; }
///
/// Constructor
///
public PdbEmbeddedSourceCustomDebugInfo() {
}
///
/// Constructor
///
/// Source code blob
public PdbEmbeddedSourceCustomDebugInfo(byte[] sourceCodeBlob) => SourceCodeBlob = sourceCodeBlob;
}
///
/// Contains the source link file
///
public sealed class PdbSourceLinkCustomDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.SourceLink;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.SourceLink;
///
/// Gets the source link file contents
///
public byte[] FileBlob { get; set; }
///
/// Constructor
///
public PdbSourceLinkCustomDebugInfo() {
}
///
/// Constructor
///
/// Source link file contents
public PdbSourceLinkCustomDebugInfo(byte[] fileBlob) => FileBlob = fileBlob;
}
///
/// Contains the source server file
///
public sealed class PdbSourceServerCustomDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.SourceServer;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => Guid.Empty;
///
/// Gets the source server file contents
///
public byte[] FileBlob { get; set; }
///
/// Constructor
///
public PdbSourceServerCustomDebugInfo() {
}
///
/// Constructor
///
/// Source server file contents
public PdbSourceServerCustomDebugInfo(byte[] fileBlob) => FileBlob = fileBlob;
}
///
/// Async method info
///
public sealed class PdbAsyncMethodCustomDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.AsyncMethod;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => Guid.Empty;
readonly IList asyncStepInfos;
///
/// Gets/sets the starting method that initiates the async operation
///
public MethodDef KickoffMethod { get; set; }
///
/// Gets/sets the instruction for the compiler generated catch handler that wraps an async method.
/// This can be null.
///
public Instruction CatchHandlerInstruction { get; set; }
///
/// Gets all step infos used by the debugger
///
public IList StepInfos => asyncStepInfos;
///
/// Constructor
///
public PdbAsyncMethodCustomDebugInfo() => asyncStepInfos = new List();
///
/// Constructor
///
/// Default capacity for
public PdbAsyncMethodCustomDebugInfo(int stepInfosCapacity) => asyncStepInfos = new List(stepInfosCapacity);
}
///
/// Async step info used by debuggers
///
public struct PdbAsyncStepInfo {
///
/// The yield instruction
///
public Instruction YieldInstruction;
///
/// Resume method
///
public MethodDef BreakpointMethod;
///
/// Resume instruction (where the debugger puts a breakpoint)
///
public Instruction BreakpointInstruction;
///
/// Constructor
///
/// The yield instruction
/// Resume method
/// Resume instruction (where the debugger puts a breakpoint)
public PdbAsyncStepInfo(Instruction yieldInstruction, MethodDef breakpointMethod, Instruction breakpointInstruction) {
YieldInstruction = yieldInstruction;
BreakpointMethod = breakpointMethod;
BreakpointInstruction = breakpointInstruction;
}
}
///
/// Iterator method
///
public sealed class PdbIteratorMethodCustomDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.IteratorMethod;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => Guid.Empty;
///
/// Gets the kickoff method
///
public MethodDef KickoffMethod { get; set; }
///
/// Constructor
///
public PdbIteratorMethodCustomDebugInfo() {
}
///
/// Constructor
///
/// Kickoff method
public PdbIteratorMethodCustomDebugInfo(MethodDef kickoffMethod) => KickoffMethod = kickoffMethod;
}
///
/// Compilation metadata references
///
public sealed class PdbCompilationMetadataReferencesCustomDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.CompilationMetadataReferences;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.CompilationMetadataReferences;
///
/// Gets all references
///
public List References { get; }
///
/// Constructor
///
public PdbCompilationMetadataReferencesCustomDebugInfo() => References = new List();
}
///
/// Compilation metadata reference flags, see https://github.com/dotnet/roslyn/blob/master/docs/features/pdb-compilation-options.md
///
[Flags]
public enum PdbCompilationMetadataReferenceFlags : byte {
///
/// No bit is set
///
None = 0,
///
/// Set if it's an assembly reference, clear if it's a module reference
///
Assembly = 0x01,
///
/// EmbedInteropTypes was enabled
///
EmbedInteropTypes = 0x02,
}
///
/// A compilation metadata reference
///
public sealed class PdbCompilationMetadataReference {
///
/// Name of the reference (eg. filename)
///
public string Name { get; set; }
///
/// Aliases (or an empty string), separated with commas
///
public string Aliases { get; set; }
///
/// Gets the flags
///
public PdbCompilationMetadataReferenceFlags Flags { get; set; }
///
/// Gets the timestamp stored in the PE header
///
public uint Timestamp { get; set; }
///
/// Gets SizeOfImage stored in the PE header
///
public uint SizeOfImage { get; set; }
///
/// Gets the MVID stored in the .NET metadata
///
public Guid Mvid { get; set; }
///
/// Constructor
///
public PdbCompilationMetadataReference() {
Name = string.Empty;
Aliases = string.Empty;
}
///
/// Constructor
///
/// Name of reference
/// Aliases (or an empty string), separated with commas
/// Reference flags
/// Timestamp in PE header
/// SizeOfImage in PE header
/// MVID stored in the .NET metadata
public PdbCompilationMetadataReference(string name, string aliases, PdbCompilationMetadataReferenceFlags flags, uint timestamp, uint sizeOfImage, Guid mvid) {
Name = name;
Aliases = aliases;
Flags = flags;
Timestamp = timestamp;
SizeOfImage = sizeOfImage;
Mvid = mvid;
}
}
///
/// Compilation options
///
public sealed class PdbCompilationOptionsCustomDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.CompilationOptions;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.CompilationOptions;
///
/// Gets all compilation options, see https://github.com/dotnet/roslyn/blob/master/docs/features/pdb-compilation-options.md .
/// Option names (key): see roslyn/src/Compilers/Core/Portable/PEWriter/CompilationOptionNames.cs
///
public List> Options { get; }
///
/// Constructor
///
public PdbCompilationOptionsCustomDebugInfo() => Options = new List>();
}
///
/// Links a TypeDef with no method IL with a PDB document.
///
public class PdbTypeDefinitionDocumentsDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.TypeDefinitionDocuments;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.TypeDefinitionDocuments;
///
/// List of documents associated with the type
///
public IList Documents {
get {
if (documents is null)
InitializeDocuments();
return documents;
}
}
///
protected IList documents;
/// Initializes
protected virtual void InitializeDocuments() =>
Interlocked.CompareExchange(ref documents, new List(), null);
}
sealed class PdbTypeDefinitionDocumentsDebugInfoMD : PdbTypeDefinitionDocumentsDebugInfo {
readonly ModuleDef readerModule;
readonly IList documentTokens;
protected override void InitializeDocuments() {
var list = new List(documentTokens.Count);
if (readerModule.PdbState is not null) {
for (var i = 0; i < documentTokens.Count; i++) {
if (readerModule.PdbState.tokenToDocument.TryGetValue(documentTokens[i], out var document))
list.Add(document);
}
}
Interlocked.CompareExchange(ref documents, list, null);
}
public PdbTypeDefinitionDocumentsDebugInfoMD(ModuleDef readerModule, IList documentTokens) {
this.readerModule = readerModule;
this.documentTokens = documentTokens;
}
}
///
/// Contains the EnC state machine state mapping
///
public sealed class PdbEditAndContinueStateMachineStateMapDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.EditAndContinueStateMachineStateMap;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.EncStateMachineStateMap;
///
/// State machine states
///
public List StateMachineStates { get; }
///
/// Constructor
///
public PdbEditAndContinueStateMachineStateMapDebugInfo() => StateMachineStates = new List();
}
///
/// State machine state information used by debuggers
///
public struct StateMachineStateInfo {
///
/// Syntax offset
///
public readonly int SyntaxOffset;
///
/// State machine state
///
public readonly StateMachineState State;
///
/// Constructor
///
/// Syntax offset
/// State machine state
public StateMachineStateInfo(int syntaxOffset, StateMachineState state) {
SyntaxOffset = syntaxOffset;
State = state;
}
}
///
/// State machine state
/// from Roslyn: StateMachineState.cs
///
public enum StateMachineState {
///
/// First state of an async iterator state machine that is used to resume the machine after yield return.
/// Initial state is not used to resume state machine that yielded. State numbers decrease as the iterator makes progress.
///
FirstResumableAsyncIteratorState = InitialAsyncIteratorState - 1,
///
/// Initial iterator state of an async iterator.
/// Distinct from so that DisposeAsync can throw in latter case.
///
InitialAsyncIteratorState = -3,
///
/// First state of an iterator state machine. State numbers decrease for subsequent finalize states.
///
FirstIteratorFinalizeState = -3,
///
/// The last state of a state machine.
///
FinishedState = -2,
///
/// State machine not started or is running
///
NotStartedOrRunningState = -1,
///
/// First unused state
///
FirstUnusedState = 0,
///
/// First state in async state machine that is used to resume the machine after await.
/// State numbers increase as the async computation makes progress.
///
FirstResumableAsyncState = 0,
///
/// Initial iterator state of an iterator.
///
InitialIteratorState = 0,
///
/// First state in iterator state machine that is used to resume the machine after yield return.
/// Initial state is not used to resume state machine that yielded. State numbers increase as the iterator makes progress.
///
FirstResumableIteratorState = InitialIteratorState + 1,
}
///
/// Primary constructor information blob
///
public sealed class PrimaryConstructorInformationBlobDebugInfo : PdbCustomDebugInfo {
///
/// Returns
///
public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.PrimaryConstructorInformationBlob;
///
/// Gets the custom debug info guid, see
///
public override Guid Guid => CustomDebugInfoGuids.PrimaryConstructorInformationBlob;
///
/// Gets the data blob
///
public byte[] Blob { get; set; }
///
/// Constructor
///
public PrimaryConstructorInformationBlobDebugInfo() {
}
///
/// Constructor
///
/// Source server file contents
public PrimaryConstructorInformationBlobDebugInfo(byte[] blob) => Blob = blob;
}
}