Correctly handle precedence of ToolsVersion value coming
[mono.git] / mcs / mcs / ecore.cs
index 08de79362884f9195ba0ecd92a5d0992fefca13d..8f3e098aaf8c340f2c0a9e071ab3463bbe009cf0 100644 (file)
@@ -458,20 +458,30 @@ namespace Mono.CSharp {
                        if (eclass != ExprClass.Unresolved)
                                return this;
 
-                       Expression e = DoResolve (ec);
+                       
+                       Expression e;
+                       try {
+                               e = DoResolve (ec);
 
-                       if (e == null)
-                               return null;
+                               if (e == null)
+                                       return null;
 
-                       if ((flags & e.ExprClassToResolveFlags) == 0) {
-                               e.Error_UnexpectedKind (ec, flags, loc);
-                               return null;
-                       }
+                               if ((flags & e.ExprClassToResolveFlags) == 0) {
+                                       e.Error_UnexpectedKind (ec, flags, loc);
+                                       return null;
+                               }
 
-                       if (e.type == null)
-                               throw new InternalErrorException ("Expression `{0}' didn't set its type in DoResolve", e.GetType ());
+                               if (e.type == null)
+                                       throw new InternalErrorException ("Expression `{0}' didn't set its type in DoResolve", e.GetType ());
 
-                       return e;
+                               return e;
+                       } catch (Exception ex) {
+                               if (loc.IsNull || Report.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled)
+                                       throw;
+
+                               ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message);
+                               return EmptyExpression.Null;
+                       }
                }
 
                /// <summary>
@@ -670,13 +680,6 @@ namespace Mono.CSharp {
                                                 name, arity, MemberKind.All, binding | BindingRestriction.AccessibleOnly, loc);
                }
 
-               public static MethodGroupExpr MethodLookup (CompilerContext ctx, TypeSpec container_type, TypeSpec queried_type,
-                                                      MemberKind kind, string name, int arity, Location loc)
-               {
-                       return (MethodGroupExpr)MemberLookup (ctx, container_type, null, queried_type, name, arity,
-                                            kind, BindingRestriction.AccessibleOnly, loc);
-               }
-
                /// <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
@@ -760,7 +763,7 @@ namespace Mono.CSharp {
                                mge.SetTypeArguments (ec, new TypeArguments (new FullNamedExpression [arity]));
                        }
 
-                       return mge;
+                       return mge.Resolve (ec);
                }
 
                protected virtual MemberExpr Error_MemberLookupFailed (ResolveContext ec, TypeSpec type, IList<MemberSpec> members)
@@ -802,23 +805,23 @@ namespace Mono.CSharp {
 
                static Expression GetOperatorTrueOrFalse (ResolveContext ec, Expression e, bool is_true, Location loc)
                {
-                       MethodGroupExpr operator_group;
-                       string mname = Operator.GetMetadataName (is_true ? Operator.OpType.True : Operator.OpType.False);
-                       operator_group = MethodLookup (ec.Compiler, ec.CurrentType, e.Type, MemberKind.Operator, mname, 0, loc) as MethodGroupExpr;
-                       if (operator_group == null)
+                       var op = is_true ? Operator.OpType.True : Operator.OpType.False;
+                       var methods = MemberCache.GetUserOperator (e.type, op, false);
+                       if (methods == null)
                                return null;
 
+                       var mg = new MethodGroupExpr (methods, e.type, loc);
+
                        Arguments arguments = new Arguments (1);
                        arguments.Add (new Argument (e));
-                       operator_group = operator_group.OverloadResolve (
-                               ec, ref arguments, false, loc);
+                       mg = mg.OverloadResolve (ec, ref arguments, false, loc);
 
-                       if (operator_group == null)
+                       if (mg == null)
                                return null;
 
-                       return new UserOperatorCall (operator_group, arguments, null, loc);
+                       return new UserOperatorCall (mg, arguments, null, loc);
                }
-
+               
                public virtual string ExprClassName
                {
                        get {
@@ -1239,21 +1242,18 @@ namespace Mono.CSharp {
                // 'child.Type' to our target type (type)
                MethodSpec GetConversionOperator (bool find_explicit)
                {
-                       string operator_name = find_explicit ? "op_Explicit" : "op_Implicit";
-
-                       // Operators are always public
-                       var mi = TypeManager.MemberLookup (child.Type, child.Type, child.Type, MemberKind.Operator,
-                               BindingRestriction.None, operator_name, 0, null);
+                       var op = find_explicit ? Operator.OpType.Explicit : Operator.OpType.Implicit;
 
+                       var mi = MemberCache.GetUserOperator (child.Type, op, true);
                        if (mi == null){
-                               mi = TypeManager.MemberLookup (type, type, type, MemberKind.Operator,
-                                       BindingRestriction.None, operator_name, 0, null);
+                               mi = MemberCache.GetUserOperator (type, op, true);
                        }
                        
                        foreach (MethodSpec oper in mi) {
-                               AParametersCollection pd = oper.Parameters;
+                               if (oper.ReturnType != type)
+                                       continue;
 
-                               if (pd.Types [0] == child.Type && oper.ReturnType == type)
+                               if (oper.Parameters.Types [0] == child.Type)
                                        return oper;
                        }
 
@@ -1301,9 +1301,7 @@ namespace Mono.CSharp {
                public Expression Resolve ()
                {
                        if (operators == null) {
-                               var all_oper = TypeManager.MemberLookup (TypeManager.decimal_type,
-                                  TypeManager.decimal_type, TypeManager.decimal_type, MemberKind.Operator,
-                                  BindingRestriction.None, "op_Explicit", 0, null);
+                               var all_oper = MemberCache.GetUserOperator (TypeManager.decimal_type, Operator.OpType.Explicit, true);
 
                                operators = new Dictionary<TypeSpec, MethodSpec> ();
                                foreach (MethodSpec oper in all_oper) {
@@ -2346,18 +2344,23 @@ namespace Mono.CSharp {
                        FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, loc, /*ignore_cs0104=*/ false);
 
                        if (fne != null) {
-                               if (HasTypeArguments && fne.Type != null && TypeManager.IsGenericType (fne.Type)) {
-                                       GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
-                                       return ct.ResolveAsTypeStep (ec, false);
+                               if (fne.Type != null && Arity > 0) {
+                                       if (HasTypeArguments) {
+                                               GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
+                                               return ct.ResolveAsTypeStep (ec, false);
+                                       }
+
+                                       return new GenericOpenTypeExpr (fne.Type, loc);
                                }
 
-                               return fne;
+                               //
+                               // dynamic namespace is ignored when dynamic is allowed (does not apply to types)
+                               //
+                               if (!(fne is Namespace))
+                                       return fne;
                        }
 
-                       if (!HasTypeArguments && Name == "dynamic" &&
-                               RootContext.Version > LanguageVersion.V_3 &&
-                               RootContext.MetadataCompatibilityVersion > MetadataVersion.v2) {
-
+                       if (Arity == 0 && Name == "dynamic" && RootContext.Version > LanguageVersion.V_3) {
                                if (!PredefinedAttributes.Get.Dynamic.IsDefined) {
                                        ec.Compiler.Report.Error (1980, Location,
                                                "Dynamic keyword requires `{0}' to be defined. Are you missing System.Core.dll assembly reference?",
@@ -2367,6 +2370,9 @@ namespace Mono.CSharp {
                                return new DynamicTypeExpr (loc);
                        }
 
+                       if (fne != null)
+                               return fne;
+
                        if (silent || errors != ec.Compiler.Report.Errors)
                                return null;
 
@@ -2429,7 +2435,7 @@ namespace Mono.CSharp {
                                                }
                                        }
 
-                                       if (HasTypeArguments && e != null)
+                                       if (e != null && Arity > 0)
                                                e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc, null, 0);
 
                                        return e;
@@ -2442,7 +2448,7 @@ namespace Mono.CSharp {
                                        else
                                                e = e.Resolve (ec);
 
-                                       if (HasTypeArguments && e != null)
+                                       if (e != null && Arity > 0)
                                                e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc, null, 0);
 
                                        return e;
@@ -2456,7 +2462,7 @@ namespace Mono.CSharp {
 //                     TypeSpec almost_matched_type = null;
 //                     IList<MemberSpec> almost_matched = null;
                        for (TypeSpec lookup_ds = ec.CurrentType; lookup_ds != null; lookup_ds = lookup_ds.DeclaringType) {
-                               e = MemberLookup (ec.Compiler, ec.CurrentType, lookup_ds, Name, arity, BindingRestriction.NoOverrides, loc);
+                               e = MemberLookup (ec.Compiler, ec.CurrentType, lookup_ds, Name, arity, BindingRestriction.DefaultMemberLookup, loc);
                                if (e != null) {
                                        PropertyExpr pe = e as PropertyExpr;
                                        if (pe != null) {
@@ -2644,32 +2650,12 @@ namespace Mono.CSharp {
                }
        }
 
-       //
-       // Used to create types from a fully qualified name.  These are just used
-       // by the parser to setup the core types.
-       //
-       public sealed class TypeLookupExpression : TypeExpr {
-               
-               public TypeLookupExpression (TypeSpec type)
-               {
-                       eclass = ExprClass.Type;
-                       this.type = type;
-               }
-
-               protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
-               {
-                       return this;
-               }
-       }
-
        /// <summary>
        ///   This class denotes an expression which evaluates to a member
        ///   of a struct or a class.
        /// </summary>
        public abstract class MemberExpr : Expression
        {
-               protected bool is_base;
-
                //
                // An instance expression associated with this member, if it's a
                // non-static member
@@ -2687,8 +2673,7 @@ namespace Mono.CSharp {
                // When base.member is used
                //
                public bool IsBase {
-                       get { return is_base; }
-                       set { is_base = value; }
+                       get { return InstanceExpression is BaseThis; }
                }
 
                /// <summary>
@@ -2712,9 +2697,35 @@ namespace Mono.CSharp {
                        get;
                }
 
-               public static void Error_BaseAccessInExpressionTree (ResolveContext ec, Location loc)
+               //
+               // Converts best base candidate for virtual method starting from QueriedBaseType
+               //
+               protected MethodSpec CandidateToBaseOverride (ResolveContext rc, MethodSpec method)
                {
-                       ec.Report.Error (831, loc, "An expression tree may not contain a base access");
+                       //
+                       // Only when base.member is used and method is virtual
+                       //
+                       if (!IsBase || method.DeclaringType == InstanceExpression.Type)
+                               return method;
+
+                       //
+                       // Overload resulution works on virtual or non-virtual members only (no overrides). That
+                       // means for base.member access we have to find the closest match after we found best candidate
+                       //
+                       if ((method.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.STATIC)) != Modifiers.STATIC) {
+                               var base_override = MemberCache.FindMember (InstanceExpression.Type, new MemberFilter (method), BindingRestriction.InstanceOnly) as MethodSpec;
+                               if (base_override != null && base_override.DeclaringType != method.DeclaringType) {
+                                       if (base_override.IsGeneric)
+                                               base_override = base_override.MakeGenericMethod (method.TypeArguments);
+
+                                       if (rc.CurrentAnonymousMethod != null)
+                                               throw new NotImplementedException ("base call hoisting");
+
+                                       return base_override;
+                               }
+                       }
+
+                       return method;
                }
 
                //
@@ -2750,9 +2761,12 @@ namespace Mono.CSharp {
                                                        AttributeTester.Report_ObsoleteMessage (oa, InstanceExpression.GetSignatureForError (), loc, rc.Report);
                                                }
                                        } else {
-                                               rc.Report.Error (176, loc,
-                                                       "Static member `{0}' cannot be accessed with an instance reference, qualify it with a type name instead",
-                                                       GetSignatureForError ());
+                                               var runtime_expr = InstanceExpression as RuntimeValueExpression;
+                                               if (runtime_expr == null || !runtime_expr.IsSuggestionOnly) {
+                                                       rc.Report.Error (176, loc,
+                                                               "Static member `{0}' cannot be accessed with an instance reference, qualify it with a type name instead",
+                                                               GetSignatureForError ());
+                                               }
                                        }
 
                                        InstanceExpression = null;
@@ -2762,7 +2776,7 @@ namespace Mono.CSharp {
                        }
 
                        if (InstanceExpression == null || InstanceExpression is TypeExpr) {
-                               if (!This.IsThisAvailable (rc, true) || InstanceExpression is TypeExpr) {
+                               if (InstanceExpression != null || !This.IsThisAvailable (rc, true)) {
                                        if (rc.HasSet (ResolveContext.Options.FieldInitializerScope))
                                                rc.Report.Error (236, loc,
                                                        "A field initializer cannot reference the nonstatic field, method, or property `{0}'",
@@ -2794,8 +2808,7 @@ namespace Mono.CSharp {
 
                public virtual MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original)
                {
-                       Constant c = left as Constant;
-                       if (c != null && c.GetValue () == null) {
+                       if (left != null && left.IsNull && TypeManager.IsReferenceType (left.Type)) {
                                ec.Report.Warning (1720, 1, left.Location,
                                        "Expression will always cause a `{0}'", "System.NullReferenceException");
                        }
@@ -2897,12 +2910,12 @@ namespace Mono.CSharp {
        {
                public interface IErrorHandler
                {
-                       bool AmbiguousCall (ResolveContext ec, MethodSpec ambiguous);
+                       bool AmbiguousCall (ResolveContext ec, MethodGroupExpr mg, MethodSpec ambiguous);
                        bool NoExactMatch (ResolveContext ec, MethodSpec method);
                }
 
                public IErrorHandler CustomErrorHandler;
-               public IList<MemberSpec> Methods;
+               protected IList<MemberSpec> Methods;
                MethodSpec best_candidate;
                // TODO: make private
                public TypeArguments type_arguments;
@@ -2937,15 +2950,17 @@ namespace Mono.CSharp {
                        queried_type = type;
                }
 
-               public override TypeSpec DeclaringType {
+               #region Properties
+
+               public MethodSpec BestCandidate {
                        get {
-                               return queried_type;
+                               return best_candidate;
                        }
                }
 
-               public MethodSpec BestCandidate {
+               public override TypeSpec DeclaringType {
                        get {
-                               return best_candidate;
+                               return queried_type;
                        }
                }
 
@@ -2955,20 +2970,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override string GetSignatureForError ()
-               {
-                       if (best_candidate != null)
-                               return best_candidate.GetSignatureForError ();
-
-                       return Methods.First ().GetSignatureForError ();
-               }
-
-               public override string Name {
-                       get {
-                               return Methods.First ().Name;
-                       }
-               }
-
                public override bool IsInstance {
                        get {
                                if (best_candidate != null)
@@ -2987,9 +2988,37 @@ namespace Mono.CSharp {
                        }
                }
 
-               public static explicit operator MethodSpec (MethodGroupExpr mg)
+               public override string Name {
+                       get {
+                               if (best_candidate != null)
+                                       return best_candidate.Name;
+
+                               // TODO: throw ?
+                               return Methods.First ().Name;
+                       }
+               }
+
+               #endregion
+
+               //
+               // When best candidate is already know this factory can be used
+               // to avoid expensive overload resolution to be called
+               //
+               // NOTE: InstanceExpression has to be set manually
+               //
+               public static MethodGroupExpr CreatePredefined (MethodSpec best, TypeSpec queriedType, Location loc)
+               {
+                       return new MethodGroupExpr (best, queriedType, loc) {
+                               best_candidate = best
+                       };
+               }
+
+               public override string GetSignatureForError ()
                {
-                       return mg.best_candidate;
+                       if (best_candidate != null)
+                               return best_candidate.GetSignatureForError ();
+
+                       return Methods.First ().GetSignatureForError ();
                }
 
                //
@@ -3267,17 +3296,16 @@ namespace Mono.CSharp {
                override public void Emit (EmitContext ec)
                {
                        throw new NotSupportedException ();
-                       // ReportUsageError ();
                }
                
                public void EmitCall (EmitContext ec, Arguments arguments)
                {
-                       Invocation.EmitCall (ec, IsBase, InstanceExpression, best_candidate, arguments, loc);                   
+                       Invocation.EmitCall (ec, InstanceExpression, best_candidate, arguments, loc);                   
                }
 
                void Error_AmbiguousCall (ResolveContext ec, MethodSpec ambiguous)
                {
-                       if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ec, ambiguous))
+                       if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ec, this, ambiguous))
                                return;
 
                        ec.Report.SymbolRelatedToPreviousError (best_candidate);
@@ -3366,14 +3394,15 @@ namespace Mono.CSharp {
                protected virtual IList<MemberSpec> GetBaseTypeMethods (ResolveContext rc, TypeSpec type)
                {
                        var arity = type_arguments == null ? -1 : type_arguments.Count;
+
                        return TypeManager.MemberLookup (rc.CurrentType, null, type,
-                               MemberKind.Method, BindingRestriction.AccessibleOnly | BindingRestriction.NoOverrides,
+                               MemberKind.Method, BindingRestriction.AccessibleOnly | BindingRestriction.DefaultMemberLookup,
                                Name, arity, null);
                }
 
                bool GetBaseTypeMethods (ResolveContext rc)
                {
-                       var base_type = Methods.First ().DeclaringType.BaseType;
+                       var base_type = Methods [0].DeclaringType.BaseType;
                        if (base_type == null)
                                return false;
 
@@ -3573,15 +3602,8 @@ namespace Mono.CSharp {
                        // Types have to be identical when ref or out modifer is used 
                        //
                        if (arg_mod != 0 || param_mod != 0) {
-                               if (TypeManager.HasElementType (parameter))
-                                       parameter = TypeManager.GetElementType (parameter);
-
-                               TypeSpec a_type = argument.Type;
-                               if (TypeManager.HasElementType (a_type))
-                                       a_type = TypeManager.GetElementType (a_type);
-
-                               if (a_type != parameter) {
-                                       if (a_type == InternalType.Dynamic)
+                               if (argument.Type != parameter) {
+                                       if (argument.Type == InternalType.Dynamic)
                                                return 0;
 
                                        return 2;
@@ -3601,26 +3623,6 @@ namespace Mono.CSharp {
                        return 0;
                }
 
-               public static MethodGroupExpr MakeUnionSet (MethodGroupExpr mg1, MethodGroupExpr mg2, Location loc)
-               {
-                       if (mg1 == null) {
-                               if (mg2 == null)
-                                       return null;
-                               return mg2;
-                       }
-
-                       if (mg2 == null)
-                               return mg1;
-
-                       var all = new List<MemberSpec> (mg1.Methods);
-                       foreach (MethodSpec m in mg2.Methods){
-                               if (!TypeManager.ArrayContainsMethod (all, m, false))
-                                       all.Add (m);
-                       }
-
-                       return new MethodGroupExpr (all, null, loc);
-               }               
-
                static TypeSpec MoreSpecific (TypeSpec p, TypeSpec q)
                {
                        if (TypeManager.IsGenericParameter (p) && !TypeManager.IsGenericParameter (q))
@@ -3679,6 +3681,10 @@ namespace Mono.CSharp {
                public virtual MethodGroupExpr OverloadResolve (ResolveContext ec, ref Arguments Arguments,
                        bool may_fail, Location loc)
                {
+                       // TODO: causes some issues with linq
+                       //if (best_candidate != null)
+                       //      return this;
+
                        var candidates = new List<MethodSpec> (2);
                        List<MethodSpec> params_candidates = null;
 
@@ -3697,70 +3703,65 @@ namespace Mono.CSharp {
                        //
                        var msg_recorder = new SessionReportPrinter ();
                        var prev_recorder = ec.Report.SetPrinter (msg_recorder);
-
-                       do {
-                               //
-                               // Methods in a base class are not candidates if any method in a derived
-                               // class is applicable
-                               //
-                               int best_candidate_rate = int.MaxValue;
-
-                               foreach (var member in Methods) {
-                                       var m = member as MethodSpec;
-                                       if (m == null) {
-                                               // TODO: It's wrong when non-member is before applicable method
-                                               // TODO: Should report only when at least 1 from the batch is applicable
-                                               if (candidates.Count != 0) {
-                                                       ec.Report.SymbolRelatedToPreviousError (candidates [0]);
-                                                       ec.Report.SymbolRelatedToPreviousError (member);
-                                                       ec.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
-                                                               candidates[0].GetSignatureForError (), member.GetSignatureForError ());
-                                               }
-                                               continue;
-                                       }
-
+                       try {
+                               do {
                                        //
-                                       // Check if candidate is applicable (section 14.4.2.1)
+                                       // Methods in a base class are not candidates if any method in a derived
+                                       // class is applicable
                                        //
-                                       bool params_expanded_form = false;
-                                       int candidate_rate = IsApplicable (ec, ref candidate_args, arg_count, ref m, ref params_expanded_form);
-
-                                       if (candidate_rate < best_candidate_rate) {
-                                               best_candidate_rate = candidate_rate;
-                                               best_candidate = m;
-                                       }
+                                       int best_candidate_rate = int.MaxValue;
+
+                                       foreach (var member in Methods) {
+                                               var m = member as MethodSpec;
+                                               if (m == null) {
+                                                       // TODO: It's wrong when non-member is before applicable method
+                                                       // TODO: Should report only when at least 1 from the batch is applicable
+                                                       if (candidates.Count != 0) {
+                                                               ec.Report.SymbolRelatedToPreviousError (candidates[0]);
+                                                               ec.Report.SymbolRelatedToPreviousError (member);
+                                                               ec.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
+                                                                       candidates[0].GetSignatureForError (), member.GetSignatureForError ());
+                                                       }
+                                                       continue;
+                                               }
 
-                                       if (params_expanded_form) {
-                                               if (params_candidates == null)
-                                                       params_candidates = new List<MethodSpec> (2);
-                                               params_candidates.Add (m);
-                                       }
+                                               //
+                                               // Check if candidate is applicable (section 14.4.2.1)
+                                               //
+                                               bool params_expanded_form = false;
+                                               int candidate_rate = IsApplicable (ec, ref candidate_args, arg_count, ref m, ref params_expanded_form);
 
-                                       if (candidate_args != Arguments) {
-                                               if (candidates_expanded == null)
-                                                       candidates_expanded = new Dictionary<MethodSpec, Arguments> (2);
+                                               if (candidate_rate < best_candidate_rate) {
+                                                       best_candidate_rate = candidate_rate;
+                                                       best_candidate = m;
+                                               }
 
-                                               candidates_expanded.Add (m, candidate_args);
-                                               candidate_args = Arguments;
-                                       }
+                                               if (params_expanded_form) {
+                                                       if (params_candidates == null)
+                                                               params_candidates = new List<MethodSpec> (2);
+                                                       params_candidates.Add (m);
+                                               }
 
-                                       if (candidate_rate != 0 || has_inaccessible_candidates_only) {
-                                               if (msg_recorder != null)
-                                                       msg_recorder.EndSession ();
-                                               continue;
-                                       }
+                                               if (candidate_args != Arguments) {
+                                                       if (candidates_expanded == null)
+                                                               candidates_expanded = new Dictionary<MethodSpec, Arguments> (2);
 
-                                       msg_recorder = null;
-                                       candidates.Add (m);
-                               }
-                       } while (candidates.Count == 0 && GetBaseTypeMethods (ec));
+                                                       candidates_expanded.Add (m, candidate_args);
+                                                       candidate_args = Arguments;
+                                               }
 
-                       ec.Report.SetPrinter (prev_recorder);
-                       if (msg_recorder != null && !msg_recorder.IsEmpty) {
-                               if (!may_fail)
-                                       msg_recorder.Merge (prev_recorder);
+                                               if (candidate_rate != 0 || has_inaccessible_candidates_only) {
+                                                       if (msg_recorder != null)
+                                                               msg_recorder.EndSession ();
+                                                       continue;
+                                               }
 
-                               return null;
+                                               msg_recorder = null;
+                                               candidates.Add (m);
+                                       }
+                               } while (candidates.Count == 0 && GetBaseTypeMethods (ec));
+                       } finally {
+                               ec.Report.SetPrinter (prev_recorder);
                        }
 
                        int candidate_top = candidates.Count;
@@ -3776,10 +3777,19 @@ namespace Mono.CSharp {
                                        if (ex_method_lookup != null) {
                                                ex_method_lookup.ExtensionExpression = InstanceExpression.Resolve (ec);
                                                ex_method_lookup.SetTypeArguments (ec, type_arguments);
-                                               return ex_method_lookup.OverloadResolve (ec, ref Arguments, may_fail, loc);
+                                               var emg = ex_method_lookup.OverloadResolve (ec, ref Arguments, may_fail, loc);
+                                               if (emg != null)
+                                                       return emg;
                                        }
                                }
-                               
+
+                               if (msg_recorder != null && !msg_recorder.IsEmpty) {
+                                       if (!may_fail)
+                                               msg_recorder.Merge (prev_recorder);
+
+                                       return null;
+                               }
+                       
                                if (may_fail)
                                        return null;
 
@@ -3880,6 +3890,8 @@ namespace Mono.CSharp {
                                return this;
                        }
 
+                       best_candidate = CandidateToBaseOverride (ec, best_candidate);
+
                        //
                        // And now check if the arguments are all
                        // compatible, perform conversions if
@@ -3894,8 +3906,12 @@ namespace Mono.CSharp {
                                return null;
 
                        if (best_candidate.Kind == MemberKind.Method) {
-                               if (InstanceExpression != null && best_candidate.IsStatic) {
-                                       InstanceExpression = ProbeIdenticalTypeName (ec, InstanceExpression, simple_name);
+                               if (InstanceExpression != null) {
+                                       if (best_candidate.IsStatic && simple_name != null) {
+                                               InstanceExpression = ProbeIdenticalTypeName (ec, InstanceExpression, simple_name);
+                                       }
+
+                                       InstanceExpression.Resolve (ec);
                                }
 
                                ResolveInstanceExpression (ec);
@@ -4094,7 +4110,7 @@ namespace Mono.CSharp {
                        //
                        if (params_initializers != null) {
                                arguments.Add (new Argument (
-                                       new ArrayCreation (new TypeExpression (pt, loc), "[]", params_initializers, loc).Resolve (ec)));
+                                       new ArrayCreation (new TypeExpression (pt, loc), params_initializers, loc).Resolve (ec)));
                                arg_count++;
                        }
 
@@ -4154,11 +4170,10 @@ namespace Mono.CSharp {
                        if (!rc.IsObsolete) {
                                var oa = constant.GetAttributeObsolete ();
                                if (oa != null)
-                                       AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (constant), loc, rc.Report);
+                                       AttributeTester.Report_ObsoleteMessage (oa, constant.GetSignatureForError (), loc, rc.Report);
                        }
 
-                       // Constants are resolved on-demand
-                       var c = constant.Value.Resolve (rc) as Constant;
+                       var c = constant.GetConstant (rc);
 
                        // Creates reference expression to the constant value
                        return Constant.CreateConstant (rc, constant.MemberType, c.GetValue (), loc);
@@ -4171,7 +4186,7 @@ namespace Mono.CSharp {
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.GetFullNameSignature (constant);
+                       return constant.GetSignatureForError ();
                }
        }
 
@@ -4656,8 +4671,11 @@ namespace Mono.CSharp {
        public class PropertyExpr : MemberExpr, IDynamicAssign
        {
                PropertySpec spec;
+
+               // getter and setter can be different for base calls
+               MethodSpec getter, setter;
+
                TypeArguments targs;
-               
                LocalTemporary temp;
                bool prepared;
 
@@ -4689,6 +4707,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public PropertySpec PropertyInfo {
+                       get {
+                               return spec;
+                       }
+               }
+
                #endregion
 
                public override Expression CreateExpressionTree (ResolveContext ec)
@@ -4700,23 +4724,18 @@ namespace Mono.CSharp {
                                return CreateExpressionFactoryCall (ec, "ArrayLength", args);
                        }
 
-                       if (is_base) {
-                               Error_BaseAccessInExpressionTree (ec, loc);
-                               return null;
-                       }
-
                        args = new Arguments (2);
                        if (InstanceExpression == null)
                                args.Add (new Argument (new NullLiteral (loc)));
                        else
                                args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
-                       args.Add (new Argument (new TypeOfMethod (spec.Get, loc)));
+                       args.Add (new Argument (new TypeOfMethod (getter, loc)));
                        return CreateExpressionFactoryCall (ec, "Property", args);
                }
 
                public Expression CreateSetterTypeOfExpression ()
                {
-                       return new TypeOfMethod (spec.Set, loc);
+                       return new TypeOfMethod (setter, loc);
                }
 
                public override TypeSpec DeclaringType {
@@ -4732,18 +4751,12 @@ namespace Mono.CSharp {
 
                public SLE.Expression MakeAssignExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) spec.Set.GetMetaInfo ());
+                       return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) setter.GetMetaInfo ());
                }
 
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) spec.Get.GetMetaInfo ());
-               }
-
-               public PropertySpec PropertyInfo {
-                       get {
-                               return spec;
-                       }
+                       return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) getter.GetMetaInfo ());
                }
 
                bool InstanceResolve (ResolveContext ec, bool lvalue_instance, bool must_do_cs1540_check)
@@ -4761,6 +4774,7 @@ namespace Mono.CSharp {
                        InstanceExpression.CheckMarshalByRefAccess (ec);
 
                        if (must_do_cs1540_check && (InstanceExpression != EmptyExpression.Null) &&
+                               !(InstanceExpression is BaseThis) &&
                            !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
                            !TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
                            !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
@@ -4824,17 +4838,19 @@ namespace Mono.CSharp {
                        if (!InstanceResolve (ec, false, must_do_cs1540_check))
                                return null;
 
+                       if (type.IsPointer && !ec.IsUnsafe) {
+                               UnsafeError (ec, loc);
+                       }
+
+                       getter = CandidateToBaseOverride (ec, spec.Get);
+
                        //
                        // Only base will allow this invocation to happen.
                        //
-                       if (IsBase && spec.IsAbstract) {
+                       if (IsBase && getter.IsAbstract) {
                                Error_CannotCallAbstractBase (ec, spec.GetSignatureForError ());
                        }
 
-                       if (type.IsPointer && !ec.IsUnsafe){
-                               UnsafeError (ec, loc);
-                       }
-
                        if (!ec.IsObsolete) {
                                ObsoleteAttribute oa = spec.GetAttributeObsolete ();
                                if (oa != null)
@@ -4898,12 +4914,14 @@ namespace Mono.CSharp {
                        
                        if (!InstanceResolve (ec, TypeManager.IsStruct (spec.DeclaringType), must_do_cs1540_check))
                                return null;
+
+                       setter = CandidateToBaseOverride (ec, spec.Set);
                        
                        //
                        // Only base will allow this invocation to happen.
                        //
-                       if (IsBase && spec.IsAbstract){
-                               Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec));
+                       if (IsBase && setter.IsAbstract){
+                               Error_CannotCallAbstractBase (ec, setter.GetSignatureForError ());
                        }
 
                        if (spec.MemberType.IsPointer && !ec.IsUnsafe) {
@@ -4937,7 +4955,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       Invocation.EmitCall (ec, IsBase, InstanceExpression, spec.Get, null, loc, prepared, false);
+                       Invocation.EmitCall (ec, InstanceExpression, getter, null, loc, prepared, false);
                        
                        if (leave_copy) {
                                ec.Emit (OpCodes.Dup);
@@ -4976,7 +4994,7 @@ namespace Mono.CSharp {
                        Arguments args = new Arguments (1);
                        args.Add (new Argument (my_source));
                        
-                       Invocation.EmitCall (ec, IsBase, InstanceExpression, spec.Set, args, loc, false, prepared);
+                       Invocation.EmitCall (ec, InstanceExpression, setter, args, loc, false, prepared);
                        
                        if (temp != null) {
                                temp.Emit (ec);
@@ -5080,17 +5098,21 @@ namespace Mono.CSharp {
                            TypeManager.IsNestedChildOf(ec.CurrentType, spec.DeclaringType)) {
                                        
                                // TODO: Breaks dynamic binder as currect context fields are imported and not compiled
-                               EventField mi = spec.MemberDefinition as EventField;
+                               // EventField mi = spec.MemberDefinition as EventField;
+
+                               if (spec.BackingField != null) {
+                                       spec.MemberDefinition.SetIsUsed ();
 
-                               if (mi != null && mi.HasBackingField) {
-                                       mi.SetIsUsed ();
-                                       if (!ec.IsObsolete)
-                                               mi.CheckObsoleteness (loc);
+                                       if (!ec.IsObsolete) {
+                                               ObsoleteAttribute oa = spec.GetAttributeObsolete ();
+                                               if (oa != null)
+                                                       AttributeTester.Report_ObsoleteMessage (oa, spec.GetSignatureForError (), loc, ec.Report);
+                                       }
 
-                                       if ((mi.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))
+                                       if ((spec.Modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))
                                                Error_AssignmentEventOnly (ec);
                                        
-                                       FieldExpr ml = new FieldExpr (mi.BackingField, loc);
+                                       FieldExpr ml = new FieldExpr (spec.BackingField, loc);
 
                                        InstanceExpression = null;
                                
@@ -5106,13 +5128,14 @@ namespace Mono.CSharp {
 
                bool InstanceResolve (ResolveContext ec, bool must_do_cs1540_check)
                {
+                       if (IsBase && spec.IsAbstract) {
+                               Error_CannotCallAbstractBase (ec, spec.GetSignatureForError ());
+                       }
+
                        if (!ResolveInstanceExpression (ec))
                                return true;
 
-                       if (IsBase && spec.IsAbstract) {
-                               Error_CannotCallAbstractBase (ec, TypeManager.CSharpSignature(spec));
-                               return false;
-                       }
+                       InstanceExpression.Resolve (ec);
 
                        //
                        // This is using the same mechanism as the CS1540 check in PropertyExpr.
@@ -5206,9 +5229,7 @@ namespace Mono.CSharp {
                {
                        Arguments args = new Arguments (1);
                        args.Add (new Argument (source));
-                       Invocation.EmitCall (ec, IsBase, InstanceExpression,
-                               is_add ? spec.AccessorAdd : spec.AccessorRemove,
-                               args, loc);
+                       Invocation.EmitCall (ec, InstanceExpression, is_add ? spec.AccessorAdd : spec.AccessorRemove, args, loc);
                }
        }