Browse Source

Improved DebugType.FullName (support arrays and generics)

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2209 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 19 years ago
parent
commit
253b43f169
  1. 2
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/TreeListViewDebuggerItem.cs
  2. 1
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
  3. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorDebug/ICorDebugTypeEnum.cs
  4. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs
  5. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs
  6. 100
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/DebugType.cs
  7. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/FieldInfo.cs
  8. 4
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value.cs
  9. 22
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugTypeEnum.cs
  10. 45
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugTypeEnum.cs
  11. 6
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/DebuggerTests.cs

2
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/TreeListViewDebuggerItem.cs

@ -78,7 +78,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -78,7 +78,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
this.SubItems[0].Text = val.Name;
this.SubItems[1].Text = val.AsString;
this.SubItems[2].Text = val.IsNull ? String.Empty : val.Type.Name;
this.SubItems[2].Text = val.IsNull ? String.Empty : val.Type.FullName;
this.ImageIndex = DebuggerIcons.GetImageListIndex(val);

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

@ -281,6 +281,7 @@ @@ -281,6 +281,7 @@
<Compile Include="Src\Wrappers\CorDebug\Autogenerated\ICorDebugValueEnum.cs" />
<Compile Include="Src\Wrappers\CorDebug\Autogenerated\ISequentialStream.cs" />
<Compile Include="Src\Wrappers\CorDebug\Autogenerated\IStream.cs" />
<Compile Include="Src\Wrappers\CorDebug\ICorDebugTypeEnum.cs" />
<Compile Include="Src\Wrappers\CorSym\Autogenerated\CorSymAddrKind.cs" />
<Compile Include="Src\Wrappers\CorSym\Autogenerated\CorSymBinder_deprecated.cs" />
<Compile Include="Src\Wrappers\CorSym\Autogenerated\CorSymBinder_deprecatedClass.cs" />

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorDebug/ICorDebugTypeEnum.cs

@ -25,7 +25,7 @@ namespace Debugger.Interop.CorDebug @@ -25,7 +25,7 @@ namespace Debugger.Interop.CorDebug
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
void GetCount(out uint pcelt);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
void Next([In] uint celt, [Out] IntPtr values, out uint pceltFetched);
void Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray)] ICorDebugType[] values, out uint pceltFetched);
}
}

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs

@ -62,7 +62,7 @@ namespace Debugger @@ -62,7 +62,7 @@ namespace Debugger
callstackItems++;
}
type = runtimeValue.Type.Name;
type = runtimeValue.Type.FullName;
}
public string Type {

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs

@ -111,7 +111,7 @@ namespace Debugger @@ -111,7 +111,7 @@ namespace Debugger
{
return new Eval(
method.Process,
"Function call: " + method.DeclaringType.Name + "." + method.Name,
"Function call: " + method.DeclaringType.FullName + "." + method.Name,
delegate(ICorDebugEval corEval) { StartMethodInvoke(corEval, method, thisValue, args); }
);
}

100
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/DebugType.cs

@ -21,12 +21,16 @@ namespace Debugger @@ -21,12 +21,16 @@ namespace Debugger
Process process;
ICorDebugType corType;
CorElementType corElementType;
string fullName;
// Class/ValueType specific data
// Class/ValueType specific
ICorDebugClass corClass;
Module module;
TypeDefProps classProps;
// Class/ValueType/Array/Ref/Ptr specific
List<DebugType> typeArguments = new List<DebugType>();
// Members of the type; empty lists if not applicable
List<FieldInfo> fields = new List<FieldInfo>();
List<MethodInfo> methods = new List<MethodInfo>();
@ -74,20 +78,41 @@ namespace Debugger @@ -74,20 +78,41 @@ namespace Debugger
}
}
/// <summary> Returns a string describing the type </summary>
public string Name {
/// <summary> Returns a string describing the type including the namespace
/// and generic arguments but excluding the assembly name. </summary>
public string FullName {
get {
// TODO: Improve
if(IsClass || IsValueType) {
return classProps.Name;
} else {
System.Type managedType = this.ManagedType;
if (managedType != null) {
return managedType.ToString();
return fullName;
}
}
/// <summary> Returns the number of dimensions of an array </summary>
/// <remarks> Throws <see cref="System.ArgumentException"/> if type is not array </remarks>
public int GetArrayRank()
{
if (IsArray) {
return (int)corType.Rank;
} else {
return "<unknown>";
throw new ArgumentException("Type is not array");
}
}
/// <summary> Returns true if the type has an element type.
/// (ie array, reference or pointer) </summary>
public bool HasElementType {
get {
return IsArray;
}
}
/// <summary> Returns an element type for array, reference or pointer.
/// Retuns null otherwise. (Secificaly, returns null for generic types) </summary>
public DebugType GetElementType()
{
if (HasElementType) {
return typeArguments[0];
} else {
return null;
}
}
@ -99,6 +124,26 @@ namespace Debugger @@ -99,6 +124,26 @@ namespace Debugger
}
}
/// <summary> Gets a value indicating whether the immediate type is generic.
/// Arrays, references and pointers are never generic types. </summary>
public bool IsGenericType {
get {
return (IsClass || IsValueType) &&
typeArguments.Count > 0;
}
}
/// <summary> Returns generics arguments for a type or an emtpy
/// array for non-generic types. </summary>
public DebugType[] GetGenericArguments()
{
if (IsGenericType) {
return typeArguments.ToArray();
} else {
return new DebugType[] {};
}
}
/// <summary> Gets a value indicating whether the type is a class </summary>
public bool IsClass {
get {
@ -183,6 +228,14 @@ namespace Debugger @@ -183,6 +228,14 @@ namespace Debugger
LoadType();
}
if (this.IsClass || this.IsValueType || this.IsArray) {
foreach(ICorDebugType t in corType.EnumerateTypeParameters().Enumerator) {
typeArguments.Add(DebugType.Create(process, t));
}
}
this.fullName = GetFullName();
}
/// <summary>
@ -193,6 +246,29 @@ namespace Debugger @@ -193,6 +246,29 @@ namespace Debugger
return process.GetDebugType(corType);
}
string GetFullName()
{
if (IsArray) {
return GetElementType().FullName + "[" + new String(',', GetArrayRank() - 1) + "]";
} else if (IsClass || IsValueType) {
if (IsGenericType) {
List<string> argNames = new List<string>();
foreach(DebugType arg in GetGenericArguments()) {
argNames.Add(arg.FullName);
}
// Remove generic parameter count at the end
string className = classProps.Name.Substring(0, classProps.Name.LastIndexOf('`'));
return className + "<" + String.Join(",", argNames.ToArray()) + ">";
} else {
return classProps.Name;
}
} else if (IsPrimitive) {
return this.ManagedType.ToString();
} else {
throw new DebuggerException("Unknown type");
}
}
/// <summary> Determines whether the current type is sublass of
/// the the given type. That is, it derives from the given type. </summary>
/// <remarks> Returns false if the given type is same as the current type </remarks>
@ -250,7 +326,7 @@ namespace Debugger @@ -250,7 +326,7 @@ namespace Debugger
}
TimeSpan totalTime = Util.HighPrecisionTimer.Now - startTime;
process.TraceMessage("Loaded type " + this.Name + " (" + totalTime.TotalMilliseconds + " ms)");
process.TraceMessage("Loaded type " + this.FullName + " (" + totalTime.TotalMilliseconds + " ms)");
}
/// <summary> Return all public fields.</summary>

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/FieldInfo.cs

@ -82,7 +82,7 @@ namespace Debugger @@ -82,7 +82,7 @@ namespace Debugger
ICorDebugValue GetCorValue(Value objectInstance)
{
if (!DeclaringType.IsInstanceOfType(objectInstance)) {
throw new CannotGetValueException("Object is not of type " + DeclaringType.Name);
throw new CannotGetValueException("Object is not of type " + DeclaringType.FullName);
}
// Current frame is used to resolve context specific static values (eg. ThreadStatic)

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

@ -77,8 +77,8 @@ namespace Debugger @@ -77,8 +77,8 @@ namespace Debugger
// AsString representation
if (IsNull) cache.AsString = "<null>";
if (IsArray) cache.AsString = "{" + this.Type.Name + "}";
if (IsObject) cache.AsString = "{" + this.Type.Name + "}";
if (IsArray) cache.AsString = "{" + this.Type.FullName + "}";
if (IsObject) cache.AsString = "{" + this.Type.FullName + "}";
//if (IsObject) cache.AsString = Eval.InvokeMethod(Process, typeof(object), "ToString", this, new Value[] {}).AsString;
if (IsPrimitive) cache.AsString = PrimitiveValue != null ? PrimitiveValue.ToString() : String.Empty;

22
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugTypeEnum.cs

@ -124,10 +124,28 @@ namespace Debugger.Wrappers.CorDebug @@ -124,10 +124,28 @@ namespace Debugger.Wrappers.CorDebug
}
}
public uint Next(uint celt, System.IntPtr values)
public uint Next(uint celt, ICorDebugType[] values)
{
uint pceltFetched;
this.WrappedObject.Next(celt, values, out pceltFetched);
Debugger.Interop.CorDebug.ICorDebugType[] array_values = new Debugger.Interop.CorDebug.ICorDebugType[values.Length];
for (int i = 0; (i < values.Length); i = (i + 1))
{
if ((values[i] != null))
{
array_values[i] = values[i].WrappedObject;
}
}
this.WrappedObject.Next(celt, array_values, out pceltFetched);
for (int i = 0; (i < values.Length); i = (i + 1))
{
if ((array_values[i] != null))
{
values[i] = ICorDebugType.Wrap(array_values[i]);
} else
{
values[i] = null;
}
}
return pceltFetched;
}
}

45
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugTypeEnum.cs

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision: 2077 $</version>
// </file>
#pragma warning disable 1591
namespace Debugger.Wrappers.CorDebug
{
using System;
using System.Collections.Generic;
public partial class ICorDebugTypeEnum
{
public IEnumerable<ICorDebugType> Enumerator {
get {
Reset();
while (true) {
ICorDebugType corType = Next();
if (corType != null) {
yield return corType;
} else {
break;
}
}
}
}
public ICorDebugType Next()
{
ICorDebugType[] corTypes = new ICorDebugType[1];
uint typesFetched = this.Next(1, corTypes);
if (typesFetched == 0) {
return null;
} else {
return corTypes[0];
}
}
}
}
#pragma warning restore 1591

6
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/DebuggerTests.cs

@ -438,7 +438,7 @@ namespace Debugger.Tests @@ -438,7 +438,7 @@ namespace Debugger.Tests
NamedValue array = process.SelectedFunction.LocalVariables["array"];
Assert.AreEqual("array", array.Name);
Assert.IsTrue(array.IsArray);
Assert.AreEqual("{System.Int32[5]}", array.AsString);
Assert.AreEqual("{System.Int32[]}", array.AsString);
NamedValueCollection elements = array.GetArrayElements();
Assert.AreEqual(5, elements.Count);
for(int i = 0; i < 5; i++) {
@ -461,7 +461,7 @@ namespace Debugger.Tests @@ -461,7 +461,7 @@ namespace Debugger.Tests
Assert.AreEqual("val", local.Name);
Assert.IsTrue(local.IsObject);
Assert.AreEqual("{Debugger.Tests.TestPrograms.ObjectValue}", local.AsString);
Assert.AreEqual("Debugger.Tests.TestPrograms.ObjectValue", local.Type.Name);
Assert.AreEqual("Debugger.Tests.TestPrograms.ObjectValue", local.Type.FullName);
NamedValueCollection subVars = local.GetMembers(null, Debugger.BindingFlags.All);
Assert.IsTrue(subVars["privateField"].IsPrimitive);
Assert.IsTrue(subVars["publicFiled"].IsPrimitive);
@ -470,7 +470,7 @@ namespace Debugger.Tests @@ -470,7 +470,7 @@ namespace Debugger.Tests
Assert.IsTrue(((MemberValue)subVars["publicFiled"]).MemberInfo.IsPublic);
Assert.IsTrue(((MemberValue)subVars["PublicProperty"]).MemberInfo.IsPublic);
DebugType baseClass = local.Type.BaseType;
Assert.AreEqual("Debugger.Tests.TestPrograms.BaseClass", baseClass.Name);
Assert.AreEqual("Debugger.Tests.TestPrograms.BaseClass", baseClass.FullName);
Assert.AreEqual("private", subVars["privateField"].AsString);
process.Continue();

Loading…
Cancel
Save