Browse Source

- Object graph visualizer - implemented visualization of IList<T> nodes

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4424 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Martin Koníček 17 years ago
parent
commit
fc0b426391
  1. 2
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj
  2. 10
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Common/ObjectPropertyComparer.cs
  3. 14
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs
  4. 50
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs
  5. 22
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/VisualizerWPFWindow.xaml.cs
  6. 3
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ValueProviders/ListValuesProvider.cs
  7. 26
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/LinqUtils.cs
  8. 26
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/StringHelper.cs

2
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj

@ -147,7 +147,9 @@ @@ -147,7 +147,9 @@
<Compile Include="Src\Visualizers\Graph\TreeModel\PropertyNode.cs" />
<Compile Include="Src\Visualizers\Utils\AtomicType.cs" />
<Compile Include="Src\Visualizers\Utils\ITreeNode.cs" />
<Compile Include="Src\Visualizers\Utils\LinqUtils.cs" />
<Compile Include="Src\Visualizers\Utils\ListHelper.cs" />
<Compile Include="Src\Visualizers\Utils\StringHelper.cs" />
<Compile Include="Src\Visualizers\Utils\TreeFlattener.cs" />
<Compile Include="Src\Visualizers\Utils\TypeResolver.cs" />
<EmbeddedResource Include="Src\Service\DebuggeeExceptionForm.resx">

10
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Common/ObjectPropertyComparer.cs

@ -22,8 +22,12 @@ namespace Debugger.AddIn.Visualizers.Common @@ -22,8 +22,12 @@ namespace Debugger.AddIn.Visualizers.Common
public int Compare(ObjectProperty prop1, ObjectProperty prop2)
{
// order by IsAtomic, Name
int comparedAtomic = prop2.IsAtomic.CompareTo(prop1.IsAtomic);
return prop1.Name.CompareTo(prop2.Name);
// order by IsAtomic, Name -
// we now don't know whether a property is atomic until rendering it,
// so IsAtomic is always true when sorting in ObjectGraphBuilder
/*int comparedAtomic = prop2.IsAtomic.CompareTo(prop1.IsAtomic);
if (comparedAtomic != 0)
{
return comparedAtomic;
@ -31,7 +35,7 @@ namespace Debugger.AddIn.Visualizers.Common @@ -31,7 +35,7 @@ namespace Debugger.AddIn.Visualizers.Common
else
{
return prop1.Name.CompareTo(prop2.Name);
}
}*/
}
}
}

14
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
// <owner name="Martin Koníček" email="martin.konicek@gmail.com"/>
// <version>$Revision$</version>
// </file>
using Debugger.AddIn.Visualizers.Utils;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@ -17,10 +18,9 @@ using System.Windows.Data; @@ -17,10 +18,9 @@ using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using Debugger.AddIn.Visualizers.Common;
using Debugger.AddIn.Visualizers.Graph.Layout;
using System.Windows.Threading;
namespace Debugger.AddIn.Visualizers.Graph.Drawing
{
@ -65,14 +65,12 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing @@ -65,14 +65,12 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing
// data virtualization, PropertyNodeViewModel implements IEvaluate
this.listView.ItemsSource = new VirtualizingObservableCollection<ContentNode>(this.view);
int maxLen = this.view.Max(contentNode => { return contentNode.Name.Length; } );
int maxLen = this.view.MaxOrDefault(contentNode => { return contentNode.Name.Length; }, 0);
int spaces = Math.Max((int)(maxLen * 1.5), 0);
string sp = "";
for (int i = 0; i < spaces; i++)
sp += " ";
string addedSpaces = StringHelper.Repeat(' ', spaces);
GridView gv = listView.View as GridView;
gv.Columns[1].Header = "Name" + sp;
gv.Columns[1].Header = "Name" + addedSpaces;
//AutoSizeColumns();

50
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs

@ -143,17 +143,58 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -143,17 +143,58 @@ namespace Debugger.AddIn.Visualizers.Graph
thisNode.Content = new ThisNode();
ThisNode contentRoot = thisNode.Content;
loadNodeContent(contentRoot, thisNode.PermanentReference, thisNode.PermanentReference.Type);
DebugType iListType;
DebugType listItemType;
if (thisNode.PermanentReference.Type.ResolveIListImplementation(out iListType, out listItemType))
{
// it is a collection
loadNodeCollectionContent(contentRoot, thisNode.PermanentReference.Expression, iListType);
}
else
{
// it is an object
loadNodeObjectContent(contentRoot, thisNode.PermanentReference, thisNode.PermanentReference.Type);
}
}
private void loadNodeCollectionContent(AbstractNode node, Expression thisObject, DebugType iListType)
{
PropertyInfo itemPropertyInfo = iListType.GetProperty("Item");
int listCount = getIListCount(thisObject, iListType);
for (int i = 0; i < listCount; i++)
{
Expression itemExpr = thisObject.AppendMemberReference(itemPropertyInfo, new PrimitiveExpression(i));
PropertyNode itemNode = new PropertyNode(
new ObjectGraphProperty { Name = "[" + i + "]", Expression = itemExpr, Value = "", IsAtomic = true, TargetNode = null });
node.AddChild(itemNode);
}
}
private int getIListCount(Expression targetObject, DebugType iListType)
{
PropertyInfo countProperty = iListType.GetGenericInterface("System.Collections.Generic.ICollection").GetProperty("Count");
Expression countExpr = targetObject.AppendPropertyReference(countProperty);
int count = 0;
try {
// Do not get string representation since it can be printed in hex later
Value countValue = countExpr.Evaluate(WindowsDebugger.CurrentProcess);
count = (int)countValue.PrimitiveValue;
} catch (GetValueException) {
count = -1;
}
return count;
}
private void loadNodeContent(AbstractNode node, Value value, DebugType type)
private void loadNodeObjectContent(AbstractNode node, Value value, DebugType type)
{
// base
if (type.BaseType != null && type.BaseType.FullName != "System.Object")
{
var baseClassNode = new BaseClassNode(type.BaseType.FullName, type.BaseType.Name);
node.AddChild(baseClassNode);
loadNodeContent(baseClassNode, value, type.BaseType);
loadNodeObjectContent(baseClassNode, value, type.BaseType);
}
// non-public members
@ -189,11 +230,10 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -189,11 +230,10 @@ namespace Debugger.AddIn.Visualizers.Graph
if (memberProp.Name.Contains("<"))
continue;
// TODO just temporary - ObjectGraphProperty needs an expression
// ObjectGraphProperty needs an expression
// to use expanded / nonexpanded (and to evaluate?)
Expression propExpression = value.Expression.AppendMemberReference(memberProp);
// Value, IsAtomic are lazy evaluated
//var t = memberProp.DeclaringType;
propertyList.Add(new ObjectGraphProperty
{ Name = memberProp.Name,
Expression = propExpression, Value = "",

22
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/VisualizerWPFWindow.xaml.cs

@ -77,7 +77,15 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -77,7 +77,15 @@ namespace Debugger.AddIn.Visualizers.Graph
private void Inspect_Button_Click(object sender, RoutedEventArgs e)
{
refreshGraph();
clearErrorMessage();
if (debuggerService.IsProcessRunning) // TODO will this solve the "Process not paused" exception?
{
showErrorMessage("Cannot inspect when the process is running.");
}
else
{
refreshGraph();
}
}
void layoutViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
@ -91,7 +99,7 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -91,7 +99,7 @@ namespace Debugger.AddIn.Visualizers.Graph
void refreshGraph()
{
bool graphBuiltOk = true;
guiClearException();
clearErrorMessage();
try
{
this.objectGraph = rebuildGraph();
@ -99,12 +107,12 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -99,12 +107,12 @@ namespace Debugger.AddIn.Visualizers.Graph
catch(DebuggerVisualizerException ex)
{
graphBuiltOk = false;
guiHandleException(ex);
showErrorMessage(ex.Message);
}
catch(Debugger.GetValueException ex)
{
graphBuiltOk = false;
guiHandleException(ex);
showErrorMessage(ex.Message);
}
if (graphBuiltOk)
{
@ -133,14 +141,14 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -133,14 +141,14 @@ namespace Debugger.AddIn.Visualizers.Graph
//this.graphDrawer.Draw(this.currentPosGraph);
}
void guiClearException()
void clearErrorMessage()
{
this.pnlError.Visibility = Visibility.Collapsed;
}
void guiHandleException(System.Exception ex)
void showErrorMessage(string message)
{
this.txtError.Text = ex.Message;
this.txtError.Text = message;
this.pnlError.Visibility = Visibility.Visible;
//MessageBox.Show(ex.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
}

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

@ -60,6 +60,9 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer @@ -60,6 +60,9 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
return listItemType.GetMembers(this.bindingFlags);
}
// TODO move to Utils iListType.EvaluateCount(Expression targetObject)
// or targetObject.EvaluateCount(iListType)
// or targetObject.EvaluateIListCount() <- calls ResolveIListImplementation
private int evaluateCount()
{
PropertyInfo countProperty = iListType.GetGenericInterface("System.Collections.Generic.ICollection").GetProperty("Count");

26
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/LinqUtils.cs

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Martin Koníček" email="martin.konicek@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System.Collections.Generic;
using System.Linq;
using System;
namespace Debugger.AddIn.Visualizers.Utils
{
/// <summary>
/// Description of LinqUtils.
/// </summary>
public static class LinqUtils
{
public static int MaxOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector, int defaultValue)
{
if (source.Count() == 0)
return defaultValue;
return source.Max(selector);
}
}
}

26
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/StringHelper.cs

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Martin Koníček" email="martin.konicek@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Debugger.AddIn.Visualizers.Utils
{
/// <summary>
/// Description of StringHelper.
/// </summary>
public class StringHelper
{
public static string Repeat(char c, int count)
{
StringBuilder sb = new StringBuilder();
sb.Append(c, count);
return sb.ToString();
}
}
}
Loading…
Cancel
Save