Browse Source

Lazy getting refactored. Started lazy getting of properties

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@835 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 20 years ago
parent
commit
7318cbb775
  1. 4
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs
  2. 26
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs
  3. 70
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PropertyVariable.cs
  4. 62
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs
  5. 12
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs

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

@ -499,7 +499,9 @@ namespace Debugger @@ -499,7 +499,9 @@ namespace Debugger
if (debugger.PausedReason != PausedReason.AllEvalsComplete) {
debugger.AddEval(eval);
}
yield return new PropertyVariable(eval, method.Name.Remove(0, 4));
yield return new PropertyVariable(debugger,
method.Name.Remove(0, 4),
delegate {return eval;});
}
}
}

26
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs

@ -27,7 +27,7 @@ namespace Debugger @@ -27,7 +27,7 @@ namespace Debugger
ICorDebugValue[] args;
bool evaluating = false;
bool completed = false;
bool evaluated = false;
bool successful = false;
Value result;
@ -43,9 +43,9 @@ namespace Debugger @@ -43,9 +43,9 @@ namespace Debugger
/// <summary>
/// True if the evaluation has been completed.
/// </summary>
public bool Completed {
public bool Evaluated {
get {
return completed;
return evaluated;
}
}
@ -74,13 +74,17 @@ namespace Debugger @@ -74,13 +74,17 @@ namespace Debugger
}
/// <summary>
/// The result of the evaluation if the evaluation is complete and has returned a value. Null otherwise.
/// The result of the evaluation. Always non-null, but it may be UnavailableValue.
/// </summary>
public Value Result {
get {
if (completed) {
if (successful) {
return result;
if (Evaluated) {
if (Successful) {
if (result != null) {
return result;
} else {
return new UnavailableValue(debugger, "No return value");
}
} else {
ObjectValue exception = (ObjectValue)result;
while (exception.Type != "System.Exception") {
@ -89,7 +93,11 @@ namespace Debugger @@ -89,7 +93,11 @@ namespace Debugger
return new UnavailableValue(debugger, result.Type + ": " + exception["_message"].Value.AsString);
}
} else {
return null;
if (Evaluating) {
return new UnavailableValue(debugger, "Evaluating...");
} else {
return new UnavailableValue(debugger, "Evaluation pending");
}
}
}
}
@ -134,7 +142,7 @@ namespace Debugger @@ -134,7 +142,7 @@ namespace Debugger
protected internal virtual void OnEvalComplete(EvalEventArgs e)
{
evaluating = false;
completed = true;
evaluated = true;
ICorDebugValue corValue;
corEval.GetResult(out corValue);

70
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PropertyVariable.cs

@ -8,72 +8,40 @@ @@ -8,72 +8,40 @@
using System;
using Debugger.Interop.CorDebug;
namespace Debugger
{
public class PropertyVariable: Variable
/// <summary>
/// Delegate that is used to get eval. This delegate may be called at any time and should never return null.
/// </summary>
public delegate Eval EvalCreator();
public class PropertyVariable: Variable
{
Eval eval;
EvalCreator evalCreator;
Eval cachedEval;
public event EventHandler<DebuggerEventArgs> ValueEvaluated;
internal PropertyVariable(Eval eval, string name):base(new UnavailableValue(eval.Debugger), name)
internal PropertyVariable(NDebugger debugger, string name, EvalCreator evalCreator):base(debugger, name, null)
{
this.Eval = eval;
this.evalCreator = evalCreator;
this.valueGetter = delegate{return Eval.Result;};
}
public bool IsEvaluated {
get {
return eval.Completed;
}
}
protected override Value GetValue()
{
if (IsEvaluated) {
if (eval.Result != null) {
return eval.Result;
} else {
return new UnavailableValue(debugger, "No return value");
}
} else {
if (eval.Evaluating) {
return new UnavailableValue(debugger, "Evaluating...");
} else {
return new UnavailableValue(debugger, "Evaluation pending");
}
return Eval.Evaluated;
}
}
public Eval Eval {
get {
return eval;
}
set {
if (debugger.PausedReason != PausedReason.AllEvalsComplete) {
eval = value;
eval.EvalStarted += EvalStarted;
eval.EvalComplete += EvalComplete;
OnValueChanged();
if (cachedEval == null || cachedEval.Result.IsExpired) {
cachedEval = evalCreator();
if (cachedEval == null) throw new DebuggerException("EvalGetter returned null");
cachedEval.EvalStarted += delegate { OnValueChanged(); };
cachedEval.EvalComplete += delegate { OnValueChanged(); };
}
}
}
void EvalStarted(object sender, EvalEventArgs args)
{
OnValueChanged();
}
void EvalComplete(object sender, EvalEventArgs args)
{
OnValueEvaluated();
OnValueChanged();
}
protected void OnValueEvaluated()
{
if (ValueEvaluated != null) {
ValueEvaluated(this, new DebuggerEventArgs(debugger));
return cachedEval;
}
}
}

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

@ -11,6 +11,9 @@ using Debugger.Interop.CorDebug; @@ -11,6 +11,9 @@ using Debugger.Interop.CorDebug;
namespace Debugger
{
/// <summary>
/// Delegate that is used to get value. This delegate may be called at any time and should never return null.
/// </summary>
public delegate Value ValueGetter();
public class Variable: RemotingObjectBase
@ -18,10 +21,10 @@ namespace Debugger @@ -18,10 +21,10 @@ namespace Debugger
protected NDebugger debugger;
string name;
Value val;
VariableCollection subVariables;
event ValueGetter updating;
protected ValueGetter valueGetter;
Value cachedValue;
public event EventHandler<VariableEventArgs> ValueChanged;
public event EventHandler<VariableCollectionEventArgs> ValueRemovedFromCollection;
@ -39,33 +42,20 @@ namespace Debugger @@ -39,33 +42,20 @@ namespace Debugger
}
/// <summary>
/// Gets value of variable, which is safe to use.
/// Gets value of variable which is safe to use (it is not null and it is not expired)
/// </summary>
public Value Value {
get {
Value v = GetValue();
if (v == null) {
return new UnavailableValue(debugger);
if (cachedValue == null || cachedValue.IsExpired) {
cachedValue = valueGetter();
if (cachedValue == null) throw new DebuggerException("ValueGetter returned null");
cachedValue.ValueChanged += delegate { OnValueChanged(); };
}
if (v.IsExpired) {
if (cachedValue.IsExpired) {
return new UnavailableValue(debugger, "The value has expired");
} else {
return v;
}
return cachedValue;
}
internal set {
val = value;
val.ValueChanged += delegate { OnValueChanged(); };
OnValueChanged();
}
}
protected virtual Value GetValue()
{
if ((val == null || val.IsExpired) && updating != null) {
val = updating();
}
return val;
}
/// <summary>
@ -81,7 +71,7 @@ namespace Debugger @@ -81,7 +71,7 @@ namespace Debugger
public bool MayHaveSubVariables {
get {
return val.MayHaveSubVariables;
return Value.MayHaveSubVariables;
}
}
@ -92,42 +82,34 @@ namespace Debugger @@ -92,42 +82,34 @@ namespace Debugger
}
}
void OnSubVariablesUpdating(object sender, VariableCollectionEventArgs e)
{
subVariables.UpdateTo(Value.GetSubVariables(delegate{return this.Value;}));
}
protected internal virtual void OnValueRemovedFromCollection(VariableCollectionEventArgs e) {
if (ValueRemovedFromCollection != null) {
ValueRemovedFromCollection(this, e);
}
}
public Variable(NDebugger debugger, ICorDebugValue corValue, string name):this(debugger, Value.CreateValue(debugger, corValue), name, null)
public Variable(NDebugger debugger, ICorDebugValue corValue, string name):this(Value.CreateValue(debugger, corValue), name)
{
}
public Variable(NDebugger debugger, string name, ValueGetter updating):this(debugger, null, name, updating)
public Variable(Value val, string name):this(val.Debugger, name, delegate {return val;})
{
}
public Variable(Value val, string name):this(val.Debugger, val, name, null)
{
}
Variable(NDebugger debugger, Value val, string name, ValueGetter updating)
public Variable(NDebugger debugger, string name, ValueGetter valueGetter)
{
this.debugger = debugger;
if (val != null) {
this.Value = val;
}
this.name = name;
this.updating = updating;
this.valueGetter = valueGetter;
this.subVariables = new VariableCollection(debugger);
this.subVariables.Updating += OnSubVariablesUpdating;
}
void OnSubVariablesUpdating(object sender, VariableCollectionEventArgs e)
{
subVariables.UpdateTo(Value.GetSubVariables(delegate{return this.Value;}));
}
}
}

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

@ -157,18 +157,8 @@ namespace Debugger @@ -157,18 +157,8 @@ namespace Debugger
foreach(Variable newVariable in newVariables) {
if (this.Contains(newVariable.Name)) {
Variable oldVariable = this[newVariable.Name];
// Update existing variable
/*if (oldVariable.Value is ObjectValue && newVariable.Value is ObjectValue && debugger.PausedReason == PausedReason.AllEvalsComplete) {
((ObjectValue)newVariable.Value).toString = ((ObjectValue)oldVariable.Value).toString;
}
if (oldVariable is PropertyVariable) {
((PropertyVariable)oldVariable).Eval = ((PropertyVariable)newVariable).Eval;
} else {
oldVariable.Value = newVariable.Value;
}*/
// Keep the variable in the list
toBeRemoved.Remove(oldVariable);
toBeRemoved.Remove(this[newVariable.Name]);
} else {
// Add new variable
this.Add(newVariable);

Loading…
Cancel
Save