Browse Source

Ensure that the root node of debugger tooltip can be re-evaluated

newNRvisualizers
David Srbecký 13 years ago
parent
commit
ae35b9e8ea
  1. 21
      src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs
  2. 23
      src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs
  3. 4
      src/AddIns/Debugger/Debugger.Core/StackFrame.cs

21
src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs

@ -710,18 +710,23 @@ namespace ICSharpCode.SharpDevelop.Services @@ -710,18 +710,23 @@ namespace ICSharpCode.SharpDevelop.Services
{
if (!(IsDebugging && CurrentProcess.IsPaused))
return;
if (e.ResolveResult == null)
var resolveResult = e.ResolveResult;
if (resolveResult == null)
return;
if (e.ResolveResult is LocalResolveResult || e.ResolveResult is MemberResolveResult || e.ResolveResult is InvocationResolveResult) {
if (resolveResult is LocalResolveResult || resolveResult is MemberResolveResult || resolveResult is InvocationResolveResult) {
string text = string.Empty;
try {
text = new ResolveResultPrettyPrinter().Print(resolveResult);
} catch (NotImplementedException) {
}
Func<Value> getValue = delegate {
ExpressionEvaluationVisitor eval = new ExpressionEvaluationVisitor(CurrentStackFrame, EvalThread, CurrentStackFrame.AppDomain.Compilation);
Value result = eval.Convert(e.ResolveResult);
string text = new ResolveResultPrettyPrinter().Print(e.ResolveResult);
e.SetToolTip(new DebuggerTooltipControl(ValueNode.GetTooltipFor(text, result)));
} catch (GetValueException ex) {
e.SetToolTip(ex.Message);
return eval.Convert(resolveResult);
};
try {
var rootNode = new ValueNode(ClassBrowserIconService.LocalVariable, text, getValue);
e.SetToolTip(new DebuggerTooltipControl(rootNode));
} catch (InvalidOperationException) {
return;
}
}
}

23
src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs

@ -72,7 +72,7 @@ namespace Debugger.AddIn.TreeModel @@ -72,7 +72,7 @@ namespace Debugger.AddIn.TreeModel
cachedValue = this.getValue().GetPermanentReference(WindowsDebugger.EvalThread);
cachedValueProcess = cachedValue.Process;
cachedValueDebuggeeState = cachedValue.Process.DebuggeeState;
LoggingService.InfoFormatted("Evaluated node '{0}' in {1} ms (result cached for future use)", this.Name, watch.ElapsedMilliseconds);
LoggingService.InfoFormatted("Evaluated node '{0}' in {1} ms (result cached)", this.Name, watch.ElapsedMilliseconds);
}
return cachedValue;
}
@ -92,9 +92,8 @@ namespace Debugger.AddIn.TreeModel @@ -92,9 +92,8 @@ namespace Debugger.AddIn.TreeModel
}
}
/// <summary>
/// Get the value of the node and update the UI text fields.
/// </summary>
/// <summary> Get the value of the node and update the UI text fields. </summary>
/// <remarks> This should be only called once so the Value is not cached. </remarks>
void GetValueAndUpdateUI()
{
try {
@ -175,7 +174,6 @@ namespace Debugger.AddIn.TreeModel @@ -175,7 +174,6 @@ namespace Debugger.AddIn.TreeModel
this.Type = string.Empty;
this.GetChildren = null;
#warning this.VisualizerCommands = null;
return;
}
}
@ -242,13 +240,6 @@ namespace Debugger.AddIn.TreeModel @@ -242,13 +240,6 @@ namespace Debugger.AddIn.TreeModel
return WindowsDebugger.CurrentStackFrame;
}
public static TreeNode GetTooltipFor(string text, Value value)
{
if (value == null)
throw new ArgumentNullException("value");
return new ValueNode(ClassBrowserIconService.LocalVariable, text, () => value);
}
public static IEnumerable<TreeNode> GetLocalVariables()
{
var stackFrame = GetCurrentStackFrame();
@ -361,15 +352,13 @@ namespace Debugger.AddIn.TreeModel @@ -361,15 +352,13 @@ namespace Debugger.AddIn.TreeModel
}
}
/// <remarks> 'getValue' really should return cached value, because we do Eval to create indices. </remarks>
static IEnumerable<TreeNode> GetIListChildren(Func<Value> getValue)
{
Value list;
IProperty itemProp;
int count = 0;
try {
// TODO: We want new list on reeval
// We need the list to survive generation of index via Eval
list = getValue().GetPermanentReference(WindowsDebugger.EvalThread);
Value list = getValue();
IType iListType = list.Type.GetAllBaseTypeDefinitions().Where(t => t.FullName == typeof(IList).FullName).FirstOrDefault();
itemProp = iListType.GetProperties(p => p.Name == "Item").Single();
// Do not get string representation since it can be printed in hex
@ -380,7 +369,7 @@ namespace Debugger.AddIn.TreeModel @@ -380,7 +369,7 @@ namespace Debugger.AddIn.TreeModel
if (count == 0) {
return new [] { new TreeNode("(empty)", null) };
} else {
return Enumerable.Range(0, count).Select(i => new ValueNode(ClassBrowserIconService.Field, "[" + i + "]", () => list.GetPropertyValue(WindowsDebugger.EvalThread, itemProp, Eval.CreateValue(WindowsDebugger.EvalThread, i))));
return Enumerable.Range(0, count).Select(i => new ValueNode(ClassBrowserIconService.Field, "[" + i + "]", () => getValue().GetPropertyValue(WindowsDebugger.EvalThread, itemProp, Eval.CreateValue(WindowsDebugger.EvalThread, i))));
}
}

4
src/AddIns/Debugger/Debugger.Core/StackFrame.cs

@ -371,7 +371,9 @@ namespace Debugger @@ -371,7 +371,9 @@ namespace Debugger
public Value GetLocalVariableValue(string name)
{
var loc = GetLocalVariables(this.IP).Where(v => v.Name == name).FirstOrDefault();
return loc != null ? loc.GetValue(this) : null;
if (loc == null)
throw new GetValueException("Local variable \"{0}\" not found", name);
return loc.GetValue(this);
}
/// <summary> Gets value indicating whether this method should be stepped over according to current options </summary>

Loading…
Cancel
Save