diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs
index a34610ab10..d78262b4de 100644
--- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs
@@ -90,7 +90,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
{
debuggerCore = debugger.DebuggerCore;
- debuggerCore.LocalVariables.VariableAdded += OnLocalVariableAdded;
+ debuggerCore.LocalVariables.VariableAdded += delegate(object sender, VariableEventArgs e) {
+ AddVariable(e.Variable);
+ };
localVarList.BeginUpdate();
foreach(Variable v in debuggerCore.LocalVariables) {
@@ -99,15 +101,10 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
localVarList.EndUpdate();
}
- void OnLocalVariableAdded(object sender, VariableEventArgs e)
- {
- if (e.Variable.Name.StartsWith("CS$")) return;
-
- AddVariable(e.Variable);
- }
-
void AddVariable(Variable variableToAdd)
{
+ if (variableToAdd.Name.StartsWith("CS$")) return;
+
TreeListViewDebuggerItem newItem = new TreeListViewDebuggerItem(variableToAdd);
debuggerCore.LocalVariables.VariableRemoved += delegate(object sender, VariableEventArgs removedArgs) {
diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/TreeListViewDebuggerItem.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/TreeListViewDebuggerItem.cs
index 32394d7e4e..8c659bdbc4 100644
--- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/TreeListViewDebuggerItem.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/TreeListViewDebuggerItem.cs
@@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
public class TreeListViewDebuggerItem: TreeListViewItem
{
Variable variable;
- bool created;
+ bool baseClassItemAdded;
public Variable Variable {
get {
@@ -43,20 +43,20 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
public TreeListViewDebuggerItem(Variable variable)
{
this.variable = variable;
- variable.ValueChanged += delegate { Update(); };
+
+ variable.ValueChanged += delegate {
+ Highlight = (Variable.Value.AsString != SubItems[1].Text);
+ Update();
+ };
SubItems.Add("");
SubItems.Add("");
Update();
-
- created = true; // Used to prevent highlighting of new variables
}
public void Update()
{
- Highlight = (Variable.Value.AsString != SubItems[1].Text && created);
-
this.SubItems[0].Text = Variable.Name;
this.SubItems[1].Text = Variable.Value.AsString;
this.SubItems[2].Text = Variable.Value.Type;
@@ -69,6 +69,11 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
this.ImageIndex = 1; // Field
}
+ if (!baseClassItemAdded) {
+ TryToAddBaseClassItem();
+ baseClassItemAdded = true;
+ }
+
// if (IsExpanded) {
// UpdateSubVariables();
// } else {
@@ -80,35 +85,22 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
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()
-// {
-// ObjectValue objectValue = uncastedVariable.Value as ObjectValue;
-// if (objectValue != null && objectValue.HasBaseClass && objectValue.BaseClass.Type != "System.Object") {
-// this.Variable = VariableFactory.CreateVariable(objectValue.BaseClass, uncastedVariable.Name);
-// }
-// }
-//
-// 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);
-// }
+ void TryToAddBaseClassItem()
+ {
+ ObjectValue objectValue = variable.Value as ObjectValue;
+ if (objectValue != null && objectValue.HasBaseClass && objectValue.BaseClass.Type != "System.Object") {
+ Variable baseClassVar = VariableFactory.CreateVariable(objectValue.BaseClass, "");
+ Items.Add(new TreeListViewDebuggerItem(baseClassVar));
+ }
+ }
}
}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs
index abaa7dafa8..7786ba013e 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs
@@ -52,7 +52,7 @@ namespace Debugger
}
runtimeValueException = runtimeValueException.BaseClass;
}
- message = runtimeValueException.SubVariables["_message"].Value.AsString;
+ message = runtimeValueException["_message"].Value.AsString;
}
if (thread.LastFunctionWithLoadedSymbols != null) {
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs
index 6127e16e9b..4265e3b931 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs
@@ -364,7 +364,7 @@ namespace Debugger
public VariableCollection GetVariables()
{
return VariableCollection.Merge(
- GetContaingClassVariables(),
+ GetContaingClassVariables(),
GetArgumentVariables(),
GetLocalVariables()
//GetPropertyVariables()
@@ -376,7 +376,9 @@ namespace Debugger
if (IsStatic) {
return VariableCollection.Empty;
} else {
- return ThisValue.SubVariables;
+ VariableCollection collection = new VariableCollection(debugger);
+ collection.UpdateTo(ThisValue.SubVariables);
+ return collection;
}
}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs
index 0bb2e7384c..6658212b2d 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs
@@ -109,7 +109,7 @@ namespace Debugger
Value runTimeValue = RuntimeValue;
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;
}
}
@@ -131,7 +131,7 @@ namespace Debugger
if (process.IsRunning) return lastName;
Value runtimeVar = RuntimeValue;
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;
lastName = runtimeName.AsString.ToString();
return lastName;
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs
index ed409d7a28..bdbce77fb0 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs
@@ -6,6 +6,7 @@
//
using System;
+using System.Collections.Generic;
using System.Collections.Specialized;
using System.Runtime.InteropServices;
@@ -110,29 +111,26 @@ namespace Debugger
return true;
}
}
-
- protected override VariableCollection GetSubVariables()
- {
- VariableCollection subVariables = new VariableCollection(debugger);
-
- uint[] indices = new uint[rank];
-
- for(;;) // Go thought all combinations
- {
- for (uint i = rank - 1; i >= 1; i--)
- if (indices[i] >= dimensions[i])
- {
- indices[i] = 0;
- indices[i-1]++;
- }
- if (indices[0] >= dimensions[0]) break; // We are done
-
- subVariables.Add(this[indices]);
-
- indices[rank - 1]++;
+
+ public override IEnumerable SubVariables {
+ get {
+ uint[] indices = new uint[rank];
+
+ for(;;) // Go thought all combinations
+ {
+ for (uint i = rank - 1; i >= 1; i--)
+ if (indices[i] >= dimensions[i])
+ {
+ indices[i] = 0;
+ indices[i-1]++;
+ }
+ if (indices[0] >= dimensions[0]) break; // We are done
+
+ yield return this[indices];
+
+ indices[rank - 1]++;
+ }
}
-
- return subVariables;
}
}
}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs
index 44f9e89985..e830898d74 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs
@@ -7,6 +7,7 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Collections.Specialized;
using System.Runtime.InteropServices;
@@ -68,39 +69,37 @@ namespace Debugger
}
}
- protected override unsafe VariableCollection GetSubVariables()
- {
- VariableCollection subVariables = new VariableCollection(debugger);
-
- // Current frame is necessary to resolve context specific static values (eg. ThreadStatic)
- ICorDebugFrame curFrame;
- if (debugger.CurrentThread == null || debugger.CurrentThread.LastFunction == null || debugger.CurrentThread.LastFunction.CorILFrame == null) {
- curFrame = null;
- } else {
- curFrame = debugger.CurrentThread.LastFunction.CorILFrame;
- }
-
- foreach(FieldProps field in metaData.EnumFields(classProps.Token)) {
+ public override IEnumerable SubVariables {
+ get {
+ // Current frame is necessary to resolve context specific static values (eg. ThreadStatic)
+ ICorDebugFrame curFrame;
+ if (debugger.CurrentThread == null || debugger.CurrentThread.LastFunction == null || debugger.CurrentThread.LastFunction.CorILFrame == null) {
+ curFrame = null;
+ } else {
+ curFrame = debugger.CurrentThread.LastFunction.CorILFrame;
+ }
- try {
- ICorDebugValue fieldValue;
- if (field.IsStatic) {
- if (field.IsLiteral) continue; // Try next field
-
- corClass.GetStaticFieldValue(field.Token, curFrame, out fieldValue);
- } else {
- if (corValue == null) continue; // Try next field
+ foreach(FieldProps field in metaData.EnumFields(classProps.Token)) {
+ Variable var;
+ try {
+ ICorDebugValue fieldValue;
+ if (field.IsStatic) {
+ if (field.IsLiteral) 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);
}
-
- subVariables.Add(VariableFactory.CreateVariable(debugger, fieldValue, field.Name));
- } catch {
- subVariables.Add(VariableFactory.CreateVariable(new UnavailableValue(debugger), field.Name));
+ yield return var;
}
}
-
- return subVariables;
}
public unsafe ObjectValue BaseClass {
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs
index ad90bc36d8..c45c3e4c08 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs
@@ -6,6 +6,7 @@
//
using System;
+using System.Collections.Generic;
using System.Runtime.InteropServices;
using Debugger.Interop.CorDebug;
@@ -17,7 +18,6 @@ namespace Debugger
protected NDebugger debugger;
protected ICorDebugValue corValue;
- VariableCollection subVariables;
public NDebugger Debugger {
get {
@@ -31,40 +31,41 @@ namespace Debugger
}
}
- public abstract string AsString {
- get;
- }
-
internal CorElementType CorType {
get {
return GetCorType(corValue);
}
}
+ public abstract string AsString {
+ get;
+ }
+
public virtual string Type {
get{
return CorTypeToString(CorType);
}
}
-
+
public abstract bool MayHaveSubVariables {
get;
}
-
- public VariableCollection SubVariables {
+
+ public virtual IEnumerable SubVariables {
get {
- if (subVariables == null) {
- subVariables = GetSubVariables();
- }
- return subVariables;
+ yield break;
}
}
- protected virtual VariableCollection GetSubVariables()
- {
- return new VariableCollection(debugger);
+ public Variable this[string variableName] {
+ get {
+ 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)
{
this.debugger = debugger;
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs
index faf011c6d3..f5d7b277fa 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs
@@ -15,6 +15,7 @@ namespace Debugger
string name;
Value val;
+ VariableCollection subVariables;
public event EventHandler ValueChanged;
@@ -40,6 +41,17 @@ namespace Debugger
}
}
+ ///
+ /// 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
+ ///
+ public VariableCollection SubVariables {
+ get {
+ subVariables.Update();
+ return subVariables;
+ }
+ }
+
protected virtual void OnValueChanged()
{
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)
{
this.debugger = debugger;
this.val = val;
this.name = name;
+ this.subVariables = new VariableCollection(debugger);
+ this.subVariables.Updating += OnSubVariablesUpdating;
}
}
}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs
index 60013b50e7..52dd96e22e 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs
@@ -101,7 +101,9 @@ namespace Debugger
///
internal void Clear()
{
- InnerList.Clear();
+ while(this.Count > 0) {
+ this.Remove(this[0]);
+ }
Updating = null;
}
@@ -117,7 +119,7 @@ namespace Debugger
if (index != -1) {
string rootVariable = variableName.Substring(0, index);
string subVariable = variableName.Substring(index + 1);
- return this[rootVariable].Value.SubVariables[subVariable];
+ return this[rootVariable].Value[subVariable];
} else {
foreach (Variable v in InnerList) {
if (v.Name == variableName) {
@@ -145,27 +147,25 @@ namespace Debugger
mergedCollection.Update();
- // Update existing variables
- foreach(Variable variable in mergedCollection) {
- if (this.Contains(variable.Name)) {
- this[variable.Name].Value = variable.Value;
- }
- }
+ UpdateTo((IEnumerable)mergedCollection.InnerList.ToArray(typeof(Variable)));
+ }
+
+ public void UpdateTo(IEnumerable newVariables)
+ {
+ ArrayList toBeRemoved = (ArrayList)this.InnerList.Clone();
- // Add new variables
- foreach(Variable variable in mergedCollection) {
- if (!this.Contains(variable.Name)) {
- this.Add(variable);
+ foreach(Variable newVariable in newVariables) {
+ if (this.Contains(newVariable.Name)) {
+ // Update existing 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 toBeRemoved = new List(); // 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) {
this.Remove(variable);
}