Ejemplo n.º 1
0
        internal static EvalResult CreateMemberDataItem(
            ResultProvider resultProvider,
            DkmInspectionContext inspectionContext,
            MemberAndDeclarationInfo member,
            DkmClrValue memberValue,
            EvalResultDataItem parent,
            CustomTypeInfoTypeArgumentMap customTypeInfoMap,
            ExpansionFlags flags)
        {
            var    fullNameProvider = resultProvider.FullNameProvider;
            var    declaredType     = member.Type;
            var    declaredTypeInfo = customTypeInfoMap.SubstituteCustomTypeInfo(member.OriginalDefinitionType, member.TypeInfo);
            string memberName;
            // Considering, we're not handling the case of a member inherited from a generic base type.
            var typeDeclaringMember     = member.GetExplicitlyImplementedInterface(out memberName) ?? member.DeclaringType;
            var typeDeclaringMemberInfo = typeDeclaringMember.IsInterface
                ? customTypeInfoMap.SubstituteCustomTypeInfo(typeDeclaringMember.GetInterfaceListEntry(member.DeclaringType), customInfo: null)
                : null;
            var    memberNameForFullName = fullNameProvider.GetClrValidIdentifier(inspectionContext, memberName);
            var    appDomain             = memberValue.Type.AppDomain;
            string fullName;

            if (memberNameForFullName == null)
            {
                fullName = null;
            }
            else
            {
                memberName = memberNameForFullName;
                fullName   = MakeFullName(
                    fullNameProvider,
                    inspectionContext,
                    memberNameForFullName,
                    new TypeAndCustomInfo(DkmClrType.Create(appDomain, typeDeclaringMember), typeDeclaringMemberInfo),    // Note: Won't include DynamicAttribute.
                    member.RequiresExplicitCast,
                    member.IsStatic,
                    parent);
            }
            return(resultProvider.CreateDataItem(
                       inspectionContext,
                       memberName,
                       typeDeclaringMemberAndInfo: (member.IncludeTypeInMemberName || typeDeclaringMember.IsInterface) ? new TypeAndCustomInfo(DkmClrType.Create(appDomain, typeDeclaringMember), typeDeclaringMemberInfo) : default(TypeAndCustomInfo), // Note: Won't include DynamicAttribute.
                       declaredTypeAndInfo: new TypeAndCustomInfo(DkmClrType.Create(appDomain, declaredType), declaredTypeInfo),
                       value: memberValue,
                       useDebuggerDisplay: parent != null,
                       expansionFlags: flags,
                       childShouldParenthesize: false,
                       fullName: fullName,
                       formatSpecifiers: Formatter.NoFormatSpecifiers,
                       category: DkmEvaluationResultCategory.Other,
                       flags: memberValue.EvalFlags,
                       evalFlags: DkmEvaluationFlags.None));
        }
Ejemplo n.º 2
0
        private static TypeAndCustomInfo GetTupleFieldTypeAndInfo(
            DkmClrAppDomain appDomain,
            FieldInfo field,
            CustomTypeInfoTypeArgumentMap customTypeInfoMap)
        {
            var declaringTypeDef = field.DeclaringType.GetGenericTypeDefinition();
            var fieldDef         = declaringTypeDef.GetTupleField(field.Name);
            var fieldType        = DkmClrType.Create(appDomain, field.FieldType);
            var fieldTypeInfo    = customTypeInfoMap.SubstituteCustomTypeInfo(fieldDef.FieldType, null);

            return(new TypeAndCustomInfo(fieldType, fieldTypeInfo));
        }
Ejemplo n.º 3
0
        private MemberExpansion(
            MemberAndDeclarationInfo[] members,
            CustomTypeInfoTypeArgumentMap customTypeInfoMap,
            bool containsFavorites = false
            )
        {
            Debug.Assert(members != null);
            Debug.Assert(members.Length > 0);
            Debug.Assert(customTypeInfoMap != null);

            _members           = members;
            _customTypeInfoMap = customTypeInfoMap;
            _containsFavorites = containsFavorites;
        }
        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));
        }
Ejemplo n.º 5
0
        private static EvalResult GetMemberRow(
            ResultProvider resultProvider,
            DkmInspectionContext inspectionContext,
            DkmClrValue value,
            MemberAndDeclarationInfo member,
            EvalResultDataItem parent,
            CustomTypeInfoTypeArgumentMap customTypeInfoMap)
        {
            var memberValue = value.GetMemberValue(member, inspectionContext);

            return(CreateMemberDataItem(
                       resultProvider,
                       inspectionContext,
                       member,
                       memberValue,
                       parent,
                       customTypeInfoMap,
                       ExpansionFlags.All));
        }
Ejemplo n.º 6
0
        internal static DynamicViewExpansion CreateExpansion(
            DkmInspectionContext inspectionContext,
            DkmClrValue value,
            ResultProvider resultProvider
            )
        {
            if (value.IsError() || value.IsNull || value.HasExceptionThrown())
            {
                return(null);
            }

            var type = value.Type.GetLmrType();

            if (!(type.IsComObject() || type.IsIDynamicMetaObjectProvider()))
            {
                return(null);
            }

            var proxyValue = value.InstantiateDynamicViewProxy(inspectionContext);

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

            // Expansion is based on the 'DynamicMetaObjectProviderDebugView.Items' property.
            var proxyType            = proxyValue.Type;
            var itemsMemberExpansion = RootHiddenExpansion.CreateExpansion(
                proxyType.GetMemberByName("Items"),
                CustomTypeInfoTypeArgumentMap.Create(new TypeAndCustomInfo(proxyType))
                );

            return(new DynamicViewExpansion(proxyValue, itemsMemberExpansion));
        }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
0
        private static void GetPublicAndNonPublicMembers(
            ArrayBuilder <MemberAndDeclarationInfo> allMembers,
            CustomTypeInfoTypeArgumentMap customTypeInfoMap,
            bool isProxyType,
            out Expansion publicExpansion,
            out Expansion nonPublicExpansion
            )
        {
            var publicExpansions = ArrayBuilder <Expansion> .GetInstance();

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

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

            foreach (var member in allMembers)
            {
                if (member.BrowsableState.HasValue)
                {
                    switch (member.BrowsableState.Value)
                    {
                    case DkmClrDebuggerBrowsableAttributeState.RootHidden:
                        if (publicMembers.Count > 0)
                        {
                            publicExpansions.Add(
                                new MemberExpansion(publicMembers.ToArray(), customTypeInfoMap)
                                );
                            publicMembers.Clear();
                        }
                        publicExpansions.Add(
                            new RootHiddenExpansion(member, customTypeInfoMap)
                            );
                        continue;

                    case DkmClrDebuggerBrowsableAttributeState.Never:
                        continue;
                    }
                }

                // The native EE shows proxy type members as public members if they have a
                // DebuggerBrowsable attribute of any value. Match that behaviour here.
                if (
                    member.HideNonPublic &&
                    !member.IsPublic &&
                    (!isProxyType || !member.BrowsableState.HasValue)
                    )
                {
                    nonPublicMembers.Add(member);
                }
                else
                {
                    publicMembers.Add(member);
                }
            }

            if (publicMembers.Count > 0)
            {
                publicExpansions.Add(
                    new MemberExpansion(publicMembers.ToArray(), customTypeInfoMap)
                    );
            }
            publicMembers.Free();

            publicExpansion = AggregateExpansion.CreateExpansion(publicExpansions);
            publicExpansions.Free();

            nonPublicExpansion =
                (nonPublicMembers.Count > 0)
                    ? new NonPublicMembersExpansion(
                    members: new MemberExpansion(
                        nonPublicMembers.ToArray(),
                        customTypeInfoMap
                        )
                    )
                    : null;
            nonPublicMembers.Free();
        }
Ejemplo n.º 9
0
 internal RootHiddenExpansion(MemberAndDeclarationInfo member, CustomTypeInfoTypeArgumentMap customTypeInfoMap)
 {
     _member            = member;
     _customTypeInfoMap = customTypeInfoMap;
 }
Ejemplo n.º 10
0
 internal static Expansion CreateExpansion(
     MemberAndDeclarationInfo members,
     CustomTypeInfoTypeArgumentMap customTypeInfoMap)
 {
     return(new RootHiddenExpansion(members, customTypeInfoMap));
 }
Ejemplo n.º 11
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));
        }
Ejemplo n.º 12
0
        private static ReadOnlyCollection <Field> GetFields(TypeAndCustomInfo declaringTypeAndInfo, int cardinality)
        {
            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;

            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);
                    var name             = CustomTypeInfo.GetTupleElementNameIfAny(tupleElementNames, offset + index);
                    if (name != null)
                    {
                        builder.Add(new Field(declaringTypeAndInfo, fieldTypeAndInfo, field, name, parent));
                    }
                    builder.Add(new Field(
                                    declaringTypeAndInfo,
                                    fieldTypeAndInfo,
                                    field,
                                    (offset == 0) ? fieldName : TypeHelpers.GetTupleFieldName(offset + index),
                                    parent));
                }

                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);
                parent = new Field(declaringTypeAndInfo, restTypeAndInfo, rest, TypeHelpers.TupleFieldRestName, parent);
                declaringTypeAndInfo = restTypeAndInfo;
                offset += TypeHelpers.TupleFieldRestPosition - 1;
            }

            // If there were any nested ValueTuples,
            // add the Rest field of the outermost.
            if (parent != null)
            {
                while (parent.Parent != null)
                {
                    parent = parent.Parent;
                }
                builder.Add(parent);
            }

            return(builder.ToImmutableAndFree());
        }