/// <summary> /// This method is called by the debug engine to retrieve the current local variables. /// The result of this call will be a query containing the names of the local variables /// as well as IL code to retrieve each variable value. /// </summary> /// <param name="inspectionContext">Context of the evaluation. This contains options/flags /// to be used during compilation. It also contains the InspectionSession. The inspection /// session is the object that provides lifetime management for our objects. When the user /// steps or continues the process, the debug engine will dispose of the inspection session</param> /// <param name="instructionAddress">Instruction address or code location to use as the /// reference point for where we need to retrieve the local variables</param> /// <param name="argumentsOnly">True if only arguments are needed</param> /// <returns>A local variables query</returns> DkmCompiledClrLocalsQuery IDkmClrExpressionCompiler.GetClrLocalVariableQuery(DkmInspectionContext inspectionContext, DkmClrInstructionAddress instructionAddress, bool argumentsOnly) { var result = inspectionContext.GetClrLocalVariableQuery(instructionAddress, argumentsOnly); var newlocals = new List <DkmClrLocalVariableInfo>(); bool changed = false; foreach (var loc in result.LocalInfo) { if (loc.VariableName.Contains("$")) { // do not add changed = true; } else if (loc.VariableName == "this") { // rename var selfName = XSharpType.FormatKeyword("SELF"); var newloc = DkmClrLocalVariableInfo.Create(selfName, selfName, loc.MethodName, loc.CompilationFlags, loc.ResultCategory, loc.CustomTypeInfo); newlocals.Add(newloc); changed = true; } else { newlocals.Add(loc); } } if (changed) { result = DkmCompiledClrLocalsQuery.Create(result.RuntimeInstance, result.DataContainer, result.LanguageId, result.Binary, result.TypeName, new ReadOnlyCollection <DkmClrLocalVariableInfo>(newlocals)); } return(result); }
private string TryFormatValue(DkmClrValue value, DkmInspectionContext inspectionContext) { if (value.ValueFlags.HasFlag(DkmClrValueFlags.Error)) { // Error message. Just show the error. return(value.HostObjectValue as string); } Type lmrType = value.Type.GetLmrType(); if (lmrType.IsEnum) { return(value.GetValueString(inspectionContext, null)); } XSharpType xType = Utility.GetXSharpTypeForLmrType(lmrType); if (xType == XSharpType.Invalid) { // We don't know how to format this value return(null); } uint radix = inspectionContext.Radix; object hostObjectValue = value.HostObjectValue; if (hostObjectValue != null) { // If the value can be marshalled into the debugger process, HostObjectValue is the // equivalent value in the debugger process. switch (System.Type.GetTypeCode(hostObjectValue.GetType())) { case TypeCode.Int32: return(FormatInteger((int)hostObjectValue, radix)); case TypeCode.Boolean: return((bool)hostObjectValue ? "TRUE" : "FALSE"); case TypeCode.String: return(FormatString(hostObjectValue.ToString(), inspectionContext.EvaluationFlags)); } } return(null); }
/// <summary> /// This method is called by the debug engine to populate the text representing the type of /// a result. /// </summary> /// <param name="inspectionContext">Context of the evaluation. This contains options/flags /// to be used during compilation. It also contains the InspectionSession. The inspection /// session is the object that provides lifetime management for our objects. When the user /// steps or continues the process, the debug engine will dispose of the inspection session</param> /// <param name="clrType">This is the raw type we want to format</param> /// <param name="customTypeInfo">If Expression Compiler passed any additional information /// about the type that doesn't exist in metadata, this parameter contais that information.</param> /// <param name="formatSpecifiers">A list of custom format specifiers that the debugger did /// not understand. If you want special format specifiers for your language, handle them /// here. The formatter should ignore any format specifiers it does not understand.</param> /// <returns>The text of the type name to display</returns> string IDkmClrFormatter.GetTypeName( DkmInspectionContext inspectionContext, DkmClrType clrType, DkmClrCustomTypeInfo customTypeInfo, ReadOnlyCollection <string> formatSpecifiers) { // Get the LMR type for the DkmClrType. LMR Types (Microsoft.VisualStudio.Debugger.Metadata.Type) // are similar to System.Type, but represent types that live in the process being debugged. Type lmrType = clrType.GetLmrType(); XSharpType xType = Utility.GetXSharpTypeForLmrType(lmrType); if (xType == XSharpType.Invalid) { // We don't know about this type. Delegate to the C# Formatter to format the // type name. return(inspectionContext.GetTypeName(clrType, customTypeInfo, formatSpecifiers)); } return(xType.ToString()); }
private static string TryGetFrameNameHelper(DkmInspectionContext inspectionContext, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags) { ImportedMethod currentMethod = TryGetCurrentMethod(inspectionContext, frame); if (currentMethod == null) { return(null); } string name = currentMethod.Name; if (argumentFlags == DkmVariableInfoFlags.None) { return(name); } var type = currentMethod.DeclaringType; if (type.IsStatic && type.Name == "Functions") { ; // No prefix for 'normal' functions } else { // static or instance method ? if (currentMethod.IsStatic) { name = type.FullName + "." + name; } else { name = type.FullName + ":" + name; } } Variable[] args = currentMethod.GetParameters(); if (args.Length == 0) { return(name + "()"); } StringBuilder nameBuilder = new StringBuilder(); nameBuilder.Append(name); nameBuilder.Append('('); bool first = true; bool showTypes = argumentFlags.HasFlag(DkmVariableInfoFlags.Types); bool showNames = argumentFlags.HasFlag(DkmVariableInfoFlags.Names); foreach (Variable arg in args) { if (first) { first = false; } else { nameBuilder.Append(", "); } XSharpType argType = arg.Type; if (showNames) { nameBuilder.Append(arg.Name); } if (showNames && showTypes) { if (arg.In && arg.Out) { nameBuilder.Append(" REF "); } else if (arg.Out) { nameBuilder.Append(" OUT "); } else { nameBuilder.Append(" AS "); } } if (showTypes) { nameBuilder.Append(argType.ToString()); } } nameBuilder.Append(')'); var result = nameBuilder.ToString(); if (result.Contains(clArgs)) { result = result.Replace(clArgs, "[ClipperArguments]"); } return(result); }
} // Parameters only public Variable(XSharpType type, string name) { Type = type; Name = name; }
public LocalVariable(string name, XSharpType type, int slot) { Variable = new Variable(type, name); Slot = slot; }