Пример #1
0
 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);
 }
        /// <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();

            IrisType irisType = Utility.GetIrisTypeForLmrType(lmrType);
            if (irisType == IrisType.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 irisType.ToString();
        }
        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, CustomTypeInfo: null, FormatSpecifiers: NoFormatSpecifiers)),
                flags);
        }
 /// <returns>
 /// The qualified name (i.e. including containing types and namespaces) of a named, pointer,
 /// or array type followed by the qualified name of the actual runtime type, if provided.
 /// </returns>
 private static string GetTypeName(DkmInspectionContext inspectionContext, DkmClrValue value, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, ExpansionKind kind)
 {
     var declaredLmrType = declaredType.GetLmrType();
     var runtimeType = value.Type;
     var runtimeLmrType = runtimeType.GetLmrType();
     var declaredTypeName = inspectionContext.GetTypeName(declaredType, declaredTypeInfo, Formatter.NoFormatSpecifiers);
     var runtimeTypeName = inspectionContext.GetTypeName(runtimeType, CustomTypeInfo: null, FormatSpecifiers: Formatter.NoFormatSpecifiers);
     var includeRuntimeTypeName =
         !string.Equals(declaredTypeName, runtimeTypeName, StringComparison.OrdinalIgnoreCase) && // Names will reflect "dynamic", types will not.
         !declaredLmrType.IsPointer &&
         (kind != ExpansionKind.PointerDereference) &&
         (!declaredLmrType.IsNullable() || value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown));
     return includeRuntimeTypeName ?
         string.Format("{0} {{{1}}}", declaredTypeName, runtimeTypeName) :
         declaredTypeName;
 }
Пример #5
0
 /// <returns>The qualified name (i.e. including containing types and namespaces) of a named,
 /// pointer, or array type followed by the qualified name of the actual runtime type, if it
 /// differs from the declared type.</returns>
 private static string GetTypeName(DkmInspectionContext inspectionContext, DkmClrType declaredType, DkmClrType runtimeType)
 {
     var declaredTypeName = inspectionContext.GetTypeName(declaredType);
     var declaredLmrType = declaredType.GetLmrType();
     var runtimeLmrType = runtimeType.GetLmrType();
     return declaredLmrType.Equals(runtimeLmrType) || declaredLmrType.IsPointer
         ? declaredTypeName
         : string.Format("{0} {{{1}}}", declaredTypeName, inspectionContext.GetTypeName(runtimeType));
 }
Пример #6
0
 string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType clrType, DkmClrCustomTypeInfo customTypeInfo, ReadOnlyCollection<string> formatSpecifiers)
 {
     return inspectionContext.GetTypeName(clrType, customTypeInfo, formatSpecifiers);
 }
Пример #7
0
 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);
 }
Пример #8
0
 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})";
 }
Пример #9
0
 /// <returns>
 /// The qualified name (i.e. including containing types and namespaces) of a named, pointer,
 /// or array type followed by the qualified name of the actual runtime type, if provided.
 /// </returns>
 internal static string GetTypeName(
     DkmInspectionContext inspectionContext,
     DkmClrValue value,
     DkmClrType declaredType,
     DkmClrCustomTypeInfo declaredTypeInfo,
     bool isPointerDereference)
 {
     var declaredLmrType = declaredType.GetLmrType();
     var runtimeType = value.Type;
     var declaredTypeName = inspectionContext.GetTypeName(declaredType, declaredTypeInfo, Formatter.NoFormatSpecifiers);
     // Include the runtime type if distinct.
     if (!declaredLmrType.IsPointer &&
         !isPointerDereference &&
         (!declaredLmrType.IsNullable() || value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown)))
     {
         // Generate the declared type name without tuple element names.
         var declaredTypeInfoNoTupleElementNames = declaredTypeInfo.WithNoTupleElementNames();
         var declaredTypeNameNoTupleElementNames = (declaredTypeInfo == declaredTypeInfoNoTupleElementNames) ?
             declaredTypeName :
             inspectionContext.GetTypeName(declaredType, declaredTypeInfoNoTupleElementNames, Formatter.NoFormatSpecifiers);
         // Generate the runtime type name with no tuple element names and no dynamic.
         var runtimeTypeName = inspectionContext.GetTypeName(runtimeType, null, FormatSpecifiers: Formatter.NoFormatSpecifiers);
         // If the two names are distinct, include both.
         if (!string.Equals(declaredTypeNameNoTupleElementNames, runtimeTypeName, StringComparison.Ordinal)) // Names will reflect "dynamic", types will not.
         {
             return string.Format("{0} {{{1}}}", declaredTypeName, runtimeTypeName);
         }
     }
     return declaredTypeName;
 }