Browse Source

API support for enumerating implemented interfaces

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2926 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 18 years ago
parent
commit
d83c92c762
  1. 1
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
  2. 6
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Module.cs
  3. 5
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs
  4. 50
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/Enums/CorTokenType.cs
  5. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/MetaData/IMetaDataImport.cs
  6. 79
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs
  7. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/MethodInfo.cs
  8. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs
  9. 25
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/InterfaceImplProps.cs
  10. 15
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MetaDataImport.cs
  11. 6
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/TypeDefProps.cs

1
src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj

@ -361,6 +361,7 @@ @@ -361,6 +361,7 @@
<Compile Include="Src\Wrappers\CorSym\SequencePoint.cs" />
<Compile Include="Src\Wrappers\ICorDebugManagedCallbacks.cs" />
<Compile Include="Src\Wrappers\MetaData\FieldProps.cs" />
<Compile Include="Src\Wrappers\MetaData\InterfaceImplProps.cs" />
<Compile Include="Src\Wrappers\MetaData\MetaDataImport.cs" />
<Compile Include="Src\Wrappers\MetaData\MethodProps.cs" />
<Compile Include="Src\Wrappers\MetaData\ParamProps.cs" />

6
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Module.cs

@ -75,6 +75,12 @@ namespace Debugger @@ -75,6 +75,12 @@ namespace Debugger
}
}
internal uint AppDomainID {
get {
return this.CorModule.Assembly.AppDomain.ID;
}
}
[Debugger.Tests.Ignore]
public string FullPath {
get {

5
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs

@ -148,6 +148,11 @@ namespace Debugger @@ -148,6 +148,11 @@ namespace Debugger
}
}
public void TraceMessage(string message, params object[] args)
{
TraceMessage(string.Format(message, args));
}
public void TraceMessage(string message)
{
System.Diagnostics.Debug.WriteLine("Debugger:" + message);

50
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/Enums/CorTokenType.cs

@ -7,31 +7,31 @@ @@ -7,31 +7,31 @@
namespace Debugger.Wrappers.MetaData
{
enum CorTokenType: uint
public enum CorTokenType: uint
{
mdtModule = 0x00000000, //
mdtTypeRef = 0x01000000, //
mdtTypeDef = 0x02000000, //
mdtFieldDef = 0x04000000, //
mdtMethodDef = 0x06000000, //
mdtParamDef = 0x08000000, //
mdtInterfaceImpl = 0x09000000, //
mdtMemberRef = 0x0a000000, //
mdtCustomAttribute = 0x0c000000, //
mdtPermission = 0x0e000000, //
mdtSignature = 0x11000000, //
mdtEvent = 0x14000000, //
mdtProperty = 0x17000000, //
mdtModuleRef = 0x1a000000, //
mdtTypeSpec = 0x1b000000, //
mdtAssembly = 0x20000000, //
mdtAssemblyRef = 0x23000000, //
mdtFile = 0x26000000, //
mdtExportedType = 0x27000000, //
mdtManifestResource = 0x28000000, //
mdtString = 0x70000000, //
mdtName = 0x71000000, //
mdtBaseType = 0x72000000, // Leave this on the high end value. This does not correspond to metadata table
Module = 0x00000000, //
TypeRef = 0x01000000, //
TypeDef = 0x02000000, //
FieldDef = 0x04000000, //
MethodDef = 0x06000000, //
ParamDef = 0x08000000, //
InterfaceImpl = 0x09000000, //
MemberRef = 0x0a000000, //
CustomAttribute = 0x0c000000, //
Permission = 0x0e000000, //
Signature = 0x11000000, //
Event = 0x14000000, //
Property = 0x17000000, //
ModuleRef = 0x1a000000, //
TypeSpec = 0x1b000000, //
Assembly = 0x20000000, //
AssemblyRef = 0x23000000, //
File = 0x26000000, //
ExportedType = 0x27000000, //
ManifestResource = 0x28000000, //
String = 0x70000000, //
Name = 0x71000000, //
BaseType = 0x72000000, // Leave this on the high end value. This does not correspond to metadata table
}
}

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/MetaData/IMetaDataImport.cs

@ -25,7 +25,7 @@ namespace Debugger.Interop.MetaData @@ -25,7 +25,7 @@ namespace Debugger.Interop.MetaData
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
void EnumTypeDefs([In, Out] ref IntPtr phEnum, ref uint rTypeDefs, uint cMax, ref uint pcTypeDefs);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
void EnumInterfaceImpls([In, Out] ref IntPtr phEnum, uint td, ref uint rImpls, uint cMax, ref uint pcImpls);
void EnumInterfaceImpls([In, Out] ref IntPtr phEnum, uint td, out uint rImpls, uint cMax, out uint pcImpls);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
void EnumTypeRefs([In, Out] ref IntPtr phEnum, ref uint rTypeRefs, uint cMax, ref uint pcTypeRefs);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]

79
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs

@ -34,6 +34,7 @@ namespace Debugger.MetaData @@ -34,6 +34,7 @@ namespace Debugger.MetaData
// Class/ValueType/Array/Ref/Ptr specific
List<DebugType> typeArguments = new List<DebugType>();
List<DebugType> interfaces = new List<DebugType>();
// Members of the type; empty list if not applicable
List<MemberInfo> members = new List<MemberInfo>();
@ -85,6 +86,13 @@ namespace Debugger.MetaData @@ -85,6 +86,13 @@ namespace Debugger.MetaData
}
}
/// <summary> Returns true if this type represents interface </summary>
public bool IsInterface {
get {
return IsClass && classProps.IsInterface;
}
}
/// <summary> Returns a string describing the type including the namespace
/// and generic arguments but excluding the assembly name. </summary>
public string FullName {
@ -140,6 +148,13 @@ namespace Debugger.MetaData @@ -140,6 +148,13 @@ namespace Debugger.MetaData
}
}
/// <summary> Gets a list of all interfaces that this type implements </summary>
public List<DebugType> Interfaces {
get {
return interfaces;
}
}
/// <summary> Returns generics arguments for a type or an emtpy
/// array for non-generic types. </summary>
public DebugType[] GetGenericArguments()
@ -215,7 +230,7 @@ namespace Debugger.MetaData @@ -215,7 +230,7 @@ namespace Debugger.MetaData
internal uint? AppDomainID {
get {
if (IsClass || IsValueType) {
return this.Module.CorModule.Assembly.AppDomain.ID;
return this.Module.AppDomainID;
} else {
return null;
}
@ -232,11 +247,11 @@ namespace Debugger.MetaData @@ -232,11 +247,11 @@ namespace Debugger.MetaData
get {
// corType.Base does not work for arrays
if (this.IsArray) {
return DebugType.GetType(this.Process, AppDomainID, "System.Array");
return DebugType.Create(this.Process, AppDomainID, "System.Array");
}
// corType.Base does not work for primitive types
if (this.IsPrimitive) {
return DebugType.GetType(this.Process, AppDomainID, "System.Object");
return DebugType.Create(this.Process, AppDomainID, "System.Object");
}
ICorDebugType baseType = corType.Base;
if (baseType != null) {
@ -270,6 +285,34 @@ namespace Debugger.MetaData @@ -270,6 +285,34 @@ namespace Debugger.MetaData
this.fullName = GetFullName();
}
public static DebugType Create(Module module, uint token)
{
if ((token & 0xFF000000) == (uint)CorTokenType.TypeDef) {
return Create(module.Process, module.CorModule.GetClassFromToken(token));
} else if ((token & 0xFF000000) == (uint)CorTokenType.TypeRef) {
string fullName = module.MetaData.GetTypeRefProps(token).Name;
return Create(module.Process, module.AppDomainID, fullName);
} else {
throw new DebuggerException("Unknown token type");
}
}
public static DebugType Create(Process process, uint? domainID, string fullTypeName)
{
foreach(Module module in process.Modules) {
if (!domainID.HasValue || domainID == module.CorModule.Assembly.AppDomain.ID) {
try {
uint token = module.MetaData.FindTypeDefByName(fullTypeName, 0 /* enclosing class for nested */).Token;
return Create(process, module.CorModule.GetClassFromToken(token));
} catch {
continue;
}
}
}
throw new DebuggerException("Can not find type " + fullTypeName);
}
static internal DebugType Create(Process process, ICorDebugClass corClass, params ICorDebugType[] typeArguments)
{
MetaDataImport metaData = process.GetModule(corClass.Module).MetaData;
@ -330,7 +373,11 @@ namespace Debugger.MetaData @@ -330,7 +373,11 @@ namespace Debugger.MetaData
type.Process.Expired += delegate { typesWithMatchingName.Remove(type); };
TimeSpan totalTime2 = Util.HighPrecisionTimer.Now - startTime;
process.TraceMessage("Loaded type " + type.FullName + " (" + totalTime2.TotalMilliseconds + " ms)");
string prefix = type.IsInterface ? "interface" : "type";
process.TraceMessage("Loaded {0} {1} ({2} ms)", prefix, type.FullName, totalTime2.TotalMilliseconds);
foreach(DebugType inter in type.Interfaces) {
process.TraceMessage(" - Implements {0}", inter.FullName);
}
return type;
}
@ -365,6 +412,15 @@ namespace Debugger.MetaData @@ -365,6 +412,15 @@ namespace Debugger.MetaData
void LoadMemberInfo()
{
// Load interfaces
foreach(InterfaceImplProps implProps in module.MetaData.EnumInterfaceImpls(this.MetadataToken)) {
if ((implProps.ptkIface & 0xFF000000) == (uint)CorTokenType.TypeDef ||
(implProps.ptkIface & 0xFF000000) == (uint)CorTokenType.TypeRef)
{
this.interfaces.Add(DebugType.Create(module, implProps.ptkIface));
}
}
// Load fields
foreach(FieldProps field in module.MetaData.EnumFields(this.MetadataToken)) {
if (field.IsStatic && field.IsLiteral) continue; // Skip static literals TODO: Why?
@ -451,21 +507,6 @@ namespace Debugger.MetaData @@ -451,21 +507,6 @@ namespace Debugger.MetaData
}
}
public static DebugType GetType(Process process, uint? domainID, string fullTypeName)
{
foreach(Module module in process.Modules) {
if (!domainID.HasValue || domainID == module.CorModule.Assembly.AppDomain.ID) {
try {
uint token = module.MetaData.FindTypeDefByName(fullTypeName, 0 /* enclosing class for nested */).Token;
return Create(process, module.CorModule.GetClassFromToken(token));
} catch {
continue;
}
}
}
return null;
}
/// <summary> Get hash code of the object </summary>
public override int GetHashCode()
{

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/MethodInfo.cs

@ -169,7 +169,7 @@ namespace Debugger.MetaData @@ -169,7 +169,7 @@ namespace Debugger.MetaData
if (type.IsGenericType) throw new DebuggerException("Not implemented for generic types");
if (type.IsGenericParameter) throw new DebuggerException("Type can not be generic parameter");
DebugType debugType = DebugType.GetType(process, domainID, type.FullName);
DebugType debugType = DebugType.Create(process, domainID, type.FullName);
if (debugType == null) {
throw new DebuggerException("Type " + type.FullName + " not found");
}

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs

@ -132,7 +132,7 @@ namespace Debugger @@ -132,7 +132,7 @@ namespace Debugger
this.rawCorValue_pauseSession = process.PauseSession;
if (this.CorValue == null) {
type = DebugType.GetType(this.Process, null, "System.Object");
type = DebugType.Create(this.Process, null, "System.Object");
} else {
ICorDebugType exactType = this.CorValue.CastTo<ICorDebugValue2>().ExactType;
type = DebugType.Create(this.Process, exactType);

25
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/InterfaceImplProps.cs

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
#pragma warning disable 1591
using System;
namespace Debugger.Wrappers.MetaData
{
public struct InterfaceImplProps
{
public uint Token;
public uint classTypeDef;
public uint ptkIface;
public override string ToString()
{
return string.Format("[InterfaceImplProps Token={0:X} ClassTypeDef={1:X} PtkIface={2:X}]", this.Token, this.classTypeDef, this.ptkIface);
}
}
}

15
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MetaDataImport.cs

@ -217,6 +217,21 @@ namespace Debugger.Wrappers.MetaData @@ -217,6 +217,21 @@ namespace Debugger.Wrappers.MetaData
return EnumerateTokens(metaData.EnumGenericParams, typeDef_methodDef);
}
public IEnumerable<InterfaceImplProps> EnumInterfaceImpls(uint typeDef)
{
foreach(uint token in EnumerateTokens(metaData.EnumInterfaceImpls, typeDef)) {
yield return GetInterfaceImplProps(token);
}
}
public InterfaceImplProps GetInterfaceImplProps(uint token)
{
InterfaceImplProps implProps = new InterfaceImplProps();
implProps.Token = token;
metaData.GetInterfaceImplProps(token, out implProps.classTypeDef, out implProps.ptkIface);
return implProps;
}
#region Util
delegate void TokenEnumerator(ref IntPtr phEnum, uint parameter, out uint token, uint maxCount, out uint fetched);

6
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/TypeDefProps.cs

@ -17,6 +17,12 @@ namespace Debugger.Wrappers.MetaData @@ -17,6 +17,12 @@ namespace Debugger.Wrappers.MetaData
public string Name;
public uint Flags;
public uint SuperClassToken;
public bool IsInterface {
get {
return (Flags & 0x00000020) != 0;
}
}
}
}

Loading…
Cancel
Save