Browse Source

Debugger visualizers - switch from DebugType to

IType in declarations - the easy part.

The next part is to port method implementations.
newNRvisualizers
Martin Konicek 13 years ago
parent
commit
63ecc56b87
  1. 1
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
  2. 12
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/GridVisualizerCommand.cs
  3. 3
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/IVisualizerDescriptor.cs
  4. 5
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/ObjectGraphVisualizerCommand.cs
  5. 3
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/TextVisualizerCommand.cs
  6. 3
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/XmlVisualizerCommand.cs
  7. 7
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs
  8. 26
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/AtomicType.cs
  9. 40
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs
  10. 42
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/TypeResolver.cs

1
src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj

@ -216,7 +216,6 @@ @@ -216,7 +216,6 @@
<Compile Include="Visualizers\PresentationBindings\GridViewHideableColumn.cs" />
<Compile Include="Visualizers\PresentationBindings\TooltipVisibilityConverter.cs" />
<Compile Include="Visualizers\TextVisualizer\TextVisualizerWindow.xaml.cs" />
<Compile Include="Visualizers\Utils\AtomicType.cs" />
<Compile Include="Visualizers\Utils\DebuggerHelpers.cs" />
<Compile Include="Visualizers\Utils\DictionaryExtensions.cs" />
<Compile Include="Visualizers\Utils\IEnumerableExtensions.cs" />

12
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/GridVisualizerCommand.cs

@ -1,6 +1,7 @@ @@ -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 ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Debugging;
using System;
using System.Collections.Generic;
@ -15,12 +16,10 @@ namespace Debugger.AddIn.Visualizers @@ -15,12 +16,10 @@ namespace Debugger.AddIn.Visualizers
{
public class GridVisualizerDescriptor : IVisualizerDescriptor
{
public bool IsVisualizerAvailable(DebugType type)
public bool IsVisualizerAvailable(IType type)
{
if (type.IsAtomic()) {
return false;
}
DebugType collectionType, itemType;
if (type.IsAtomic()) return false;
IType collectionType, itemType;
// Visualizer available for IEnumerable<T> (that is, also IList<T>)
return type.ResolveIEnumerableImplementation(out collectionType, out itemType);
}
@ -36,7 +35,8 @@ namespace Debugger.AddIn.Visualizers @@ -36,7 +35,8 @@ namespace Debugger.AddIn.Visualizers
/// </summary>
public class GridVisualizerCommand : ExpressionVisualizerCommand
{
public GridVisualizerCommand(string valueName, Func<Value> getValue) : base(valueName, getValue)
public GridVisualizerCommand(string valueName, Func<Value> getValue)
: base(valueName, getValue)
{
}

3
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/IVisualizerDescriptor.cs

@ -1,6 +1,7 @@ @@ -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 ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Debugging;
using System;
using System.Collections.Generic;
@ -15,7 +16,7 @@ namespace Debugger.AddIn.Visualizers @@ -15,7 +16,7 @@ namespace Debugger.AddIn.Visualizers
/// </summary>
public interface IVisualizerDescriptor
{
bool IsVisualizerAvailable(DebugType type);
bool IsVisualizerAvailable(IType type);
IVisualizerCommand CreateVisualizerCommand(string valueName, Func<Value> getValue);
}
}

5
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/ObjectGraphVisualizerCommand.cs

@ -8,6 +8,7 @@ using System.Linq; @@ -8,6 +8,7 @@ using System.Linq;
using Debugger.AddIn.TreeModel;
using Debugger.AddIn.Visualizers.Graph;
using Debugger.MetaData;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Debugging;
using Debugger.AddIn.Visualizers.Utils;
using ICSharpCode.SharpDevelop.Services;
@ -16,7 +17,7 @@ namespace Debugger.AddIn.Visualizers @@ -16,7 +17,7 @@ namespace Debugger.AddIn.Visualizers
{
public class ObjectGraphVisualizerDescriptor : IVisualizerDescriptor
{
public bool IsVisualizerAvailable(DebugType type)
public bool IsVisualizerAvailable(IType type)
{
return !type.IsAtomic() && !type.IsSystemDotObject();
}
@ -44,7 +45,7 @@ namespace Debugger.AddIn.Visualizers @@ -44,7 +45,7 @@ namespace Debugger.AddIn.Visualizers
public override void Execute()
{
var objectGraphWindow = ObjectGraphWindow.EnsureShown();
objectGraphWindow.ShownExpression = new GraphExpression(new IdentifierExpression(this.ValueName), this.GetValue);
objectGraphWindow.ShownExpression = new GraphExpression(this.ValueName, this.GetValue);
}
}
}

3
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/TextVisualizerCommand.cs

@ -8,6 +8,7 @@ using System.Linq; @@ -8,6 +8,7 @@ using System.Linq;
using Debugger.AddIn.TreeModel;
using Debugger.AddIn.Visualizers.TextVisualizer;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Services;
@ -15,7 +16,7 @@ namespace Debugger.AddIn.Visualizers @@ -15,7 +16,7 @@ namespace Debugger.AddIn.Visualizers
{
public class TextVisualizerDescriptor : IVisualizerDescriptor
{
public bool IsVisualizerAvailable(DebugType type)
public bool IsVisualizerAvailable(IType type)
{
return type.FullName == typeof(string).FullName;
}

3
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/XmlVisualizerCommand.cs

@ -8,6 +8,7 @@ using System.Linq; @@ -8,6 +8,7 @@ using System.Linq;
using Debugger.AddIn.TreeModel;
using Debugger.AddIn.Visualizers.TextVisualizer;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Services;
@ -15,7 +16,7 @@ namespace Debugger.AddIn.Visualizers @@ -15,7 +16,7 @@ namespace Debugger.AddIn.Visualizers
{
public class XmlVisualizerDescriptor : IVisualizerDescriptor
{
public bool IsVisualizerAvailable(DebugType type)
public bool IsVisualizerAvailable(IType type)
{
return type.FullName == typeof(string).FullName;
}

7
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs

@ -10,6 +10,7 @@ using Debugger.AddIn.Visualizers.Utils; @@ -10,6 +10,7 @@ using Debugger.AddIn.Visualizers.Utils;
using Debugger.MetaData;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Services;
@ -187,10 +188,10 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -187,10 +188,10 @@ namespace Debugger.AddIn.Visualizers.Graph
}
}*/
void LoadNodeObjectContent(AbstractNode node, GraphExpression expression, DebugType type)
void LoadNodeObjectContent(AbstractNode node, GraphExpression expression, IType type)
{
// base
if (type.BaseType != null && type.BaseType.FullName != "System.Object") {
if (type.BaseType != null && !type.IsSystemDotObject()) {
var baseClassNode = new BaseClassNode(type.BaseType.FullName, type.BaseType.Name);
node.AddChild(baseClassNode);
LoadNodeObjectContent(baseClassNode, expression, (DebugType)type.BaseType);
@ -212,7 +213,7 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -212,7 +213,7 @@ namespace Debugger.AddIn.Visualizers.Graph
}
}
private List<ObjectGraphProperty> getProperties(GraphExpression expression, DebugType shownType, BindingFlags flags)
private List<ObjectGraphProperty> getProperties(GraphExpression expression, IType shownType, BindingFlags flags)
{
List<ObjectGraphProperty> propertyList = new List<ObjectGraphProperty>();

26
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/AtomicType.cs

@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
// 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 Debugger.MetaData;
using System;
using ICSharpCode.SharpDevelop.Services;
using ICSharpCode.NRefactory.Ast;
namespace Debugger.AddIn.Visualizers.Utils
{
/// <summary>
/// Atomic type is a type that "cannot be expanded".
/// </summary>
public static class AtomicType
{
/// <summary>
/// Checks whether given expression's type is atomic.
/// </summary>
/// <param name="expr">Expression.</param>
/// <returns>True if expression's type is atomic, false otherwise.</returns>
public static bool IsAtomic(this DebugType type)
{
return type.IsPrimitive || type.FullName == "System.String" || type.IsEnum();
}
}
}

40
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs

@ -10,6 +10,7 @@ using System.Reflection; @@ -10,6 +10,7 @@ using System.Reflection;
using Debugger;
using Debugger.MetaData;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Services;
@ -41,12 +42,12 @@ namespace Debugger.AddIn.Visualizers.Utils @@ -41,12 +42,12 @@ namespace Debugger.AddIn.Visualizers.Utils
/// </summary>
public static Value CreateListFromIEnumerable(Value iEnumerableValue)
{
DebugType iEnumerableType, itemType;
IType iEnumerableType, itemType;
if (!iEnumerableValue.Type.ResolveIEnumerableImplementation(out iEnumerableType, out itemType))
throw new GetValueException("Value is not IEnumerable");
DebugType listType = DebugType.CreateFromType(iEnumerableValue.AppDomain, typeof(System.Collections.Generic.List<>), itemType);
DebugConstructorInfo ctor = (DebugConstructorInfo)listType.GetConstructor(BindingFlags.Default, null, CallingConventions.Any, new System.Type[] { iEnumerableType }, null);
// FIXME
IType listType = DebugType.CreateFromType(iEnumerableValue.AppDomain, typeof(System.Collections.Generic.List<>), itemType);
DebugConstructorInfo ctor = listType.GetConstructor(BindingFlags.Default, null, CallingConventions.Any, new System.Type[] { iEnumerableType }, null);
if (ctor == null)
throw new DebuggerException("List<T> constructor not found");
@ -67,23 +68,31 @@ namespace Debugger.AddIn.Visualizers.Utils @@ -67,23 +68,31 @@ namespace Debugger.AddIn.Visualizers.Utils
/// <summary>
/// Returns true if this type is enum.
/// </summary>
public static bool IsEnum(this DebugType type)
public static bool IsEnum(this IType type)
{
return (type.BaseType != null) && (type.BaseType.FullName == "System.Enum");
return type.DirectBaseTypes.Select(t => t.FullName).Contains("System.Enum");
}
/// <summary>
/// Returns true is this type is just System.Object.
/// Returns true is this type is System.Object.
/// </summary>
public static bool IsSystemDotObject(this DebugType type)
public static bool IsSystemDotObject(this IType type)
{
return type.FullName == "System.Object";
}
/// <summary>
/// Checks whether given type is a primitive type, String, or enum.
/// </summary>
public static bool IsAtomic(this IType type)
{
return TypeSystemExtensions.IsPrimitiveType(type) || type.FullName == "System.String" || type.Kind == TypeKind.Enum;
}
/// <summary>
/// System.Runtime.CompilerServices.GetHashCode method, for obtaining non-overriden hash codes from debuggee.
/// </summary>
private static DebugMethodInfo hashCodeMethod;
private static IMethod hashCodeMethod;
/// <summary>
/// Invokes RuntimeHelpers.GetHashCode on given value, that is a default hashCode ignoring user overrides.
/// </summary>
@ -91,17 +100,16 @@ namespace Debugger.AddIn.Visualizers.Utils @@ -91,17 +100,16 @@ namespace Debugger.AddIn.Visualizers.Utils
/// <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);
// TODO reimplement check for Process.HasExited (debuggee restarted)
if (hashCodeMethod == null /*|| hashCodeMethod.Process.HasExited*/) {
IType runtimeHelpers = DebugType.CreateFromType(value.AppDomain, typeof(System.Runtime.CompilerServices.RuntimeHelpers));
hashCodeMethod = runtimeHelpers.GetMethods(m => m.FullName == "GetHashCode").FirstOrDefault();
if (hashCodeMethod == null) {
throw new DebuggerException("Cannot obtain method System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode");
throw new DebuggerException(
"Cannot find method System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode().");
}
}
Value defaultHashCode = Eval.InvokeMethod(WindowsDebugger.EvalThread, 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;
}

42
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/TypeResolver.cs

@ -6,6 +6,7 @@ using System.Collections; @@ -6,6 +6,7 @@ using System.Collections;
using Debugger.MetaData;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
namespace Debugger.AddIn.Visualizers.Utils
{
@ -14,30 +15,13 @@ namespace Debugger.AddIn.Visualizers.Utils @@ -14,30 +15,13 @@ namespace Debugger.AddIn.Visualizers.Utils
/// </summary>
public static class TypeResolver
{
/// <summary>
/// Gets generic interface this type implements.
/// The generic argument of the interface does not have to be specified.
/// If you know the generic argument, use DebugType.GetInterface.
/// </summary>
/// <param name="fullNamePrefix">Eg. "System.Collections.Generic.IList"</param>
public static DebugType GetGenericInterface(this DebugType type, string fullNamePrefix)
{
foreach(DebugType inter in type.GetInterfaces()) {
if (inter.FullName.StartsWith(fullNamePrefix) && inter.GetGenericArguments().Length > 0) {
return inter;
}
}
// not found, search BaseType
return type.BaseType == null ? null : (DebugType)type.BaseType.GetInterface(fullNamePrefix);
}
/// <summary>
/// Resolves implementation of System.Collections.Generic.IList on this type.
/// </summary>
/// <param name="iListType">Result found implementation of System.Collections.Generic.IList.</param>
/// <param name="itemType">The only generic argument of <paramref name="implementation"/></param>
/// <returns>True if found, false otherwise.</returns>
public static bool ResolveIListImplementation(this DebugType type, out DebugType iListType, out DebugType itemType)
public static bool ResolveIListImplementation(this IType type, out IType iListType, out IType itemType)
{
return type.ResolveGenericInterfaceImplementation(
"System.Collections.Generic.IList", out iListType, out itemType);
@ -49,7 +33,7 @@ namespace Debugger.AddIn.Visualizers.Utils @@ -49,7 +33,7 @@ namespace Debugger.AddIn.Visualizers.Utils
/// <param name="iEnumerableType">Result found implementation of System.Collections.Generic.IEnumerable.</param>
/// <param name="itemType">The only generic argument of <paramref name="implementation"/></param>
/// <returns>True if found, false otherwise.</returns>
public static bool ResolveIEnumerableImplementation(this DebugType type, out DebugType iEnumerableType, out DebugType itemType)
public static bool ResolveIEnumerableImplementation(this IType type, out IType iEnumerableType, out IType itemType)
{
return type.ResolveGenericInterfaceImplementation(
"System.Collections.Generic.IEnumerable", out iEnumerableType, out itemType);
@ -62,20 +46,20 @@ namespace Debugger.AddIn.Visualizers.Utils @@ -62,20 +46,20 @@ namespace Debugger.AddIn.Visualizers.Utils
/// <param name="implementation">Result found implementation.</param>
/// <param name="itemType">The only generic argument of <paramref name="implementation"/></param>
/// <returns>True if found, false otherwise.</returns>
public static bool ResolveGenericInterfaceImplementation(this DebugType type, string fullNamePrefix, out DebugType implementation, out DebugType itemType)
public static bool ResolveGenericInterfaceImplementation(this IType type, string fullNamePrefix, out ParameterizedType implementation, out IType itemType)
{
if (type == null)
throw new ArgumentNullException("type");
if (type == null) throw new ArgumentNullException("type");
implementation = null;
itemType = null;
implementation = type.GetGenericInterface(fullNamePrefix);
implementation =
type.GetAllBaseTypes().
Where(t => (t is ParameterizedType) && t.FullName.StartsWith(fullNamePrefix)).
Select(t => (ParameterizedType)t).
Where(t => t.TypeParameterCount == 1)
.FirstOrDefault();
if (implementation != null) {
if (implementation.GetGenericArguments().Length == 1) {
itemType = (DebugType)implementation.GetGenericArguments()[0];
return true;
}
itemType = implementation.GetTypeArgument(0);
return true;
}
return false;
}

Loading…
Cancel
Save