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 @@ -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 @@ -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) {

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

@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -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 @@ -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 @@ -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 @@ -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, "<Base class>");
Items.Add(new TreeListViewDebuggerItem(baseClassVar));
}
}
}
}

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

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

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

@ -364,7 +364,7 @@ namespace Debugger @@ -364,7 +364,7 @@ namespace Debugger
public VariableCollection GetVariables()
{
return VariableCollection.Merge(
GetContaingClassVariables(),
GetContaingClassVariables(),
GetArgumentVariables(),
GetLocalVariables()
//GetPropertyVariables()
@ -376,7 +376,9 @@ namespace Debugger @@ -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;
}
}

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

@ -109,7 +109,7 @@ namespace Debugger @@ -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 @@ -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;

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

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
// </file>
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Runtime.InteropServices;
@ -110,29 +111,26 @@ namespace Debugger @@ -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<Variable> 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;
}
}
}

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

@ -7,6 +7,7 @@ @@ -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 @@ -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<Variable> 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 {

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

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
// </file>
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Debugger.Interop.CorDebug;
@ -17,7 +18,6 @@ namespace Debugger @@ -17,7 +18,6 @@ namespace Debugger
protected NDebugger debugger;
protected ICorDebugValue corValue;
VariableCollection subVariables;
public NDebugger Debugger {
get {
@ -31,40 +31,41 @@ namespace Debugger @@ -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<Variable> 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;

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

@ -15,6 +15,7 @@ namespace Debugger @@ -15,6 +15,7 @@ namespace Debugger
string name;
Value val;
VariableCollection subVariables;
public event EventHandler<VariableEventArgs> ValueChanged;
@ -40,6 +41,17 @@ namespace Debugger @@ -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()
{
if (ValueChanged != null) {
@ -47,11 +59,22 @@ namespace Debugger @@ -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;
}
}
}

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

@ -101,7 +101,9 @@ namespace Debugger @@ -101,7 +101,9 @@ namespace Debugger
/// </summary>
internal void Clear()
{
InnerList.Clear();
while(this.Count > 0) {
this.Remove(this[0]);
}
Updating = null;
}
@ -117,7 +119,7 @@ namespace Debugger @@ -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 @@ -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<Variable>)mergedCollection.InnerList.ToArray(typeof(Variable)));
}
public void UpdateTo(IEnumerable<Variable> 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<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) {
this.Remove(variable);
}

Loading…
Cancel
Save