diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs
index edf0a95862..667323c4c2 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs
@@ -4,13 +4,13 @@
using System;
using System.Collections.Generic;
using System.Reflection;
-
using Debugger.AddIn.Visualizers.Common;
using Debugger.AddIn.Visualizers.Utils;
using Debugger.MetaData;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Visitors;
+using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn.Visualizers.Graph
@@ -150,7 +150,7 @@ namespace Debugger.AddIn.Visualizers.Graph
DebugType listItemType;
if (thisNode.PermanentReference.Type.ResolveIListImplementation(out iListType, out listItemType))
{
- // it is a collection
+ // it is an IList
loadNodeCollectionContent(contentRoot, thisNode.Expression, iListType);
}
else
@@ -236,7 +236,7 @@ namespace Debugger.AddIn.Visualizers.Graph
}
// ObjectGraphProperty needs an expression
- // to use expanded / nonexpanded (and to evaluate?)
+ // to know whether it is expanded, and to evaluate
Expression propExpression = expression.AppendMemberReference((IDebugMemberInfo)memberProp);
// Value, IsAtomic are lazy evaluated
propertyList.Add(new ObjectGraphProperty
@@ -259,13 +259,12 @@ namespace Debugger.AddIn.Visualizers.Graph
foreach(ObjectGraphProperty complexProperty in thisNode.Properties)
{
ObjectGraphNode targetNode = null;
- // we are only evaluating expanded nodes here
- // (we have to do this to know the "shape" of the graph)
- // property laziness makes sense, as we are not evaluating atomic and non-expanded properties out of user's view
- if (/*!complexProperty.IsNull && we dont know yet if it's null */expandedNodes.IsExpanded(complexProperty.Expression))
+ // We are only evaluating expanded nodes here.
+ // We have to do this to know the "shape" of the graph.
+ // We do not evaluate atomic and non-expanded properties, those will be lazy evaluated when drawn.
+ if (expandedNodes.IsExpanded(complexProperty.Expression))
{
// if expanded, evaluate this property
- // complexProperty.Evaluate(); // consider
Value memberValue = complexProperty.Expression.Evaluate(this.debuggerService.DebuggedProcess);
if (memberValue.IsNull)
{
@@ -302,8 +301,12 @@ namespace Debugger.AddIn.Visualizers.Graph
/// New empty object node representing the value.
private ObjectGraphNode createNewNode(Value permanentReference, Expression expression)
{
+ if (permanentReference == null) throw new ArgumentNullException("permanentReference");
+
ObjectGraphNode newNode = new ObjectGraphNode();
- newNode.TypeName = permanentReference.Type.Name;
+ if (permanentReference.Type != null) {
+ newNode.TypeName = permanentReference.Type.FormatNameCSharp();
+ }
newNode.HashCode = permanentReference.InvokeDefaultGetHashCode();
resultGraph.AddNode(newNode);
@@ -366,7 +369,6 @@ namespace Debugger.AddIn.Visualizers.Graph
DebugType typeOfValue = expr.Evaluate(debuggerService.DebuggedProcess).Type;
if (typeOfValue.IsArray)
{
- // arrays will be supported of course in the final version
throw new DebuggerVisualizerException("Arrays are not supported yet");
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs
index 165f739a48..148d63802a 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs
@@ -1,6 +1,7 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
+using System.Linq;
using Debugger.Interop.CorDebug;
using System;
using System.Collections.Generic;
@@ -8,6 +9,7 @@ using System.Reflection;
using Debugger;
using Debugger.MetaData;
using ICSharpCode.NRefactory.Ast;
+using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn.Visualizers.Utils
@@ -84,10 +86,6 @@ namespace Debugger.AddIn.Visualizers.Utils
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;
@@ -95,6 +93,19 @@ namespace Debugger.AddIn.Visualizers.Utils
return (int)defaultHashCode.PrimitiveValue;
}
+ ///
+ /// Formats System.Type to the C# format, that is generic parameters in angle brackets.
+ ///
+ public static string FormatNameCSharp(this Type type)
+ {
+ string typeName = type.Name.CutoffEnd("`"); // get rid of the `n in generic type names
+ if (type.IsGenericType) {
+ return typeName + "<" + string.Join(", ", type.GetGenericArguments().Select(a => FormatNameCSharp(a))) + ">";
+ } else {
+ return typeName;
+ }
+ }
+
public static Value EvalPermanentReference(this Expression expr)
{
return expr.Evaluate(WindowsDebugger.CurrentProcess).GetPermanentReference();
diff --git a/src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs b/src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs
index d1d1964238..7355567520 100644
--- a/src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs
+++ b/src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs
@@ -284,7 +284,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
}
// Special case for Attributes
if (insertedText.EndsWith("Attribute") && IsInAttributeContext(editor, context.StartOffset)) {
- insertedText = insertedText.RemoveEnd("Attribute");
+ insertedText = insertedText.RemoveFromEnd("Attribute");
}
} else if (this.Entity is IMethod) {
addUsing = !IsKnownName(nameResult);
diff --git a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/AbstractProjectBrowserTreeNode.cs b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/AbstractProjectBrowserTreeNode.cs
index 75ab003073..979319eaac 100644
--- a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/AbstractProjectBrowserTreeNode.cs
+++ b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/AbstractProjectBrowserTreeNode.cs
@@ -178,7 +178,7 @@ namespace ICSharpCode.SharpDevelop.Project
return this;
}
- string currentPath = relativePath.Trim('/', '\\').RemoveStart(targets[0]).Trim('/', '\\');
+ string currentPath = relativePath.Trim('/', '\\').RemoveFromStart(targets[0]).Trim('/', '\\');
//LoggingService.Debug("entering depth loop...");
//LoggingService.DebugFormatted(@"\- looking for '{0}'", relativePath);
//LoggingService.DebugFormatted(@"\- starting at '{0}'", targetNode != null ? targetNode.Text : "null");
diff --git a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs
index ef7ec8814a..1726e6efee 100644
--- a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs
+++ b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs
@@ -325,7 +325,7 @@ namespace ICSharpCode.SharpDevelop
/// Removes from the start of this string.
/// Throws ArgumentException if this string does not start with .
///
- public static string RemoveStart(this string s, string stringToRemove)
+ public static string RemoveFromStart(this string s, string stringToRemove)
{
if (s == null)
return null;
@@ -337,13 +337,12 @@ namespace ICSharpCode.SharpDevelop
}
///
- /// Removes from the end of this string.
- /// Throws ArgumentException if this string does not end with .
+ /// Removes from the end of this string.
+ /// Throws ArgumentException if this string does not end with .
///
- public static string RemoveEnd(this string s, string stringToRemove)
+ public static string RemoveFromEnd(this string s, string stringToRemove)
{
- if (s == null)
- return null;
+ if (s == null) return null;
if (string.IsNullOrEmpty(stringToRemove))
return s;
if (!s.EndsWith(stringToRemove))
@@ -351,6 +350,21 @@ namespace ICSharpCode.SharpDevelop
return s.Substring(0, s.Length - stringToRemove.Length);
}
+ ///
+ /// Trims the string from the first occurence of to the end, including .
+ /// If the string does not contain , just returns the original string.
+ ///
+ public static string CutoffEnd(this string s, string cutoffStart)
+ {
+ if (s == null) return null;
+ int pos = s.IndexOf(cutoffStart);
+ if (pos != -1) {
+ return s.Substring(0, pos);
+ } else {
+ return s;
+ }
+ }
+
///
/// Takes at most first characters from string.
/// String can be null.