Пример #1
0
 /// <summary>
 /// Gets all candidate extension methods.
 /// Note: this includes candidates that are not eligible due to an inapplicable
 /// this argument.
 /// The candidates will only be specialized if the type arguments were provided explicitly.
 /// </summary>
 /// <remarks>
 /// The results are stored in nested lists because they are grouped by using scope.
 /// That is, for "using SomeExtensions; namespace X { using MoreExtensions; ... }",
 /// the return value will be
 /// new List {
 ///    new List { all extensions from MoreExtensions },
 ///    new List { all extensions from SomeExtensions }
 /// }
 /// </remarks>
 public IEnumerable<IEnumerable<IMethod>> GetExtensionMethods()
 {
     if (resolver != null)
     {
         Debug.Assert(extensionMethods == null);
         try
         {
             extensionMethods = resolver.GetExtensionMethods(methodName, typeArguments);
         }
         finally
         {
             resolver = null;
         }
     }
     return extensionMethods ?? Enumerable.Empty<IEnumerable<IMethod>>();
 }
Пример #2
0
        public Expression ResolveMemberAccess(ResolveContext rc, VSC.AST.Expression target, string identifier, IList <IType> typeArguments, NameLookupMode lookupMode = NameLookupMode.Expression)
        {
            // V# 4.0 spec: §7.6.4

            bool           parameterizeResultType = !(typeArguments.Count != 0 && typeArguments.All(t => t.Kind == TypeKind.UnboundTypeArgument));
            AliasNamespace nrr = target as AliasNamespace;

            if (nrr != null)
            {
                return(ResolveMemberAccessOnNamespace(nrr, identifier, typeArguments, parameterizeResultType));
            }

            // TODO:Dynamic Resolution
            //if (target.Type.Kind == TypeKind.Dynamic)
            //    return new DynamicMemberResolveResult(target, identifier);

            MemberLookup lookup = rc.CreateMemberLookup(lookupMode);
            Expression   result;

            switch (lookupMode)
            {
            case NameLookupMode.Expression:
                result = lookup.Lookup(target, identifier, typeArguments, isInvocation: false);
                break;

            case NameLookupMode.InvocationTarget:
                result = lookup.Lookup(target, identifier, typeArguments, isInvocation: true);
                break;

            case NameLookupMode.Type:
            case NameLookupMode.TypeInUsingDeclaration:
            case NameLookupMode.BaseTypeReference:
                // Don't do the UnknownMemberResolveResult/MethodGroupResolveResult processing,
                // it's only relevant for expressions.
                return(lookup.LookupType(target.Type, identifier, typeArguments, parameterizeResultType));

            default:
                throw new NotSupportedException("Invalid value for NameLookupMode");
            }
            if (result is UnknownMemberExpression)
            {
                // We intentionally use all extension methods here, not just the eligible ones.
                // Proper eligibility checking is only possible for the full invocation
                // (after we know the remaining arguments).
                // The eligibility check in GetExtensionMethods is only intended for code completion.
                var extensionMethods = rc.GetExtensionMethods(identifier, typeArguments);
                if (extensionMethods.Count > 0)
                {
                    return(new MethodGroupExpression(target, identifier, EmptyList <MethodListWithDeclaringType> .Instance, typeArguments)
                    {
                        extensionMethods = extensionMethods
                    });
                }
            }
            else
            {
                MethodGroupExpression mgrr = result as MethodGroupExpression;
                if (mgrr != null)
                {
                    Debug.Assert(mgrr.extensionMethods == null);
                    // set the values that are necessary to make MethodGroupResolveResult.GetExtensionMethods() work
                    mgrr.resolver = rc;
                }
            }
            return(result);
        }