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