示例#1
0
        //
        // If member is a virtual member that implicitly overrides a member in a base class, return the overridden member.
        // Otherwise, return null.
        //
        // - MethodImpls ignored. (I didn't say it made sense, this is just how the desktop api we're porting behaves.)
        // - Implemented interfaces ignores. (I didn't say it made sense, this is just how the desktop api we're porting behaves.)
        //
        public static M GetImplicitlyOverriddenBaseClassMember <M>(this M member) where M : MemberInfo
        {
            MemberPolicies <M> policies = MemberPolicies <M> .Default;
            MethodAttributes   visibility;
            bool isStatic;
            bool isVirtual;
            bool isNewSlot;

            policies.GetMemberAttributes(member, out visibility, out isStatic, out isVirtual, out isNewSlot);
            if (isNewSlot || !isVirtual)
            {
                return(null);
            }
            String   name     = member.Name;
            TypeInfo typeInfo = member.DeclaringType.GetTypeInfo();

            for (;;)
            {
                Type baseType = typeInfo.BaseType;
                if (baseType == null)
                {
                    return(null);
                }
                typeInfo = baseType.GetTypeInfo();
                foreach (M candidate in policies.GetDeclaredMembers(typeInfo))
                {
                    if (candidate.Name != name)
                    {
                        continue;
                    }
                    MethodAttributes candidateVisibility;
                    bool             isCandidateStatic;
                    bool             isCandidateVirtual;
                    bool             isCandidateNewSlot;
                    policies.GetMemberAttributes(member, out candidateVisibility, out isCandidateStatic, out isCandidateVirtual, out isCandidateNewSlot);
                    if (!isCandidateVirtual)
                    {
                        continue;
                    }
                    if (!policies.ImplicitlyOverrides(candidate, member))
                    {
                        continue;
                    }
                    return(candidate);
                }
            }
        }
示例#2
0
        //
        // Take the result of Stage1Filter and filter by the BindingFlag bits.
        //
        private static IEnumerable <M> Stage2Filter <M>(Type type, String optionalNameFilter, BindingFlags bindingFlags, bool allowPrefixing) where M : MemberInfo
        {
            MemberPolicies <M> policies = MemberPolicies <M> .Default;

            bindingFlags = policies.ModifyBindingFlags(bindingFlags);
            bool ignoreCase   = (bindingFlags & BindingFlags.IgnoreCase) != 0;
            bool declaredOnly = (bindingFlags & BindingFlags.DeclaredOnly) != 0;
            QueriedMemberList <M> queriedMembers = Stage1Filter <M>(type, optionalNameFilter, ignoreCase: ignoreCase, declaredOnly: declaredOnly, allowPrefixing: allowPrefixing);

            for (int i = 0; i < queriedMembers.Count; i++)
            {
                BindingFlags allFlagsThatMustMatch = queriedMembers.AllFlagsThatMustMatchNoCopy[i];
                if ((bindingFlags & allFlagsThatMustMatch) == allFlagsThatMustMatch)
                {
                    yield return(queriedMembers.MembersNoCopy[i]);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Returns a single member, null or throws AmbigousMatchException, for the Type.Get*(string name,...) family of apis.
        /// </summary>
        public M?Disambiguate()
        {
            if (_queriedMembers == null)
            {
                return(null); // This is an uninitialized QueryResult<M>, which is supported and represents a 0-length list of matches.
            }
            int unfilteredCount = UnfilteredCount;

            M?match = null;

            for (int i = 0; i < unfilteredCount; i++)
            {
                if (_queriedMembers.Matches(i, _bindingAttr))
                {
                    if (match != null)
                    {
                        M challenger = _queriedMembers[i];

                        // Assuming the policy says it's ok to ignore the ambiguity, we're to resolve in favor of the member
                        // declared by the most derived type. Since QueriedMemberLists are sorted in order of decreasing derivation,
                        // that means we let the first match win - unless, of course, they're both the "most derived member".
                        if (match.DeclaringType !.Equals(challenger.DeclaringType))
                        {
                            throw new AmbiguousMatchException();
                        }

                        MemberPolicies <M> policies = MemberPolicies <M> .Default;
                        if (!policies.OkToIgnoreAmbiguity(match, challenger))
                        {
                            throw new AmbiguousMatchException();
                        }
                    }
                    else
                    {
                        match = _queriedMembers[i];
                    }
                }
            }
            return(match);
        }
示例#4
0
        //
        // Filter by name and visibility from the ReflectedType.
        //
        public static QueriedMemberList <M> Create(RuntimeTypeInfo type, string filter, bool ignoreCase, bool immediateTypeOnly)
        {
            RuntimeTypeInfo reflectedType = type;

            MemberPolicies <M> policies = MemberPolicies <M> .Default;

            NameFilter nameFilter;

            if (filter == null)
            {
                nameFilter = null;
            }
            else if (ignoreCase)
            {
                nameFilter = new NameFilterCaseInsensitive(filter);
            }
            else
            {
                nameFilter = new NameFilterCaseSensitive(filter);
            }

            bool inBaseClass = false;
            QueriedMemberList <M> queriedMembers = new QueriedMemberList <M>(immediateTypeOnly);

            while (type != null)
            {
                int numCandidatesInDerivedTypes = queriedMembers._totalCount;

                foreach (M member in policies.CoreGetDeclaredMembers(type, nameFilter, reflectedType))
                {
                    policies.GetMemberAttributes(member, out MethodAttributes visibility, out bool isStatic, out bool isVirtual, out bool isNewSlot);

                    if (inBaseClass && visibility == MethodAttributes.Private)
                    {
                        continue;
                    }

                    if (numCandidatesInDerivedTypes != 0 && policies.IsSuppressedByMoreDerivedMember(member, queriedMembers._members, startIndex: 0, endIndex: numCandidatesInDerivedTypes))
                    {
                        continue;
                    }

                    BindingFlags allFlagsThatMustMatch = default;
                    allFlagsThatMustMatch |= (isStatic ? BindingFlags.Static : BindingFlags.Instance);
                    if (isStatic && inBaseClass)
                    {
                        allFlagsThatMustMatch |= BindingFlags.FlattenHierarchy;
                    }
                    allFlagsThatMustMatch |= ((visibility == MethodAttributes.Public) ? BindingFlags.Public : BindingFlags.NonPublic);

                    queriedMembers.Add(member, allFlagsThatMustMatch);
                }

                if (!inBaseClass)
                {
                    queriedMembers._declaredOnlyCount = queriedMembers._totalCount;

                    if (immediateTypeOnly)
                    {
                        break;
                    }

                    if (policies.AlwaysTreatAsDeclaredOnly)
                    {
                        break;
                    }
                    inBaseClass = true;
                }

                type = type.BaseType.CastToRuntimeTypeInfo();
                if (type != null && !type.CanBrowseWithoutMissingMetadataExceptions())
                {
                    // If we got here, one of the base classes is missing metadata. We don't want to throw a MissingMetadataException now because we may be
                    // building a cached result for a caller who passed BindingFlags.DeclaredOnly. So we'll mark the results in a way that
                    // it will throw a MissingMetadataException if a caller attempts to iterate past the declared-only subset.
                    queriedMembers._typeThatBlockedBrowsing = type;
                    queriedMembers._totalCount = queriedMembers._declaredOnlyCount;
                    break;
                }
            }

            return(queriedMembers);
        }
示例#5
0
        //
        // Filter by name and visibility from the ReflectedType.
        //
        public static QueriedMemberList <M> Create(RuntimeTypeInfo type, string optionalNameFilter, bool ignoreCase)
        {
            RuntimeTypeInfo reflectedType = type;

            MemberPolicies <M> policies = MemberPolicies <M> .Default;

            NameFilter?nameFilter;

            if (optionalNameFilter == null)
            {
                nameFilter = null;
            }
            else if (ignoreCase)
            {
                nameFilter = new NameFilterCaseInsensitive(optionalNameFilter);
            }
            else
            {
                nameFilter = new NameFilterCaseSensitive(optionalNameFilter);
            }

            bool inBaseClass = false;
            QueriedMemberList <M> queriedMembers = new QueriedMemberList <M>();

            while (type != null)
            {
                int numCandidatesInDerivedTypes = queriedMembers._totalCount;

                foreach (M member in policies.CoreGetDeclaredMembers(type, nameFilter, reflectedType))
                {
                    MethodAttributes visibility;
                    bool             isStatic;
                    bool             isVirtual;
                    bool             isNewSlot;
                    policies.GetMemberAttributes(member, out visibility, out isStatic, out isVirtual, out isNewSlot);

                    if (inBaseClass && visibility == MethodAttributes.Private)
                    {
                        continue;
                    }

                    if (numCandidatesInDerivedTypes != 0 && policies.IsSuppressedByMoreDerivedMember(member, queriedMembers._members, startIndex: 0, endIndex: numCandidatesInDerivedTypes))
                    {
                        continue;
                    }

                    BindingFlags allFlagsThatMustMatch = default(BindingFlags);
                    allFlagsThatMustMatch |= (isStatic ? BindingFlags.Static : BindingFlags.Instance);
                    if (isStatic && inBaseClass)
                    {
                        allFlagsThatMustMatch |= BindingFlags.FlattenHierarchy;
                    }
                    allFlagsThatMustMatch |= ((visibility == MethodAttributes.Public) ? BindingFlags.Public : BindingFlags.NonPublic);

                    queriedMembers.Add(member, allFlagsThatMustMatch);
                }

                if (!inBaseClass)
                {
                    queriedMembers._declaredOnlyCount = queriedMembers._totalCount;
                    if (policies.AlwaysTreatAsDeclaredOnly)
                    {
                        break;
                    }
                    inBaseClass = true;
                }

                type = type.BaseType.CastToRuntimeTypeInfo();
            }

            return(queriedMembers);
        }
示例#6
0
        //
        // Filter by name and visibility from the ReflectedType.
        //
        private static QueriedMemberList <M> Stage1Filter <M>(Type type, String optionalNameFilter, bool ignoreCase, bool declaredOnly, bool allowPrefixing) where M : MemberInfo
        {
            Type reflectedType = type;

            MemberPolicies <M> policies = MemberPolicies <M> .Default;

            StringComparison comparisonType = ignoreCase ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture;
            bool             inBaseClass    = false;

            bool nameFilterIsPrefix = false;

            if (allowPrefixing && optionalNameFilter != null && optionalNameFilter.EndsWith("*", StringComparison.Ordinal))
            {
                nameFilterIsPrefix = true;
                optionalNameFilter = optionalNameFilter.Substring(0, optionalNameFilter.Length - 1);
            }

            QueriedMemberList <M> queriedMembers = new QueriedMemberList <M>();

            while (type != null)
            {
                int numCandidatesInDerivedTypes = queriedMembers.Count;

                TypeInfo typeInfo = type.GetTypeInfo();

                foreach (M member in policies.GetDeclaredMembers(typeInfo))
                {
                    if (optionalNameFilter != null)
                    {
                        if (nameFilterIsPrefix)
                        {
                            if (!member.Name.StartsWith(optionalNameFilter, comparisonType))
                            {
                                continue;
                            }
                        }
                        else if (!member.Name.Equals(optionalNameFilter, comparisonType))
                        {
                            continue;
                        }
                    }

                    MethodAttributes visibility;
                    bool             isStatic;
                    bool             isVirtual;
                    bool             isNewSlot;
                    policies.GetMemberAttributes(member, out visibility, out isStatic, out isVirtual, out isNewSlot);

                    if (inBaseClass && visibility == MethodAttributes.Private)
                    {
                        continue;
                    }

                    if (numCandidatesInDerivedTypes != 0 && policies.IsSuppressedByMoreDerivedMember(member, queriedMembers.MembersNoCopy, startIndex: 0, endIndex: numCandidatesInDerivedTypes))
                    {
                        continue;
                    }

                    BindingFlags allFlagsThatMustMatch = (BindingFlags)0;
                    allFlagsThatMustMatch |= (isStatic ? BindingFlags.Static : BindingFlags.Instance);
                    if (isStatic && inBaseClass)
                    {
                        allFlagsThatMustMatch |= BindingFlags.FlattenHierarchy;
                    }
                    allFlagsThatMustMatch |= ((visibility == MethodAttributes.Public) ? BindingFlags.Public : BindingFlags.NonPublic);

                    if (inBaseClass)
                    {
                        queriedMembers.Add(policies.GetInheritedMemberInfo(member, reflectedType), allFlagsThatMustMatch);
                    }
                    else
                    {
                        queriedMembers.Add(member, allFlagsThatMustMatch);
                    }
                }

                if (declaredOnly)
                {
                    break;
                }

                inBaseClass = true;
                type        = typeInfo.BaseType;
            }

            return(queriedMembers);
        }