-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
237 changed files
with
54,331 additions
and
466 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
using System; | ||
|
||
namespace ClrDebug.DIA | ||
{ | ||
public static partial class DiaExtensions | ||
{ | ||
#region DiaEnumDebugStreamData | ||
|
||
/// <summary> | ||
/// Creates a <see cref="ComObject{T}"/> around an interface supported by the <see cref="IDiaEnumDebugStreamData"/> interface.<para/> | ||
/// Possible conversions include <see cref="DiaImageData"/> and <see cref="DiaEnumDebugStreamData"/>. | ||
/// </summary> | ||
/// <typeparam name="T">A type that wraps one of the interfaces <see cref="IDiaEnumDebugStreamData"/> supports.</typeparam> | ||
/// <param name="diaEnumDebugStreamData">The existing wrapper to create the new wrapper from.</param> | ||
/// <returns>A wrapper of type <typeparamref name="T"/>.</returns> | ||
/// <exception cref="NotSupportedException">A type is specified that is not known to this function.</exception> | ||
public static T As<T>(this DiaEnumDebugStreamData diaEnumDebugStreamData) | ||
{ | ||
var t = typeof(T); | ||
object result; | ||
|
||
var raw = diaEnumDebugStreamData.Raw; | ||
|
||
if (t == typeof(DiaImageData)) | ||
result = new DiaImageData((IDiaImageData) raw); | ||
else if (t == typeof(DiaEnumDebugStreamData)) | ||
result = diaEnumDebugStreamData; | ||
else | ||
throw Extensions.GetAsNotSupportedException<T, IDiaEnumDebugStreamData>(); | ||
|
||
return (T) result; | ||
} | ||
|
||
#endregion | ||
#region As<DiaPropertyStorage> | ||
|
||
/// <summary> | ||
/// Creates a <see cref="ComObject{T}"/> around an interface supported by the <see cref="IDiaSectionContrib"/> interface.<para/> | ||
/// The only supported conversion is <see cref="DiaPropertyStorage"/>. | ||
/// </summary> | ||
/// <typeparam name="T">The <see cref="DiaPropertyStorage"/> type.</typeparam> | ||
/// <param name="diaSectionContrib">The existing wrapper to create the new wrapper from.</param> | ||
/// <returns>A wrapper of type <typeparamref name="T"/>.</returns> | ||
/// <exception cref="NotSupportedException">A type is specified that is not known to this function.</exception> | ||
public static T As<T>(this DiaSectionContrib diaSectionContrib) where T : DiaPropertyStorage => | ||
(T) AsDiaPropertyStorage(diaSectionContrib.Raw); | ||
|
||
/// <summary> | ||
/// Creates a <see cref="ComObject{T}"/> around an interface supported by the <see cref="IDiaSegment"/> interface.<para/> | ||
/// The only supported conversion is <see cref="DiaPropertyStorage"/>. | ||
/// </summary> | ||
/// <typeparam name="T">The <see cref="DiaPropertyStorage"/> type.</typeparam> | ||
/// <param name="diaSegment">The existing wrapper to create the new wrapper from.</param> | ||
/// <returns>A wrapper of type <typeparamref name="T"/>.</returns> | ||
/// <exception cref="NotSupportedException">A type is specified that is not known to this function.</exception> | ||
public static T As<T>(this DiaSegment diaSegment) where T : DiaPropertyStorage => | ||
(T) AsDiaPropertyStorage(diaSegment.Raw); | ||
|
||
/// <summary> | ||
/// Creates a <see cref="ComObject{T}"/> around an interface supported by the <see cref="IDiaInjectedSource"/> interface.<para/> | ||
/// The only supported conversion is <see cref="DiaPropertyStorage"/>. | ||
/// </summary> | ||
/// <typeparam name="T">The <see cref="DiaPropertyStorage"/> type.</typeparam> | ||
/// <param name="diaInjectedSource">The existing wrapper to create the new wrapper from.</param> | ||
/// <returns>A wrapper of type <typeparamref name="T"/>.</returns> | ||
/// <exception cref="NotSupportedException">A type is specified that is not known to this function.</exception> | ||
public static T As<T>(this DiaInjectedSource diaInjectedSource) where T : DiaPropertyStorage => | ||
(T) AsDiaPropertyStorage(diaInjectedSource.Raw); | ||
|
||
/// <summary> | ||
/// Creates a <see cref="ComObject{T}"/> around an interface supported by the <see cref="IDiaFrameData"/> interface.<para/> | ||
/// The only supported conversion is <see cref="DiaPropertyStorage"/>. | ||
/// </summary> | ||
/// <typeparam name="T">The <see cref="DiaPropertyStorage"/> type.</typeparam> | ||
/// <param name="diaFrameData">The existing wrapper to create the new wrapper from.</param> | ||
/// <returns>A wrapper of type <typeparamref name="T"/>.</returns> | ||
/// <exception cref="NotSupportedException">A type is specified that is not known to this function.</exception> | ||
public static T As<T>(this DiaFrameData diaFrameData) where T : DiaPropertyStorage => | ||
(T) AsDiaPropertyStorage(diaFrameData.Raw); | ||
|
||
/// <summary> | ||
/// Creates a <see cref="ComObject{T}"/> around an interface supported by the <see cref="IDiaSymbol"/> interface.<para/> | ||
/// The only supported conversion is <see cref="DiaPropertyStorage"/>. | ||
/// </summary> | ||
/// <typeparam name="T">The <see cref="DiaPropertyStorage"/> type.</typeparam> | ||
/// <param name="diaSymbol">The existing wrapper to create the new wrapper from.</param> | ||
/// <returns>A wrapper of type <typeparamref name="T"/>.</returns> | ||
/// <exception cref="NotSupportedException">A type is specified that is not known to this function.</exception> | ||
public static T As<T>(this DiaSymbol diaSymbol) where T : DiaPropertyStorage => | ||
(T) AsDiaPropertyStorage(diaSymbol.Raw); | ||
|
||
/// <summary> | ||
/// Creates a <see cref="ComObject{T}"/> around an interface supported by the <see cref="IDiaSourceFile"/> interface.<para/> | ||
/// The only supported conversion is <see cref="DiaPropertyStorage"/>. | ||
/// </summary> | ||
/// <typeparam name="T">The <see cref="DiaPropertyStorage"/> type.</typeparam> | ||
/// <param name="diaSourceFile">The existing wrapper to create the new wrapper from.</param> | ||
/// <returns>A wrapper of type <typeparamref name="T"/>.</returns> | ||
/// <exception cref="NotSupportedException">A type is specified that is not known to this function.</exception> | ||
public static T As<T>(this DiaSourceFile diaSourceFile) where T : DiaPropertyStorage => | ||
(T) AsDiaPropertyStorage(diaSourceFile.Raw); | ||
|
||
/// <summary> | ||
/// Creates a <see cref="ComObject{T}"/> around an interface supported by the <see cref="IDiaLineNumber"/> interface.<para/> | ||
/// The only supported conversion is <see cref="DiaPropertyStorage"/>. | ||
/// </summary> | ||
/// <typeparam name="T">The <see cref="DiaPropertyStorage"/> type.</typeparam> | ||
/// <param name="diaLineNumber">The existing wrapper to create the new wrapper from.</param> | ||
/// <returns>A wrapper of type <typeparamref name="T"/>.</returns> | ||
/// <exception cref="NotSupportedException">A type is specified that is not known to this function.</exception> | ||
public static T As<T>(this DiaLineNumber diaLineNumber) where T : DiaPropertyStorage => | ||
(T) AsDiaPropertyStorage(diaLineNumber.Raw); | ||
|
||
private static object AsDiaPropertyStorage<T>(T value) => | ||
new DiaPropertyStorage((IDiaPropertyStorage) value); | ||
|
||
#endregion | ||
#region DiaTable | ||
|
||
/// <summary> | ||
/// Creates a <see cref="ComObject{T}"/> around an interface supported by the <see cref="IDiaTable"/> interface.<para/> | ||
/// Each <see cref="IDiaTable"/> instance is in fact an enumerator for iterating over one and only one type of resource. | ||
/// To locate the <see cref="IDiaTable"/> that implements given enumerator interface, see the <see cref="GetTable{T}(DiaSession)"/> extension | ||
/// method. This method should only be used when you already know for certain which enumerator a given <see cref="IDiaTable"/> represents. | ||
/// Possible conversions include <see cref="DiaEnumSymbols"/>, <see cref="DiaEnumSourceFiles"/>, <see cref="DiaEnumLineNumbers"/>, | ||
/// <see cref="DiaEnumSectionContribs"/>, <see cref="DiaEnumSegments"/>, <see cref="DiaEnumInjectedSources"/> | ||
/// and <see cref="DiaEnumFrameData"/>. | ||
/// </summary> | ||
/// <typeparam name="T">A type that wraps one of the interfaces <see cref="IDiaTable"/> supports.</typeparam> | ||
/// <param name="diaTable">The existing wrapper to create the new wrapper from.</param> | ||
/// <returns>A wrapper of type <typeparamref name="T"/>.</returns> | ||
/// <exception cref="NotSupportedException">A type is specified that is not known to this function.</exception> | ||
private static T As<T>(this DiaTable diaTable) | ||
{ | ||
//This method is implemented for completeness, however due to the fact that each IDiaTable exclusively implements one of the available | ||
//enumerator interfaces, it is inherently unsafe to forcefully cast an IDiaTable to a given interface. To locate the IDiaTable | ||
//that implements a given enumerator, use the GetTable<T>() extension method. | ||
|
||
var t = typeof(T); | ||
object result; | ||
|
||
var raw = diaTable.Raw; | ||
|
||
Exception invalidTable<TInterface>() | ||
{ | ||
throw new InvalidCastException( | ||
$"Cannot convert the specified {nameof(IDiaTable)} instance to type '{typeof(TInterface).Name}': interface '{typeof(TInterface).Name}' is not supported. " + | ||
$"Each {nameof(IDiaTable)} represents a specific type of enumerator. To locate the {nameof(IDiaTable)} that contains a specific " + | ||
$"type of enumerator, please see the {nameof(GetTable)}<T>() extension method." | ||
); | ||
} | ||
|
||
if (t == typeof(DiaEnumSymbols)) | ||
{ | ||
if (raw is IDiaEnumSymbols i) | ||
result = new DiaEnumSymbols(i); | ||
else | ||
throw invalidTable<IDiaEnumSymbols>(); | ||
} | ||
else if (t == typeof(DiaEnumSourceFiles)) | ||
{ | ||
if (raw is IDiaEnumSourceFiles i) | ||
result = new DiaEnumSourceFiles(i); | ||
else | ||
throw invalidTable<IDiaEnumSymbols>(); | ||
} | ||
|
||
else if (t == typeof(DiaEnumLineNumbers)) | ||
{ | ||
if (raw is IDiaEnumLineNumbers i) | ||
result = new DiaEnumLineNumbers(i); | ||
else | ||
throw invalidTable<IDiaEnumSymbols>(); | ||
} | ||
|
||
else if (t == typeof(DiaEnumSectionContribs)) | ||
{ | ||
if (raw is IDiaEnumSectionContribs i) | ||
result = new DiaEnumSectionContribs(i); | ||
else | ||
throw invalidTable<IDiaEnumSymbols>(); | ||
} | ||
|
||
else if (t == typeof(DiaEnumSegments)) | ||
{ | ||
if (raw is IDiaEnumSegments i) | ||
result = new DiaEnumSegments(i); | ||
else | ||
throw invalidTable<IDiaEnumSymbols>(); | ||
} | ||
|
||
else if (t == typeof(DiaEnumInjectedSources)) | ||
{ | ||
if (raw is IDiaEnumInjectedSources i) | ||
result = new DiaEnumInjectedSources(i); | ||
else | ||
throw invalidTable<IDiaEnumSymbols>(); | ||
} | ||
|
||
else if (t == typeof(DiaEnumFrameData)) | ||
{ | ||
if (raw is IDiaEnumFrameData i) | ||
result = new DiaEnumFrameData(i); | ||
else | ||
throw invalidTable<IDiaEnumSymbols>(); | ||
} | ||
else | ||
throw Extensions.GetAsNotSupportedException<T, IDiaTable>(); | ||
|
||
return (T) result; | ||
} | ||
|
||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using System; | ||
|
||
namespace ClrDebug.DIA | ||
{ | ||
public static partial class DiaExtensions | ||
{ | ||
/// <summary> | ||
/// Locates the table that implements the specified enumerator type from the specified <see cref="DiaSession"/>.<para/> | ||
/// Possible tables include <see cref="DiaEnumSymbols"/>, <see cref="DiaEnumSourceFiles"/>, <see cref="DiaEnumLineNumbers"/>, | ||
/// <see cref="DiaEnumSectionContribs"/>, <see cref="DiaEnumSegments"/>, <see cref="DiaEnumInjectedSources"/> | ||
/// and <see cref="DiaEnumFrameData"/>. | ||
/// </summary> | ||
/// <typeparam name="T">The type of table to retrieve.</typeparam> | ||
/// <param name="diaSession">The session to get the table from.</param> | ||
/// <returns>The specified enumerator wrapper.</returns> | ||
public static T GetTable<T>(this DiaSession diaSession) | ||
{ | ||
/* The IDiaSession.getEnumTables member is special. Contrary to what you might think, it doesn't | ||
* return a mere collection of "table objects"; rather, it returns a collection of "table enumerators". | ||
* You iterate over this collection of table enumerators to find the specific table enumerator you're | ||
* after. e.g. if you want to get information source files, you ask for the source file enumerator table. | ||
* Once you've found the enumerator table you're after, thats it */ | ||
|
||
TInterface getTableInternal<TInterface>(DiaEnumTables tables) where TInterface : class | ||
{ | ||
foreach (var table in tables) | ||
{ | ||
if (table.Raw is TInterface qi) | ||
return qi; | ||
} | ||
|
||
throw new NotSupportedException($"Could not find an {nameof(IDiaTable)} that implements interface {typeof(TInterface).Name}"); | ||
} | ||
|
||
var t = typeof(T); | ||
object result; | ||
|
||
var enumTables = diaSession.EnumTables; | ||
|
||
if (t == typeof(DiaEnumSymbols)) | ||
result = new DiaEnumSymbols(getTableInternal<IDiaEnumSymbols>(enumTables)); | ||
else if (t == typeof(DiaEnumSourceFiles)) | ||
result = new DiaEnumSourceFiles(getTableInternal<IDiaEnumSourceFiles>(enumTables)); | ||
else if (t == typeof(DiaEnumLineNumbers)) | ||
result = new DiaEnumLineNumbers(getTableInternal<IDiaEnumLineNumbers>(enumTables)); | ||
else if (t == typeof(DiaEnumSectionContribs)) | ||
result = new DiaEnumSectionContribs(getTableInternal<IDiaEnumSectionContribs>(enumTables)); | ||
else if (t == typeof(DiaEnumSegments)) | ||
result = new DiaEnumSegments(getTableInternal<IDiaEnumSegments>(enumTables)); | ||
else if (t == typeof(DiaEnumInjectedSources)) | ||
result = new DiaEnumInjectedSources(getTableInternal<IDiaEnumInjectedSources>(enumTables)); | ||
else if (t == typeof(DiaEnumFrameData)) | ||
result = new DiaEnumFrameData(getTableInternal<IDiaEnumFrameData>(enumTables)); | ||
else | ||
throw Extensions.GetAsNotSupportedException<T, IDiaTable>(); | ||
|
||
return (T) result; | ||
} | ||
} | ||
} |
Oops, something went wrong.