Ejemplo n.º 1
0
        internal static bool IsOrInheritsFrom(this Type type, Type baseType)
        {
            Debug.Assert(type != null);
            Debug.Assert(baseType != null);
            Debug.Assert(!baseType.IsInterface);

            if (type.IsInterface)
            {
                return(false);
            }

            do
            {
                if (type.Equals(baseType))
                {
                    return(true);
                }
                type = type.BaseType;
            }while (type != null);

            return(false);
        }
Ejemplo n.º 2
0
        internal static void AppendTypeMembers(
            this Type type,
            ArrayBuilder <MemberAndDeclarationInfo> includedMembers,
            Predicate <MemberInfo> predicate,
            Type declaredType,
            DkmClrAppDomain appDomain,
            bool includeInherited,
            bool hideNonPublic)
        {
            Debug.Assert(!type.IsInterface);

            var memberLocation         = DeclarationInfo.FromSubTypeOfDeclaredType;
            var previousDeclarationMap = includeInherited ? new Dictionary <string, DeclarationInfo>() : null;

            int inheritanceLevel = 0;

            while (!type.IsObject())
            {
                if (type.Equals(declaredType))
                {
                    Debug.Assert(memberLocation == DeclarationInfo.FromSubTypeOfDeclaredType);
                    memberLocation = DeclarationInfo.FromDeclaredTypeOrBase;
                }

                // Get the state from DebuggerBrowsableAttributes for the members of the current type.
                var browsableState = DkmClrType.Create(appDomain, type).GetDebuggerBrowsableAttributeState();

                // Hide non-public members if hideNonPublic is specified (intended to reflect the
                // DkmInspectionContext's DkmEvaluationFlags), and the type is from an assembly
                // with no symbols.
                var hideNonPublicBehavior = DeclarationInfo.None;
                if (hideNonPublic)
                {
                    var moduleInstance = appDomain.FindClrModuleInstance(type.Module.ModuleVersionId);
                    if (moduleInstance == null || moduleInstance.Module == null)
                    {
                        // Synthetic module or no symbols loaded.
                        hideNonPublicBehavior = DeclarationInfo.HideNonPublic;
                    }
                }

                foreach (var member in type.GetMembers(MemberBindingFlags))
                {
                    if (!predicate(member))
                    {
                        continue;
                    }

                    var memberName = member.Name;
                    // This represents information about the immediately preceding (more derived)
                    // declaration with the same name as the current member.
                    var previousDeclaration   = DeclarationInfo.None;
                    var memberNameAlreadySeen = false;
                    if (includeInherited)
                    {
                        memberNameAlreadySeen = previousDeclarationMap.TryGetValue(memberName, out previousDeclaration);
                        if (memberNameAlreadySeen)
                        {
                            // There was a name conflict, so we'll need to include the declaring
                            // type of the member to disambiguate.
                            previousDeclaration |= DeclarationInfo.IncludeTypeInMemberName;
                        }

                        // Update previous member with name hiding (casting) and declared location information for next time.
                        previousDeclarationMap[memberName] =
                            (previousDeclaration & ~(DeclarationInfo.RequiresExplicitCast |
                                                     DeclarationInfo.FromSubTypeOfDeclaredType)) |
                            member.AccessingBaseMemberWithSameNameRequiresExplicitCast() |
                            memberLocation;
                    }

                    Debug.Assert(memberNameAlreadySeen != (previousDeclaration == DeclarationInfo.None));

                    // Decide whether to include this member in the list of members to display.
                    if (!memberNameAlreadySeen || previousDeclaration.IsSet(DeclarationInfo.RequiresExplicitCast))
                    {
                        DkmClrDebuggerBrowsableAttributeState?browsableStateValue = null;
                        if (browsableState != null)
                        {
                            DkmClrDebuggerBrowsableAttributeState value;
                            if (browsableState.TryGetValue(memberName, out value))
                            {
                                browsableStateValue = value;
                            }
                        }

                        if (memberLocation.IsSet(DeclarationInfo.FromSubTypeOfDeclaredType))
                        {
                            // If the current type is a sub-type of the declared type, then
                            // we always need to insert a cast to access the member
                            previousDeclaration |= DeclarationInfo.RequiresExplicitCast;
                        }
                        else if (previousDeclaration.IsSet(DeclarationInfo.FromSubTypeOfDeclaredType))
                        {
                            // If the immediately preceding member (less derived) was
                            // declared on a sub-type of the declared type, then we'll
                            // ignore the casting bit.  Accessing a member through the
                            // declared type is the same as casting to that type, so
                            // the cast would be redundant.
                            previousDeclaration &= ~DeclarationInfo.RequiresExplicitCast;
                        }

                        previousDeclaration |= hideNonPublicBehavior;

                        includedMembers.Add(new MemberAndDeclarationInfo(member, browsableStateValue, previousDeclaration, inheritanceLevel));
                    }
                }

                if (!includeInherited)
                {
                    break;
                }

                type = type.BaseType;
                inheritanceLevel++;
            }

            includedMembers.Sort(MemberAndDeclarationInfo.Comparer);
        }
Ejemplo n.º 3
0
        private static string MakeFullName(
            Formatter formatter,
            string name,
            Type typeDeclaringMember,
            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 (!typeDeclaringMember.IsInterface)
            {
                string qualifier;
                if (memberIsStatic)
                {
                    qualifier = formatter.GetTypeName(typeDeclaringMember, escapeKeywordIdentifiers: false);
                }
                else if (memberAccessRequiresExplicitCast)
                {
                    var typeName = formatter.GetTypeName(typeDeclaringMember, 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 (typeDeclaringMember.Equals(parent.DeclaredType))
                {
                    var memberAccessTemplate = parent.ChildShouldParenthesize
                        ? "({0}).{1}"
                        : "{0}.{1}";
                    return(string.Format(memberAccessTemplate, parent.ChildFullNamePrefix, name));
                }
                else
                {
                    var interfaceName        = formatter.GetTypeName(typeDeclaringMember, escapeKeywordIdentifiers: true);
                    var memberAccessTemplate = parent.ChildShouldParenthesize
                        ? "(({0})({1})).{2}"
                        : "(({0}){1}).{2}";
                    return(string.Format(memberAccessTemplate, interfaceName, parent.ChildFullNamePrefix, name));
                }
            }
        }