From 0e1ab4a415f19f223a6db075b1ecb51e927a2ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Tue, 15 Nov 2005 13:01:07 +0000 Subject: [PATCH] Debugger SubVariables property moved from Value to Variable. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@754 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Src/Pads/LocalVarPad.cs | 13 ++--- .../Src/Pads/TreeListViewDebuggerItem.cs | 58 ++++++++----------- .../Project/Src/Threads/Exception.cs | 2 +- .../Project/Src/Threads/Function.cs | 6 +- .../Project/Src/Threads/Thread.cs | 4 +- .../Project/Src/Variables/ArrayValue.cs | 42 +++++++------- .../Project/Src/Variables/ObjectValue.cs | 55 +++++++++--------- .../Project/Src/Variables/Value.cs | 33 ++++++----- .../Project/Src/Variables/Variable.cs | 23 ++++++++ .../Src/Variables/VariableCollection.cs | 38 ++++++------ 10 files changed, 143 insertions(+), 131 deletions(-) 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); }