예제 #1
0
        internal static DynamicViewExpansion CreateExpansion(DkmInspectionContext inspectionContext, DkmClrValue value, Formatter formatter)
        {
            if (value.IsError() || value.IsNull || value.HasExceptionThrown())
            {
                return null;
            }

            var type = value.Type.GetLmrType();
            if (!(type.IsComObject() || type.IsIDynamicMetaObjectProvider()))
            {
                return null;
            }

            var proxyValue = value.InstantiateDynamicViewProxy(inspectionContext);
            Debug.Assert((proxyValue == null) || (!proxyValue.IsNull && !proxyValue.IsError() && !proxyValue.HasExceptionThrown()));
            // InstantiateDynamicViewProxy may return null (if required assembly is missing, for instance).
            if (proxyValue == null)
            {
                return null;
            }

            // Expansion is based on the 'DynamicMetaObjectProviderDebugView.Items' property.
            var proxyType = proxyValue.Type;
            var itemsMemberExpansion = RootHiddenExpansion.CreateExpansion(
                proxyType.GetMemberByName("Items"),
                DynamicFlagsMap.Create(new TypeAndCustomInfo(proxyType)));
            return new DynamicViewExpansion(proxyValue, itemsMemberExpansion);
        }
        /// <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);
        }
예제 #3
0
 internal static string GetExceptionMessage(this DkmClrValue value, string fullNameWithoutFormatSpecifiers, Formatter formatter)
 {
     return string.Format(
         Resources.ExceptionThrown,
         fullNameWithoutFormatSpecifiers,
         formatter.GetTypeName(value.Type.GetLmrType()));
 }
예제 #4
0
 internal static string GetExceptionMessage(this DkmClrValue value, string fullNameWithoutFormatSpecifiers, Formatter formatter)
 {
     bool unused;
     return string.Format(
         Resources.ExceptionThrown,
         fullNameWithoutFormatSpecifiers,
         formatter.GetTypeName(new TypeAndCustomInfo(value.Type), escapeKeywordIdentifiers: false, sawInvalidIdentifier: out unused));
 }
 internal static ResultsViewExpansion CreateExpansion(DkmInspectionContext inspectionContext, DkmClrValue value, Formatter formatter)
 {
     var enumerableType = GetEnumerableType(value);
     if (enumerableType == null)
     {
         return null;
     }
     return CreateExpansion(inspectionContext, value, enumerableType, formatter);
 }
예제 #6
0
 internal static EvalResultDataItem CreateMembersOnlyRow(
     DkmInspectionContext inspectionContext,
     string name,
     DkmClrValue value,
     Formatter formatter)
 {
     var expansion = CreateExpansion(inspectionContext, value, formatter);
     return (expansion != null) ?
         expansion.CreateDynamicViewRow(inspectionContext, name, parent: null, formatter: formatter) :
         new EvalResultDataItem(name, Resources.DynamicViewNotDynamic);
 }
예제 #7
0
        internal static DkmEvaluationResult CreateResultsOnly(
            string name,
            DkmClrType declaredType,
            DkmClrValue value,
            EvalResultDataItem parent,
            Formatter formatter)
        {
            string errorMessage;
            if (value.IsError())
            {
                errorMessage = (string)value.HostObjectValue;
            }
            else if (value.HasExceptionThrown(parent))
            {
                errorMessage = value.GetExceptionMessage(name, formatter);
            }
            else
            {
                var enumerableType = GetEnumerableType(value);
                if (enumerableType != null)
                {
                    var expansion = CreateExpansion(value, enumerableType, formatter);
                    if (expansion != null)
                    {
                        return expansion.CreateEvaluationResult(name, parent, formatter);
                    }
                    errorMessage = Resources.ResultsViewNoSystemCore;
                }
                else
                {
                    errorMessage = Resources.ResultsViewNotEnumerable;
                }
            }

            Debug.Assert(errorMessage != null);
            return DkmFailedEvaluationResult.Create(
                InspectionContext: value.InspectionContext,
                StackFrame: value.StackFrame,
                Name: name,
                FullName: null,
                ErrorMessage: errorMessage,
                Flags: DkmEvaluationResultFlags.None,
                Type: null,
                DataItem: null);
        }
        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);
        }
 private EvalResultDataItem CreateResultsViewRow(
     DkmInspectionContext inspectionContext,
     string name,
     TypeAndCustomInfo declaredTypeAndInfo,
     DkmClrValue value,
     bool includeResultsFormatSpecifier,
     Formatter formatter)
 {
     var proxyTypeAndInfo = new TypeAndCustomInfo(_proxyValue.Type);
     ReadOnlyCollection<string> formatSpecifiers;
     var fullName = formatter.TrimAndGetFormatSpecifiers(name, out formatSpecifiers);
     if (includeResultsFormatSpecifier)
     {
         formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, ResultsFormatSpecifier);
     }
     bool unused;
     var childFullNamePrefix = formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true, sawInvalidIdentifier: out unused), fullName);
     return new EvalResultDataItem(
         ExpansionKind.Default,
         name,
         typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
         declaredTypeAndInfo: declaredTypeAndInfo,
         parent: null,
         value: value,
         displayValue: null,
         expansion: new IndirectExpansion(_proxyValue, _proxyMembers),
         childShouldParenthesize: false,
         fullName: fullName,
         childFullNamePrefixOpt: childFullNamePrefix,
         formatSpecifiers: formatSpecifiers,
         category: DkmEvaluationResultCategory.Method,
         flags: DkmEvaluationResultFlags.ReadOnly,
         editableValue: null,
         inspectionContext: inspectionContext);
 }
예제 #10
0
 private static string GetFullName(EvalResultDataItem parent, string name, Formatter formatter)
 {
     var parentFullName = parent.ChildFullNamePrefix;
     if (parent.ChildShouldParenthesize)
     {
         parentFullName = $"({parentFullName})";
     }
     var parentRuntimeType = parent.Value.Type.GetLmrType();
     if (!parent.DeclaredTypeAndInfo.Type.Equals(parentRuntimeType))
     {
         parentFullName = formatter.GetCastExpression(
             parentFullName,
             formatter.GetTypeName(new TypeAndCustomInfo(parentRuntimeType), escapeKeywordIdentifiers: true),
             parenthesizeEntireExpression: true);
     }
     return parentFullName + name;
 }
예제 #11
0
        internal static Expansion CreateExpansion(
            DkmInspectionContext inspectionContext,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            ExpansionFlags flags,
            Predicate <MemberInfo> predicate,
            Formatter formatter)
        {
            // For members of type DynamicProperty (part of Dynamic View expansion), we want
            // to expand the underlying value (not the members of the DynamicProperty type).
            var type = value.Type;
            var isDynamicProperty = type.GetLmrType().IsDynamicProperty();

            if (isDynamicProperty)
            {
                Debug.Assert(!value.IsNull);
                value = value.GetFieldValue("value", inspectionContext);
            }

            var runtimeType = type.GetLmrType();

            // Primitives, enums and null values with a declared type that is an interface have no visible members.
            Debug.Assert(!runtimeType.IsInterface || value.IsNull);
            if (formatter.IsPredefinedType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface)
            {
                return(null);
            }

            // As in the old C# EE, DynamicProperty members are only expandable if they have a Dynamic View expansion.
            var dynamicViewExpansion = DynamicViewExpansion.CreateExpansion(inspectionContext, value, formatter);

            if (isDynamicProperty && (dynamicViewExpansion == null))
            {
                return(null);
            }

            var dynamicFlagsMap = DynamicFlagsMap.Create(declaredTypeAndInfo);

            var expansions = ArrayBuilder <Expansion> .GetInstance();

            // From the members, collect the fields and properties,
            // separated into static and instance members.
            var staticMembers = ArrayBuilder <MemberAndDeclarationInfo> .GetInstance();

            var instanceMembers = ArrayBuilder <MemberAndDeclarationInfo> .GetInstance();

            var appDomain = value.Type.AppDomain;

            // Expand members. (Ideally, this should be done lazily.)
            var allMembers = ArrayBuilder <MemberAndDeclarationInfo> .GetInstance();

            var includeInherited = (flags & ExpansionFlags.IncludeBaseMembers) == ExpansionFlags.IncludeBaseMembers;
            var hideNonPublic    = (inspectionContext.EvaluationFlags & DkmEvaluationFlags.HideNonPublicMembers) == DkmEvaluationFlags.HideNonPublicMembers;

            runtimeType.AppendTypeMembers(allMembers, predicate, declaredTypeAndInfo.Type, appDomain, includeInherited, hideNonPublic);

            foreach (var member in allMembers)
            {
                var name = member.Name;
                if (name.IsCompilerGenerated())
                {
                    continue;
                }
                if (member.IsStatic)
                {
                    staticMembers.Add(member);
                }
                else if (!value.IsNull)
                {
                    instanceMembers.Add(member);
                }
            }

            allMembers.Free();

            // Public and non-public instance members.
            Expansion publicInstanceExpansion;
            Expansion nonPublicInstanceExpansion;

            GetPublicAndNonPublicMembers(
                instanceMembers,
                dynamicFlagsMap,
                out publicInstanceExpansion,
                out nonPublicInstanceExpansion);

            // Public and non-public static members.
            Expansion publicStaticExpansion;
            Expansion nonPublicStaticExpansion;

            GetPublicAndNonPublicMembers(
                staticMembers,
                dynamicFlagsMap,
                out publicStaticExpansion,
                out nonPublicStaticExpansion);

            if (publicInstanceExpansion != null)
            {
                expansions.Add(publicInstanceExpansion);
            }

            if ((publicStaticExpansion != null) || (nonPublicStaticExpansion != null))
            {
                var staticExpansions = ArrayBuilder <Expansion> .GetInstance();

                if (publicStaticExpansion != null)
                {
                    staticExpansions.Add(publicStaticExpansion);
                }
                if (nonPublicStaticExpansion != null)
                {
                    staticExpansions.Add(nonPublicStaticExpansion);
                }
                Debug.Assert(staticExpansions.Count > 0);
                var staticMembersExpansion = new StaticMembersExpansion(
                    runtimeType,
                    AggregateExpansion.CreateExpansion(staticExpansions));
                staticExpansions.Free();
                expansions.Add(staticMembersExpansion);
            }

            if (value.NativeComPointer != 0)
            {
                expansions.Add(NativeViewExpansion.Instance);
            }

            if (nonPublicInstanceExpansion != null)
            {
                expansions.Add(nonPublicInstanceExpansion);
            }

            // Include Results View if necessary.
            if ((flags & ExpansionFlags.IncludeResultsView) != 0)
            {
                var resultsViewExpansion = ResultsViewExpansion.CreateExpansion(inspectionContext, value, formatter);
                if (resultsViewExpansion != null)
                {
                    expansions.Add(resultsViewExpansion);
                }
            }

            if (dynamicViewExpansion != null)
            {
                expansions.Add(dynamicViewExpansion);
            }

            var result = AggregateExpansion.CreateExpansion(expansions);

            expansions.Free();
            return(result);
        }
 private EvalResultDataItem CreateResultsViewRow(DkmInspectionContext inspectionContext, EvalResultDataItem parent, Formatter formatter)
 {
     Debug.Assert(parent != null);
     var proxyTypeAndInfo = new TypeAndCustomInfo(_proxyValue.Type);
     var fullName = parent.ChildFullNamePrefix;
     bool unused;
     var childFullNamePrefix = (fullName == null) ?
         null :
         formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true, sawInvalidIdentifier: out unused), fullName);
     return new EvalResultDataItem(
         ExpansionKind.ResultsView,
         Resources.ResultsView,
         typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
         declaredTypeAndInfo: proxyTypeAndInfo,
         parent: null,
         value: _proxyValue,
         displayValue: Resources.ResultsViewValueWarning,
         expansion: _proxyMembers,
         childShouldParenthesize: false,
         fullName: fullName,
         childFullNamePrefixOpt: childFullNamePrefix,
         formatSpecifiers: Formatter.AddFormatSpecifier(parent.FormatSpecifiers, ResultsFormatSpecifier),
         category: DkmEvaluationResultCategory.Method,
         flags: DkmEvaluationResultFlags.ReadOnly,
         editableValue: null,
         inspectionContext: inspectionContext);
 }
예제 #13
0
        internal EvalResult CreateDataItem(
            DkmInspectionContext inspectionContext,
            string name,
            TypeAndCustomInfo typeDeclaringMemberAndInfo,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            bool useDebuggerDisplay,
            ExpansionFlags expansionFlags,
            bool childShouldParenthesize,
            string fullName,
            ReadOnlyCollection <string> formatSpecifiers,
            DkmEvaluationResultCategory category,
            DkmEvaluationResultFlags flags,
            DkmEvaluationFlags evalFlags)
        {
            if ((evalFlags & DkmEvaluationFlags.ShowValueRaw) != 0)
            {
                formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, "raw");
            }

            Expansion expansion;
            // If the declared type is Nullable<T>, the value should
            // have no expansion if null, or be expanded as a T.
            var declaredType       = declaredTypeAndInfo.Type;
            var lmrNullableTypeArg = declaredType.GetNullableTypeArgument();

            if (lmrNullableTypeArg != null && !value.HasExceptionThrown())
            {
                Debug.Assert(value.Type.GetProxyType() == null);

                DkmClrValue nullableValue;
                if (value.IsError())
                {
                    expansion = null;
                }
                else if ((nullableValue = value.GetNullableValue(lmrNullableTypeArg, inspectionContext)) == null)
                {
                    Debug.Assert(declaredType.Equals(value.Type.GetLmrType()));
                    // No expansion of "null".
                    expansion = null;
                }
                else
                {
                    value = nullableValue;
                    Debug.Assert(lmrNullableTypeArg.Equals(value.Type.GetLmrType())); // If this is not the case, add a test for includeRuntimeTypeIfNecessary.
                    // CONSIDER: The DynamicAttribute for the type argument should just be Skip(1) of the original flag array.
                    expansion = this.GetTypeExpansion(inspectionContext, new TypeAndCustomInfo(DkmClrType.Create(declaredTypeAndInfo.ClrType.AppDomain, lmrNullableTypeArg)), value, ExpansionFlags.IncludeResultsView);
                }
            }
            else if (value.IsError() || (inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0)
            {
                expansion = null;
            }
            else
            {
                expansion = DebuggerTypeProxyExpansion.CreateExpansion(
                    this,
                    inspectionContext,
                    name,
                    typeDeclaringMemberAndInfo,
                    declaredTypeAndInfo,
                    value,
                    childShouldParenthesize,
                    fullName,
                    flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName,
                    formatSpecifiers,
                    flags,
                    Formatter2.GetEditableValueString(value, inspectionContext, declaredTypeAndInfo.Info));
                if (expansion == null)
                {
                    expansion = value.HasExceptionThrown()
                        ? this.GetTypeExpansion(inspectionContext, new TypeAndCustomInfo(value.Type), value, expansionFlags)
                        : this.GetTypeExpansion(inspectionContext, declaredTypeAndInfo, value, expansionFlags);
                }
            }

            return(new EvalResult(
                       ExpansionKind.Default,
                       name,
                       typeDeclaringMemberAndInfo,
                       declaredTypeAndInfo,
                       useDebuggerDisplay: useDebuggerDisplay,
                       value: value,
                       displayValue: null,
                       expansion: expansion,
                       childShouldParenthesize: childShouldParenthesize,
                       fullName: fullName,
                       childFullNamePrefixOpt: flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName,
                       formatSpecifiers: formatSpecifiers,
                       category: category,
                       flags: flags,
                       editableValue: Formatter2.GetEditableValueString(value, inspectionContext, declaredTypeAndInfo.Info),
                       inspectionContext: inspectionContext));
        }
        private static ResultsViewExpansion CreateExpansion(DkmInspectionContext inspectionContext, DkmClrValue value, DkmClrType enumerableType, Formatter formatter)
        {
            var proxyValue = value.InstantiateResultsViewProxy(inspectionContext, enumerableType);
            // InstantiateResultsViewProxy may return null (if required assembly is missing, for instance).
            if (proxyValue == null)
            {
                return null;
            }

            var proxyMembers = MemberExpansion.CreateExpansion(
                inspectionContext,
                new TypeAndCustomInfo(proxyValue.Type),
                proxyValue,
                flags: ExpansionFlags.None,
                predicate: TypeHelpers.IsPublic,
                formatter: formatter);
            return new ResultsViewExpansion(proxyValue, proxyMembers);
        }
예제 #15
0
        private DebuggerTypeProxyExpansion(
            DkmInspectionContext inspectionContext,
            DkmClrValue proxyValue,
            string name,
            TypeAndCustomInfo typeDeclaringMemberAndInfoOpt,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            bool childShouldParenthesize,
            string fullName,
            string childFullNamePrefix,
            ReadOnlyCollection <string> formatSpecifiers,
            DkmEvaluationResultFlags flags,
            string editableValue,
            Formatter formatter)
        {
            Debug.Assert(proxyValue != null);
            var proxyType        = proxyValue.Type.GetLmrType();
            var proxyTypeAndInfo = new TypeAndCustomInfo(proxyType);
            var proxyMembers     = MemberExpansion.CreateExpansion(
                inspectionContext,
                proxyTypeAndInfo,
                proxyValue,
                ExpansionFlags.IncludeBaseMembers,
                TypeHelpers.IsPublic,
                formatter);

            if (proxyMembers != null)
            {
                var proxyMemberFullNamePrefix = (childFullNamePrefix == null) ?
                                                null :
                                                formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true), childFullNamePrefix);
                _proxyItem = new EvalResultDataItem(
                    ExpansionKind.Default,
                    name: string.Empty,
                    typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                    declaredTypeAndInfo: proxyTypeAndInfo,
                    parent: null,
                    value: proxyValue,
                    displayValue: null,
                    expansion: proxyMembers,
                    childShouldParenthesize: false,
                    fullName: null,
                    childFullNamePrefixOpt: proxyMemberFullNamePrefix,
                    formatSpecifiers: Formatter.NoFormatSpecifiers,
                    category: default(DkmEvaluationResultCategory),
                    flags: default(DkmEvaluationResultFlags),
                    editableValue: null,
                    inspectionContext: inspectionContext);
            }

            _name = name;
            _typeDeclaringMemberAndInfoOpt = typeDeclaringMemberAndInfoOpt;
            _declaredTypeAndInfo           = declaredTypeAndInfo;
            _value = value;
            _childShouldParenthesize = childShouldParenthesize;
            _fullName            = fullName;
            _childFullNamePrefix = childFullNamePrefix;
            _formatSpecifiers    = formatSpecifiers;
            _flags         = flags;
            _editableValue = editableValue;
        }
예제 #16
0
 internal static string GetExceptionMessage(this DkmClrValue value, string fullNameWithoutFormatSpecifiers, Formatter formatter)
 {
     return(string.Format(
                Resources.ExceptionThrown,
                fullNameWithoutFormatSpecifiers,
                formatter.GetTypeName(new TypeAndCustomInfo(value.Type))));
 }
예제 #17
0
        private static string MakeFullName(
            Formatter formatter,
            string name,
            TypeAndCustomInfo typeDeclaringMemberAndInfo,
            bool memberAccessRequiresExplicitCast,
            bool memberIsStatic,
            EvalResultDataItem parent)
        {
            // If the parent is an exception thrown during evaluation,
            // there is no valid fullname expression for the child.
            if (parent.Value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown))
            {
                return(null);
            }

            var parentFullName = parent.ChildFullNamePrefix;

            if (parentFullName == null)
            {
                return(null);
            }

            if (parent.ChildShouldParenthesize)
            {
                parentFullName = $"({parentFullName})";
            }

            if (!typeDeclaringMemberAndInfo.Type.IsInterface)
            {
                string qualifier;
                if (memberIsStatic)
                {
                    qualifier = formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: false);
                }
                else if (memberAccessRequiresExplicitCast)
                {
                    var typeName = formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: true);
                    qualifier = formatter.GetCastExpression(
                        parentFullName,
                        typeName,
                        parenthesizeEntireExpression: true);
                }
                else
                {
                    qualifier = parentFullName;
                }
                return($"{qualifier}.{name}");
            }
            else
            {
                // NOTE: This should never interact with debugger proxy types:
                //   1) Interfaces cannot have debugger proxy types.
                //   2) Debugger proxy types cannot be interfaces.
                if (typeDeclaringMemberAndInfo.Type.Equals(parent.DeclaredTypeAndInfo.Type))
                {
                    var memberAccessTemplate = parent.ChildShouldParenthesize
                        ? "({0}).{1}"
                        : "{0}.{1}";
                    return(string.Format(memberAccessTemplate, parent.ChildFullNamePrefix, name));
                }
                else
                {
                    var interfaceName        = formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: true);
                    var memberAccessTemplate = parent.ChildShouldParenthesize
                        ? "(({0})({1})).{2}"
                        : "(({0}){1}).{2}";
                    return(string.Format(memberAccessTemplate, interfaceName, parent.ChildFullNamePrefix, name));
                }
            }
        }
예제 #18
0
        private static ResultsViewExpansion CreateExpansion(DkmClrValue value, DkmClrType enumerableType, Formatter formatter)
        {
            var proxyValue = value.InstantiateResultsViewProxy(enumerableType);

            // InstantiateResultsViewProxy may return null
            // (if assembly is missing for instance).
            if (proxyValue == null)
            {
                return(null);
            }

            var proxyMembers = MemberExpansion.CreateExpansion(
                proxyValue.Type.GetLmrType(),
                proxyValue,
                ExpansionFlags.None,
                TypeHelpers.IsPublic,
                formatter);

            return(new ResultsViewExpansion(proxyValue, proxyMembers));
        }
예제 #19
0
        internal static Expansion CreateExpansion(
            DkmInspectionContext inspectionContext,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            ExpansionFlags flags,
            Predicate<MemberInfo> predicate,
            Formatter formatter)
        {
            // For members of type DynamicProperty (part of Dynamic View expansion), we want
            // to expand the underlying value (not the members of the DynamicProperty type).
            var type = value.Type;
            var isDynamicProperty = type.GetLmrType().IsDynamicProperty();
            if (isDynamicProperty)
            {
                Debug.Assert(!value.IsNull);
                value = value.GetFieldValue("value", inspectionContext);
            }

            var runtimeType = type.GetLmrType();
            // Primitives, enums and null values with a declared type that is an interface have no visible members.
            Debug.Assert(!runtimeType.IsInterface || value.IsNull);
            if (formatter.IsPredefinedType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface)
            {
                return null;
            }

            // As in the old C# EE, DynamicProperty members are only expandable if they have a Dynamic View expansion.
            var dynamicViewExpansion = DynamicViewExpansion.CreateExpansion(inspectionContext, value, formatter);
            if (isDynamicProperty && (dynamicViewExpansion == null))
            {
                return null;
            }

            var dynamicFlagsMap = DynamicFlagsMap.Create(declaredTypeAndInfo);

            var expansions = ArrayBuilder<Expansion>.GetInstance();

            // From the members, collect the fields and properties,
            // separated into static and instance members.
            var staticMembers = ArrayBuilder<MemberAndDeclarationInfo>.GetInstance();
            var instanceMembers = ArrayBuilder<MemberAndDeclarationInfo>.GetInstance();
            var appDomain = value.Type.AppDomain;

            // Expand members. (Ideally, this should be done lazily.)
            var allMembers = ArrayBuilder<MemberAndDeclarationInfo>.GetInstance();
            var includeInherited = (flags & ExpansionFlags.IncludeBaseMembers) == ExpansionFlags.IncludeBaseMembers;
            var hideNonPublic = (inspectionContext.EvaluationFlags & DkmEvaluationFlags.HideNonPublicMembers) == DkmEvaluationFlags.HideNonPublicMembers;
            runtimeType.AppendTypeMembers(allMembers, predicate, declaredTypeAndInfo.Type, appDomain, includeInherited, hideNonPublic);

            foreach (var member in allMembers)
            {
                var name = member.Name;
                if (name.IsCompilerGenerated())
                {
                    continue;
                }
                if (member.IsStatic)
                {
                    staticMembers.Add(member);
                }
                else if (!value.IsNull)
                {
                    instanceMembers.Add(member);
                }
            }

            allMembers.Free();

            // Public and non-public instance members.
            Expansion publicInstanceExpansion;
            Expansion nonPublicInstanceExpansion;
            GetPublicAndNonPublicMembers(
                instanceMembers,
                dynamicFlagsMap,
                out publicInstanceExpansion,
                out nonPublicInstanceExpansion);

            // Public and non-public static members.
            Expansion publicStaticExpansion;
            Expansion nonPublicStaticExpansion;
            GetPublicAndNonPublicMembers(
                staticMembers,
                dynamicFlagsMap,
                out publicStaticExpansion,
                out nonPublicStaticExpansion);

            if (publicInstanceExpansion != null)
            {
                expansions.Add(publicInstanceExpansion);
            }

            if ((publicStaticExpansion != null) || (nonPublicStaticExpansion != null))
            {
                var staticExpansions = ArrayBuilder<Expansion>.GetInstance();
                if (publicStaticExpansion != null)
                {
                    staticExpansions.Add(publicStaticExpansion);
                }
                if (nonPublicStaticExpansion != null)
                {
                    staticExpansions.Add(nonPublicStaticExpansion);
                }
                Debug.Assert(staticExpansions.Count > 0);
                var staticMembersExpansion = new StaticMembersExpansion(
                    runtimeType,
                    AggregateExpansion.CreateExpansion(staticExpansions));
                staticExpansions.Free();
                expansions.Add(staticMembersExpansion);
            }

            if (value.NativeComPointer != 0)
            {
                expansions.Add(NativeViewExpansion.Instance);
            }

            if (nonPublicInstanceExpansion != null)
            {
                expansions.Add(nonPublicInstanceExpansion);
            }

            // Include Results View if necessary.
            if ((flags & ExpansionFlags.IncludeResultsView) != 0)
            {
                var resultsViewExpansion = ResultsViewExpansion.CreateExpansion(inspectionContext, value, formatter);
                if (resultsViewExpansion != null)
                {
                    expansions.Add(resultsViewExpansion);
                }
            }

            if (dynamicViewExpansion != null)
            {
                expansions.Add(dynamicViewExpansion);
            }

            var result = AggregateExpansion.CreateExpansion(expansions);
            expansions.Free();
            return result;
        }
예제 #20
0
        private static ResultsViewExpansion CreateExpansion(DkmClrValue value, DkmClrType enumerableType, Formatter formatter)
        {
            var proxyValue = value.InstantiateResultsViewProxy(enumerableType);
            // InstantiateResultsViewProxy may return null
            // (if assembly is missing for instance).
            if (proxyValue == null)
            {
                return null;
            }

            var proxyMembers = MemberExpansion.CreateExpansion(
                proxyValue.Type.GetLmrType(),
                proxyValue,
                ExpansionFlags.None,
                TypeHelpers.IsPublic,
                formatter);
            return new ResultsViewExpansion(proxyValue, proxyMembers);
        }
예제 #21
0
        private static EvalResult GetMemberRow(
            ResultProvider resultProvider,
            DkmInspectionContext inspectionContext,
            DkmClrValue value,
            Field field,
            EvalResultDataItem parent,
            int cardinality)
        {
            var fullNameProvider = resultProvider.FullNameProvider;
            var parentFullName   = parent.ChildFullNamePrefix;

            if (parentFullName != null)
            {
                if (parent.ChildShouldParenthesize)
                {
                    parentFullName = parentFullName.Parenthesize();
                }
                var parentRuntimeType = parent.Value.Type;
                if (!parent.DeclaredTypeAndInfo.Type.Equals(parentRuntimeType.GetLmrType()))
                {
                    parentFullName = fullNameProvider.GetClrCastExpression(
                        inspectionContext,
                        parentFullName,
                        parentRuntimeType,
                        customTypeInfo: null,
                        castExpressionOptions: DkmClrCastExpressionOptions.ParenthesizeEntireExpression);
                }
            }

            // Ideally if the caller requests multiple items in a nested tuple
            // we should only evaluate Rest once, and should only calculate
            // the full name for Rest once.
            string fullName;
            var    fieldValue = GetValueAndFullName(
                fullNameProvider,
                inspectionContext,
                value,
                field,
                parentFullName,
                out fullName);
            var name = field.Name;
            var typeDeclaringMemberAndInfo = default(TypeAndCustomInfo);
            var declaredTypeAndInfo        = field.FieldTypeAndInfo;
            var flags            = fieldValue.EvalFlags;
            var formatSpecifiers = Formatter.NoFormatSpecifiers;

            if (field.IsRest)
            {
                var displayValue = fieldValue.GetValueString(inspectionContext, Formatter.NoFormatSpecifiers);
                var displayType  = ResultProvider.GetTypeName(
                    inspectionContext,
                    fieldValue,
                    declaredTypeAndInfo.ClrType,
                    declaredTypeAndInfo.Info,
                    isPointerDereference: false);
                var expansion = new TupleExpansion(declaredTypeAndInfo, cardinality - (TypeHelpers.TupleFieldRestPosition - 1), useRawView: true);
                return(new EvalResult(
                           ExpansionKind.Explicit,
                           name,
                           typeDeclaringMemberAndInfo,
                           declaredTypeAndInfo,
                           useDebuggerDisplay: false,
                           value: fieldValue,
                           displayValue: displayValue,
                           expansion: expansion,
                           childShouldParenthesize: false,
                           fullName: fullName,
                           childFullNamePrefixOpt: flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName,
                           formatSpecifiers: Formatter.AddFormatSpecifier(formatSpecifiers, "raw"),
                           category: DkmEvaluationResultCategory.Other,
                           flags: flags,
                           editableValue: null,
                           inspectionContext: inspectionContext,
                           displayName: name,
                           displayType: displayType));
            }

            return(resultProvider.CreateDataItem(
                       inspectionContext,
                       name,
                       typeDeclaringMemberAndInfo: typeDeclaringMemberAndInfo,
                       declaredTypeAndInfo: declaredTypeAndInfo,
                       value: fieldValue,
                       useDebuggerDisplay: false,
                       expansionFlags: ExpansionFlags.All,
                       childShouldParenthesize: false,
                       fullName: fullName,
                       formatSpecifiers: formatSpecifiers,
                       category: DkmEvaluationResultCategory.Other,
                       flags: flags,
                       evalFlags: DkmEvaluationFlags.None,
                       canFavorite: false,
                       isFavorite: false,
                       supportsFavorites: true));
        }
예제 #22
0
        private DebuggerTypeProxyExpansion(
            DkmInspectionContext inspectionContext,
            DkmClrValue proxyValue,
            string name,
            TypeAndCustomInfo typeDeclaringMemberAndInfoOpt,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            bool childShouldParenthesize,
            string fullName,
            string childFullNamePrefix,
            ReadOnlyCollection<string> formatSpecifiers,
            DkmEvaluationResultFlags flags,
            string editableValue,
            Formatter formatter)
        {
            Debug.Assert(proxyValue != null);
            var proxyType = proxyValue.Type.GetLmrType();
            var proxyTypeAndInfo = new TypeAndCustomInfo(proxyType);
            var proxyMembers = MemberExpansion.CreateExpansion(
                inspectionContext,
                proxyTypeAndInfo,
                proxyValue,
                ExpansionFlags.IncludeBaseMembers,
                TypeHelpers.IsPublic,
                formatter);
            if (proxyMembers != null)
            {
                var proxyMemberFullNamePrefix = (childFullNamePrefix == null) ?
                    null :
                    formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true), childFullNamePrefix);
                _proxyItem = new EvalResultDataItem(
                    ExpansionKind.Default,
                    name: string.Empty,
                    typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                    declaredTypeAndInfo: proxyTypeAndInfo,
                    parent: null,
                    value: proxyValue,
                    displayValue: null,
                    expansion: proxyMembers,
                    childShouldParenthesize: false,
                    fullName: null,
                    childFullNamePrefixOpt: proxyMemberFullNamePrefix,
                    formatSpecifiers: Formatter.NoFormatSpecifiers,
                    category: default(DkmEvaluationResultCategory),
                    flags: default(DkmEvaluationResultFlags),
                    editableValue: null,
                    inspectionContext: inspectionContext);
            }

            _name = name;
            _typeDeclaringMemberAndInfoOpt = typeDeclaringMemberAndInfoOpt;
            _declaredTypeAndInfo = declaredTypeAndInfo;
            _value = value;
            _childShouldParenthesize = childShouldParenthesize;
            _fullName = fullName;
            _childFullNamePrefix = childFullNamePrefix;
            _formatSpecifiers = formatSpecifiers;
            _flags = flags;
            _editableValue = editableValue;
        }
예제 #23
0
 internal ResultProvider(Formatter formatter)
 {
     this.Formatter = formatter;
 }
예제 #24
0
        private DkmEvaluationResult CreateEvaluationResult(string name, EvalResultDataItem parent, Formatter formatter)
        {
            var proxyType = _proxyValue.Type.GetLmrType();
            string fullName;
            ReadOnlyCollection<string> formatSpecifiers;
            bool childShouldParenthesize;
            if (parent == null)
            {
                Debug.Assert(name != null);
                fullName = formatter.TrimAndGetFormatSpecifiers(name, out formatSpecifiers);
                childShouldParenthesize = formatter.NeedsParentheses(fullName);
            }
            else
            {
                fullName = parent.ChildFullNamePrefix;
                formatSpecifiers = parent.FormatSpecifiers;
                childShouldParenthesize = false;
            }

            var childFullNamePrefix = (fullName == null) ?
                null :
                formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyType, escapeKeywordIdentifiers: true), fullName);
            var dataItem = new EvalResultDataItem(
                name: name,
                typeDeclaringMember: null,
                declaredType: proxyType,
                value: _proxyValue,
                expansion: _proxyMembers,
                childShouldParenthesize: childShouldParenthesize,
                fullName: fullName,
                childFullNamePrefixOpt: childFullNamePrefix,
                formatSpecifiers: Formatter.AddFormatSpecifier(formatSpecifiers, "results"),
                category: DkmEvaluationResultCategory.Method,
                flags: DkmEvaluationResultFlags.ReadOnly,
                editableValue: null);
            return ResultProvider.CreateEvaluationResult(
                value: _proxyValue,
                name: name,
                typeName: string.Empty,
                display: Resources.ResultsViewValueWarning,
                dataItem: dataItem);
        }
예제 #25
0
        private DkmEvaluationResult CreateEvaluationResult(string name, EvalResultDataItem parent, Formatter formatter)
        {
            var    proxyType = _proxyValue.Type.GetLmrType();
            string fullName;
            ReadOnlyCollection <string> formatSpecifiers;
            bool childShouldParenthesize;

            if (parent == null)
            {
                Debug.Assert(name != null);
                fullName = formatter.TrimAndGetFormatSpecifiers(name, out formatSpecifiers);
                childShouldParenthesize = formatter.NeedsParentheses(fullName);
            }
            else
            {
                fullName                = parent.ChildFullNamePrefix;
                formatSpecifiers        = parent.FormatSpecifiers;
                childShouldParenthesize = false;
            }

            var childFullNamePrefix = (fullName == null) ?
                                      null :
                                      formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyType, escapeKeywordIdentifiers: true), fullName);
            var dataItem = new EvalResultDataItem(
                name: name,
                typeDeclaringMember: null,
                declaredType: proxyType,
                value: _proxyValue,
                expansion: _proxyMembers,
                childShouldParenthesize: childShouldParenthesize,
                fullName: fullName,
                childFullNamePrefixOpt: childFullNamePrefix,
                formatSpecifiers: Formatter.AddFormatSpecifier(formatSpecifiers, "results"),
                category: DkmEvaluationResultCategory.Method,
                flags: DkmEvaluationResultFlags.ReadOnly,
                editableValue: null);

            return(ResultProvider.CreateEvaluationResult(
                       value: _proxyValue,
                       name: name,
                       typeName: string.Empty,
                       display: Resources.ResultsViewValueWarning,
                       dataItem: dataItem));
        }
예제 #26
0
        private static string MakeFullName(
            Formatter formatter,
            string name,
            TypeAndCustomInfo typeDeclaringMemberAndInfo,
            bool memberAccessRequiresExplicitCast,
            bool memberIsStatic,
            EvalResultDataItem parent)
        {
            // If the parent is an exception thrown during evaluation,
            // there is no valid fullname expression for the child.
            if (parent.Value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown))
            {
                return null;
            }

            var parentFullName = parent.ChildFullNamePrefix;
            if (parentFullName == null)
            {
                return null;
            }

            if (parent.ChildShouldParenthesize)
            {
                parentFullName = $"({parentFullName})";
            }

            if (!typeDeclaringMemberAndInfo.Type.IsInterface)
            {
                string qualifier;
                if (memberIsStatic)
                {
                    qualifier = formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: false);
                }
                else if (memberAccessRequiresExplicitCast)
                {
                    var typeName = formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: true);
                    qualifier = formatter.GetCastExpression(
                        parentFullName,
                        typeName,
                        parenthesizeEntireExpression: true);
                }
                else
                {
                    qualifier = parentFullName;
                }
                return $"{qualifier}.{name}";
            }
            else
            {
                // NOTE: This should never interact with debugger proxy types:
                //   1) Interfaces cannot have debugger proxy types.
                //   2) Debugger proxy types cannot be interfaces.
                if (typeDeclaringMemberAndInfo.Type.Equals(parent.DeclaredTypeAndInfo.Type))
                {
                    var memberAccessTemplate = parent.ChildShouldParenthesize
                        ? "({0}).{1}"
                        : "{0}.{1}";
                    return string.Format(memberAccessTemplate, parent.ChildFullNamePrefix, name);
                }
                else
                {
                    var interfaceName = formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: true);
                    var memberAccessTemplate = parent.ChildShouldParenthesize
                        ? "(({0})({1})).{2}"
                        : "(({0}){1}).{2}";
                    return string.Format(memberAccessTemplate, interfaceName, parent.ChildFullNamePrefix, name);
                }
            }
        }
예제 #27
0
 private EvalResultDataItem CreateDynamicViewRow(DkmInspectionContext inspectionContext, string name, EvalResultDataItem parent, Formatter formatter)
 {
     var proxyTypeAndInfo = new TypeAndCustomInfo(_proxyValue.Type);
     var isRootExpression = parent == null;
     Debug.Assert(isRootExpression != (name == Resources.DynamicView));
     var fullName = (!isRootExpression) ? parent.ChildFullNamePrefix : name;
     var childFullNamePrefix = (fullName == null) ?
         null :
         formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true), fullName);
     var formatSpecifiers = (!isRootExpression) ? parent.FormatSpecifiers : Formatter.NoFormatSpecifiers;
     return new EvalResultDataItem(
         ExpansionKind.DynamicView,
         name,
         typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
         declaredTypeAndInfo: proxyTypeAndInfo,
         parent: null,
         value: _proxyValue,
         displayValue: Resources.DynamicViewValueWarning,
         expansion: _proxyMembers,
         childShouldParenthesize: false,
         fullName: fullName,
         childFullNamePrefixOpt: childFullNamePrefix,
         formatSpecifiers: Formatter.AddFormatSpecifier(formatSpecifiers, DynamicFormatSpecifier),
         category: DkmEvaluationResultCategory.Method,
         flags: DkmEvaluationResultFlags.ReadOnly,
         editableValue: null,
         inspectionContext: inspectionContext);
 }
예제 #28
0
 internal ResultProvider(Formatter formatter)
 {
     this.Formatter = formatter;
 }
        private DebuggerTypeProxyExpansion(
            DkmClrValue proxyValue,
            string name,
            Type typeDeclaringMemberOpt,
            Type declaredType,
            DkmClrValue value,
            bool childShouldParenthesize,
            string fullName,
            string childFullNamePrefix,
            ReadOnlyCollection<string> formatSpecifiers,
            DkmEvaluationResultFlags flags,
            string editableValue,
            Formatter formatter)
        {
            Debug.Assert(proxyValue != null);
            var proxyType = proxyValue.Type.GetLmrType();
            var proxyMembers = MemberExpansion.CreateExpansion(
                proxyType,
                proxyValue,
                ExpansionFlags.IncludeBaseMembers,
                TypeHelpers.IsPublic,
                formatter);
            if (proxyMembers != null)
            {
                var proxyMemberFullNamePrefix = (childFullNamePrefix == null) ?
                    null :
                    formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyType, escapeKeywordIdentifiers: true), childFullNamePrefix);
                this.proxyItem = new EvalResultDataItem(
                    name: null,
                    typeDeclaringMember: null,
                    declaredType: proxyType,
                    value: proxyValue,
                    expansion: proxyMembers,
                    childShouldParenthesize: false,
                    fullName: null,
                    childFullNamePrefixOpt: proxyMemberFullNamePrefix,
                    formatSpecifiers: Formatter.NoFormatSpecifiers,
                    category: default(DkmEvaluationResultCategory),
                    flags: default(DkmEvaluationResultFlags),
                    editableValue: null);
            }

            this.name = name;
            this.typeDeclaringMemberOpt = typeDeclaringMemberOpt;
            _declaredType = declaredType;
            this.value = value;
            this.childShouldParenthesize = childShouldParenthesize;
            this.fullName = fullName;
            this.childFullNamePrefix = childFullNamePrefix;
            this.formatSpecifiers = formatSpecifiers;
            this.flags = flags;
            this.editableValue = editableValue;
        }