/// <summary> /// This is a wrapper for MemberLookup that is not used to "probe", but /// to find a final definition. If the final definition is not found, we /// look for private members and display a useful debugging message if we /// find it. /// </summary> protected Expression MemberLookupFinal(ResolveContext ec, TypeSpec qualifier_type, TypeSpec queried_type, string name, int arity, MemberKind mt, BindingRestriction bf, Location loc) { Expression e; int errors = ec.Report.Errors; e = MemberLookup (ec.Compiler, ec.CurrentType, qualifier_type, queried_type, name, arity, mt, bf, loc); if (e != null || errors != ec.Report.Errors) return e; // No errors were reported by MemberLookup, but there was an error. return Error_MemberLookupFailed (ec, ec.CurrentType, qualifier_type, queried_type, name, arity, null, mt, bf); }
public static Expression MemberLookup(CompilerContext ctx, TypeSpec container_type, TypeSpec qualifier_type, TypeSpec queried_type, string name, int arity, BindingRestriction binding, Location loc) { return MemberLookup (ctx, container_type, qualifier_type, queried_type, name, arity, MemberKind.All, binding | BindingRestriction.AccessibleOnly, loc); }
protected virtual Expression Error_MemberLookupFailed(ResolveContext ec, TypeSpec container_type, TypeSpec qualifier_type, TypeSpec queried_type, string name, int arity, string class_name, MemberKind mt, BindingRestriction bf) { IList<MemberSpec> lookup = null; if (queried_type == null) { class_name = "global::"; } else { BindingRestriction restriction = bf & BindingRestriction.DeclaredOnly; lookup = TypeManager.MemberLookup (queried_type, null, queried_type, mt, restriction, name, arity, null); if (lookup != null) { Expression e = Error_MemberLookupFailed (ec, queried_type, lookup); // // FIXME: This is still very wrong, it should be done inside // OverloadResolve to do correct arguments matching. // Requires MemberLookup accessiblity check removal // if (e == null || (mt & (MemberKind.Method | MemberKind.Constructor)) == 0) { var mi = lookup.First (); ec.Report.SymbolRelatedToPreviousError (mi); if ((mi.Modifiers & Modifiers.PROTECTED) != 0 && qualifier_type != null && container_type != null && qualifier_type != container_type && TypeManager.IsNestedFamilyAccessible (container_type, mi.DeclaringType)) { // Although a derived class can access protected members of // its base class it cannot do so through an instance of the // base class (CS1540). If the qualifier_type is a base of the // ec.CurrentType and the lookup succeeds with the latter one, // then we are in this situation. Error_CannotAccessProtected (ec, loc, mi, qualifier_type, container_type); } else { ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (mi), ec.Report); } } return e; } lookup = TypeManager.MemberLookup (queried_type, null, queried_type, MemberKind.All, BindingRestriction.None, name, -System.Math.Max (1, arity), null); } if (lookup == null) { if (class_name != null) { ec.Report.Error (103, loc, "The name `{0}' does not exist in the current context", name); } else { Error_TypeDoesNotContainDefinition (ec, queried_type, name); } return null; } var mge = Error_MemberLookupFailed (ec, queried_type, lookup); if (arity > 0 && mge != null) { mge.SetTypeArguments (ec, new TypeArguments (new FullNamedExpression [arity])); } return mge; }
// // Lookup type `queried_type' for code in class `container_type' with a qualifier of // `qualifier_type' or null to lookup members in the current class. // public static Expression MemberLookup(CompilerContext ctx, TypeSpec container_type, TypeSpec qualifier_type, TypeSpec queried_type, string name, int arity, MemberKind mt, BindingRestriction binding, Location loc) { var mi = TypeManager.MemberLookup (container_type, qualifier_type, queried_type, mt, binding, name, arity, null); if (mi == null) return null; var first = mi [0]; if (mi.Count > 1) { foreach (var mc in mi) { if (mc is MethodSpec) return new MethodGroupExpr (mi, queried_type, loc); } ctx.Report.SymbolRelatedToPreviousError (mi [1]); ctx.Report.SymbolRelatedToPreviousError (first); ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'", first.GetSignatureForError (), mi [1].GetSignatureForError ()); } if (first is MethodSpec) return new MethodGroupExpr (mi, queried_type, loc); return ExprClassFromMemberInfo (container_type, first, loc); }
// // FIXME: Probably implement a cache for (t,name,current_access_set)? // // This code could use some optimizations, but we need to do some // measurements. For example, we could use a delegate to `flag' when // something can not any longer be a method-group (because it is something // else). // // Return values: // If the return value is an Array, then it is an array of // MethodBases // // If the return value is an MemberInfo, it is anything, but a Method // // null on error. // // FIXME: When calling MemberLookup inside an `Invocation', we should pass // the arguments here and have MemberLookup return only the methods that // match the argument count/type, unlike we are doing now (we delay this // decision). // // This is so we can catch correctly attempts to invoke instance methods // from a static body (scan for error 120 in ResolveSimpleName). // // // FIXME: Potential optimization, have a static ArrayList // public static Expression MemberLookup(CompilerContext ctx, TypeSpec container_type, TypeSpec queried_type, string name, int arity, MemberKind mt, BindingRestriction bf, Location loc) { return MemberLookup (ctx, container_type, null, queried_type, name, arity, mt, bf, loc); }
// // Looks up a member called `name' in the `queried_type'. This lookup // is done by code that is contained in the definition for `invocation_type' // through a qualifier of type `qualifier_type' (or null if there is no qualifier). // // `invocation_type' is used to check whether we're allowed to access the requested // member wrt its protection level. // // When called from MemberAccess, `qualifier_type' is the type which is used to access // the requested member (`class B { A a = new A (); a.foo = 5; }'; here invocation_type // is B and qualifier_type is A). This is used to do the CS1540 check. // // When resolving a SimpleName, `qualifier_type' is null. // // The `qualifier_type' is used for the CS1540 check; it's normally either null or // the same than `queried_type' - except when we're being called from BaseAccess; // in this case, `invocation_type' is the current type and `queried_type' the base // type, so this'd normally trigger a CS1540. // // The binding flags are `bf' and the kind of members being looked up are `mt' // // The return value always includes private members which code in `invocation_type' // is allowed to access (using the specified `qualifier_type' if given); only use // BindingFlags.NonPublic to bypass the permission check. // // The 'almost_match' argument is used for reporting error CS1540. // // Returns an array of a single element for everything but Methods/Constructors // that might return multiple matches. // public static IList<MemberSpec> MemberLookup(TypeSpec invocation_type, TypeSpec qualifier_type, TypeSpec queried_type, MemberKind mt, BindingRestriction opt, string name, int arity, IList<MemberSpec> almost_match) { Timer.StartTimer (TimerType.MemberLookup); var retval = RealMemberLookup (invocation_type, qualifier_type, queried_type, mt, opt, name, arity, almost_match); Timer.StopTimer (TimerType.MemberLookup); return retval; }
static IList<MemberSpec> RealMemberLookup(TypeSpec invocation_type, TypeSpec qualifier_type, TypeSpec queried_type, MemberKind mt, BindingRestriction bf, string name, int arity, IList<MemberSpec> almost_match) { MemberFilter filter = new MemberFilter (name, arity, mt, null, null); if ((bf & BindingRestriction.AccessibleOnly) != 0) { filter.InvocationType = invocation_type ?? InternalType.FakeInternalType; } return MemberCache.FindMembers (queried_type, filter, bf); }
protected override Expression Error_MemberLookupFailed(ResolveContext ec, TypeSpec container_type, TypeSpec qualifier_type, TypeSpec queried_type, string name, int arity, string class_name, MemberKind mt, BindingRestriction bf) { ec.Report.Error (1935, loc, "An implementation of `{0}' query expression pattern could not be found. " + "Are you missing `System.Linq' using directive or `System.Core.dll' assembly reference?", name); return null; }