mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
4.5 KiB
111 lines
4.5 KiB
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) |
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) |
|
using Debugger.Interop.CorDebug; |
|
using System; |
|
using System.Collections.Generic; |
|
using System.Reflection; |
|
using Debugger; |
|
using Debugger.MetaData; |
|
using ICSharpCode.NRefactory.Ast; |
|
|
|
namespace ILSpy.Debugger.Services.Debugger |
|
{ |
|
public static class DebuggerHelpers |
|
{ |
|
/// <summary> |
|
/// Creates an expression which, when evaluated, creates a List<T> in the debugee |
|
/// filled with contents of IEnumerable<T> from the debugee. |
|
/// </summary> |
|
/// <param name="iEnumerableVariable">Expression for IEnumerable variable in the debugee.</param> |
|
/// <param name="itemType"> |
|
/// The generic argument of IEnumerable<T> that <paramref name="iEnumerableVariable"/> implements.</param> |
|
public static Expression CreateDebugListExpression(Expression iEnumerableVariable, DebugType itemType, out DebugType listType) |
|
{ |
|
// is using itemType.AppDomain ok? |
|
listType = DebugType.CreateFromType(itemType.AppDomain, typeof(System.Collections.Generic.List<>), itemType); |
|
var iEnumerableType = DebugType.CreateFromType(itemType.AppDomain, typeof(IEnumerable<>), itemType); |
|
// explicitely cast the variable to IEnumerable<T>, where T is itemType |
|
Expression iEnumerableVariableExplicitCast = new CastExpression(iEnumerableType.GetTypeReference() , iEnumerableVariable, CastType.Cast); |
|
return new ObjectCreateExpression(listType.GetTypeReference(), iEnumerableVariableExplicitCast.ToList()); |
|
} |
|
|
|
/// <summary> |
|
/// Gets underlying address of object in the debuggee. |
|
/// </summary> |
|
public static ulong GetObjectAddress(this Value val) |
|
{ |
|
if (val.IsNull) return 0; |
|
ICorDebugReferenceValue refVal = val.CorReferenceValue; |
|
return refVal.GetValue(); |
|
} |
|
|
|
/// <summary> |
|
/// Returns true if this type is enum. |
|
/// </summary> |
|
public static bool IsEnum(this DebugType type) |
|
{ |
|
return (type.BaseType != null) && (type.BaseType.FullName == "System.Enum"); |
|
} |
|
|
|
/// <summary> |
|
/// Returns true is this type is just System.Object. |
|
/// </summary> |
|
public static bool IsSystemDotObject(this DebugType type) |
|
{ |
|
return type.FullName == "System.Object"; |
|
} |
|
|
|
/// <summary> |
|
/// Evaluates expression and gets underlying address of object in the debuggee. |
|
/// </summary> |
|
public static ulong GetObjectAddress(this Expression expr) |
|
{ |
|
return expr.Evaluate(WindowsDebugger.CurrentProcess).GetObjectAddress(); |
|
} |
|
|
|
/// <summary> |
|
/// System.Runtime.CompilerServices.GetHashCode method, for obtaining non-overriden hash codes from debuggee. |
|
/// </summary> |
|
private static DebugMethodInfo hashCodeMethod; |
|
|
|
/// <summary> |
|
/// Invokes RuntimeHelpers.GetHashCode on given value, that is a default hashCode ignoring user overrides. |
|
/// </summary> |
|
/// <param name="value">Valid value.</param> |
|
/// <returns>Hash code of the object in the debugee.</returns> |
|
public static int InvokeDefaultGetHashCode(this Value value) |
|
{ |
|
if (hashCodeMethod == null || hashCodeMethod.Process.HasExited) { |
|
DebugType typeRuntimeHelpers = DebugType.CreateFromType(value.AppDomain, typeof(System.Runtime.CompilerServices.RuntimeHelpers)); |
|
hashCodeMethod = (DebugMethodInfo)typeRuntimeHelpers.GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Static); |
|
if (hashCodeMethod == null) { |
|
throw new DebuggerException("Cannot obtain method System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode"); |
|
} |
|
} |
|
// David: I had hard time finding out how to invoke static method. |
|
// value.InvokeMethod is nice for instance methods. |
|
// what about MethodInfo.Invoke() ? |
|
// also, there could be an overload that takes 1 parameter instead of array |
|
Value defaultHashCode = Eval.InvokeMethod(DebuggerHelpers.hashCodeMethod, null, new Value[]{value}); |
|
|
|
//MethodInfo method = value.Type.GetMember("GetHashCode", BindingFlags.Method | BindingFlags.IncludeSuperType) as MethodInfo; |
|
//string hashCode = value.InvokeMethod(method, null).AsString; |
|
return (int)defaultHashCode.PrimitiveValue; |
|
} |
|
|
|
public static Value EvalPermanentReference(this Expression expr) |
|
{ |
|
return expr.Evaluate(WindowsDebugger.CurrentProcess).GetPermanentReference(); |
|
} |
|
|
|
public static bool IsNull(this Expression expr) |
|
{ |
|
return expr.Evaluate(WindowsDebugger.CurrentProcess).IsNull; |
|
} |
|
|
|
public static DebugType GetType(this Expression expr) |
|
{ |
|
return expr.Evaluate(WindowsDebugger.CurrentProcess).Type; |
|
} |
|
} |
|
}
|
|
|