/// <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>>(); }
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); }