示例#1
0
        /// <summary>
        /// Adds all candidates from the method lists.
        ///
        /// This method implements the logic that causes applicable methods in derived types to hide
        /// all methods in base types.
        /// </summary>
        /// <param name="methodLists">The methods, grouped by declaring type. Base types must come first in the list.</param>
        public void AddMethodLists(IList <MethodListWithDeclaringType> methodLists)
        {
            if (methodLists == null)
            {
                throw new ArgumentNullException("methodLists");
            }
            // Base types come first, so go through the list backwards (derived types first)
            bool[] isHiddenByDerivedType;
            if (methodLists.Count > 1)
            {
                isHiddenByDerivedType = new bool[methodLists.Count];
            }
            else
            {
                isHiddenByDerivedType = null;
            }
            for (int i = methodLists.Count - 1; i >= 0; i--)
            {
                if (isHiddenByDerivedType != null && isHiddenByDerivedType[i])
                {
                    continue;
                }


                MethodListWithDeclaringType methodList     = methodLists[i];
                bool foundApplicableCandidateInCurrentList = false;

                for (int j = 0; j < methodList.Count; j++)
                {
                    IParameterizedMember     method = methodList[j];
                    OverloadResolutionErrors errors = AddCandidate(method);
                    foundApplicableCandidateInCurrentList |= IsApplicable(errors);
                }

                if (foundApplicableCandidateInCurrentList && i > 0)
                {
                    foreach (IType baseType in methodList.DeclaringType.GetAllBaseTypes())
                    {
                        for (int j = 0; j < i; j++)
                        {
                            if (!isHiddenByDerivedType[j] && baseType.Equals(methodLists[j].DeclaringType))
                            {
                                isHiddenByDerivedType[j] = true;
                            }
                        }
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Looks up the indexers on the target type.
        /// </summary>
        public IList <MethodListWithDeclaringType> LookupIndexers(Expression targetExpression)
        {
            if (targetExpression == null)
            {
                throw new ArgumentNullException("targetExpression");
            }

            IType targetType                       = targetExpression.Type;
            bool  allowProtectedAccess             = IsProtectedAccessAllowed(targetExpression);
            Predicate <IUnresolvedProperty> filter = p => p.IsIndexer;

            List <LookupGroup> lookupGroups = new List <LookupGroup>();

            foreach (IType type in targetType.GetNonInterfaceBaseTypes())
            {
                List <IParameterizedMember> newMethods = null;
                IMember newNonMethod = null;

                IEnumerable <IType> typeBaseTypes = null;

                var members = type.GetProperties(filter, GetMemberOptions.IgnoreInheritedMembers);
                AddMembers(type, members, allowProtectedAccess, lookupGroups, true, ref typeBaseTypes, ref newMethods, ref newNonMethod);

                if (newMethods != null || newNonMethod != null)
                {
                    lookupGroups.Add(new LookupGroup(type, null, newMethods, newNonMethod));
                }
            }

            // Remove interface members hidden by class members.
            if (targetType.Kind == TypeKind.TypeParameter)
            {
                // This can happen only with type parameters.
                RemoveInterfaceMembersHiddenByClassMembers(lookupGroups);
            }

            // Remove all hidden groups
            lookupGroups.RemoveAll(g => g.MethodsAreHidden || g.Methods.Count == 0);

            MethodListWithDeclaringType[] methodLists = new MethodListWithDeclaringType[lookupGroups.Count];
            for (int i = 0; i < methodLists.Length; i++)
            {
                methodLists[i] = new MethodListWithDeclaringType(lookupGroups[i].DeclaringType, lookupGroups[i].Methods);
            }
            return(methodLists);
        }
示例#3
0
        Expression CreateResult(Expression targetExpression, List <LookupGroup> lookupGroups, string name, IList <IType> typeArguments)
        {
            // Remove all hidden groups
            lookupGroups.RemoveAll(g => g.AllHidden);

            if (lookupGroups.Count == 0)
            {
                // No members found
                return(new UnknownMemberExpression(targetExpression.Type, name, typeArguments));
            }

            if (lookupGroups.Any(g => !g.MethodsAreHidden && g.Methods.Count > 0))
            {
                // If there are methods, make a MethodGroupResolveResult.
                // Note that a conflict between a member and a method (possible with multiple interface inheritance)
                // is only a warning, not an error, and the V# compiler will prefer the method group.
                List <MethodListWithDeclaringType> methodLists = new List <MethodListWithDeclaringType>();
                foreach (var lookupGroup in lookupGroups)
                {
                    if (!lookupGroup.MethodsAreHidden && lookupGroup.Methods.Count > 0)
                    {
                        var methodListWithDeclType = new MethodListWithDeclaringType(lookupGroup.DeclaringType);
                        foreach (var method in lookupGroup.Methods)
                        {
                            methodListWithDeclType.Add((IMethod)method);
                        }
                        methodLists.Add(methodListWithDeclType);
                    }
                }

                return(new MethodGroupExpression(targetExpression, name, methodLists, typeArguments));
            }

            // If there are ambiguities, report the most-derived result (last group)
            LookupGroup resultGroup = lookupGroups[lookupGroups.Count - 1];

            if (resultGroup.NestedTypes != null && resultGroup.NestedTypes.Count > 0)
            {
                if (resultGroup.NestedTypes.Count > 1 || !resultGroup.NonMethodIsHidden || lookupGroups.Count > 1)
                {
                    //   return new AmbiguousTypeResolveResult(resultGroup.NestedTypes[0]); // TODO:ERROR AMBIGIOUS
                    return(null);
                }
                else
                {
                    return(new TypeExpression(resultGroup.NestedTypes[0]));
                }
            }

            if (resultGroup.NonMethod.IsStatic && targetExpression is SelfReference)
            {
                targetExpression = new TypeExpression(targetExpression.Type);
            }

            if (lookupGroups.Count > 1)
            {
                throw new ArgumentException(string.Format("Ambigious member {1} found on target {0}",
                                                          targetExpression.GetSignatureForError(), resultGroup.NonMethod));
            }
            else
            {
                if (isInEnumMemberInitializer)
                {
                    IField field = resultGroup.NonMethod as IField;
                    if (field != null && field.DeclaringTypeDefinition != null && field.DeclaringTypeDefinition.Kind == TypeKind.Enum)
                    {
                        return(new MemberExpressionStatement(
                                   targetExpression, field,
                                   field.DeclaringTypeDefinition.EnumUnderlyingType,
                                   field.IsConst, field.ConstantValue));
                    }
                }
                return(new MemberExpressionStatement(targetExpression, resultGroup.NonMethod));
            }
        }