throw;
ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message);
- return EmptyExpression.Null; // TODO: Add location
+ return ErrorExpression.Instance; // TODO: Add location
}
}
}
var r = new OverloadResolver (ctors, OverloadResolver.Restrictions.NoBaseMembers, loc);
- var ctor = r.ResolveMember<MethodSpec> (rc, ref args);
- if (ctor == null)
- return null;
-
- if ((ctor.Modifiers & Modifiers.PROTECTED) != 0 && !rc.HasSet (ResolveContext.Options.BaseInitializer)) {
- MemberExpr.CheckProtectedMemberAccess (rc, ctor, ctor.DeclaringType, loc);
+ if (!rc.HasSet (ResolveContext.Options.BaseInitializer)) {
+ r.InstanceQualifier = new ConstructorInstanceQualifier (type);
}
- return ctor;
+ return r.ResolveMember<MethodSpec> (rc, ref args);
}
[Flags]
{
throw new NotImplementedException ("MakeExpression for " + GetType ());
}
+
+ public virtual object Accept (StructuralVisitor visitor)
+ {
+ return visitor.Visit (this);
+ }
}
/// <summary>
//if (ec.CurrentBlock == null || ec.CurrentBlock.CheckInvariantMeaningInBlock (Name, e, Location))
return e;
}
+
+ public override object Accept (StructuralVisitor visitor)
+ {
+ return visitor.Visit (this);
+ }
}
/// <summary>
/// This class denotes an expression which evaluates to a member
/// of a struct or a class.
/// </summary>
- public abstract class MemberExpr : Expression
+ public abstract class MemberExpr : Expression, OverloadResolver.IInstanceQualifier
{
//
// An instance expression associated with this member, if it's a
get;
}
+ TypeSpec OverloadResolver.IInstanceQualifier.InstanceType {
+ get {
+ return InstanceExpression.Type;
+ }
+ }
+
//
// Converts best base candidate for virtual method starting from QueriedBaseType
//
return method;
}
- protected void CheckProtectedMemberAccess<T> (ResolveContext rc, T member) where T : MemberSpec
+ protected void CheckProtectedMemberAccess (ResolveContext rc, MemberSpec member)
{
if (InstanceExpression == null)
return;
if ((member.Modifiers & Modifiers.PROTECTED) != 0 && !(InstanceExpression is This)) {
- CheckProtectedMemberAccess (rc, member, InstanceExpression.Type, loc);
+ if (!CheckProtectedMemberAccess (rc, member, InstanceExpression.Type)) {
+ Error_ProtectedMemberAccess (rc, member, InstanceExpression.Type, loc);
+ }
}
}
- public static void CheckProtectedMemberAccess<T> (ResolveContext rc, T member, TypeSpec qualifier, Location loc) where T : MemberSpec
+ bool OverloadResolver.IInstanceQualifier.CheckProtectedMemberAccess (ResolveContext rc, MemberSpec member)
+ {
+ if (InstanceExpression == null)
+ return true;
+
+ return InstanceExpression is This || CheckProtectedMemberAccess (rc, member, InstanceExpression.Type);
+ }
+
+ public static bool CheckProtectedMemberAccess<T> (ResolveContext rc, T member, TypeSpec qualifier) where T : MemberSpec
{
var ct = rc.CurrentType;
if (ct == qualifier)
- return;
+ return true;
if ((member.Modifiers & Modifiers.INTERNAL) != 0 && member.DeclaringType.MemberDefinition.IsInternalAsPublic (ct.MemberDefinition.DeclaringAssembly))
- return;
+ return true;
qualifier = qualifier.GetDefinition ();
if (ct != qualifier && !IsSameOrBaseQualifier (ct, qualifier)) {
- rc.Report.SymbolRelatedToPreviousError (member);
- rc.Report.Error (1540, loc,
- "Cannot access protected member `{0}' via a qualifier of type `{1}'. The qualifier must be of type `{2}' or derived from it",
- member.GetSignatureForError (), qualifier.GetSignatureForError (), ct.GetSignatureForError ());
+ return false;
}
+
+ return true;
}
public override bool ContainsEmitWithAwait ()
rc.Report.Error (205, loc, "Cannot call an abstract base member `{0}'", name);
}
+ public static void Error_ProtectedMemberAccess (ResolveContext rc, MemberSpec member, TypeSpec qualifier, Location loc)
+ {
+ rc.Report.SymbolRelatedToPreviousError (member);
+ rc.Report.Error (1540, loc,
+ "Cannot access protected member `{0}' via a qualifier of type `{1}'. The qualifier must be of type `{2}' or derived from it",
+ member.GetSignatureForError (), qualifier.GetSignatureForError (), rc.CurrentType.GetSignatureForError ());
+ }
+
//
// Implements identicial simple name and type-name
//
var r = new OverloadResolver (Methods, type_arguments, restr, loc);
if ((restr & OverloadResolver.Restrictions.NoBaseMembers) == 0) {
r.BaseMembersProvider = this;
+ r.InstanceQualifier = this;
}
if (cerrors != null)
}
ResolveInstanceExpression (ec, null);
- if (InstanceExpression != null)
- CheckProtectedMemberAccess (ec, best_candidate);
}
var base_override = CandidateToBaseOverride (ec, best_candidate);
#endregion
}
+ struct ConstructorInstanceQualifier : OverloadResolver.IInstanceQualifier
+ {
+ public ConstructorInstanceQualifier (TypeSpec type)
+ : this ()
+ {
+ InstanceType = type;
+ }
+
+ public TypeSpec InstanceType { get; private set; }
+
+ public bool CheckProtectedMemberAccess (ResolveContext rc, MemberSpec member)
+ {
+ return MemberExpr.CheckProtectedMemberAccess (rc, member, InstanceType);
+ }
+ }
+
public struct OverloadResolver
{
[Flags]
bool TypeInferenceFailed (ResolveContext rc, MemberSpec best);
}
+ public interface IInstanceQualifier
+ {
+ TypeSpec InstanceType { get; }
+ bool CheckProtectedMemberAccess (ResolveContext rc, MemberSpec member);
+ }
+
sealed class NoBaseMembers : IBaseMembersProvider
{
public static readonly IBaseMembersProvider Instance = new NoBaseMembers ();
TypeArguments type_arguments;
IBaseMembersProvider base_provider;
IErrorHandler custom_errors;
+ IInstanceQualifier instance_qualifier;
Restrictions restrictions;
MethodGroupExpr best_candidate_extension_group;
TypeSpec best_candidate_return_type;
}
}
+ public IInstanceQualifier InstanceQualifier {
+ get {
+ return instance_qualifier;
+ }
+ set {
+ instance_qualifier = value;
+ }
+ }
+
bool IsProbingOnly {
get {
return (restrictions & Restrictions.ProbingOnly) != 0;
var ac_p = p as ArrayContainer;
if (ac_p != null) {
- var ac_q = ((ArrayContainer) q);
+ var ac_q = q as ArrayContainer;
+ if (ac_q == null)
+ return null;
+
TypeSpec specific = MoreSpecific (ac_p.Element, ac_q.Element);
if (specific == ac_p.Element)
return p;
if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc))
continue;
+
+ if ((member.Modifiers & (Modifiers.PROTECTED | Modifiers.STATIC)) == Modifiers.PROTECTED &&
+ instance_qualifier != null && !instance_qualifier.CheckProtectedMemberAccess (rc, member)) {
+ continue;
+ }
}
IParametersMember pm = member as IParametersMember;
if (error_mode)
break;
+ if (lambda_conv_msgs != null && !lambda_conv_msgs.IsEmpty)
+ break;
+
lambda_conv_msgs = null;
error_mode = true;
}
return;
}
+
+ if ((best_candidate.Modifiers & (Modifiers.PROTECTED | Modifiers.STATIC)) == Modifiers.PROTECTED &&
+ InstanceQualifier != null && !InstanceQualifier.CheckProtectedMemberAccess (rc, best_candidate)) {
+ MemberExpr.Error_ProtectedMemberAccess (rc, best_candidate, InstanceQualifier.InstanceType, loc);
+ }
+
//
// For candidates which match on parameters count report more details about incorrect arguments
//
return CreateExpressionFactoryCall (ec, "Property", args);
}
- public Expression CreateSetterTypeOfExpression ()
+ public Expression CreateSetterTypeOfExpression (ResolveContext rc)
{
+ DoResolveLValue (rc, null);
return new TypeOfMethod (Setter, loc);
}