Browse Source

Grid visualizer uses DebuggerHelpers.CreateDebugListExpression to fill a List by IEnumerable inside the debuggee and then display the List.

Implemented ExpressionEvaluator.VisitObjectCreateExpression.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4821 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Martin Koníček 16 years ago
parent
commit
e56d8c0501
  1. 7
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ChildNodesOfObject.cs
  2. 29
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/GridVisualizerWindow.xaml.cs
  3. 7
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ValueProviders/EnumerableValuesProvider.cs
  4. 13
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ValueProviders/ListValuesProvider.cs
  5. 20
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/DebuggerHelpers.cs
  6. 7
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/ListHelper.cs
  7. 27
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs
  8. 15
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs
  9. 4
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionExtensionMethods.cs
  10. 12
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs

7
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ChildNodesOfObject.cs

@ -68,7 +68,12 @@ namespace Debugger.AddIn.TreeModel @@ -68,7 +68,12 @@ namespace Debugger.AddIn.TreeModel
DebugType iListType = shownType.GetInterface(typeof(IList).FullName);
if (iListType != null) {
yield return new IListNode(targetObject, iListType);
}
} /*else {
DebugType iEnumerableType = shownType.GetInterface(typeof(IEnumerable).FullName);
if (iEnumerableType != null) {
yield return new IEnumerableNode(targetObject, iEnumerableType);
}
}*/
foreach(TreeNode node in LazyGetMembersOfObject(targetObject, shownType, publicInstanceFlags)) {
yield return node;

29
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/GridVisualizerWindow.xaml.cs

@ -33,9 +33,6 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer @@ -33,9 +33,6 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
WindowsDebugger debuggerService;
GridViewColumnHider columnHider;
/// <summary> Number of items shown initially when visualizing IEnumerable. </summary>
static readonly int initialIEnumerableItemsCount = 24;
public GridVisualizerWindow()
{
InitializeComponent();
@ -125,23 +122,19 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer @@ -125,23 +122,19 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
// Value is IList
DebugType iListType, listItemType;
if (val.Type.ResolveIListImplementation(out iListType, out listItemType)) {
var listValuesProvider = new ListValuesProvider(val.ExpressionTree, iListType, listItemType);
var virtCollection = new VirtualizingCollection<ObjectValue>(listValuesProvider);
this.listView.ItemsSource = virtCollection;
gridValuesProvider = listValuesProvider;
gridValuesProvider = CreateListValuesProvider(val.ExpressionTree, iListType, listItemType);
} else {
// Value is IEnumerable
DebugType iEnumerableType, itemType;
if (val.Type.ResolveIEnumerableImplementation(out iEnumerableType, out itemType)) {
var lazyListViewWrapper = new LazyItemsControl<ObjectValue>(this.listView, initialIEnumerableItemsCount);
// original
/*var lazyListViewWrapper = new LazyItemsControl<ObjectValue>(this.listView, initialIEnumerableItemsCount);
var enumerableValuesProvider = new EnumerableValuesProvider(val.ExpressionTree, iEnumerableType, itemType);
lazyListViewWrapper.ItemsSource = new VirtualizingIEnumerable<ObjectValue>(enumerableValuesProvider.ItemsSource);
gridValuesProvider = enumerableValuesProvider;
/*var systemObjectType = DebugType.CreateFromType(val.AppDomain, typeof(System.Object));
var listType = DebugType.CreateFromType(val.AppDomain, typeof(System.Collections.Generic.List<>), systemObjectType);
Value list = Eval.NewObject(listType , val);*/
gridValuesProvider = enumerableValuesProvider;*/
DebugType debugListType;
var debugListExpression = DebuggerHelpers.CreateDebugListExpression(val.ExpressionTree, itemType, out debugListType);
gridValuesProvider = CreateListValuesProvider(debugListExpression, debugListType, itemType);
} else {
// Value cannot be displayed in GridVisualizer
return;
@ -155,6 +148,14 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer @@ -155,6 +148,14 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
}
}
ListValuesProvider CreateListValuesProvider(ICSharpCode.NRefactory.Ast.Expression targetObject, DebugType iListType, DebugType listItemType)
{
var listValuesProvider = new ListValuesProvider(targetObject, iListType, listItemType);
var virtCollection = new VirtualizingCollection<ObjectValue>(listValuesProvider);
this.listView.ItemsSource = virtCollection;
return listValuesProvider;
}
void InitializeColumns(GridView gridView, IList<MemberInfo> itemTypeMembers)
{
gridView.Columns.Clear();

7
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ValueProviders/EnumerableValuesProvider.cs

@ -4,13 +4,14 @@ @@ -4,13 +4,14 @@
// <owner name="Martin Koníček" email="martin.konicek@gmail.com"/>
// <version>$Revision$</version>
// </file>
using Debugger.MetaData;
using Debugger.AddIn.Visualizers.Utils;
using ICSharpCode.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using ICSharpCode.SharpDevelop.Services;
using Debugger.AddIn.Visualizers.Utils;
using Debugger.MetaData;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn.Visualizers.GridVisualizer
{

13
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ValueProviders/ListValuesProvider.cs

@ -48,16 +48,13 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer @@ -48,16 +48,13 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
// TODO move to Utils iListType.EvaluateCount(Expression targetObject)
// or targetObject.EvaluateCount(iListType)
// or targetObject.EvaluateIListCount() <- calls ResolveIListImplementation
private int evaluateCount()
int evaluateCount()
{
PropertyInfo countProperty = this.collectionType.GetGenericInterface("System.Collections.Generic.ICollection").GetProperty("Count");
try {
// Do not get string representation since it can be printed in hex later
Value countValue = targetObject.Evaluate(WindowsDebugger.CurrentProcess).GetPropertyValue(countProperty);
return (int)countValue.PrimitiveValue;
} catch (GetValueException) {
return -1;
}
// Do not get string representation since it can be printed in hex later
Value countValue = targetObject.Evaluate(WindowsDebugger.CurrentProcess).GetPropertyValue(countProperty);
//Value countValue = targetObject.AppendMemberReference(countProperty).Evaluate(WindowsDebugger.CurrentProcess);
return (int)countValue.PrimitiveValue;
}
}
}

20
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/DebuggerHelpers.cs

@ -5,16 +5,34 @@ @@ -5,16 +5,34 @@
// <version>$Revision$</version>
// </file>
using System;
using Debugger;
using Debugger.MetaData;
using Debugger.Wrappers.CorDebug;
using ICSharpCode.SharpDevelop.Services;
using System.Collections.Generic;
using Expression = ICSharpCode.NRefactory.Ast.Expression;
using ICSharpCode.NRefactory.Ast;
namespace Debugger.AddIn.Visualizers.Utils
{
public static class DebuggerHelpers
{
/// <summary>
/// Creates an expression which, when evaluated, creates a List&lt;T&gt; in the debugee
/// filled with contents of IEnumerable&lt;T&gt; from the debugee.
/// </summary>
/// <param name="iEnumerableVariable">Expression for IEnumerable variable in the debugee.</param>
/// <param name="itemType">
/// The generic argument of IEnumerable&lt;T&gt; 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.ToTypeReference() , iEnumerableVariable, CastType.Cast);
return new ObjectCreateExpression(listType.ToTypeReference(), iEnumerableVariableExplicitCast.ToList());
}
/// <summary>
/// Gets underlying address of object in the debuggee.
/// </summary>

7
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/ListHelper.cs

@ -27,5 +27,12 @@ namespace Debugger.AddIn.Visualizers.Utils @@ -27,5 +27,12 @@ namespace Debugger.AddIn.Visualizers.Utils
list.Sort();
return list;
}
public static List<T> ToList<T>(this T singleItem)
{
var newList = new List<T>();
newList.Add(singleItem);
return newList;
}
}
}

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

@ -336,14 +336,9 @@ namespace Debugger @@ -336,14 +336,9 @@ namespace Debugger
#region Convenience methods
public static Value NewObject(DebugType debugType, params Value[] constructorArguments)
public static Value NewObject(DebugType debugType, Value[] constructorArguments, DebugType[] constructorArgumentsTypes)
{
return NewObject(debugType, new List<Value>(constructorArguments));
}
public static Value NewObject(DebugType debugType, List<Value> constructorArguments)
{
return AsyncNewObject(debugType, constructorArguments).WaitForResult();
return AsyncNewObject(debugType, constructorArguments, constructorArgumentsTypes).WaitForResult();
}
public static Value NewObjectNoConstructor(DebugType debugType)
@ -353,12 +348,14 @@ namespace Debugger @@ -353,12 +348,14 @@ namespace Debugger
#endregion
public static Eval AsyncNewObject(DebugType debugType, List<Value> constructorArguments)
public static Eval AsyncNewObject(DebugType debugType, Value[] constructorArguments, DebugType[] constructorArgumentsTypes)
{
List<Expression> constructorArgumentsExpressions = SelectExpressions(constructorArguments);
// constructorArgumentsTypes = SelectTypes(constructorArguments);
ICorDebugValue[] constructorArgsCorDebug = ValuesAsCorDebug(constructorArguments);
MethodInfo constructor = debugType.GetMethod(".ctor"); // TODO
MethodInfo constructor = debugType.GetMethod(".ctor", constructorArgumentsTypes);
if (constructor == null) {
throw new DebuggerException(string.Format("Type {0} has no constructor overload with given argument types.", debugType.FullName));
}
return new Eval(
debugType.AppDomain,
"New object: " + debugType.FullName,
@ -383,19 +380,19 @@ namespace Debugger @@ -383,19 +380,19 @@ namespace Debugger
);
}
static ICorDebugValue[] ValuesAsCorDebug(List<Value> values)
static ICorDebugValue[] ValuesAsCorDebug(Value[] values)
{
ICorDebugValue[] valuesAsCorDebug = new ICorDebugValue[values.Count];
for(int i = 0; i < values.Count; i++)
ICorDebugValue[] valuesAsCorDebug = new ICorDebugValue[values.Length];
for(int i = 0; i < values.Length; i++)
{
valuesAsCorDebug[i] = values[i].CorValue;
}
return valuesAsCorDebug;
}
static List<Expression> SelectExpressions(List<Value> values)
static List<Expression> SelectExpressions(Value[] values)
{
List<Expression> expressions = new List<Expression>(values.Count);
List<Expression> expressions = new List<Expression>(values.Length);
foreach (Value value in values) {
expressions.Add(value.ExpressionTree);
}

15
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs

@ -336,6 +336,21 @@ namespace Debugger @@ -336,6 +336,21 @@ namespace Debugger
return target.InvokeMethod(method, args.ToArray());
}
public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
{
List<Expression> constructorParameters = objectCreateExpression.Parameters;
DebugType[] constructorParameterTypes = new DebugType[constructorParameters.Count];
for (int i = 0; i < constructorParameters.Count; i++) {
constructorParameterTypes[i] = GetDebugType(constructorParameters[i]);
}
Value[] constructorParameterValues = new Value[constructorParameters.Count];
for (int i = 0; i < constructorParameters.Count; i++) {
constructorParameterValues[i] = Evaluate(constructorParameters[i]);
}
return Eval.NewObject(DebugType.CreateFromTypeReference(context.AppDomain, objectCreateExpression.CreateType),
constructorParameterValues, constructorParameterTypes);
}
public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
{
Value target = Evaluate(memberReferenceExpression.TargetObject);

4
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionExtensionMethods.cs

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision: 4767 $</version>
// <version>$Revision$</version>
// </file>
using ICSharpCode.NRefactory.PrettyPrinter;
using System;
@ -102,7 +102,7 @@ namespace Debugger @@ -102,7 +102,7 @@ namespace Debugger
return typedArgs;
}
static TypeReference ToTypeReference(this DebugType type)
public static TypeReference ToTypeReference(this DebugType type)
{
List<int> arrayRanks = new List<int>();
int pointerNest = 0;

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

@ -353,7 +353,7 @@ namespace Debugger.MetaData @@ -353,7 +353,7 @@ namespace Debugger.MetaData
if (module.AppDomain == appDomain) {
uint token;
try {
token = module.MetaData.FindTypeDefPropsByName(typeName, enclosingType == null ? 0 : enclosingType.Token).Token;
token = module.MetaData.FindTypeDefPropsByName(GetQualifiedName(typeName, genericArguments), enclosingType == null ? 0 : enclosingType.Token).Token;
} catch {
continue;
}
@ -363,6 +363,16 @@ namespace Debugger.MetaData @@ -363,6 +363,16 @@ namespace Debugger.MetaData
throw new DebuggerException("Can not find type " + typeName);
}
/// <summary> Converts type name to the form suitable for COM API. </summary>
static string GetQualifiedName(string typeName, params DebugType[] genericArguments)
{
if (genericArguments != null && genericArguments.Length > 0 && !typeName.Contains("`")) {
return typeName + "`" + genericArguments.Length;
} else {
return typeName;
}
}
public static DebugType CreateFromTypeSpec(Module module, uint token, DebugType declaringType)
{
CorTokenType tokenType = (CorTokenType)(token & 0xFF000000);

Loading…
Cancel
Save