Пример #1
0
            internal Field(
                TypeAndCustomInfo declaringTypeAndInfo,
                TypeAndCustomInfo fieldTypeAndInfo,
                FieldInfo fieldInfo,
                string name,
                Field parent,
                bool isRest
            )
            {
                Debug.Assert(declaringTypeAndInfo.ClrType != null);
                Debug.Assert(fieldTypeAndInfo.ClrType != null);
                Debug.Assert(fieldInfo != null);
                Debug.Assert(name != null);
                Debug.Assert(declaringTypeAndInfo.Type.Equals(fieldInfo.DeclaringType));
                Debug.Assert(fieldTypeAndInfo.Type.Equals(fieldInfo.FieldType));
                Debug.Assert(
                    parent == null || parent.FieldInfo.FieldType.Equals(fieldInfo.DeclaringType)
                );

                DeclaringTypeAndInfo = declaringTypeAndInfo;
                FieldTypeAndInfo = fieldTypeAndInfo;
                FieldInfo = fieldInfo;
                Name = name;
                Parent = parent;
                IsRest = isRest;
            }
Пример #2
0
        /// <returns>The qualified name (i.e. including containing types and namespaces) of a named,
        /// pointer, or array type.</returns>
        internal string GetTypeName(TypeAndCustomInfo typeAndInfo, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier)
        {
            var type = typeAndInfo.Type;

            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            ReadOnlyCollection <byte>   dynamicFlags      = null;
            ReadOnlyCollection <string> tupleElementNames = null;
            var typeInfo = typeAndInfo.Info;

            if (typeInfo != null)
            {
                CustomTypeInfo.Decode(typeInfo.PayloadTypeId, typeInfo.Payload, out dynamicFlags, out tupleElementNames);
            }

            var dynamicFlagIndex  = 0;
            var tupleElementIndex = 0;
            var pooled            = PooledStringBuilder.GetInstance();

            AppendQualifiedTypeName(
                pooled.Builder,
                type,
                dynamicFlags,
                ref dynamicFlagIndex,
                tupleElementNames,
                ref tupleElementIndex,
                escapeKeywordIdentifiers,
                out sawInvalidIdentifier);
            return(pooled.ToStringAndFree());
        }
Пример #3
0
            private static EvalResult GetRow(
                ResultProvider resultProvider,
                DkmInspectionContext inspectionContext,
                TypeAndCustomInfo declaredTypeAndInfo,
                DkmClrValue value,
                Expansion expansion)
            {
                var fullName = resultProvider.FullNameProvider.GetClrTypeName(inspectionContext, declaredTypeAndInfo.ClrType, declaredTypeAndInfo.Info);

                return(new EvalResult(
                           ExpansionKind.StaticMembers,
                           name: resultProvider.StaticMembersString,
                           typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                           declaredTypeAndInfo: declaredTypeAndInfo,
                           useDebuggerDisplay: false,
                           value: value,
                           displayValue: null,
                           expansion: expansion,
                           childShouldParenthesize: false,
                           fullName: fullName,
                           childFullNamePrefixOpt: fullName,
                           formatSpecifiers: Formatter.NoFormatSpecifiers,
                           category: DkmEvaluationResultCategory.Class,
                           flags: DkmEvaluationResultFlags.ReadOnly,
                           editableValue: null,
                           inspectionContext: inspectionContext));
            }
Пример #4
0
        private EvalResult CreateDynamicViewRow(DkmInspectionContext inspectionContext, string name, EvalResultDataItem parent, IDkmClrFullNameProvider fullNameProvider)
        {
            var proxyTypeAndInfo    = new TypeAndCustomInfo(_proxyValue.Type);
            var isRootExpression    = parent == null;
            var fullName            = isRootExpression ? name : parent.ChildFullNamePrefix;
            var childFullNamePrefix = (fullName == null) ?
                                      null :
                                      fullNameProvider.GetClrObjectCreationExpression(
                inspectionContext,
                proxyTypeAndInfo.ClrType,
                proxyTypeAndInfo.Info,
                new[] { fullName });
            var formatSpecifiers = isRootExpression ? Formatter.NoFormatSpecifiers : parent.FormatSpecifiers;

            return(new EvalResult(
                       ExpansionKind.DynamicView,
                       name,
                       typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                       declaredTypeAndInfo: proxyTypeAndInfo,
                       useDebuggerDisplay: false,
                       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));
        }
Пример #5
0
        private EvalResultDataItem CreateResultsViewRow(DkmInspectionContext inspectionContext, EvalResultDataItem parent, Formatter formatter)
        {
            Debug.Assert(parent != null);
            var proxyTypeAndInfo     = new TypeAndCustomInfo(_proxyValue.Type);
            var fullName             = parent.ChildFullNamePrefix;
            var sawInvalidIdentifier = false;
            var childFullNamePrefix  = (fullName == null) ?
                                       null :
                                       formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true, sawInvalidIdentifier: out sawInvalidIdentifier), fullName);

            Debug.Assert(!sawInvalidIdentifier); // Expected proxy type name is "System.Linq.SystemCore_EnumerableDebugView".
            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));
        }
Пример #6
0
        /// <returns>The qualified name (i.e. including containing types and namespaces) of a named,
        /// pointer, or array type.</returns>
        internal string GetTypeName(TypeAndCustomInfo typeAndInfo, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier)
        {
            var type = typeAndInfo.Type;
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            ReadOnlyCollection<byte> dynamicFlags = null;
            ReadOnlyCollection<string> tupleElementNames = null;
            var typeInfo = typeAndInfo.Info;
            if (typeInfo != null)
            {
                CustomTypeInfo.Decode(typeInfo.PayloadTypeId, typeInfo.Payload, out dynamicFlags, out tupleElementNames);
            }

            var dynamicFlagIndex = 0;
            var tupleElementIndex = 0;
            var pooled = PooledStringBuilder.GetInstance();
            AppendQualifiedTypeName(
                pooled.Builder,
                type,
                dynamicFlags,
                ref dynamicFlagIndex,
                tupleElementNames,
                ref tupleElementIndex,
                escapeKeywordIdentifiers,
                out sawInvalidIdentifier);
            return pooled.ToStringAndFree();
        }
Пример #7
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 ? name : parent.ChildFullNamePrefix;
            var sawInvalidIdentifier = false;
            var childFullNamePrefix  = (fullName == null) ?
                                       null :
                                       formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true, sawInvalidIdentifier: out sawInvalidIdentifier), fullName);

            Debug.Assert(!sawInvalidIdentifier); // Expected type name is "Microsoft.CSharp.RuntimeBinder.DynamicMetaObjectProviderDebugView".
            var formatSpecifiers = isRootExpression ? Formatter.NoFormatSpecifiers : parent.FormatSpecifiers;

            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));
        }
Пример #8
0
        private EvalResult CreateResultsViewRow(
            DkmInspectionContext inspectionContext,
            string name,
            string fullName,
            ReadOnlyCollection <string> formatSpecifiers,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            bool includeResultsFormatSpecifier,
            IDkmClrFullNameProvider fullNameProvider)
        {
            if (includeResultsFormatSpecifier)
            {
                formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, ResultsFormatSpecifier);
            }
            var childFullNamePrefix = fullNameProvider.GetClrObjectCreationExpression(inspectionContext, _proxyValue.Type, customTypeInfo: null, arguments: fullName);

            return(new EvalResult(
                       ExpansionKind.Default,
                       name,
                       typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                       declaredTypeAndInfo: declaredTypeAndInfo,
                       useDebuggerDisplay: false,
                       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));
        }
Пример #9
0
            private static EvalResultDataItem GetRow(
                ResultProvider resultProvider,
                DkmInspectionContext inspectionContext,
                TypeAndCustomInfo declaredTypeAndInfo,
                DkmClrValue value,
                Expansion expansion)
            {
                var formatter = resultProvider.Formatter;
                var fullName  = formatter.GetTypeName(declaredTypeAndInfo, escapeKeywordIdentifiers: true);

                return(new EvalResultDataItem(
                           ExpansionKind.StaticMembers,
                           name: formatter.StaticMembersString,
                           typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                           declaredTypeAndInfo: declaredTypeAndInfo,
                           parent: null,
                           value: value,
                           displayValue: null,
                           expansion: expansion,
                           childShouldParenthesize: false,
                           fullName: fullName,
                           childFullNamePrefixOpt: fullName,
                           formatSpecifiers: Formatter.NoFormatSpecifiers,
                           category: DkmEvaluationResultCategory.Class,
                           flags: DkmEvaluationResultFlags.ReadOnly,
                           editableValue: null,
                           inspectionContext: inspectionContext));
            }
Пример #10
0
 private ArrayExpansion(TypeAndCustomInfo elementTypeAndInfo, ReadOnlyCollection<int> sizes, ReadOnlyCollection<int> lowerBounds, int count)
 {
     Debug.Assert(count > 0);
     _elementTypeAndInfo = elementTypeAndInfo;
     _divisors = CalculateDivisors(sizes);
     _lowerBounds = lowerBounds;
     _count = count;
 }
Пример #11
0
 private static Expansion CreateRawView(
     ResultProvider resultProvider,
     DkmInspectionContext inspectionContext,
     TypeAndCustomInfo declaredTypeAndInfo,
     DkmClrValue value)
 {
     return(resultProvider.GetTypeExpansion(inspectionContext, declaredTypeAndInfo, value, ExpansionFlags.IncludeBaseMembers));
 }
Пример #12
0
 private ArrayExpansion(TypeAndCustomInfo elementTypeAndInfo, ReadOnlyCollection <int> sizes, ReadOnlyCollection <int> lowerBounds, int count)
 {
     Debug.Assert(count > 0);
     _elementTypeAndInfo = elementTypeAndInfo;
     _divisors           = CalculateDivisors(sizes);
     _lowerBounds        = lowerBounds;
     _count = count;
 }
Пример #13
0
 internal static TupleExpansion CreateExpansion(DkmClrValue value, TypeAndCustomInfo declaredTypeAndInfo, int cardinality)
 {
     if (value.IsNull)
     {
         // No expansion.
         return(null);
     }
     return(new TupleExpansion(new TypeAndCustomInfo(value.Type, declaredTypeAndInfo.Info), cardinality));
 }
Пример #14
0
 internal static TupleExpansion CreateExpansion(DkmClrValue value, TypeAndCustomInfo declaredTypeAndInfo, int cardinality)
 {
     if (value.IsNull)
     {
         // No expansion.
         return null;
     }
     return new TupleExpansion(new TypeAndCustomInfo(value.Type, declaredTypeAndInfo.Info), cardinality);
 }
Пример #15
0
        private static EvalResult GetRow(
            ResultProvider resultProvider,
            DkmInspectionContext inspectionContext,
            DkmClrValue pointer,
            TypeAndCustomInfo elementTypeAndInfo,
            EvalResultDataItem parent
            )
        {
            var value = pointer.Dereference(inspectionContext);
            var wasExceptionThrown = value.EvalFlags.Includes(
                DkmEvaluationResultFlags.ExceptionThrown
                );

            var expansion = wasExceptionThrown
                ? null
                : resultProvider.GetTypeExpansion(
                inspectionContext,
                elementTypeAndInfo,
                value,
                ExpansionFlags.None,
                supportsFavorites: false
                );
            var parentFullName = parent.ChildFullNamePrefix;
            var fullName       = parentFullName == null ? null : $"*{parentFullName}";
            var editableValue  = resultProvider.Formatter2.GetEditableValueString(
                value,
                inspectionContext,
                elementTypeAndInfo.Info
                );

            // NB: Full name is based on the real (i.e. not DebuggerDisplay) name.  This is a change from dev12,
            // which used the DebuggerDisplay name, causing surprising results in "Add Watch" scenarios.
            return(new EvalResult(
                       ExpansionKind.PointerDereference,
                       name: fullName ?? $"*{parent.Name}",
                       typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                       declaredTypeAndInfo: elementTypeAndInfo,
                       useDebuggerDisplay: false,
                       value: value,
                       displayValue: wasExceptionThrown
                  ? string.Format(Resources.InvalidPointerDereference, fullName ?? parent.Name)
                  : null,
                       expansion: expansion,
                       childShouldParenthesize: true,
                       fullName: fullName,
                       childFullNamePrefixOpt: fullName,
                       formatSpecifiers: Formatter.NoFormatSpecifiers,
                       category: DkmEvaluationResultCategory.Other,
                       flags: DkmEvaluationResultFlags.None,
                       editableValue: editableValue,
                       inspectionContext: inspectionContext
                       ));
        }
Пример #16
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})");
        }
Пример #17
0
        public EvalResult(
            ExpansionKind kind,
            string name,
            TypeAndCustomInfo typeDeclaringMemberAndInfo,
            TypeAndCustomInfo declaredTypeAndInfo,
            bool useDebuggerDisplay,
            DkmClrValue value,
            string displayValue,
            Expansion expansion,
            bool childShouldParenthesize,
            string fullName,
            string childFullNamePrefixOpt,
            ReadOnlyCollection <string> formatSpecifiers,
            DkmEvaluationResultCategory category,
            DkmEvaluationResultFlags flags,
            string editableValue,
            DkmInspectionContext inspectionContext,
            string displayName = null,
            string displayType = null,
            bool canFavorite   = false,
            bool isFavorite    = false
            )
        {
            Debug.Assert(name != null);
            Debug.Assert(formatSpecifiers != null);
            Debug.Assert((flags & DkmEvaluationResultFlags.Expandable) == 0);

            m_rawFlags = flags;

            this.Kind = kind;
            this.Name = name;
            this.TypeDeclaringMemberAndInfo = typeDeclaringMemberAndInfo;
            this.DeclaredTypeAndInfo        = declaredTypeAndInfo;
            this.UseDebuggerDisplay         = useDebuggerDisplay;
            this.Value                           = value;
            this.DisplayValue                    = displayValue;
            this.ChildShouldParenthesize         = childShouldParenthesize;
            this.FullNameWithoutFormatSpecifiers = fullName;
            this.ChildFullNamePrefix             = childFullNamePrefixOpt;
            this.FormatSpecifiers                = formatSpecifiers;
            this.Category                        = category;
            this.EditableValue                   = editableValue;
            this.Flags                           =
                flags | GetFlags(value, inspectionContext, expansion, canFavorite, isFavorite);
            this.Expansion         = expansion;
            this.InspectionContext = inspectionContext;
            this.DisplayName       = displayName;
            this.DisplayType       = displayType;
            this.CanFavorite       = canFavorite;
            this.IsFavorite        = isFavorite;
        }
Пример #18
0
        internal static CustomTypeInfoTypeArgumentMap Create(TypeAndCustomInfo typeAndInfo)
        {
            var typeInfo = typeAndInfo.Info;

            if (typeInfo == null)
            {
                return(s_empty);
            }

            var type = typeAndInfo.Type;

            Debug.Assert(type != null);
            if (!type.IsGenericType)
            {
                return(s_empty);
            }

            ReadOnlyCollection <byte>   dynamicFlags;
            ReadOnlyCollection <string> tupleElementNames;

            CustomTypeInfo.Decode(
                typeInfo.PayloadTypeId,
                typeInfo.Payload,
                out dynamicFlags,
                out tupleElementNames
                );
            if (dynamicFlags == null && tupleElementNames == null)
            {
                return(s_empty);
            }

            var typeDefinition = type.GetGenericTypeDefinition();

            Debug.Assert(typeDefinition != null);

            var dynamicFlagStartIndices =
                (dynamicFlags == null) ? null : GetStartIndices(type, t => 1);
            var tupleElementNameStartIndices =
                (tupleElementNames == null)
                    ? null
                    : GetStartIndices(type, TypeHelpers.GetTupleCardinalityIfAny);

            return(new CustomTypeInfoTypeArgumentMap(
                       typeDefinition,
                       dynamicFlags,
                       dynamicFlagStartIndices,
                       tupleElementNames,
                       tupleElementNameStartIndices
                       ));
        }
Пример #19
0
        /// <returns>The qualified name (i.e. including containing types and namespaces) of a named,
        /// pointer, or array type.</returns>
        internal string GetTypeName(TypeAndCustomInfo typeAndInfo, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier)
        {
            var type = typeAndInfo.Type;
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            var dynamicFlags = DynamicFlagsCustomTypeInfo.Create(typeAndInfo.Info);
            var index = 0;
            var pooled = PooledStringBuilder.GetInstance();
            AppendQualifiedTypeName(pooled.Builder, type, dynamicFlags, ref index, escapeKeywordIdentifiers, out sawInvalidIdentifier);
            return pooled.ToStringAndFree();
        }
Пример #20
0
        internal static ArrayExpansion CreateExpansion(TypeAndCustomInfo elementTypeAndInfo, ReadOnlyCollection<int> sizes, ReadOnlyCollection<int> lowerBounds)
        {
            Debug.Assert(elementTypeAndInfo.Type != null);
            Debug.Assert(sizes != null);
            Debug.Assert(lowerBounds != null);
            Debug.Assert(sizes.Count > 0);
            Debug.Assert(sizes.Count == lowerBounds.Count);

            int count = 1;
            foreach (var size in sizes)
            {
                count *= size;
            }
            return (count > 0) ? new ArrayExpansion(elementTypeAndInfo, sizes, lowerBounds, count) : null;
        }
Пример #21
0
        internal static TupleExpansion CreateExpansion(
            DkmInspectionContext inspectionContext,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            int cardinality)
        {
            if (value.IsNull)
            {
                // No expansion.
                return null;
            }

            bool useRawView = (inspectionContext.EvaluationFlags & DkmEvaluationFlags.ShowValueRaw) != 0;
            return new TupleExpansion(new TypeAndCustomInfo(value.Type, declaredTypeAndInfo.Info), cardinality, useRawView);
        }
Пример #22
0
        private static string MakeFullName(
            IDkmClrFullNameProvider fullNameProvider,
            DkmInspectionContext inspectionContext,
            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.Parenthesize();
            }

            var typeDeclaringMember = typeDeclaringMemberAndInfo.Type;

            if (typeDeclaringMember.IsInterface)
            {
                memberAccessRequiresExplicitCast = !typeDeclaringMember.Equals(
                    parent.DeclaredTypeAndInfo.Type
                    );
            }

            return(fullNameProvider.GetClrMemberName(
                       inspectionContext,
                       parentFullName,
                       typeDeclaringMemberAndInfo.ClrType,
                       typeDeclaringMemberAndInfo.Info,
                       name,
                       memberAccessRequiresExplicitCast,
                       memberIsStatic
                       ));
        }
Пример #23
0
        internal TypeVariablesExpansion(TypeAndCustomInfo declaredTypeAndInfo)
        {
            var declaredType = declaredTypeAndInfo.Type;
            Debug.Assert(declaredType.IsGenericType);
            Debug.Assert(!declaredType.IsGenericTypeDefinition);

            _customTypeInfoMap = CustomTypeInfoTypeArgumentMap.Create(declaredTypeAndInfo);

            var typeDef = declaredType.GetGenericTypeDefinition();
            _typeParameters = typeDef.GetGenericArguments();
            _typeArguments = declaredType.GetGenericArguments();

            Debug.Assert(_typeParameters.Length == _typeArguments.Length);
            Debug.Assert(Array.TrueForAll(_typeParameters, t => t.IsGenericParameter));
            Debug.Assert(Array.TrueForAll(_typeArguments, t => !t.IsGenericParameter));
        }
Пример #24
0
        internal static TupleExpansion CreateExpansion(
            DkmInspectionContext inspectionContext,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            int cardinality)
        {
            if (value.IsNull)
            {
                // No expansion.
                return(null);
            }

            bool useRawView = (inspectionContext.EvaluationFlags & DkmEvaluationFlags.ShowValueRaw) != 0;

            return(new TupleExpansion(new TypeAndCustomInfo(value.Type, declaredTypeAndInfo.Info), cardinality, useRawView));
        }
Пример #25
0
        /// <returns>The qualified name (i.e. including containing types and namespaces) of a named,
        /// pointer, or array type.</returns>
        internal string GetTypeName(TypeAndCustomInfo typeAndInfo, bool escapeKeywordIdentifiers = false)
        {
            var type = typeAndInfo.Type;

            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            var dynamicFlags = new DynamicFlagsCustomTypeInfo(typeAndInfo.Info);
            var index        = 0;
            var pooled       = PooledStringBuilder.GetInstance();

            AppendQualifiedTypeName(pooled.Builder, type, dynamicFlags, ref index, escapeKeywordIdentifiers);
            return(pooled.ToStringAndFree());
        }
Пример #26
0
        internal static ArrayExpansion CreateExpansion(TypeAndCustomInfo elementTypeAndInfo, ReadOnlyCollection <int> sizes, ReadOnlyCollection <int> lowerBounds)
        {
            Debug.Assert(elementTypeAndInfo.Type != null);
            Debug.Assert(sizes != null);
            Debug.Assert(lowerBounds != null);
            Debug.Assert(sizes.Count > 0);
            Debug.Assert(sizes.Count == lowerBounds.Count);

            int count = 1;

            foreach (var size in sizes)
            {
                count *= size;
            }
            return((count > 0) ? new ArrayExpansion(elementTypeAndInfo, sizes, lowerBounds, count) : null);
        }
        internal TypeVariablesExpansion(TypeAndCustomInfo declaredTypeAndInfo)
        {
            var declaredType = declaredTypeAndInfo.Type;

            Debug.Assert(declaredType.IsGenericType);
            Debug.Assert(!declaredType.IsGenericTypeDefinition);

            _customTypeInfoMap = CustomTypeInfoTypeArgumentMap.Create(declaredTypeAndInfo);

            var typeDef = declaredType.GetGenericTypeDefinition();

            _typeParameters = typeDef.GetGenericArguments();
            _typeArguments  = declaredType.GetGenericArguments();

            Debug.Assert(_typeParameters.Length == _typeArguments.Length);
            Debug.Assert(Array.TrueForAll(_typeParameters, t => t.IsGenericParameter));
            Debug.Assert(Array.TrueForAll(_typeArguments, t => !t.IsGenericParameter));
        }
Пример #28
0
 public EvalResultDataItem(
     string name,
     TypeAndCustomInfo declaredTypeAndInfo,
     DkmClrValue value,
     Expansion expansion,
     bool childShouldParenthesize,
     string fullNameWithoutFormatSpecifiers,
     string childFullNamePrefixOpt,
     ReadOnlyCollection <string> formatSpecifiers)
 {
     this.Name = name;
     this.DeclaredTypeAndInfo = declaredTypeAndInfo;
     this.Value = value;
     this.ChildShouldParenthesize         = childShouldParenthesize;
     this.FullNameWithoutFormatSpecifiers = fullNameWithoutFormatSpecifiers;
     this.ChildFullNamePrefix             = childFullNamePrefixOpt;
     this.FormatSpecifiers = formatSpecifiers;
     this.Expansion        = expansion;
 }
Пример #29
0
 public EvalResultDataItem(
     string name,
     TypeAndCustomInfo declaredTypeAndInfo,
     DkmClrValue value,
     Expansion expansion,
     bool childShouldParenthesize,
     string fullNameWithoutFormatSpecifiers,
     string childFullNamePrefixOpt,
     ReadOnlyCollection<string> formatSpecifiers)
 {
     this.Name = name;
     this.DeclaredTypeAndInfo = declaredTypeAndInfo;
     this.Value = value;
     this.ChildShouldParenthesize = childShouldParenthesize;
     this.FullNameWithoutFormatSpecifiers = fullNameWithoutFormatSpecifiers;
     this.ChildFullNamePrefix = childFullNamePrefixOpt;
     this.FormatSpecifiers = formatSpecifiers;
     this.Expansion = expansion;
 }
Пример #30
0
        internal static DynamicFlagsMap Create(TypeAndCustomInfo typeAndInfo)
        {
            var type = typeAndInfo.Type;

            Debug.Assert(type != null);
            if (!type.IsGenericType)
            {
                return(s_empty);
            }

            var dynamicFlags = DynamicFlagsCustomTypeInfo.Create(typeAndInfo.Info);

            if (!dynamicFlags.Any())
            {
                return(s_empty);
            }

            var typeDefinition = type.GetGenericTypeDefinition();

            Debug.Assert(typeDefinition != null);

            var typeArgs = type.GetGenericArguments();

            Debug.Assert(typeArgs.Length > 0);

            int pos           = 1; // Consider "type" to have already been consumed.
            var startsBuilder = ArrayBuilder <int> .GetInstance();

            foreach (var typeArg in typeArgs)
            {
                startsBuilder.Add(pos);

                foreach (Type curr in new TypeWalker(typeArg))
                {
                    pos++;
                }
            }

            Debug.Assert(pos > 1);
            startsBuilder.Add(pos);

            return(new DynamicFlagsMap(typeDefinition, dynamicFlags, startsBuilder.ToArrayAndFree()));
        }
Пример #31
0
        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 sawInvalidIdentifier;
            var  childFullNamePrefix = formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true, sawInvalidIdentifier: out sawInvalidIdentifier), fullName);

            Debug.Assert(!sawInvalidIdentifier); // Expected proxy type name is "System.Linq.SystemCore_EnumerableDebugView".
            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));
        }
Пример #32
0
        internal static DynamicFlagsMap Create(TypeAndCustomInfo typeAndInfo)
        {
            var type = typeAndInfo.Type;
            Debug.Assert(type != null);
            if (!type.IsGenericType)
            {
                return s_empty;
            }

            var dynamicFlags = DynamicFlagsCustomTypeInfo.Create(typeAndInfo.Info);
            if (!dynamicFlags.Any())
            {
                return s_empty;
            }

            var typeDefinition = type.GetGenericTypeDefinition();
            Debug.Assert(typeDefinition != null);

            var typeArgs = type.GetGenericArguments();
            Debug.Assert(typeArgs.Length > 0);

            int pos = 1; // Consider "type" to have already been consumed.
            var startsBuilder = ArrayBuilder<int>.GetInstance();
            foreach (var typeArg in typeArgs)
            {
                startsBuilder.Add(pos);

                foreach (Type curr in new TypeWalker(typeArg))
                {
                    pos++;
                }
            }

            Debug.Assert(pos > 1);
            startsBuilder.Add(pos);

            return new DynamicFlagsMap(typeDefinition, dynamicFlags, startsBuilder.ToArrayAndFree());
        }
Пример #33
0
        public EvalResultDataItem(
            ExpansionKind kind,
            string name,
            TypeAndCustomInfo typeDeclaringMemberAndInfo,
            TypeAndCustomInfo declaredTypeAndInfo,
            EvalResultDataItem parent,
            DkmClrValue value,
            string displayValue,
            Expansion expansion,
            bool childShouldParenthesize,
            string fullName,
            string childFullNamePrefixOpt,
            ReadOnlyCollection <string> formatSpecifiers,
            DkmEvaluationResultCategory category,
            DkmEvaluationResultFlags flags,
            string editableValue,
            DkmInspectionContext inspectionContext)
        {
            Debug.Assert(name != null);
            Debug.Assert(formatSpecifiers != null);
            Debug.Assert((flags & DkmEvaluationResultFlags.Expandable) == 0);

            this.Kind = kind;
            this.Name = name;
            this.TypeDeclaringMemberAndInfo = typeDeclaringMemberAndInfo;
            this.DeclaredTypeAndInfo        = declaredTypeAndInfo;
            this.Parent                          = parent;
            this.Value                           = value;
            this.DisplayValue                    = displayValue;
            this.ChildShouldParenthesize         = childShouldParenthesize;
            this.FullNameWithoutFormatSpecifiers = fullName;
            this.ChildFullNamePrefix             = childFullNamePrefixOpt;
            this.FormatSpecifiers                = formatSpecifiers;
            this.Category                        = category;
            this.EditableValue                   = editableValue;
            this.Flags                           = flags | GetFlags(value, inspectionContext) | ((expansion == null) ? DkmEvaluationResultFlags.None : DkmEvaluationResultFlags.Expandable);
            this.Expansion                       = expansion;
        }
        private static EvalResultDataItem GetRow(
            ResultProvider resultProvider,
            DkmInspectionContext inspectionContext,
            DkmClrValue pointer,
            TypeAndCustomInfo elementTypeAndInfo,
            EvalResultDataItem parent)
        {
            var value = pointer.Dereference(inspectionContext);
            var wasExceptionThrown = value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown);

            var expansion = wasExceptionThrown ?
                null :
                resultProvider.GetTypeExpansion(inspectionContext, elementTypeAndInfo, value, ExpansionFlags.None);
            var parentFullName = parent.ChildFullNamePrefix;
            var fullName = parentFullName == null ? null : $"*{parentFullName}";
            var editableValue = resultProvider.Formatter.GetEditableValue(value, inspectionContext);

            // NB: Full name is based on the real (i.e. not DebuggerDisplay) name.  This is a change from dev12, 
            // which used the DebuggerDisplay name, causing surprising results in "Add Watch" scenarios.
            return new EvalResultDataItem(
                ExpansionKind.PointerDereference,
                name: fullName ?? $"*{parent.Name}",
                typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                declaredTypeAndInfo: elementTypeAndInfo,
                parent: null,
                value: value,
                displayValue: wasExceptionThrown ? string.Format(Resources.InvalidPointerDereference, fullName ?? parent.Name) : null,
                expansion: expansion,
                childShouldParenthesize: true,
                fullName: fullName,
                childFullNamePrefixOpt: fullName,
                formatSpecifiers: Formatter.NoFormatSpecifiers,
                category: DkmEvaluationResultCategory.Other,
                flags: DkmEvaluationResultFlags.None,
                editableValue: editableValue,
                inspectionContext: inspectionContext);
        }
Пример #35
0
        internal static Expansion CreateExpansion(
            ResultProvider resultProvider,
            DkmInspectionContext inspectionContext,
            string name,
            TypeAndCustomInfo typeDeclaringMemberAndInfoOpt,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            bool childShouldParenthesize,
            string fullName,
            string childFullNamePrefix,
            ReadOnlyCollection <string> formatSpecifiers,
            DkmEvaluationResultFlags flags,
            string editableValue)
        {
            Debug.Assert((inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) == 0);

            // Note: The native EE uses the proxy type, even for
            // null instances, so statics on the proxy type are
            // displayed. That case is not supported currently.
            if (!value.IsNull)
            {
                var proxyType = value.Type.GetProxyType();
                if (proxyType != null)
                {
                    if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ShowValueRaw) != 0)
                    {
                        var rawView = CreateRawView(resultProvider, inspectionContext, declaredTypeAndInfo, value);
                        Debug.Assert(rawView != null);
                        return(rawView);
                    }

                    DkmClrValue proxyValue;
                    try
                    {
                        proxyValue = value.InstantiateProxyType(inspectionContext, proxyType);
                    }
                    catch
                    {
                        proxyValue = null;
                    }

                    if (proxyValue != null)
                    {
                        return(new DebuggerTypeProxyExpansion(
                                   inspectionContext,
                                   proxyValue,
                                   name,
                                   typeDeclaringMemberAndInfoOpt,
                                   declaredTypeAndInfo,
                                   value,
                                   childShouldParenthesize,
                                   fullName,
                                   childFullNamePrefix,
                                   formatSpecifiers,
                                   flags,
                                   editableValue,
                                   resultProvider));
                    }
                }
            }

            return(null);
        }
Пример #36
0
        internal static Expansion CreateExpansion(
            DkmInspectionContext inspectionContext,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            ExpansionFlags flags,
            Predicate <MemberInfo> predicate,
            ResultProvider resultProvider,
            bool isProxyType)
        {
            // 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 runtimeType       = type.GetLmrType();
            var isDynamicProperty = runtimeType.IsDynamicProperty();

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

            // Primitives, enums, function pointers, IntPtr, UIntPtr and null values with a declared type that is an interface have no visible members.
            Debug.Assert(!runtimeType.IsInterface || value.IsNull);
            if (resultProvider.IsPrimitiveType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface || runtimeType.IsFunctionPointer() ||
                runtimeType.IsIntPtr() || runtimeType.IsUIntPtr())
            {
                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, resultProvider);

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

            var customTypeInfoMap = CustomTypeInfoTypeArgumentMap.Create(declaredTypeAndInfo);

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

            // Expand members. TODO: Ideally, this would be done lazily (https://github.com/dotnet/roslyn/issues/32800)
            // 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;

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

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

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

            foreach (var member in allMembers)
            {
                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,
                customTypeInfoMap,
                isProxyType,
                out publicInstanceExpansion,
                out nonPublicInstanceExpansion);

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

            GetPublicAndNonPublicMembers(
                staticMembers,
                customTypeInfoMap,
                isProxyType,
                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(
                    type,
                    AggregateExpansion.CreateExpansion(staticExpansions));
                staticExpansions.Free();
                expansions.Add(staticMembersExpansion);
            }

            instanceMembers.Free();
            staticMembers.Free();

            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, resultProvider);
                if (resultsViewExpansion != null)
                {
                    expansions.Add(resultsViewExpansion);
                }
            }

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

            var result = AggregateExpansion.CreateExpansion(expansions);

            expansions.Free();
            return(result);
        }
Пример #37
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);
 }
Пример #38
0
 private EvalResult CreateResultsViewRow(
     DkmInspectionContext inspectionContext,
     string name,
     string fullName,
     ReadOnlyCollection<string> formatSpecifiers,
     TypeAndCustomInfo declaredTypeAndInfo,
     DkmClrValue value,
     bool includeResultsFormatSpecifier,
     IDkmClrFullNameProvider fullNameProvider)
 {
     if (includeResultsFormatSpecifier)
     {
         formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, ResultsFormatSpecifier);
     }
     var childFullNamePrefix = fullNameProvider.GetClrObjectCreationExpression(inspectionContext, _proxyValue.Type, customTypeInfo: null, arguments: fullName);
     return new EvalResult(
         ExpansionKind.Default,
         name,
         typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
         declaredTypeAndInfo: declaredTypeAndInfo,
         useDebuggerDisplay: false,
         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);
 }
 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);
 }
Пример #40
0
 public PointerDereferenceExpansion(TypeAndCustomInfo elementTypeAndInfo)
 {
     Debug.Assert(elementTypeAndInfo.Type != null);
     _elementTypeAndInfo = elementTypeAndInfo;
 }
Пример #41
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})";
 }
Пример #42
0
        internal Expansion GetTypeExpansion(
            DkmInspectionContext inspectionContext,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            ExpansionFlags flags)
        {
            var declaredType = declaredTypeAndInfo.Type;
            Debug.Assert(!declaredType.IsTypeVariables());

            if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0)
            {
                return null;
            }

            var runtimeType = value.Type.GetLmrType();

            // If the value is an array, expand the array elements.
            if (runtimeType.IsArray)
            {
                var sizes = value.ArrayDimensions;
                if (sizes == null)
                {
                    // Null array. No expansion.
                    return null;
                }
                var lowerBounds = value.ArrayLowerBounds;

                Type elementType;
                DkmClrCustomTypeInfo elementTypeInfo;
                if (declaredType.IsArray)
                {
                    elementType = declaredType.GetElementType();
                    elementTypeInfo = DynamicFlagsCustomTypeInfo.Create(declaredTypeAndInfo.Info).SkipOne().GetCustomTypeInfo();
                }
                else
                {
                    elementType = runtimeType.GetElementType();
                    elementTypeInfo = null;
                }

                return ArrayExpansion.CreateExpansion(new TypeAndCustomInfo(elementType, elementTypeInfo), sizes, lowerBounds);
            }

            if (this.Formatter.IsPredefinedType(runtimeType))
            {
                return null;
            }

            if(declaredType.IsFunctionPointer())
            {
                // Function pointers have no expansion
                return null;
            }

            if (declaredType.IsPointer)
            {
                // If this ever happens, the element type info is just .SkipOne().
                Debug.Assert(!DynamicFlagsCustomTypeInfo.Create(declaredTypeAndInfo.Info).Any());
                var elementType = declaredType.GetElementType();
                return value.IsNull || elementType.IsVoid()
                    ? null
                    : new PointerDereferenceExpansion(new TypeAndCustomInfo(elementType));
            }

            if (value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown) &&
                runtimeType.IsEmptyResultsViewException())
            {
                // The value is an exception thrown expanding an empty
                // IEnumerable. Use the runtime type of the exception and
                // skip base types. (This matches the native EE behavior
                // to expose a single property from the exception.)
                flags &= ~ExpansionFlags.IncludeBaseMembers;
            }

            return MemberExpansion.CreateExpansion(inspectionContext, declaredTypeAndInfo, value, flags, TypeHelpers.IsVisibleMember, this.Formatter);
        }
Пример #43
0
 private static EvalResultDataItem GetRow(
     ResultProvider resultProvider,
     DkmInspectionContext inspectionContext,
     TypeAndCustomInfo declaredTypeAndInfo,
     DkmClrValue value,
     Expansion expansion)
 {
     var formatter = resultProvider.Formatter;
     var fullName = formatter.GetTypeName(declaredTypeAndInfo, escapeKeywordIdentifiers: true);
     return new EvalResultDataItem(
         ExpansionKind.StaticMembers,
         name: formatter.StaticMembersString,
         typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
         declaredTypeAndInfo: declaredTypeAndInfo,
         parent: null,
         value: value,
         displayValue: null,
         expansion: expansion,
         childShouldParenthesize: false,
         fullName: fullName,
         childFullNamePrefixOpt: fullName,
         formatSpecifiers: Formatter.NoFormatSpecifiers,
         category: DkmEvaluationResultCategory.Class,
         flags: DkmEvaluationResultFlags.ReadOnly,
         editableValue: null,
         inspectionContext: inspectionContext);
 }
Пример #44
0
        private void GetRootResultAndContinue(
            DkmClrValue value,
            WorkList workList,
            DkmClrType declaredType,
            DkmClrCustomTypeInfo declaredTypeInfo,
            DkmInspectionContext inspectionContext,
            string name,
            string fullName,
            ReadOnlyCollection <string> formatSpecifiers,
            CompletionRoutine <DkmEvaluationResult> completionRoutine)
        {
            Debug.Assert(formatSpecifiers != null);

            var type = value.Type.GetLmrType();

            if (type.IsTypeVariables())
            {
                Debug.Assert(type.Equals(declaredType.GetLmrType()));
                var declaredTypeAndInfo = new TypeAndCustomInfo(declaredType, declaredTypeInfo);
                var expansion           = new TypeVariablesExpansion(declaredTypeAndInfo);
                var dataItem            = new EvalResult(
                    ExpansionKind.Default,
                    name,
                    typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                    declaredTypeAndInfo: declaredTypeAndInfo,
                    useDebuggerDisplay: false,
                    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.ToDataItem()));
            }
            else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ResultsOnly) != 0)
            {
                var dataItem = ResultsViewExpansion.CreateResultsOnlyRow(
                    inspectionContext,
                    name,
                    fullName,
                    formatSpecifiers,
                    declaredType,
                    declaredTypeInfo,
                    value,
                    this);
                CreateEvaluationResultAndContinue(
                    dataItem,
                    workList,
                    inspectionContext,
                    value.StackFrame,
                    completionRoutine);
            }
            else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.DynamicView) != 0)
            {
                var dataItem = DynamicViewExpansion.CreateMembersOnlyRow(
                    inspectionContext,
                    name,
                    value,
                    this);
                CreateEvaluationResultAndContinue(
                    dataItem,
                    workList,
                    inspectionContext,
                    value.StackFrame,
                    completionRoutine);
            }
            else
            {
                var dataItem = ResultsViewExpansion.CreateResultsOnlyRowIfSynthesizedEnumerable(
                    inspectionContext,
                    name,
                    fullName,
                    formatSpecifiers,
                    declaredType,
                    declaredTypeInfo,
                    value,
                    this);
                if (dataItem != null)
                {
                    CreateEvaluationResultAndContinue(
                        dataItem,
                        workList,
                        inspectionContext,
                        value.StackFrame,
                        completionRoutine);
                }
                else
                {
                    var useDebuggerDisplay = (inspectionContext.EvaluationFlags & NotRoot) != 0;
                    var expansionFlags     = (inspectionContext.EvaluationFlags & NoResults) != 0 ?
                                             ExpansionFlags.IncludeBaseMembers :
                                             ExpansionFlags.All;
                    dataItem = CreateDataItem(
                        inspectionContext,
                        name,
                        typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                        declaredTypeAndInfo: new TypeAndCustomInfo(declaredType, declaredTypeInfo),
                        value: value,
                        useDebuggerDisplay: useDebuggerDisplay,
                        expansionFlags: expansionFlags,
                        childShouldParenthesize: (fullName == null) ? false : FullNameProvider.ClrExpressionMayRequireParentheses(inspectionContext, fullName),
                        fullName: fullName,
                        formatSpecifiers: formatSpecifiers,
                        category: DkmEvaluationResultCategory.Other,
                        flags: value.EvalFlags,
                        evalFlags: inspectionContext.EvaluationFlags);
                    GetResultAndContinue(dataItem, workList, declaredType, declaredTypeInfo, inspectionContext, useDebuggerDisplay, completionRoutine);
                }
            }
        }
Пример #45
0
        internal EvalResultDataItem CreateDataItem(
            DkmInspectionContext inspectionContext,
            string name,
            TypeAndCustomInfo typeDeclaringMemberAndInfo,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            EvalResultDataItem parent,
            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(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(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,
                    this.Formatter.GetEditableValue(value, inspectionContext));
                if (expansion == null)
                {
                    expansion = value.HasExceptionThrown()
                        ? this.GetTypeExpansion(inspectionContext, new TypeAndCustomInfo(value.Type), value, expansionFlags)
                        : this.GetTypeExpansion(inspectionContext, declaredTypeAndInfo, value, expansionFlags);
                }
            }

            return new EvalResultDataItem(
                ExpansionKind.Default,
                name,
                typeDeclaringMemberAndInfo,
                declaredTypeAndInfo,
                parent: parent,
                value: value,
                displayValue: null,
                expansion: expansion,
                childShouldParenthesize: childShouldParenthesize,
                fullName: fullName,
                childFullNamePrefixOpt: flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName,
                formatSpecifiers: formatSpecifiers,
                category: category,
                flags: flags,
                editableValue: this.Formatter.GetEditableValue(value, inspectionContext),
                inspectionContext: inspectionContext);
        }
Пример #46
0
 private static EvalResult GetRow(
     ResultProvider resultProvider,
     DkmInspectionContext inspectionContext,
     TypeAndCustomInfo declaredTypeAndInfo,
     DkmClrValue value,
     Expansion expansion)
 {
     var fullName = resultProvider.FullNameProvider.GetClrTypeName(inspectionContext, declaredTypeAndInfo.ClrType, declaredTypeAndInfo.Info);
     return new EvalResult(
         ExpansionKind.StaticMembers,
         name: resultProvider.StaticMembersString,
         typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
         declaredTypeAndInfo: declaredTypeAndInfo,
         useDebuggerDisplay: false,
         value: value,
         displayValue: null,
         expansion: expansion,
         childShouldParenthesize: false,
         fullName: fullName,
         childFullNamePrefixOpt: fullName,
         formatSpecifiers: Formatter.NoFormatSpecifiers,
         category: DkmEvaluationResultCategory.Class,
         flags: DkmEvaluationResultFlags.ReadOnly,
         editableValue: null,
         inspectionContext: inspectionContext);
 }
Пример #47
0
            internal Field(
                TypeAndCustomInfo declaringTypeAndInfo,
                TypeAndCustomInfo fieldTypeAndInfo,
                FieldInfo fieldInfo,
                string name,
                Field parent,
                bool isRest)
            {
                Debug.Assert(declaringTypeAndInfo.ClrType != null);
                Debug.Assert(fieldTypeAndInfo.ClrType != null);
                Debug.Assert(fieldInfo != null);
                Debug.Assert(name != null);
                Debug.Assert(declaringTypeAndInfo.Type.Equals(fieldInfo.DeclaringType));
                Debug.Assert(fieldTypeAndInfo.Type.Equals(fieldInfo.FieldType));
                Debug.Assert(parent == null || parent.FieldInfo.FieldType.Equals(fieldInfo.DeclaringType));

                DeclaringTypeAndInfo = declaringTypeAndInfo;
                FieldTypeAndInfo = fieldTypeAndInfo;
                FieldInfo = fieldInfo;
                Name = name;
                Parent = parent;
                IsRest = isRest;
            }
Пример #48
0
        internal static Expansion CreateExpansion(
            DkmInspectionContext inspectionContext,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            ExpansionFlags flags,
            Predicate<MemberInfo> predicate,
            Formatter formatter)
        {
            var runtimeType = value.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;
            }

            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);
                }
            }

            var result = AggregateExpansion.CreateExpansion(expansions);
            expansions.Free();
            return result;
        }
Пример #49
0
        private static Fields GetFields(TypeAndCustomInfo declaringTypeAndInfo, int cardinality, bool useRawView)
        {
            Debug.Assert(declaringTypeAndInfo.Type.GetTupleCardinalityIfAny() == cardinality);

            var appDomain = declaringTypeAndInfo.ClrType.AppDomain;
            var customTypeInfoMap = CustomTypeInfoTypeArgumentMap.Create(declaringTypeAndInfo);
            var tupleElementNames = customTypeInfoMap.TupleElementNames;

            var builder = ArrayBuilder<Field>.GetInstance();
            Field parent = null;
            int offset = 0;
            bool includeRawView = false;

            while (true)
            {
                var declaringType = declaringTypeAndInfo.Type;
                int n = Math.Min(cardinality, TypeHelpers.TupleFieldRestPosition - 1);
                for (int index = 0; index < n; index++)
                {
                    var fieldName = TypeHelpers.GetTupleFieldName(index);
                    var field = declaringType.GetTupleField(fieldName);
                    if (field == null)
                    {
                        // Ignore missing fields.
                        continue;
                    }

                    var fieldTypeAndInfo = GetTupleFieldTypeAndInfo(appDomain, field, customTypeInfoMap);
                    if (!useRawView)
                    {
                        var name = CustomTypeInfo.GetTupleElementNameIfAny(tupleElementNames, offset + index);
                        if (name != null)
                        {
                            includeRawView = true;
                            builder.Add(new Field(declaringTypeAndInfo, fieldTypeAndInfo, field, name, parent, isRest: false));
                            continue;
                        }
                    }

                    builder.Add(new Field(
                        declaringTypeAndInfo,
                        fieldTypeAndInfo,
                        field,
                        (offset == 0) ? fieldName : TypeHelpers.GetTupleFieldName(offset + index),
                        parent,
                        isRest: false));
                }

                cardinality -= n;
                if (cardinality == 0)
                {
                    break;
                }

                var rest = declaringType.GetTupleField(TypeHelpers.TupleFieldRestName);
                if (rest == null)
                {
                    // Ignore remaining fields.
                    break;
                }

                var restTypeAndInfo = GetTupleFieldTypeAndInfo(appDomain, rest, customTypeInfoMap);
                var restField = new Field(declaringTypeAndInfo, restTypeAndInfo, rest, TypeHelpers.TupleFieldRestName, parent, isRest: true);

                if (useRawView)
                {
                    builder.Add(restField);
                    break;
                }

                includeRawView = true;
                parent = restField;
                declaringTypeAndInfo = restTypeAndInfo;
                offset += TypeHelpers.TupleFieldRestPosition - 1;
            }

            return new Fields(builder.ToImmutableAndFree(), includeRawView);
        }
Пример #50
0
 private TupleExpansion(TypeAndCustomInfo typeAndInfo, int cardinality, bool useRawView)
 {
     _typeAndInfo = typeAndInfo;
     _cardinality = cardinality;
     _useRawView = useRawView;
 }
Пример #51
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,
            ResultProvider resultProvider)
        {
            Debug.Assert(proxyValue != null);
            var proxyType        = proxyValue.Type;
            var proxyTypeAndInfo = new TypeAndCustomInfo(proxyType);
            var proxyMembers     = MemberExpansion.CreateExpansion(
                inspectionContext,
                proxyTypeAndInfo,
                proxyValue,
                ExpansionFlags.IncludeBaseMembers,
                TypeHelpers.IsPublic,
                resultProvider,
                isProxyType: true);

            if (proxyMembers != null)
            {
                string proxyMemberFullNamePrefix = null;
                if (childFullNamePrefix != null)
                {
                    proxyMemberFullNamePrefix = resultProvider.FullNameProvider.GetClrObjectCreationExpression(
                        inspectionContext,
                        proxyTypeAndInfo.ClrType,
                        proxyTypeAndInfo.Info,
                        new[] { childFullNamePrefix });
                }
                _proxyItem = new EvalResult(
                    ExpansionKind.Default,
                    name: string.Empty,
                    typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                    declaredTypeAndInfo: proxyTypeAndInfo,
                    useDebuggerDisplay: false,
                    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;
        }
Пример #52
0
        internal Expansion GetTypeExpansion(
            DkmInspectionContext inspectionContext,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            ExpansionFlags flags)
        {
            var declaredType = declaredTypeAndInfo.Type;

            Debug.Assert(!declaredType.IsTypeVariables());

            if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0)
            {
                return(null);
            }

            var runtimeType = value.Type.GetLmrType();

            // If the value is an array, expand the array elements.
            if (runtimeType.IsArray)
            {
                var sizes = value.ArrayDimensions;
                if (sizes == null)
                {
                    // Null array. No expansion.
                    return(null);
                }
                var lowerBounds = value.ArrayLowerBounds;

                Type elementType;
                DkmClrCustomTypeInfo elementTypeInfo;
                if (declaredType.IsArray)
                {
                    elementType     = declaredType.GetElementType();
                    elementTypeInfo = CustomTypeInfo.SkipOne(declaredTypeAndInfo.Info);
                }
                else
                {
                    elementType     = runtimeType.GetElementType();
                    elementTypeInfo = null;
                }

                return(ArrayExpansion.CreateExpansion(new TypeAndCustomInfo(DkmClrType.Create(declaredTypeAndInfo.ClrType.AppDomain, elementType), elementTypeInfo), sizes, lowerBounds));
            }

            if (this.IsPrimitiveType(runtimeType))
            {
                return(null);
            }

            if (declaredType.IsFunctionPointer())
            {
                // Function pointers have no expansion
                return(null);
            }

            if (declaredType.IsPointer)
            {
                // If this assert fails, the element type info is just .SkipOne().
                Debug.Assert(declaredTypeAndInfo.Info?.PayloadTypeId != CustomTypeInfo.PayloadTypeId);
                var elementType = declaredType.GetElementType();
                return(value.IsNull || elementType.IsVoid()
                    ? null
                    : new PointerDereferenceExpansion(new TypeAndCustomInfo(DkmClrType.Create(declaredTypeAndInfo.ClrType.AppDomain, elementType))));
            }

            if (value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown) &&
                runtimeType.IsEmptyResultsViewException())
            {
                // The value is an exception thrown expanding an empty
                // IEnumerable. Use the runtime type of the exception and
                // skip base types. (This matches the native EE behavior
                // to expose a single property from the exception.)
                flags &= ~ExpansionFlags.IncludeBaseMembers;
            }

            return(MemberExpansion.CreateExpansion(inspectionContext, declaredTypeAndInfo, value, flags, TypeHelpers.IsVisibleMember, this));
        }
Пример #53
0
        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);
                }
            }
        }
 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);
 }
Пример #55
0
        private static string MakeFullName(
            IDkmClrFullNameProvider fullNameProvider,
            DkmInspectionContext inspectionContext,
            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.Parenthesize();
            }

            var typeDeclaringMember = typeDeclaringMemberAndInfo.Type;
            if (typeDeclaringMember.IsInterface)
            {
                memberAccessRequiresExplicitCast = !typeDeclaringMember.Equals(parent.DeclaredTypeAndInfo.Type);
            }

            return fullNameProvider.GetClrMemberName(
                inspectionContext,
                parentFullName,
                typeDeclaringMemberAndInfo.ClrType,
                typeDeclaringMemberAndInfo.Info,
                name,
                memberAccessRequiresExplicitCast,
                memberIsStatic);
        }
Пример #56
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);
                }
            }
        }
Пример #57
0
 private EvalResult CreateDynamicViewRow(DkmInspectionContext inspectionContext, string name, EvalResultDataItem parent, IDkmClrFullNameProvider fullNameProvider)
 {
     var proxyTypeAndInfo = new TypeAndCustomInfo(_proxyValue.Type);
     var isRootExpression = parent == null;
     var fullName = isRootExpression ? name : parent.ChildFullNamePrefix;
     var childFullNamePrefix = (fullName == null) ?
         null :
         fullNameProvider.GetClrObjectCreationExpression(inspectionContext, proxyTypeAndInfo.ClrType, proxyTypeAndInfo.Info, fullName);
     var formatSpecifiers = isRootExpression ? Formatter.NoFormatSpecifiers : parent.FormatSpecifiers;
     return new EvalResult(
         ExpansionKind.DynamicView,
         name,
         typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
         declaredTypeAndInfo: proxyTypeAndInfo,
         useDebuggerDisplay: false,
         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);
 }
 public PointerDereferenceExpansion(TypeAndCustomInfo elementTypeAndInfo)
 {
     Debug.Assert(elementTypeAndInfo.Type != null);
     _elementTypeAndInfo = elementTypeAndInfo;
 }
Пример #59
0
        public EvalResultDataItem(
            ExpansionKind kind,
            string name,
            TypeAndCustomInfo typeDeclaringMemberAndInfo,
            TypeAndCustomInfo declaredTypeAndInfo,
            EvalResultDataItem parent,
            DkmClrValue value,
            string displayValue,
            Expansion expansion,
            bool childShouldParenthesize,
            string fullName,
            string childFullNamePrefixOpt,
            ReadOnlyCollection<string> formatSpecifiers,
            DkmEvaluationResultCategory category,
            DkmEvaluationResultFlags flags,
            string editableValue,
            DkmInspectionContext inspectionContext)
        {
            Debug.Assert(name != null);
            Debug.Assert(formatSpecifiers != null);
            Debug.Assert((flags & DkmEvaluationResultFlags.Expandable) == 0);

            this.Kind = kind;
            this.Name = name;
            this.TypeDeclaringMemberAndInfo = typeDeclaringMemberAndInfo;
            this.DeclaredTypeAndInfo = declaredTypeAndInfo;
            this.Parent = parent;
            this.Value = value;
            this.DisplayValue = displayValue;
            this.ChildShouldParenthesize = childShouldParenthesize;
            this.FullNameWithoutFormatSpecifiers = fullName;
            this.ChildFullNamePrefix = childFullNamePrefixOpt;
            this.FormatSpecifiers = formatSpecifiers;
            this.Category = category;
            this.EditableValue = editableValue;
            this.Flags = flags | GetFlags(value, inspectionContext) | ((expansion == null) ? DkmEvaluationResultFlags.None : DkmEvaluationResultFlags.Expandable);
            this.Expansion = expansion;
        }
Пример #60
0
        internal static Expansion CreateExpansion(
            DkmInspectionContext inspectionContext,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            ExpansionFlags flags,
            Predicate<MemberInfo> predicate,
            ResultProvider resultProvider)
        {
            // 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, function pointers, and null values with a declared type that is an interface have no visible members.
            Debug.Assert(!runtimeType.IsInterface || value.IsNull);
            if (resultProvider.IsPrimitiveType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface || runtimeType.IsFunctionPointer())
            {
                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, resultProvider);
            if (isDynamicProperty && (dynamicViewExpansion == null))
            {
                return null;
            }

            var customTypeInfoMap = CustomTypeInfoTypeArgumentMap.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,
                customTypeInfoMap,
                out publicInstanceExpansion,
                out nonPublicInstanceExpansion);

            // Public and non-public static members.
            Expansion publicStaticExpansion;
            Expansion nonPublicStaticExpansion;
            GetPublicAndNonPublicMembers(
                staticMembers,
                customTypeInfoMap,
                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(
                    type,
                    AggregateExpansion.CreateExpansion(staticExpansions));
                staticExpansions.Free();
                expansions.Add(staticMembersExpansion);
            }

            instanceMembers.Free();
            staticMembers.Free();

            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, resultProvider);
                if (resultsViewExpansion != null)
                {
                    expansions.Add(resultsViewExpansion);
                }
            }

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

            var result = AggregateExpansion.CreateExpansion(expansions);
            expansions.Free();
            return result;
        }