Browse Source

Support for variables captured by delegate

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4836 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 16 years ago
parent
commit
704a87db67
  1. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs
  2. 79
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/MethodInfo.cs
  3. 109
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/CompilerGeneratedClasses.cs

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs

@ -733,7 +733,7 @@ namespace Debugger.MetaData @@ -733,7 +733,7 @@ namespace Debugger.MetaData
public bool IsDisplayClass {
get {
return this.IsCompilerGenerated && this.Name.Contains("DisplayClass");
return this.Name.StartsWith("<>") && this.Name.Contains("__DisplayClass");
}
}

79
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/MethodInfo.cs

@ -427,7 +427,7 @@ namespace Debugger.MetaData @@ -427,7 +427,7 @@ namespace Debugger.MetaData
public List<LocalVariableInfo> LocalVariables {
get {
if (this.SymMethod != null) { // TODO: Is this needed?
return GetLocalVariablesInScope(this.SymMethod.RootScope);
return GetLocalVariables();
} else {
return new List<LocalVariableInfo>();
}
@ -446,25 +446,84 @@ namespace Debugger.MetaData @@ -446,25 +446,84 @@ namespace Debugger.MetaData
}
}
List<LocalVariableInfo> localVariables; // Cache
List<LocalVariableInfo> GetLocalVariables()
{
if (localVariables != null) return localVariables;
localVariables = GetLocalVariablesInScope(this.SymMethod.RootScope);
if (!this.IsStatic && this.DeclaringType.IsDisplayClass) {
// Get display class from self
localVariables.AddRange(GetLocalVariablesFromDisplayClass(
delegate(StackFrame context) {
return context.GetThisValue();
},
this.DeclaringType
));
// Get dispaly classes from fields
foreach(FieldInfo fieldInfo in this.DeclaringType.GetFields()) {
FieldInfo fieldInfoCopy = fieldInfo;
if (fieldInfo.Name.StartsWith("CS$")) {
localVariables.AddRange(GetLocalVariablesFromDisplayClass(
delegate(StackFrame context) {
return context.GetThisValue().GetFieldValue(fieldInfoCopy);
},
fieldInfo.Type
));
}
}
}
return localVariables;
}
List<LocalVariableInfo> GetLocalVariablesFromDisplayClass(ValueGetter getDisplayClass, DebugType displayClassType)
{
List<LocalVariableInfo> vars = new List<LocalVariableInfo>();
if (displayClassType.IsDisplayClass) {
foreach(FieldInfo fieldInfo in displayClassType.GetFields()) {
FieldInfo fieldInfoCopy = fieldInfo;
if (!fieldInfo.Name.StartsWith("CS$")) {
vars.Add(
new LocalVariableInfo(
fieldInfo.Name,
fieldInfo.Type,
delegate(StackFrame context) {
return getDisplayClass(context).GetFieldValue(fieldInfoCopy);
}
)
);
}
}
}
return vars;
}
List<LocalVariableInfo> GetLocalVariablesInScope(ISymUnmanagedScope symScope)
{
List<LocalVariableInfo> vars = new List<LocalVariableInfo>();
foreach (ISymUnmanagedVariable symVar in symScope.Locals) {
ISymUnmanagedVariable symVarCopy = symVar;
int start;
SignatureReader sigReader = new SignatureReader(symVar.Signature);
LocalVarSig.LocalVariable locVarSig = sigReader.ReadLocalVariable(sigReader.Blob, 0, out start);
DebugType type = DebugType.CreateFromSignature(this.Module, locVarSig.Type, this.DeclaringType);
DebugType locVarType = DebugType.CreateFromSignature(this.Module, locVarSig.Type, this.DeclaringType);
// Compiler generated?
// NB: Display class does not have the compiler-generated flag
if ((symVar.Attributes & 1) == 1 || symVar.Name.StartsWith("CS$")) {
if (type.IsDisplayClass) {
// Get display class from local variable
if (locVarType.IsDisplayClass) {
vars.AddRange(GetLocalVariablesFromDisplayClass(
delegate(StackFrame context) {
return GetLocalVariableValue(context, symVarCopy);
},
locVarType
));
}
} else {
ISymUnmanagedVariable symVarCopy = symVar;
LocalVariableInfo locVar = new LocalVariableInfo(
symVar.Name,
type,
locVarType,
delegate(StackFrame context) {
return GetLocalVariableValue(context, symVarCopy);
}
@ -491,13 +550,13 @@ namespace Debugger.MetaData @@ -491,13 +550,13 @@ namespace Debugger.MetaData
}
}
public delegate Value ValueGetter(StackFrame context);
public class LocalVariableInfo
{
public delegate Value LocalVariableValueGetter(StackFrame context);
string name;
DebugType type;
LocalVariableValueGetter getter;
ValueGetter getter;
public string Name {
get { return name; }
@ -507,7 +566,7 @@ namespace Debugger.MetaData @@ -507,7 +566,7 @@ namespace Debugger.MetaData
get { return type; }
}
public LocalVariableInfo(string name, DebugType type, LocalVariableValueGetter getter)
public LocalVariableInfo(string name, DebugType type, ValueGetter getter)
{
this.name = name;
this.type = type;

109
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/CompilerGeneratedClasses.cs

@ -16,10 +16,10 @@ namespace Debugger.Tests.TestPrograms @@ -16,10 +16,10 @@ namespace Debugger.Tests.TestPrograms
public static void Main()
{
new List<object>(MyEnum());
new List<object>(new CompilerGeneratedClasses().MyEnum());
}
static IEnumerable<object> MyEnum()
IEnumerable<object> MyEnum()
{
int stateFullVar = 101;
int stateFullVar_DelegRef = 102;
@ -46,9 +46,13 @@ namespace Debugger.Tests.TestPrograms @@ -46,9 +46,13 @@ namespace Debugger.Tests.TestPrograms
Console.WriteLine(delegVar_NestedDelegRef);
Console.WriteLine(stateFullVar_NestedDelegRef);
Console.WriteLine(stateLessVar_NestedDelegRef);
Console.WriteLine(this);
System.Diagnostics.Debugger.Break();
};
System.Diagnostics.Debugger.Break();
nestedDeleg(402);
};
deleg(401);
}
@ -71,7 +75,12 @@ namespace Debugger.Tests { @@ -71,7 +75,12 @@ namespace Debugger.Tests {
Select(v => new { v.Name, Value = v.GetValue(process.SelectedStackFrame) })
);
process.Continue();
ObjectDump("DelegateLocalVariables",
ObjectDump("OutterDelegateLocalVariables",
process.SelectedStackFrame.MethodInfo.LocalVariables.
Select(v => new { v.Name, Value = v.GetValue(process.SelectedStackFrame) })
);
process.Continue();
ObjectDump("InnterDelegateLocalVariables",
process.SelectedStackFrame.MethodInfo.LocalVariables.
Select(v => new { v.Name, Value = v.GetValue(process.SelectedStackFrame) })
);
@ -101,9 +110,19 @@ namespace Debugger.Tests { @@ -101,9 +110,19 @@ namespace Debugger.Tests {
Name="deleg"
Value="deleg = null" />
</Item>
<Item>
<AnonymousType
Name="stateLessVar_DelegRef"
Value="(()(CS$&lt;&gt;8__locals5)).stateLessVar_DelegRef = 202" />
</Item>
<Item>
<AnonymousType
Name="stateLessVar_NestedDelegRef"
Value="(()(CS$&lt;&gt;8__locals5)).stateLessVar_NestedDelegRef = 203" />
</Item>
</YieldLocalVariables>
<DebuggingPaused>Break CompilerGeneratedClasses.cs:51,6-51,42</DebuggingPaused>
<DelegateLocalVariables>
<DebuggingPaused>Break CompilerGeneratedClasses.cs:54,6-54,42</DebuggingPaused>
<OutterDelegateLocalVariables>
<Item>
<AnonymousType
Name="delegVar"
@ -114,7 +133,85 @@ namespace Debugger.Tests { @@ -114,7 +133,85 @@ namespace Debugger.Tests {
Name="nestedDeleg"
Value="nestedDeleg = {IntDelegate}" />
</Item>
</DelegateLocalVariables>
<Item>
<AnonymousType
Name="delegVar_NestedDelegRef"
Value="(()(CS$&lt;&gt;8__locals7)).delegVar_NestedDelegRef = 302" />
</Item>
<Item>
<AnonymousType
Name="delegArg_NestedDelegRef"
Value="(()(CS$&lt;&gt;8__locals7)).delegArg_NestedDelegRef = 401" />
</Item>
<Item>
<AnonymousType
Name="stateLessVar_DelegRef"
Value="(()(this)).stateLessVar_DelegRef = 202" />
</Item>
<Item>
<AnonymousType
Name="stateLessVar_NestedDelegRef"
Value="(()(this)).stateLessVar_NestedDelegRef = 203" />
</Item>
<Item>
<AnonymousType
Name="stateFullVar_DelegRef"
Value="(()((()(this)).CS$&lt;&gt;8__locals3)).stateFullVar_DelegRef = 102" />
</Item>
<Item>
<AnonymousType
Name="stateFullVar_NestedDelegRef"
Value="(()((()(this)).CS$&lt;&gt;8__locals3)).stateFullVar_NestedDelegRef = 103" />
</Item>
<Item>
<AnonymousType
Name="&lt;&gt;4__this"
Value="(()((()(this)).CS$&lt;&gt;8__locals3)).&lt;&gt;4__this = {Debugger.Tests.TestPrograms.CompilerGeneratedClasses}" />
</Item>
</OutterDelegateLocalVariables>
<DebuggingPaused>Break CompilerGeneratedClasses.cs:51,7-51,43</DebuggingPaused>
<InnterDelegateLocalVariables>
<Item>
<AnonymousType
Name="nestedDelegVar"
Value="nestedDelegVar = 303" />
</Item>
<Item>
<AnonymousType
Name="delegVar_NestedDelegRef"
Value="(()(this)).delegVar_NestedDelegRef = 302" />
</Item>
<Item>
<AnonymousType
Name="delegArg_NestedDelegRef"
Value="(()(this)).delegArg_NestedDelegRef = 401" />
</Item>
<Item>
<AnonymousType
Name="stateLessVar_DelegRef"
Value="(()((()(this)).CS$&lt;&gt;8__locals5)).stateLessVar_DelegRef = 202" />
</Item>
<Item>
<AnonymousType
Name="stateLessVar_NestedDelegRef"
Value="(()((()(this)).CS$&lt;&gt;8__locals5)).stateLessVar_NestedDelegRef = 203" />
</Item>
<Item>
<AnonymousType
Name="stateFullVar_DelegRef"
Value="(()((()(this)).CS$&lt;&gt;8__locals3)).stateFullVar_DelegRef = 102" />
</Item>
<Item>
<AnonymousType
Name="stateFullVar_NestedDelegRef"
Value="(()((()(this)).CS$&lt;&gt;8__locals3)).stateFullVar_NestedDelegRef = 103" />
</Item>
<Item>
<AnonymousType
Name="&lt;&gt;4__this"
Value="(()((()(this)).CS$&lt;&gt;8__locals3)).&lt;&gt;4__this = {Debugger.Tests.TestPrograms.CompilerGeneratedClasses}" />
</Item>
</InnterDelegateLocalVariables>
<ProcessExited />
</Test>
</DebuggerTests>

Loading…
Cancel
Save