Browse Source

Support for local variables captured by yield

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5095 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 17 years ago
parent
commit
98377f4d0f
  1. 7
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs
  2. 66
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/MethodInfo.cs
  3. 5
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/DebugType.cs
  4. 20
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/DebugType_CompilerGeneratedClasses.cs
  5. 19
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Expressions.cs

7
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs

@ -399,7 +399,12 @@ namespace Debugger @@ -399,7 +399,12 @@ namespace Debugger
public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data)
{
return context.GetThisValue();
// This is needed so that captured 'this' is supported
foreach(LocalVariableInfo locVar in context.MethodInfo.LocalVariables) {
if (locVar.IsThis)
return locVar.GetValue(context);
}
throw new GetValueException(context.MethodInfo.FullName + " does not have \"this\"");
}
public override object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data)

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

@ -453,57 +453,82 @@ namespace Debugger.MetaData @@ -453,57 +453,82 @@ namespace Debugger.MetaData
if (localVariables != null) return localVariables;
localVariables = GetLocalVariablesInScope(this.SymMethod.RootScope);
if (!this.IsStatic && this.DeclaringType.IsDisplayClass) {
if (this.DeclaringType.IsDisplayClass || this.DeclaringType.IsYieldEnumerator) {
// Get display class from self
localVariables.AddRange(GetLocalVariablesFromDisplayClass(
AddCapturedLocalVariables(
localVariables,
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(
AddCapturedLocalVariables(
localVariables,
delegate(StackFrame context) {
return context.GetThisValue().GetFieldValue(fieldInfoCopy);
},
fieldInfo.Type
));
);
}
}
} else {
// Add this
if (!this.IsStatic) {
LocalVariableInfo thisVar = new LocalVariableInfo(
"this",
this.DeclaringType,
delegate(StackFrame context) {
return context.GetThisValue();
}
);
thisVar.IsThis = true;
localVariables.Add(thisVar);
}
if (this.DeclaringType.IsYieldEnumerator) {
}
return localVariables;
}
List<LocalVariableInfo> GetLocalVariablesFromDisplayClass(ValueGetter getDisplayClass, DebugType displayClassType)
static void AddCapturedLocalVariables(List<LocalVariableInfo> vars, ValueGetter getCaptureClass, DebugType captureClassType)
{
List<LocalVariableInfo> vars = new List<LocalVariableInfo>();
if (displayClassType.IsDisplayClass) {
foreach(FieldInfo fieldInfo in displayClassType.GetFields()) {
if (captureClassType.IsDisplayClass || captureClassType.IsYieldEnumerator) {
foreach(FieldInfo fieldInfo in captureClassType.GetFields()) {
FieldInfo fieldInfoCopy = fieldInfo;
if (!fieldInfo.Name.StartsWith("CS$")) {
if (fieldInfo.Name.StartsWith("CS$")) continue; // Ignore
LocalVariableInfo locVar = new LocalVariableInfo(
fieldInfo.Name,
fieldInfo.Type,
delegate(StackFrame context) {
return getDisplayClass(context).GetFieldValue(fieldInfoCopy);
return getCaptureClass(context).GetFieldValue(fieldInfoCopy);
}
);
locVar.IsCapturedByDelegate = true;
if (fieldInfo.Name.StartsWith("<>") && fieldInfo.Name.EndsWith("__this")) {
locVar.IsCaptured = true;
if (locVar.Name.StartsWith("<>")) {
bool hasThis = false;
foreach(LocalVariableInfo l in vars) {
if (l.IsThis) {
hasThis = true;
break;
}
}
if (!hasThis && locVar.Name.EndsWith("__this")) {
locVar.Name = "this";
locVar.IsThis = true;
} else {
continue; // Ignore
}
vars.Add(locVar);
}
if (locVar.Name.StartsWith("<")) {
int endIndex = locVar.Name.IndexOf('>');
if (endIndex == -1) continue; // Ignore
locVar.Name = fieldInfo.Name.Substring(1, endIndex - 1);
}
vars.Add(locVar);
}
}
return vars;
}
List<LocalVariableInfo> GetLocalVariablesInScope(ISymUnmanagedScope symScope)
@ -520,12 +545,13 @@ namespace Debugger.MetaData @@ -520,12 +545,13 @@ namespace Debugger.MetaData
if ((symVar.Attributes & 1) == 1 || symVar.Name.StartsWith("CS$")) {
// Get display class from local variable
if (locVarType.IsDisplayClass) {
vars.AddRange(GetLocalVariablesFromDisplayClass(
AddCapturedLocalVariables(
vars,
delegate(StackFrame context) {
return GetLocalVariableValue(context, symVarCopy);
},
locVarType
));
);
}
} else {
LocalVariableInfo locVar = new LocalVariableInfo(
@ -566,7 +592,7 @@ namespace Debugger.MetaData @@ -566,7 +592,7 @@ namespace Debugger.MetaData
public string Name { get; internal set; }
public DebugType Type { get; private set; }
public bool IsThis { get; internal set; }
public bool IsCapturedByDelegate { get; internal set; }
public bool IsCaptured { get; internal set; }
public LocalVariableInfo(string name, DebugType type, ValueGetter getter)
{

5
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/DebugType.cs

@ -298,6 +298,7 @@ namespace Debugger.Tests { @@ -298,6 +298,7 @@ namespace Debugger.Tests {
FullName="Access.get_publicProperty"
IsPublic="True"
IsSpecialName="True"
LocalVariableNames="{this}"
Module="DebugType.exe"
Name="get_publicProperty"
ReturnType="System.Int32" />
@ -307,6 +308,7 @@ namespace Debugger.Tests { @@ -307,6 +308,7 @@ namespace Debugger.Tests {
DeclaringType="Access"
FullName="Access.publicMethod"
IsPublic="True"
LocalVariableNames="{this}"
Module="DebugType.exe"
Name="publicMethod" />
</Item>
@ -316,6 +318,7 @@ namespace Debugger.Tests { @@ -316,6 +318,7 @@ namespace Debugger.Tests {
FullName="Access..ctor"
IsPublic="True"
IsSpecialName="True"
LocalVariableNames="{this}"
Module="DebugType.exe"
Name=".ctor" />
</Item>
@ -348,6 +351,7 @@ namespace Debugger.Tests { @@ -348,6 +351,7 @@ namespace Debugger.Tests {
FullName="MyInterfaceImpl&lt;System.Int32&gt;.get_Prop"
IsPublic="True"
IsSpecialName="True"
LocalVariableNames="{this}"
Module="DebugType.exe"
Name="get_Prop"
ReturnType="System.Collections.Generic.List&lt;System.Int32&gt;" />
@ -357,6 +361,7 @@ namespace Debugger.Tests { @@ -357,6 +361,7 @@ namespace Debugger.Tests {
DeclaringType="MyInterfaceImpl&lt;System.Int32&gt;"
FullName="MyInterfaceImpl&lt;System.Int32&gt;.Fun2"
IsPublic="True"
LocalVariableNames="{this}"
Module="DebugType.exe"
Name="Fun2"
ParameterCount="3"

20
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/DebugType_CompilerGeneratedClasses.cs

@ -120,6 +120,26 @@ namespace Debugger.Tests { @@ -120,6 +120,26 @@ namespace Debugger.Tests {
Name="stateLessVar_NestedDelegRef"
Value="203" />
</Item>
<Item>
<AnonymousType
Name="this"
Value="{Debugger.Tests.TestPrograms.DebugType_CompilerGeneratedClasses}" />
</Item>
<Item>
<AnonymousType
Name="stateFullVar"
Value="101" />
</Item>
<Item>
<AnonymousType
Name="stateFullVar_DelegRef"
Value="102" />
</Item>
<Item>
<AnonymousType
Name="stateFullVar_NestedDelegRef"
Value="103" />
</Item>
</YieldLocalVariables>
<DebuggingPaused>Break DebugType_CompilerGeneratedClasses.cs:54,6-54,42</DebuggingPaused>
<OutterDelegateLocalVariables>

19
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Expressions.cs

@ -130,8 +130,8 @@ namespace Debugger.Tests { @@ -130,8 +130,8 @@ namespace Debugger.Tests {
</Item>
</Arguments>
<LocalVariables
Capacity="4"
Count="4">
Capacity="8"
Count="5">
<Item>
<Value
AsString="0"
@ -165,6 +165,13 @@ namespace Debugger.Tests { @@ -165,6 +165,13 @@ namespace Debugger.Tests {
PrimitiveValue="baseClassString"
Type="System.String" />
</Item>
<Item>
<Value
AsString="{Debugger.Tests.TestPrograms.TestClass}"
IsReference="True"
PrimitiveValue="{Exception: Value is not a primitive type}"
Type="Debugger.Tests.TestPrograms.TestClass" />
</Item>
</LocalVariables>
<this>
<Item>
@ -236,6 +243,7 @@ namespace Debugger.Tests { @@ -236,6 +243,7 @@ namespace Debugger.Tests {
FullName="Debugger.Tests.TestPrograms.TestClass.get_Name"
IsPublic="True"
IsSpecialName="True"
LocalVariableNames="{this}"
Module="Expressions.exe"
Name="get_Name"
ReturnType="System.String"
@ -255,7 +263,7 @@ namespace Debugger.Tests { @@ -255,7 +263,7 @@ namespace Debugger.Tests {
DeclaringType="Debugger.Tests.TestPrograms.TestClass"
FullName="Debugger.Tests.TestPrograms.TestClass.Test"
IsPublic="True"
LocalVariableNames="{array, array2, BaseClass, i}"
LocalVariableNames="{array, array2, BaseClass, i, this}"
Module="Expressions.exe"
Name="Test"
ParameterCount="1"
@ -266,6 +274,7 @@ namespace Debugger.Tests { @@ -266,6 +274,7 @@ namespace Debugger.Tests {
DeclaringType="Debugger.Tests.TestPrograms.TestClass"
FullName="Debugger.Tests.TestPrograms.TestClass.Test"
IsPublic="True"
LocalVariableNames="{this}"
Module="Expressions.exe"
Name="Test"
ParameterCount="1"
@ -276,6 +285,7 @@ namespace Debugger.Tests { @@ -276,6 +285,7 @@ namespace Debugger.Tests {
DeclaringType="Debugger.Tests.TestPrograms.TestClass"
FullName="Debugger.Tests.TestPrograms.TestClass.Test"
IsPublic="True"
LocalVariableNames="{this}"
Module="Expressions.exe"
Name="Test"
ParameterCount="1"
@ -286,6 +296,7 @@ namespace Debugger.Tests { @@ -286,6 +296,7 @@ namespace Debugger.Tests {
DeclaringType="Debugger.Tests.TestPrograms.TestClass"
FullName="Debugger.Tests.TestPrograms.TestClass.Foo"
IsPublic="True"
LocalVariableNames="{this}"
Module="Expressions.exe"
Name="Foo"
ParameterCount="1"
@ -297,6 +308,7 @@ namespace Debugger.Tests { @@ -297,6 +308,7 @@ namespace Debugger.Tests {
DeclaringType="Debugger.Tests.TestPrograms.TestClass"
FullName="Debugger.Tests.TestPrograms.TestClass.Foo"
IsPublic="True"
LocalVariableNames="{this}"
Module="Expressions.exe"
Name="Foo"
ParameterCount="1"
@ -309,6 +321,7 @@ namespace Debugger.Tests { @@ -309,6 +321,7 @@ namespace Debugger.Tests {
FullName="Debugger.Tests.TestPrograms.TestClass..ctor"
IsPublic="True"
IsSpecialName="True"
LocalVariableNames="{this}"
Module="Expressions.exe"
Name=".ctor" />
</Item>

Loading…
Cancel
Save