static void AddCapturedLocalVariables(List <DebugLocalVariableInfo> vars, int scopeStartOffset, int scopeEndOffset, ValueGetter getCaptureClass, DebugType captureClassType) { if (captureClassType.IsDisplayClass || captureClassType.IsYieldEnumerator || captureClassType.IsAsyncStateMachine) { foreach (DebugFieldInfo fieldInfo in captureClassType.GetFields()) { DebugFieldInfo fieldInfoCopy = fieldInfo; if (fieldInfo.Name.StartsWith("CS$")) { continue; // Ignore } DebugLocalVariableInfo locVar = new DebugLocalVariableInfo( fieldInfo.Name, -1, scopeStartOffset, scopeEndOffset, (DebugType)fieldInfo.FieldType, delegate(StackFrame context) { return(getCaptureClass(context).GetFieldValue(fieldInfoCopy)); } ); locVar.IsCaptured = true; if (locVar.Name.StartsWith("<>")) { bool hasThis = false; foreach (DebugLocalVariableInfo l in vars) { if (l.IsThis) { hasThis = true; break; } } if (!hasThis && locVar.Name.EndsWith("__this")) { locVar.Name = "this"; locVar.IsThis = true; } else { continue; // Ignore } } 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); } } }
static Value GetLiteralValue(DebugFieldInfo fieldInfo) { CorElementType corElemType = (CorElementType)fieldInfo.FieldProps.ConstantType; if (corElemType == CorElementType.CLASS) { // Only null literals are allowed return Eval.CreateValue(fieldInfo.AppDomain, null); } else if (corElemType == CorElementType.STRING) { string str = Marshal.PtrToStringUni(fieldInfo.FieldProps.ConstantPtr, (int)fieldInfo.FieldProps.ConstantStringLength); return Eval.CreateValue(fieldInfo.AppDomain, str); } else { DebugType type = DebugType.CreateFromType(fieldInfo.AppDomain.Mscorlib, DebugType.CorElementTypeToManagedType(corElemType)); if (fieldInfo.FieldType.IsEnum && fieldInfo.FieldType.GetEnumUnderlyingType() == type) { Value val = Eval.NewObjectNoConstructor((DebugType)fieldInfo.FieldType); Value backingField = val.GetMemberValue("value__"); backingField.CorGenericValue.SetValue(fieldInfo.FieldProps.ConstantPtr); return val; } else { Value val = Eval.NewObjectNoConstructor(type); val.CorGenericValue.SetValue(fieldInfo.FieldProps.ConstantPtr); return val; } } }
public List <DebugLocalVariableInfo> GetLocalVariables() { if (localVariables != null) { return(localVariables); } // Generated constructor may not have any symbols if (this.SymMethod == null) { return(new List <DebugLocalVariableInfo>()); } localVariables = GetLocalVariablesInScope(this.SymMethod.GetRootScope()); if (declaringType.IsDisplayClass || declaringType.IsYieldEnumerator || declaringType.IsAsyncStateMachine) { // Get display class from self AddCapturedLocalVariables( localVariables, 0, int.MaxValue, delegate(StackFrame context) { return(context.GetThisValue()); }, declaringType ); // Get dispaly classes from fields foreach (DebugFieldInfo fieldInfo in this.DeclaringType.GetFields()) { DebugFieldInfo fieldInfoCopy = fieldInfo; if (fieldInfo.Name.StartsWith("CS$")) { AddCapturedLocalVariables( localVariables, 0, int.MaxValue, delegate(StackFrame context) { return(context.GetThisValue().GetFieldValue(fieldInfoCopy)); }, (DebugType)fieldInfo.FieldType ); } } } else { // Add this if (!this.IsStatic) { DebugLocalVariableInfo thisVar = new DebugLocalVariableInfo( "this", -1, 0, int.MaxValue, declaringType, delegate(StackFrame context) { return(context.GetThisValue()); } ); thisVar.IsThis = true; localVariables.Add(thisVar); } } return(localVariables); }