private static string GetQualifiedMemberName( DkmInspectionContext inspectionContext, TypeAndCustomInfo typeDeclaringMember, string memberName, IDkmClrFullNameProvider fullNameProvider) { var typeName = fullNameProvider.GetClrTypeName(inspectionContext, typeDeclaringMember.ClrType, typeDeclaringMember.Info) ?? inspectionContext.GetTypeName(typeDeclaringMember.ClrType, typeDeclaringMember.Info, Formatter.NoFormatSpecifiers); return(typeDeclaringMember.Type.IsInterface ? $"{typeName}.{memberName}" : $"{memberName} ({typeName})"); }
internal static string GetExceptionMessage( this DkmClrValue value, DkmInspectionContext inspectionContext, string fullNameWithoutFormatSpecifiers ) { var typeName = inspectionContext.GetTypeName( value.Type, null, Formatter.NoFormatSpecifiers ); return(string.Format( Resources.ExceptionThrown, fullNameWithoutFormatSpecifiers, typeName )); }
/// <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 EvalResult GetRow( DkmInspectionContext inspectionContext, DkmClrValue value, int index, EvalResultDataItem parent ) { var typeParameter = _typeParameters[index]; var typeArgument = _typeArguments[index]; var typeArgumentInfo = _customTypeInfoMap.SubstituteCustomTypeInfo( typeParameter, customInfo: null ); var formatSpecifiers = Formatter.NoFormatSpecifiers; return(new EvalResult( ExpansionKind.TypeVariable, typeParameter.Name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: new TypeAndCustomInfo( DkmClrType.Create(value.Type.AppDomain, typeArgument), typeArgumentInfo ), useDebuggerDisplay: parent != null, value: value, displayValue: inspectionContext.GetTypeName( DkmClrType.Create(value.Type.AppDomain, typeArgument), typeArgumentInfo, formatSpecifiers ), expansion: null, childShouldParenthesize: false, fullName: null, childFullNamePrefixOpt: null, formatSpecifiers: formatSpecifiers, category: DkmEvaluationResultCategory.Data, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext )); }
private EvalResultDataItem GetRow(ResultProvider resultProvider, DkmInspectionContext inspectionContext, DkmClrValue value, int index, EvalResultDataItem parent) { var typeParameter = _typeParameters[index]; var typeArgument = _typeArguments[index]; var formatSpecifiers = Formatter.NoFormatSpecifiers; return(new EvalResultDataItem( ExpansionKind.TypeVariables, typeParameter.Name, typeDeclaringMember: null, declaredType: typeArgument, parent: parent, value: value, displayValue: inspectionContext.GetTypeName(DkmClrType.Create(value.Type.AppDomain, typeArgument), formatSpecifiers), expansion: null, childShouldParenthesize: false, fullName: null, childFullNamePrefixOpt: null, formatSpecifiers: formatSpecifiers, category: DkmEvaluationResultCategory.Data, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext)); }
internal string GetValueString(DkmClrValue value, DkmInspectionContext inspectionContext, ObjectDisplayOptions options, GetValueFlags flags) { if (value.IsError()) { return((string)value.HostObjectValue); } if (UsesHexadecimalNumbers(inspectionContext)) { options |= ObjectDisplayOptions.UseHexadecimalNumbers; } var lmrType = value.Type.GetLmrType(); if (IsPredefinedType(lmrType) && !lmrType.IsObject()) { if (lmrType.IsString()) { var stringValue = (string)value.HostObjectValue; if (stringValue == null) { return(_nullString); } return(IncludeObjectId( value, FormatString(stringValue, options), flags)); } else if (lmrType.IsCharacter()) { return(IncludeObjectId( value, FormatLiteral((char)value.HostObjectValue, options | ObjectDisplayOptions.IncludeCodePoints), flags)); } else { return(IncludeObjectId( value, FormatPrimitive(value, options & ~ObjectDisplayOptions.UseQuotes, inspectionContext), flags)); } } else if (value.IsNull && !lmrType.IsPointer) { return(_nullString); } else if (lmrType.IsEnum) { return(IncludeObjectId( value, GetEnumDisplayString(lmrType, value, options, (flags & GetValueFlags.IncludeTypeName) != 0, inspectionContext), flags)); } else if (lmrType.IsArray) { return(IncludeObjectId( value, GetArrayDisplayString(lmrType, value.ArrayDimensions, value.ArrayLowerBounds, options), flags)); } else if (lmrType.IsPointer) { // NOTE: the HostObjectValue will have a size corresponding to the process bitness // and FormatPrimitive will adjust accordingly. var tmp = FormatPrimitive(value, ObjectDisplayOptions.UseHexadecimalNumbers, inspectionContext); // Always in hex. Debug.Assert(tmp != null); return(tmp); } else if (lmrType.IsNullable()) { var nullableValue = value.GetNullableValue(inspectionContext); // It should be impossible to nest nullables, so this recursion should introduce only a single extra stack frame. return(nullableValue == null ? _nullString : GetValueString(nullableValue, inspectionContext, ObjectDisplayOptions.None, GetValueFlags.IncludeTypeName)); } // "value.EvaluateToString()" will check "Call string-conversion function on objects in variables windows" // (Tools > Options setting) and call "value.ToString()" if appropriate. return(IncludeObjectId( value, string.Format(_defaultFormat, value.EvaluateToString(inspectionContext) ?? inspectionContext.GetTypeName(value.Type, Formatter.NoFormatSpecifiers)), flags)); }
private string GetValueString( DkmClrValue value, DkmInspectionContext inspectionContext, ObjectDisplayOptions options, GetValueFlags flags ) { if (value.IsError()) { return((string)value.HostObjectValue); } if (UsesHexadecimalNumbers(inspectionContext)) { options |= ObjectDisplayOptions.UseHexadecimalNumbers; } var lmrType = value.Type.GetLmrType(); if (IsPredefinedType(lmrType) && !lmrType.IsObject()) { if (lmrType.IsString()) { var stringValue = (string)value.HostObjectValue; if (stringValue == null) { return(_nullString); } return(IncludeObjectId(value, FormatString(stringValue, options), flags)); } else if (lmrType.IsCharacter()) { // check if HostObjectValue is null, since any of these types might actually be a synthetic value as well. if (value.HostObjectValue == null) { return(_hostValueNotFoundString); } return(IncludeObjectId( value, FormatLiteral( (char)value.HostObjectValue, options | ObjectDisplayOptions.IncludeCodePoints ), flags )); } else { return(IncludeObjectId( value, FormatPrimitive( value, options & ~( ObjectDisplayOptions.UseQuotes | ObjectDisplayOptions.EscapeNonPrintableCharacters ), inspectionContext ), flags )); } } else if (value.IsNull && !lmrType.IsPointer) { return(_nullString); } else if (lmrType.IsEnum) { return(IncludeObjectId( value, GetEnumDisplayString( lmrType, value, options, (flags & GetValueFlags.IncludeTypeName) != 0, inspectionContext ), flags )); } else if (lmrType.IsArray) { return(IncludeObjectId( value, GetArrayDisplayString( value.Type.AppDomain, lmrType, value.ArrayDimensions, value.ArrayLowerBounds, options ), flags )); } else if (lmrType.IsPointer) { // NOTE: the HostObjectValue will have a size corresponding to the process bitness // and FormatPrimitive will adjust accordingly. var tmp = FormatPrimitive( value, ObjectDisplayOptions.UseHexadecimalNumbers, inspectionContext ); // Always in hex. Debug.Assert(tmp != null); return(tmp); } else if (lmrType.IsNullable()) { var nullableValue = value.GetNullableValue(inspectionContext); // It should be impossible to nest nullables, so this recursion should introduce only a single extra stack frame. return(nullableValue == null ? _nullString : GetValueString( nullableValue, inspectionContext, ObjectDisplayOptions.None, GetValueFlags.IncludeTypeName )); } else if (lmrType.IsIntPtr()) { // check if HostObjectValue is null, since any of these types might actually be a synthetic value as well. if (value.HostObjectValue == null) { return(_hostValueNotFoundString); } if (IntPtr.Size == 8) { var intPtr = ((IntPtr)value.HostObjectValue).ToInt64(); return(FormatPrimitiveObject( intPtr, ObjectDisplayOptions.UseHexadecimalNumbers )); } else { var intPtr = ((IntPtr)value.HostObjectValue).ToInt32(); return(FormatPrimitiveObject( intPtr, ObjectDisplayOptions.UseHexadecimalNumbers )); } } else if (lmrType.IsUIntPtr()) { // check if HostObjectValue is null, since any of these types might actually be a synthetic value as well. if (value.HostObjectValue == null) { return(_hostValueNotFoundString); } if (UIntPtr.Size == 8) { var uIntPtr = ((UIntPtr)value.HostObjectValue).ToUInt64(); return(FormatPrimitiveObject( uIntPtr, ObjectDisplayOptions.UseHexadecimalNumbers )); } else { var uIntPtr = ((UIntPtr)value.HostObjectValue).ToUInt32(); return(FormatPrimitiveObject( uIntPtr, ObjectDisplayOptions.UseHexadecimalNumbers )); } } else { int cardinality; if (lmrType.IsTupleCompatible(out cardinality) && (cardinality > 1)) { var values = ArrayBuilder <string> .GetInstance(); if (value.TryGetTupleFieldValues(cardinality, values, inspectionContext)) { return(IncludeObjectId( value, GetTupleExpression(values.ToArrayAndFree()), flags )); } values.Free(); } } // "value.EvaluateToString()" will check "Call string-conversion function on objects in variables windows" // (Tools > Options setting) and call "value.ToString()" if appropriate. return(IncludeObjectId( value, string.Format( _defaultFormat, value.EvaluateToString(inspectionContext) ?? inspectionContext.GetTypeName( value.Type, CustomTypeInfo: null, FormatSpecifiers: NoFormatSpecifiers ) ), flags )); }
string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType clrType, DkmClrCustomTypeInfo customTypeInfo, ReadOnlyCollection <string> formatSpecifiers) { return(inspectionContext.GetTypeName(clrType, customTypeInfo, formatSpecifiers)); }