Browse Source

Support creation of all primitive types

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3238 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 18 years ago
parent
commit
ee345d0825
  1. 4
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Expressions/EvaluateAstVisitor.cs
  2. 2
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ValueNode.cs
  3. 26
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs
  4. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/PrimitiveExpression.cs
  5. 81
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs
  6. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs
  7. 17
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.Primitive.cs
  8. 93
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugGenericValue.cs
  9. 6
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/DebugTypes.cs

4
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Expressions/EvaluateAstVisitor.cs

@ -108,7 +108,9 @@ namespace Debugger.AddIn @@ -108,7 +108,9 @@ namespace Debugger.AddIn
public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
{
return Eval.CreateValue(context.Process, primitiveExpression.Value);
Value val = Eval.NewObjectNoConstructor(DebugType.Create(context.Process, null, value.GetType().FullName))
val.PrimitiveValue = primitiveExpression.Value;
return val;
}
public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data)

2
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ValueNode.cs

@ -138,7 +138,7 @@ namespace Debugger.AddIn.TreeModel @@ -138,7 +138,7 @@ namespace Debugger.AddIn.TreeModel
return true;
} catch (NotSupportedException) {
string format = ResourceService.GetString("MainWindow.Windows.Debug.LocalVariables.CannotSetValue.BadFormat");
string msg = String.Format(format, newText, val.Type.ManagedType.ToString());
string msg = String.Format(format, newText, val.Type.PrimitiveType.ToString());
MessageService.ShowMessage(msg ,"${res:MainWindow.Windows.Debug.LocalVariables.CannotSetValue.Title}");
} catch (System.Runtime.InteropServices.COMException) {
// COMException (0x80131330): Cannot perfrom SetValue on non-leaf frames.

26
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs

@ -244,21 +244,14 @@ namespace Debugger @@ -244,21 +244,14 @@ namespace Debugger
);
}
// The following function create values only for the purpuse of evalutaion
// They actually do not allocate memory on the managed heap
// The advantage is that it does not continue the process
public static Value CreateValue(Process process, object value)
{
if (value is string) {
return NewString(process, (string)value);
}
CorElementType corElemType;
if (value is int) {
corElemType = CorElementType.I4;
} else if (value is byte) {
corElemType = CorElementType.U1;
} else if (value is char) {
corElemType = CorElementType.CHAR;
} else {
throw new NotImplementedException();
}
if (value == null) throw new ArgumentNullException("value");
if (value is string) throw new DebuggerException("Can not create string this way");
CorElementType corElemType = DebugType.TypeNameToCorElementType(value.GetType().FullName);
ICorDebugEval corEval = CreateCorEval(process);
ICorDebugValue corValue = corEval.CreateValue((uint)corElemType, null);
Value v = new Value(process, new Expressions.PrimitiveExpression(value), corValue);
@ -266,13 +259,6 @@ namespace Debugger @@ -266,13 +259,6 @@ namespace Debugger
return v;
}
public static Value CreateValueForType(DebugType debugType)
{
ICorDebugEval corEval = CreateCorEval(debugType.Process);
ICorDebugValue corValue = corEval.CastTo<ICorDebugEval2>().CreateValueForType(debugType.CorType);
return new Value(debugType.Process, new EmptyExpression(), corValue);
}
#region Convenience methods
public static Value NewString(Process process, string textToCreate)

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/PrimitiveExpression.cs

@ -39,7 +39,7 @@ namespace Debugger.Expressions @@ -39,7 +39,7 @@ namespace Debugger.Expressions
protected override Value EvaluateInternal(StackFrame context)
{
return Eval.CreateValue(context.Process, value);
return Eval.CreateValue(context.Process, this.Value);
}
#region GetHashCode and Equals

81
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs

@ -275,37 +275,68 @@ namespace Debugger.MetaData @@ -275,37 +275,68 @@ namespace Debugger.MetaData
#endregion
/// <summary>
/// Returns simple managed type coresponding to the debug type.
/// Any class yields System.Object
/// </summary>
/// <summary> Returns simple managed type coresponding to the primitive type. </summary>
[Tests.Ignore]
public System.Type ManagedType {
public System.Type PrimitiveType {
get {
switch(this.corElementType) {
case CorElementType.BOOLEAN: return typeof(System.Boolean);
case CorElementType.CHAR: return typeof(System.Char);
case CorElementType.I1: return typeof(System.SByte);
case CorElementType.U1: return typeof(System.Byte);
case CorElementType.I2: return typeof(System.Int16);
case CorElementType.U2: return typeof(System.UInt16);
case CorElementType.I4: return typeof(System.Int32);
case CorElementType.U4: return typeof(System.UInt32);
case CorElementType.I8: return typeof(System.Int64);
case CorElementType.U8: return typeof(System.UInt64);
case CorElementType.R4: return typeof(System.Single);
case CorElementType.R8: return typeof(System.Double);
case CorElementType.I: return typeof(int);
case CorElementType.U: return typeof(uint);
case CorElementType.SZARRAY:
case CorElementType.ARRAY: return typeof(System.Array);
case CorElementType.OBJECT: return typeof(System.Object);
case CorElementType.STRING: return typeof(System.String);
default: return null;
if (corElementType == CorElementType.VALUETYPE) {
CorElementType corType;
try {
corType = TypeNameToCorElementType(this.FullName);
} catch (DebuggerException) {
return null;
}
return CorElementTypeToManagedType(corType);
} else {
return CorElementTypeToManagedType(corElementType);
}
}
}
internal static Type CorElementTypeToManagedType(CorElementType corElementType)
{
switch(corElementType) {
case CorElementType.BOOLEAN: return typeof(System.Boolean);
case CorElementType.CHAR: return typeof(System.Char);
case CorElementType.I1: return typeof(System.SByte);
case CorElementType.U1: return typeof(System.Byte);
case CorElementType.I2: return typeof(System.Int16);
case CorElementType.U2: return typeof(System.UInt16);
case CorElementType.I4: return typeof(System.Int32);
case CorElementType.U4: return typeof(System.UInt32);
case CorElementType.I8: return typeof(System.Int64);
case CorElementType.U8: return typeof(System.UInt64);
case CorElementType.R4: return typeof(System.Single);
case CorElementType.R8: return typeof(System.Double);
case CorElementType.I: return typeof(System.IntPtr);
case CorElementType.U: return typeof(System.UIntPtr);
case CorElementType.STRING: return typeof(System.String);
default: return null;
}
}
internal static CorElementType TypeNameToCorElementType(string fullname)
{
switch (fullname) {
case "System.Boolean": return CorElementType.BOOLEAN;
case "System.Char": return CorElementType.CHAR;
case "System.SByte": return CorElementType.I1;
case "System.Byte": return CorElementType.U1;
case "System.Int16": return CorElementType.I2;
case "System.UInt16": return CorElementType.U2;
case "System.Int32": return CorElementType.I4;
case "System.UInt32": return CorElementType.U4;
case "System.Int64": return CorElementType.I8;
case "System.UInt64": return CorElementType.U8;
case "System.Single": return CorElementType.R4;
case "System.Double": return CorElementType.R8;
case "System.IntPtr": return CorElementType.I;
case "System.UIntPtr": return CorElementType.U;
case "System.String": return CorElementType.STRING;
default: throw new DebuggerException("Not a primitive type");
}
}
/*
* Find the super class manually - unused since we have ICorDebugType.GetBase() in .NET 2.0
*

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

@ -474,7 +474,7 @@ namespace Debugger.MetaData @@ -474,7 +474,7 @@ namespace Debugger.MetaData
return className;
}
} else if (IsPrimitive) {
return this.ManagedType.ToString();
return this.PrimitiveType.ToString();
} else if (IsPointer) {
return this.ElementType.FullName + (this.corElementType == CorElementType.BYREF ? "&" : "*");
} else if (IsVoid) {

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

@ -35,28 +35,27 @@ namespace Debugger @@ -35,28 +35,27 @@ namespace Debugger
/// </summary>
public object PrimitiveValue {
get {
if (!this.Type.IsPrimitive) throw new DebuggerException("Value is not a primitive type");
if (this.Type.PrimitiveType == null) throw new DebuggerException("Value is not a primitive type");
if (this.Type.IsString) {
if (this.IsNull) return null;
return this.CorReferenceValue.Dereference().CastTo<ICorDebugStringValue>().String;
} else {
return CorGenericValue.Value;
return CorGenericValue.GetValue(this.Type.PrimitiveType);
}
}
set {
if (this.Type.PrimitiveType == null) throw new DebuggerException("Value is not a primitive type");
if (this.Type.IsString) {
throw new NotImplementedException();
this.SetValue(Eval.NewString(this.Process, value.ToString()));
} else {
if (value == null) {
throw new DebuggerException("Can not set primitive value to null");
}
if (value == null) throw new DebuggerException("Can not set primitive value to null");
object newValue;
try {
newValue = Convert.ChangeType(value, this.Type.ManagedType);
newValue = Convert.ChangeType(value, this.Type.PrimitiveType);
} catch {
throw new NotSupportedException("Can not convert " + value.GetType().ToString() + " to " + this.Type.ManagedType.ToString());
throw new NotSupportedException("Can not convert " + value.GetType().ToString() + " to " + this.Type.PrimitiveType.ToString());
}
CorGenericValue.Value = newValue;
CorGenericValue.SetValue(this.Type.PrimitiveType, newValue);
}
}
}

93
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugGenericValue.cs

@ -32,55 +32,54 @@ namespace Debugger.Wrappers.CorDebug @@ -32,55 +32,54 @@ namespace Debugger.Wrappers.CorDebug
}
}
public unsafe object Value {
get {
object retValue;
IntPtr pValue = Marshal.AllocHGlobal((int)Size);
GetValue(pValue);
switch((CorElementType)Type)
{
case CorElementType.BOOLEAN: retValue = *((System.Boolean*)pValue); break;
case CorElementType.CHAR: retValue = *((System.Char*) pValue); break;
case CorElementType.I1: retValue = *((System.SByte*) pValue); break;
case CorElementType.U1: retValue = *((System.Byte*) pValue); break;
case CorElementType.I2: retValue = *((System.Int16*) pValue); break;
case CorElementType.U2: retValue = *((System.UInt16*) pValue); break;
case CorElementType.I4: retValue = *((System.Int32*) pValue); break;
case CorElementType.U4: retValue = *((System.UInt32*) pValue); break;
case CorElementType.I8: retValue = *((System.Int64*) pValue); break;
case CorElementType.U8: retValue = *((System.UInt64*) pValue); break;
case CorElementType.R4: retValue = *((System.Single*) pValue); break;
case CorElementType.R8: retValue = *((System.Double*) pValue); break;
case CorElementType.I: retValue = *((int*) pValue); break;
case CorElementType.U: retValue = *((uint*) pValue); break;
default: throw new NotSupportedException();
}
Marshal.FreeHGlobal(pValue);
return retValue;
public unsafe object GetValue(Type type)
{
object retValue;
IntPtr pValue = Marshal.AllocHGlobal((int)Size);
GetValue(pValue);
switch(type.FullName) {
case "System.Boolean": retValue = *((System.Boolean*)pValue); break;
case "System.Char": retValue = *((System.Char*) pValue); break;
case "System.SByte": retValue = *((System.SByte*) pValue); break;
case "System.Byte": retValue = *((System.Byte*) pValue); break;
case "System.Int16": retValue = *((System.Int16*) pValue); break;
case "System.UInt16": retValue = *((System.UInt16*) pValue); break;
case "System.Int32": retValue = *((System.Int32*) pValue); break;
case "System.UInt32": retValue = *((System.UInt32*) pValue); break;
case "System.Int64": retValue = *((System.Int64*) pValue); break;
case "System.UInt64": retValue = *((System.UInt64*) pValue); break;
case "System.Single": retValue = *((System.Single*) pValue); break;
case "System.Double": retValue = *((System.Double*) pValue); break;
case "System.IntPtr": retValue = *((System.IntPtr*) pValue); break;
case "System.UIntPtr": retValue = *((System.UIntPtr*)pValue); break;
default: throw new NotSupportedException();
}
set {
IntPtr pValue = Marshal.AllocHGlobal((int)Size);
switch((CorElementType)Type)
{
case CorElementType.BOOLEAN: *((System.Boolean*)pValue) = (System.Boolean)value; break;
case CorElementType.CHAR: *((System.Char*) pValue) = (System.Char) value; break;
case CorElementType.I1: *((System.SByte*) pValue) = (System.SByte) value; break;
case CorElementType.U1: *((System.Byte*) pValue) = (System.Byte) value; break;
case CorElementType.I2: *((System.Int16*) pValue) = (System.Int16) value; break;
case CorElementType.U2: *((System.UInt16*) pValue) = (System.UInt16) value; break;
case CorElementType.I4: *((System.Int32*) pValue) = (System.Int32) value; break;
case CorElementType.U4: *((System.UInt32*) pValue) = (System.UInt32) value; break;
case CorElementType.I8: *((System.Int64*) pValue) = (System.Int64) value; break;
case CorElementType.U8: *((System.UInt64*) pValue) = (System.UInt64) value; break;
case CorElementType.R4: *((System.Single*) pValue) = (System.Single) value; break;
case CorElementType.R8: *((System.Double*) pValue) = (System.Double) value; break;
case CorElementType.I: *((int*) pValue) = (int) value; break;
case CorElementType.U: *((uint*) pValue) = (uint) value; break;
default: throw new NotSupportedException();
}
SetValue(pValue);
Marshal.FreeHGlobal(pValue);
Marshal.FreeHGlobal(pValue);
return retValue;
}
public unsafe void SetValue(Type type, object value)
{
IntPtr pValue = Marshal.AllocHGlobal((int)Size);
switch(type.FullName) {
case "System.Boolean": *((System.Boolean*)pValue) = (System.Boolean)value; break;
case "System.Char": *((System.Char*) pValue) = (System.Char) value; break;
case "System.SByte": *((System.SByte*) pValue) = (System.SByte) value; break;
case "System.Byte": *((System.Byte*) pValue) = (System.Byte) value; break;
case "System.Int16": *((System.Int16*) pValue) = (System.Int16) value; break;
case "System.UInt16": *((System.UInt16*) pValue) = (System.UInt16) value; break;
case "System.Int32": *((System.Int32*) pValue) = (System.Int32) value; break;
case "System.UInt32": *((System.UInt32*) pValue) = (System.UInt32) value; break;
case "System.Int64": *((System.Int64*) pValue) = (System.Int64) value; break;
case "System.UInt64": *((System.UInt64*) pValue) = (System.UInt64) value; break;
case "System.Single": *((System.Single*) pValue) = (System.Single) value; break;
case "System.Double": *((System.Double*) pValue) = (System.Double) value; break;
case "System.IntPtr": *((System.IntPtr*) pValue) = (System.IntPtr) value; break;
case "System.UIntPtr": *((System.UIntPtr*)pValue) = (System.UIntPtr)value; break;
default: throw new NotSupportedException();
}
SetValue(pValue);
Marshal.FreeHGlobal(pValue);
}
}
}

6
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/DebugTypes.cs

@ -623,7 +623,7 @@ namespace Debugger.Tests { @@ -623,7 +623,7 @@ namespace Debugger.Tests {
IsInvalid="False"
IsNull="False"
IsReference="True"
PrimitiveValue="{Exception: Value is not a primitive type}"
PrimitiveValue="40"
Type="System.Int32">
<Type>
<DebugType
@ -1132,7 +1132,7 @@ namespace Debugger.Tests { @@ -1132,7 +1132,7 @@ namespace Debugger.Tests {
IsInvalid="False"
IsNull="False"
IsReference="True"
PrimitiveValue="{Exception: Value is not a primitive type}"
PrimitiveValue="40"
Type="System.Int32">
<Type>
<DebugType
@ -1158,7 +1158,7 @@ namespace Debugger.Tests { @@ -1158,7 +1158,7 @@ namespace Debugger.Tests {
IsInvalid="False"
IsNull="False"
IsReference="True"
PrimitiveValue="{Exception: Value is not a primitive type}"
PrimitiveValue="40"
Type="System.Int32">
<Type>
<DebugType

Loading…
Cancel
Save