Browse Source

Debugger SubVariables property moved from Value to Variable.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@754 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 20 years ago
parent
commit
0e1ab4a415
  1. 13
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs
  2. 58
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/TreeListViewDebuggerItem.cs
  3. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs
  4. 6
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs
  5. 4
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs
  6. 42
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs
  7. 55
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs
  8. 33
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs
  9. 23
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs
  10. 38
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs

13
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs

@ -90,7 +90,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
{ {
debuggerCore = debugger.DebuggerCore; debuggerCore = debugger.DebuggerCore;
debuggerCore.LocalVariables.VariableAdded += OnLocalVariableAdded; debuggerCore.LocalVariables.VariableAdded += delegate(object sender, VariableEventArgs e) {
AddVariable(e.Variable);
};
localVarList.BeginUpdate(); localVarList.BeginUpdate();
foreach(Variable v in debuggerCore.LocalVariables) { foreach(Variable v in debuggerCore.LocalVariables) {
@ -99,15 +101,10 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
localVarList.EndUpdate(); localVarList.EndUpdate();
} }
void OnLocalVariableAdded(object sender, VariableEventArgs e)
{
if (e.Variable.Name.StartsWith("CS$")) return;
AddVariable(e.Variable);
}
void AddVariable(Variable variableToAdd) void AddVariable(Variable variableToAdd)
{ {
if (variableToAdd.Name.StartsWith("CS$")) return;
TreeListViewDebuggerItem newItem = new TreeListViewDebuggerItem(variableToAdd); TreeListViewDebuggerItem newItem = new TreeListViewDebuggerItem(variableToAdd);
debuggerCore.LocalVariables.VariableRemoved += delegate(object sender, VariableEventArgs removedArgs) { debuggerCore.LocalVariables.VariableRemoved += delegate(object sender, VariableEventArgs removedArgs) {

58
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/TreeListViewDebuggerItem.cs

@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
public class TreeListViewDebuggerItem: TreeListViewItem public class TreeListViewDebuggerItem: TreeListViewItem
{ {
Variable variable; Variable variable;
bool created; bool baseClassItemAdded;
public Variable Variable { public Variable Variable {
get { get {
@ -43,20 +43,20 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
public TreeListViewDebuggerItem(Variable variable) public TreeListViewDebuggerItem(Variable variable)
{ {
this.variable = variable; this.variable = variable;
variable.ValueChanged += delegate { Update(); };
variable.ValueChanged += delegate {
Highlight = (Variable.Value.AsString != SubItems[1].Text);
Update();
};
SubItems.Add(""); SubItems.Add("");
SubItems.Add(""); SubItems.Add("");
Update(); Update();
created = true; // Used to prevent highlighting of new variables
} }
public void Update() public void Update()
{ {
Highlight = (Variable.Value.AsString != SubItems[1].Text && created);
this.SubItems[0].Text = Variable.Name; this.SubItems[0].Text = Variable.Name;
this.SubItems[1].Text = Variable.Value.AsString; this.SubItems[1].Text = Variable.Value.AsString;
this.SubItems[2].Text = Variable.Value.Type; this.SubItems[2].Text = Variable.Value.Type;
@ -69,6 +69,11 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
this.ImageIndex = 1; // Field this.ImageIndex = 1; // Field
} }
if (!baseClassItemAdded) {
TryToAddBaseClassItem();
baseClassItemAdded = true;
}
// if (IsExpanded) { // if (IsExpanded) {
// UpdateSubVariables(); // UpdateSubVariables();
// } else { // } else {
@ -80,35 +85,22 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
public void BeforeExpand() public void BeforeExpand()
{ {
// Do not sort names of array items
if (variable.Value is ArrayValue) {
this.Items.SortOrder = SortOrder.None;
} else {
this.Items.SortOrder = SortOrder.Ascending;
}
} }
// public GetBaseClass() void TryToAddBaseClassItem()
// { {
// ObjectValue objectValue = uncastedVariable.Value as ObjectValue; ObjectValue objectValue = variable.Value as ObjectValue;
// if (objectValue != null && objectValue.HasBaseClass && objectValue.BaseClass.Type != "System.Object") { if (objectValue != null && objectValue.HasBaseClass && objectValue.BaseClass.Type != "System.Object") {
// this.Variable = VariableFactory.CreateVariable(objectValue.BaseClass, uncastedVariable.Name); Variable baseClassVar = VariableFactory.CreateVariable(objectValue.BaseClass, "<Base class>");
// } Items.Add(new TreeListViewDebuggerItem(baseClassVar));
// } }
// }
// protected void UpdateSubVariables() {
// if (!baseClassItemAdded) {
// VariableListItem baseClassItem = new BaseClassItem(variable);
// if (baseClassItem.IsValid) {
// this.Items.Add(baseClassItem);
// }
// baseClassItemAdded = true;
// }
//
// // Do not sort names of array items
// if (Variable.Value is ArrayValue) {
// this.Items.SortOrder = SortOrder.None;
// } else {
// this.Items.SortOrder = SortOrder.Ascending;
// }
//
// LocalVarPad.UpdateVariables(this.Items, Variable.Value.SubVariables);
// }
} }
} }

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs

@ -52,7 +52,7 @@ namespace Debugger
} }
runtimeValueException = runtimeValueException.BaseClass; runtimeValueException = runtimeValueException.BaseClass;
} }
message = runtimeValueException.SubVariables["_message"].Value.AsString; message = runtimeValueException["_message"].Value.AsString;
} }
if (thread.LastFunctionWithLoadedSymbols != null) { if (thread.LastFunctionWithLoadedSymbols != null) {

6
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs

@ -364,7 +364,7 @@ namespace Debugger
public VariableCollection GetVariables() public VariableCollection GetVariables()
{ {
return VariableCollection.Merge( return VariableCollection.Merge(
GetContaingClassVariables(), GetContaingClassVariables(),
GetArgumentVariables(), GetArgumentVariables(),
GetLocalVariables() GetLocalVariables()
//GetPropertyVariables() //GetPropertyVariables()
@ -376,7 +376,9 @@ namespace Debugger
if (IsStatic) { if (IsStatic) {
return VariableCollection.Empty; return VariableCollection.Empty;
} else { } else {
return ThisValue.SubVariables; VariableCollection collection = new VariableCollection(debugger);
collection.UpdateTo(ThisValue.SubVariables);
return collection;
} }
} }

4
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs

@ -109,7 +109,7 @@ namespace Debugger
Value runTimeValue = RuntimeValue; Value runTimeValue = RuntimeValue;
if (runTimeValue is NullValue) return ThreadPriority.Normal; if (runTimeValue is NullValue) return ThreadPriority.Normal;
lastPriority = (ThreadPriority)(int)(runTimeValue.SubVariables["m_Priority"].Value as PrimitiveValue).Primitive; lastPriority = (ThreadPriority)(int)(runTimeValue["m_Priority"].Value as PrimitiveValue).Primitive;
return lastPriority; return lastPriority;
} }
} }
@ -131,7 +131,7 @@ namespace Debugger
if (process.IsRunning) return lastName; if (process.IsRunning) return lastName;
Value runtimeVar = RuntimeValue; Value runtimeVar = RuntimeValue;
if (runtimeVar is NullValue) return lastName; if (runtimeVar is NullValue) return lastName;
Value runtimeName = runtimeVar.SubVariables["m_Name"].Value; Value runtimeName = runtimeVar["m_Name"].Value;
if (runtimeName is NullValue) return string.Empty; if (runtimeName is NullValue) return string.Empty;
lastName = runtimeName.AsString.ToString(); lastName = runtimeName.AsString.ToString();
return lastName; return lastName;

42
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs

@ -6,6 +6,7 @@
// </file> // </file>
using System; using System;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -110,29 +111,26 @@ namespace Debugger
return true; return true;
} }
} }
protected override VariableCollection GetSubVariables() public override IEnumerable<Variable> SubVariables {
{ get {
VariableCollection subVariables = new VariableCollection(debugger); uint[] indices = new uint[rank];
uint[] indices = new uint[rank]; for(;;) // Go thought all combinations
{
for(;;) // Go thought all combinations for (uint i = rank - 1; i >= 1; i--)
{ if (indices[i] >= dimensions[i])
for (uint i = rank - 1; i >= 1; i--) {
if (indices[i] >= dimensions[i]) indices[i] = 0;
{ indices[i-1]++;
indices[i] = 0; }
indices[i-1]++; if (indices[0] >= dimensions[0]) break; // We are done
}
if (indices[0] >= dimensions[0]) break; // We are done yield return this[indices];
subVariables.Add(this[indices]); indices[rank - 1]++;
}
indices[rank - 1]++;
} }
return subVariables;
} }
} }
} }

55
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs

@ -7,6 +7,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -68,39 +69,37 @@ namespace Debugger
} }
} }
protected override unsafe VariableCollection GetSubVariables() public override IEnumerable<Variable> SubVariables {
{ get {
VariableCollection subVariables = new VariableCollection(debugger); // Current frame is necessary to resolve context specific static values (eg. ThreadStatic)
ICorDebugFrame curFrame;
// Current frame is necessary to resolve context specific static values (eg. ThreadStatic) if (debugger.CurrentThread == null || debugger.CurrentThread.LastFunction == null || debugger.CurrentThread.LastFunction.CorILFrame == null) {
ICorDebugFrame curFrame; curFrame = null;
if (debugger.CurrentThread == null || debugger.CurrentThread.LastFunction == null || debugger.CurrentThread.LastFunction.CorILFrame == null) { } else {
curFrame = null; curFrame = debugger.CurrentThread.LastFunction.CorILFrame;
} else { }
curFrame = debugger.CurrentThread.LastFunction.CorILFrame;
}
foreach(FieldProps field in metaData.EnumFields(classProps.Token)) {
try { foreach(FieldProps field in metaData.EnumFields(classProps.Token)) {
ICorDebugValue fieldValue; Variable var;
if (field.IsStatic) { try {
if (field.IsLiteral) continue; // Try next field ICorDebugValue fieldValue;
if (field.IsStatic) {
corClass.GetStaticFieldValue(field.Token, curFrame, out fieldValue); if (field.IsLiteral) continue; // Try next field
} else {
if (corValue == null) continue; // Try next field corClass.GetStaticFieldValue(field.Token, curFrame, out fieldValue);
} else {
if (corValue == null) continue; // Try next field
((ICorDebugObjectValue)corValue).GetFieldValue(corClass, field.Token, out fieldValue);
}
((ICorDebugObjectValue)corValue).GetFieldValue(corClass, field.Token, out fieldValue); var = VariableFactory.CreateVariable(debugger, fieldValue, field.Name);
} catch {
var = VariableFactory.CreateVariable(new UnavailableValue(debugger), field.Name);
} }
yield return var;
subVariables.Add(VariableFactory.CreateVariable(debugger, fieldValue, field.Name));
} catch {
subVariables.Add(VariableFactory.CreateVariable(new UnavailableValue(debugger), field.Name));
} }
} }
return subVariables;
} }
public unsafe ObjectValue BaseClass { public unsafe ObjectValue BaseClass {

33
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs

@ -6,6 +6,7 @@
// </file> // </file>
using System; using System;
using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Debugger.Interop.CorDebug; using Debugger.Interop.CorDebug;
@ -17,7 +18,6 @@ namespace Debugger
protected NDebugger debugger; protected NDebugger debugger;
protected ICorDebugValue corValue; protected ICorDebugValue corValue;
VariableCollection subVariables;
public NDebugger Debugger { public NDebugger Debugger {
get { get {
@ -31,40 +31,41 @@ namespace Debugger
} }
} }
public abstract string AsString {
get;
}
internal CorElementType CorType { internal CorElementType CorType {
get { get {
return GetCorType(corValue); return GetCorType(corValue);
} }
} }
public abstract string AsString {
get;
}
public virtual string Type { public virtual string Type {
get{ get{
return CorTypeToString(CorType); return CorTypeToString(CorType);
} }
} }
public abstract bool MayHaveSubVariables { public abstract bool MayHaveSubVariables {
get; get;
} }
public VariableCollection SubVariables { public virtual IEnumerable<Variable> SubVariables {
get { get {
if (subVariables == null) { yield break;
subVariables = GetSubVariables();
}
return subVariables;
} }
} }
protected virtual VariableCollection GetSubVariables() public Variable this[string variableName] {
{ get {
return new VariableCollection(debugger); foreach(Variable v in SubVariables) {
if (v.Name == variableName) return v;
}
throw new DebuggerException("Subvariable " + variableName + " does not exist");
}
} }
internal Value(NDebugger debugger, ICorDebugValue corValue) internal Value(NDebugger debugger, ICorDebugValue corValue)
{ {
this.debugger = debugger; this.debugger = debugger;

23
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs

@ -15,6 +15,7 @@ namespace Debugger
string name; string name;
Value val; Value val;
VariableCollection subVariables;
public event EventHandler<VariableEventArgs> ValueChanged; public event EventHandler<VariableEventArgs> ValueChanged;
@ -40,6 +41,17 @@ namespace Debugger
} }
} }
/// <summary>
/// Return up-to-date collection of subvariables.
/// This collection is lazy - you need to call its method Update if you want to use it later
/// </summary>
public VariableCollection SubVariables {
get {
subVariables.Update();
return subVariables;
}
}
protected virtual void OnValueChanged() protected virtual void OnValueChanged()
{ {
if (ValueChanged != null) { if (ValueChanged != null) {
@ -47,11 +59,22 @@ namespace Debugger
} }
} }
void OnSubVariablesUpdating(object sender, VariableCollectionEventArgs e)
{
VariableCollection newVariables = new VariableCollection(debugger);
foreach(Variable v in Value.SubVariables) {
newVariables.Add(v);
}
subVariables.UpdateTo(newVariables);
}
public Variable(NDebugger debugger, Value val, string name) public Variable(NDebugger debugger, Value val, string name)
{ {
this.debugger = debugger; this.debugger = debugger;
this.val = val; this.val = val;
this.name = name; this.name = name;
this.subVariables = new VariableCollection(debugger);
this.subVariables.Updating += OnSubVariablesUpdating;
} }
} }
} }

38
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs

@ -101,7 +101,9 @@ namespace Debugger
/// </summary> /// </summary>
internal void Clear() internal void Clear()
{ {
InnerList.Clear(); while(this.Count > 0) {
this.Remove(this[0]);
}
Updating = null; Updating = null;
} }
@ -117,7 +119,7 @@ namespace Debugger
if (index != -1) { if (index != -1) {
string rootVariable = variableName.Substring(0, index); string rootVariable = variableName.Substring(0, index);
string subVariable = variableName.Substring(index + 1); string subVariable = variableName.Substring(index + 1);
return this[rootVariable].Value.SubVariables[subVariable]; return this[rootVariable].Value[subVariable];
} else { } else {
foreach (Variable v in InnerList) { foreach (Variable v in InnerList) {
if (v.Name == variableName) { if (v.Name == variableName) {
@ -145,27 +147,25 @@ namespace Debugger
mergedCollection.Update(); mergedCollection.Update();
// Update existing variables UpdateTo((IEnumerable<Variable>)mergedCollection.InnerList.ToArray(typeof(Variable)));
foreach(Variable variable in mergedCollection) { }
if (this.Contains(variable.Name)) {
this[variable.Name].Value = variable.Value; public void UpdateTo(IEnumerable<Variable> newVariables)
} {
} ArrayList toBeRemoved = (ArrayList)this.InnerList.Clone();
// Add new variables foreach(Variable newVariable in newVariables) {
foreach(Variable variable in mergedCollection) { if (this.Contains(newVariable.Name)) {
if (!this.Contains(variable.Name)) { // Update existing variable
this.Add(variable); this[newVariable.Name].Value = newVariable.Value;
// Keep the variable in the list
toBeRemoved.Remove(this[newVariable.Name]);
} else {
// Add new variable
this.Add(newVariable);
} }
} }
// Remove variables that are not in merged collection
List<Variable> toBeRemoved = new List<Variable>(); // We can NOT modify collection which are using!!!
foreach(Variable variable in this) {
if (!mergedCollection.Contains(variable.Name)) {
toBeRemoved.Add(variable);
}
}
foreach(Variable variable in toBeRemoved) { foreach(Variable variable in toBeRemoved) {
this.Remove(variable); this.Remove(variable);
} }

Loading…
Cancel
Save