Beispiel #1
0
        internal DkmClrValue(
            object value,
            object hostObjectValue,
            DkmClrType type,
            string alias,
            DkmEvaluationResultFlags evalFlags,
            DkmClrValueFlags valueFlags,
            DkmEvaluationResultCategory category = default(DkmEvaluationResultCategory),
            DkmEvaluationResultAccessType access = default(DkmEvaluationResultAccessType),
            ulong nativeComPointer = 0)
        {
            Debug.Assert((type == null) || !type.GetLmrType().IsTypeVariables() || (valueFlags == DkmClrValueFlags.Synthetic));
            Debug.Assert((alias == null) || evalFlags.Includes(DkmEvaluationResultFlags.HasObjectId));
            // The "real" DkmClrValue will always have a value of zero for null pointers.
            Debug.Assert((type == null) || !type.GetLmrType().IsPointer || (value != null));

            this.RawValue = value;
            this.HostObjectValue = hostObjectValue;
            this.Type = type;
            this.Alias = alias;
            this.EvalFlags = evalFlags;
            this.ValueFlags = valueFlags;
            this.Category = category;
            this.Access = access;
            this.NativeComPointer = nativeComPointer;
        }
Beispiel #2
0
        internal DkmClrValue(
            object value,
            object hostObjectValue,
            DkmClrType type,
            string alias,
            IDkmClrFormatter formatter,
            DkmEvaluationResultFlags evalFlags,
            DkmClrValueFlags valueFlags,
            DkmInspectionContext inspectionContext)
        {
            Debug.Assert(!type.GetLmrType().IsTypeVariables() || (valueFlags == DkmClrValueFlags.Synthetic));
            Debug.Assert((alias == null) || evalFlags.Includes(DkmEvaluationResultFlags.HasObjectId));
            // The "real" DkmClrValue will always have a value of zero for null pointers.
            Debug.Assert(!type.GetLmrType().IsPointer || (value != null));

            _rawValue = value;
            this.HostObjectValue = hostObjectValue;
            this.Type = type;
            _formatter = formatter;
            this.Alias = alias;
            this.EvalFlags = evalFlags;
            this.ValueFlags = valueFlags;
            this.InspectionContext = inspectionContext ?? new DkmInspectionContext(formatter, DkmEvaluationFlags.None, 10);
        }
        internal static EvalResultDataItem CreateResultsOnlyRow(
            DkmInspectionContext inspectionContext,
            string name,
            DkmClrType declaredType,
            DkmClrCustomTypeInfo declaredTypeInfo,
            DkmClrValue value,
            Formatter formatter)
        {
            string errorMessage;
            if (value.IsError())
            {
                errorMessage = (string)value.HostObjectValue;
            }
            else if (value.HasExceptionThrown())
            {
                errorMessage = value.GetExceptionMessage(name, formatter);
            }
            else
            {
                var enumerableType = GetEnumerableType(value);
                if (enumerableType != null)
                {
                    var expansion = CreateExpansion(inspectionContext, value, enumerableType, formatter);
                    if (expansion != null)
                    {
                        return expansion.CreateResultsViewRow(
                            inspectionContext,
                            name,
                            new TypeAndCustomInfo(declaredType.GetLmrType(), declaredTypeInfo),
                            value,
                            includeResultsFormatSpecifier: true,
                            formatter: formatter);
                    }
                    errorMessage = Resources.ResultsViewNoSystemCore;
                }
                else
                {
                    errorMessage = Resources.ResultsViewNotEnumerable;
                }
            }

            Debug.Assert(errorMessage != null);
            return new EvalResultDataItem(name, errorMessage);
        }
        /// <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();
        }
Beispiel #5
0
        public DkmClrValue InstantiateProxyType(DkmInspectionContext inspectionContext, DkmClrType proxyType)
        {
            if (inspectionContext == null)
            {
                throw new ArgumentNullException(nameof(inspectionContext));
            }

            var lmrType = proxyType.GetLmrType();
            Debug.Assert(!lmrType.IsGenericTypeDefinition);
            const BindingFlags bindingFlags =
                BindingFlags.CreateInstance |
                BindingFlags.Instance |
                BindingFlags.NonPublic |
                BindingFlags.Public;
            var constructor = lmrType.GetConstructors(bindingFlags).Single();
            var value = constructor.Invoke(bindingFlags, null, new[] { RawValue }, null);
            return new DkmClrValue(
                value,
                value,
                type: proxyType,
                alias: null,
                evalFlags: DkmEvaluationResultFlags.None,
                valueFlags: DkmClrValueFlags.None);
        }
Beispiel #6
0
 string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo typeInfo, ReadOnlyCollection<string> formatSpecifiers)
 {
     return GetTypeName(new TypeAndCustomInfo(type.GetLmrType(), typeInfo));
 }
Beispiel #7
0
 string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo typeInfo, ReadOnlyCollection<string> formatSpecifiers)
 {
     bool unused;
     return GetTypeName(new TypeAndCustomInfo(type.GetLmrType(), typeInfo), escapeKeywordIdentifiers: false, sawInvalidIdentifier: out unused);
 }
Beispiel #8
0
        private DkmEvaluationResult GetRootResult(DkmClrValue value, DkmClrType declaredType, string resultName)
        {
            var type = value.Type.GetLmrType();
            if (type.IsTypeVariables())
            {
                var expansion = new TypeVariablesExpansion(type);
                var dataItem = new EvalResultDataItem(
                    resultName,
                    typeDeclaringMember: null,
                    declaredType: type,
                    value: value,
                    expansion: expansion,
                    childShouldParenthesize: false,
                    fullName: null,
                    childFullNamePrefixOpt: null,
                    formatSpecifiers: Formatter.NoFormatSpecifiers,
                    category: DkmEvaluationResultCategory.Data,
                    flags: DkmEvaluationResultFlags.ReadOnly,
                    editableValue: null);

                Debug.Assert(dataItem.Flags == (DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable));

                // Note: We're not including value.EvalFlags in Flags parameter
                // below (there shouldn't be a reason to do so).
                return DkmSuccessEvaluationResult.Create(
                    InspectionContext: value.InspectionContext,
                    StackFrame: value.StackFrame,
                    Name: Resources.TypeVariablesName,
                    FullName: dataItem.FullName,
                    Flags: dataItem.Flags,
                    Value: "",
                    EditableValue: null,
                    Type: "",
                    Category: dataItem.Category,
                    Access: value.Access,
                    StorageType: value.StorageType,
                    TypeModifierFlags: value.TypeModifierFlags,
                    Address: value.Address,
                    CustomUIVisualizers: null,
                    ExternalModules: null,
                    DataItem: dataItem);
            }
            else
            {
                var inspectionContext = value.InspectionContext;
                if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ResultsOnly) != 0)
                {
                    return ResultsViewExpansion.CreateResultsOnly(resultName, declaredType, value, null, this.Formatter);
                }

                ReadOnlyCollection<string> formatSpecifiers;
                var fullName = this.Formatter.TrimAndGetFormatSpecifiers(resultName, out formatSpecifiers);
                var dataItem = CreateDataItem(
                    inspectionContext,
                    resultName,
                    typeDeclaringMember: null,
                    declaredType: declaredType.GetLmrType(),
                    value: value,
                    parent: null,
                    expansionFlags: ExpansionFlags.All,
                    childShouldParenthesize: this.Formatter.NeedsParentheses(fullName),
                    fullName: fullName,
                    formatSpecifiers: formatSpecifiers,
                    category: DkmEvaluationResultCategory.Other,
                    flags: value.EvalFlags,
                    evalFlags: inspectionContext.EvaluationFlags);
                return GetResult(dataItem, value.Type, declaredType, parent: null);
            }
        }
Beispiel #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 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));
 }
 public TypeAndCustomInfo(DkmClrType type)
     : this(type.GetLmrType(), null)
 {
 }
Beispiel #11
0
 public DkmClrValue InstantiateProxyType(DkmClrType proxyType)
 {
     var lmrType = proxyType.GetLmrType();
     Debug.Assert(!lmrType.IsGenericTypeDefinition);
     const BindingFlags bindingFlags =
         BindingFlags.CreateInstance |
         BindingFlags.Instance |
         BindingFlags.NonPublic |
         BindingFlags.Public;
     var constructor = lmrType.GetConstructors(bindingFlags).Single();
     var value = constructor.Invoke(bindingFlags, null, new[] { _rawValue }, null);
     return new DkmClrValue(
         value,
         value,
         type: proxyType,
         alias: null,
         formatter: _formatter,
         evalFlags: DkmEvaluationResultFlags.None,
         valueFlags: DkmClrValueFlags.None,
         inspectionContext: this.InspectionContext);
 }
        /// <summary>
        /// Generate a Results Only row if the value is a synthesized
        /// value declared as IEnumerable or IEnumerable&lt;T&gt;.
        /// </summary>
        internal static EvalResultDataItem CreateResultsOnlyRowIfSynthesizedEnumerable(
            DkmInspectionContext inspectionContext,
            string name,
            DkmClrType declaredType,
            DkmClrCustomTypeInfo declaredTypeInfo,
            DkmClrValue value,
            Formatter formatter)
        {
            if ((value.ValueFlags & DkmClrValueFlags.Synthetic) == 0)
            {
                return null;
            }

            // Must be declared as IEnumerable or IEnumerable<T>, not a derived type.
            var enumerableType = GetEnumerableType(value, declaredType, requireExactInterface: true);
            if (enumerableType == null)
            {
                return null;
            }

            var expansion = CreateExpansion(inspectionContext, value, enumerableType, formatter);
            if (expansion == null)
            {
                return null;
            }

            return expansion.CreateResultsViewRow(
                inspectionContext,
                name,
                new TypeAndCustomInfo(declaredType.GetLmrType(), declaredTypeInfo),
                value,
                includeResultsFormatSpecifier: false,
                formatter: formatter);
        }
        private static DkmClrType GetEnumerableType(DkmClrValue value, DkmClrType valueType, bool requireExactInterface)
        {
            if (!IsEnumerableCandidate(value))
            {
                return null;
            }

            var type = valueType.GetLmrType();
            Type enumerableType;
            if (requireExactInterface)
            {
                if (!type.IsIEnumerable() && !type.IsIEnumerableOfT())
                {
                    return null;
                }
                enumerableType = type;
            }
            else
            {
                enumerableType = type.GetIEnumerableImplementationIfAny();
                if (enumerableType == null)
                {
                    return null;
                }
            }

            return DkmClrType.Create(valueType.AppDomain, enumerableType);
        }
Beispiel #14
0
 string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType clrType)
 {
     return GetTypeName(clrType.GetLmrType());
 }
Beispiel #15
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;
 }
 /// <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;
 }
        private void GetRootResultAndContinue(
            DkmClrValue value,
            WorkList workList,
            DkmClrType declaredType,
            DkmClrCustomTypeInfo declaredTypeInfo,
            DkmInspectionContext inspectionContext,
            string name,
            CompletionRoutine<DkmEvaluationResult> completionRoutine)
        {
            var type = value.Type.GetLmrType();
            if (type.IsTypeVariables())
            {
                Debug.Assert(type.Equals(declaredType.GetLmrType()));
                var declaredTypeAndInfo = new TypeAndCustomInfo(type, declaredTypeInfo);
                var expansion = new TypeVariablesExpansion(declaredTypeAndInfo);
                var dataItem = new EvalResultDataItem(
                    ExpansionKind.Default,
                    name,
                    typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                    declaredTypeAndInfo: declaredTypeAndInfo,
                    parent: null,
                    value: value,
                    displayValue: null,
                    expansion: expansion,
                    childShouldParenthesize: false,
                    fullName: null,
                    childFullNamePrefixOpt: null,
                    formatSpecifiers: Formatter.NoFormatSpecifiers,
                    category: DkmEvaluationResultCategory.Data,
                    flags: DkmEvaluationResultFlags.ReadOnly,
                    editableValue: null,
                    inspectionContext: inspectionContext);

                Debug.Assert(dataItem.Flags == (DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable));

                // Note: We're not including value.EvalFlags in Flags parameter
                // below (there shouldn't be a reason to do so).
                completionRoutine(DkmSuccessEvaluationResult.Create(
                    InspectionContext: inspectionContext,
                    StackFrame: value.StackFrame,
                    Name: Resources.TypeVariablesName,
                    FullName: dataItem.FullName,
                    Flags: dataItem.Flags,
                    Value: "",
                    EditableValue: null,
                    Type: "",
                    Category: dataItem.Category,
                    Access: value.Access,
                    StorageType: value.StorageType,
                    TypeModifierFlags: value.TypeModifierFlags,
                    Address: value.Address,
                    CustomUIVisualizers: null,
                    ExternalModules: null,
                    DataItem: dataItem));
            }
            else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ResultsOnly) != 0)
            {
                var dataItem = ResultsViewExpansion.CreateResultsOnlyRow(
                    inspectionContext,
                    name,
                    declaredType,
                    declaredTypeInfo,
                    value,
                    this.Formatter);
                CreateEvaluationResultAndContinue(
                    dataItem,
                    workList,
                    inspectionContext,
                    value.StackFrame,
                    completionRoutine);
            }
            else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.DynamicView) != 0)
            {
                var dataItem = DynamicViewExpansion.CreateMembersOnlyRow(
                    inspectionContext,
                    name,
                    value,
                    this.Formatter);
                CreateEvaluationResultAndContinue(
                    dataItem,
                    workList,
                    inspectionContext,
                    value.StackFrame,
                    completionRoutine);
            }
            else
            {
                var dataItem = ResultsViewExpansion.CreateResultsOnlyRowIfSynthesizedEnumerable(
                    inspectionContext,
                    name,
                    declaredType,
                    declaredTypeInfo,
                    value,
                    this.Formatter);
                if (dataItem != null)
                {
                    CreateEvaluationResultAndContinue(
                        dataItem,
                        workList,
                        inspectionContext,
                        value.StackFrame,
                        completionRoutine);
                }
                else
                {
                    ReadOnlyCollection<string> formatSpecifiers;
                    var fullName = this.Formatter.TrimAndGetFormatSpecifiers(name, out formatSpecifiers);
                    dataItem = CreateDataItem(
                        inspectionContext,
                        name,
                        typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                        declaredTypeAndInfo: new TypeAndCustomInfo(declaredType.GetLmrType(), declaredTypeInfo),
                        value: value,
                        parent: null,
                        expansionFlags: ExpansionFlags.All,
                        childShouldParenthesize: this.Formatter.NeedsParentheses(fullName),
                        fullName: fullName,
                        formatSpecifiers: formatSpecifiers,
                        category: DkmEvaluationResultCategory.Other,
                        flags: value.EvalFlags,
                        evalFlags: inspectionContext.EvaluationFlags);
                    GetResultAndContinue(dataItem, workList, declaredType, declaredTypeInfo, inspectionContext, parent: null, completionRoutine: completionRoutine);
                }
            }
        }
 void IDkmClrResultProvider.GetResult(DkmClrValue clrValue, DkmWorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo customTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine)
 {
     clrValue.GetResult(
         workList,
         declaredType,
         customTypeInfo,
         inspectionContext,
         formatSpecifiers,
         resultName,
         resultFullName,
         result =>
         {
             var type = declaredType.GetLmrType();
             if (type.IsPointer)
             {
                 var r = (DkmSuccessEvaluationResult)result.Result;
                 // TODO: Why aren't modopts for & properties included?
                 r.GetChildren(
                     workList,
                     1,
                     inspectionContext,
                     children =>
                     {
                         var c = (DkmSuccessEvaluationResult)children.InitialChildren[0];
                         r = DkmSuccessEvaluationResult.Create(
                             c.InspectionContext,
                             c.StackFrame,
                             r.Name,
                             r.FullName,
                             c.Flags,
                             c.Value,
                             r.EditableValue,
                             r.Type,
                             r.Category,
                             r.Access,
                             r.StorageType,
                             r.TypeModifierFlags,
                             null,
                             r.CustomUIVisualizers,
                             null,
                             null);
                         completionRoutine(new DkmEvaluationAsyncResult(r));
                     });
             }
             else
             {
                 completionRoutine(result);
             }
         });
 }