2006-09-21 Marek Sieradzki <marek.sieradzki@gmail.com>
[mono.git] / mcs / gmcs / ecore.cs
index a556534351588ec296884992cd44e2854e6aab90..d40ee8a8ad912394d19b7ae55059d46e94a45a5d 100644 (file)
@@ -241,8 +241,20 @@ namespace Mono.CSharp {
 
                        ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (te.Type);
                        if (obsolete_attr != null && !ec.IsInObsoleteScope) {
-                               AttributeTester.Report_ObsoleteMessage (obsolete_attr, GetSignatureForError (), Location);
+                               AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location);
                        }
+
+                       // Constrains don't need to be checked for overrides
+                       GenericMethod gm = ec.GenericDeclContainer as GenericMethod;
+                       if (gm != null && (gm.ModFlags & Modifiers.OVERRIDE) != 0) {
+                               te.loc = loc;
+                               return te;
+                       }
+
+                       ConstructedType ct = te as ConstructedType;
+                       if ((ct != null) && !ct.CheckConstraints (ec))
+                               return null;
+
                        return te;
                }
 
@@ -267,21 +279,11 @@ namespace Mono.CSharp {
                        TypeExpr te = fne as TypeExpr;
 
                        if (!te.CheckAccessLevel (ec.DeclContainer)) {
+                               Report.SymbolRelatedToPreviousError (te.Type);
                                ErrorIsInaccesible (loc, TypeManager.CSharpName (te.Type));
                                return null;
                        }
 
-                       // Constrains don't need to be checked for overrides
-                       GenericMethod gm = ec.DeclContainer as GenericMethod;
-                       if (gm != null && (gm.ModFlags & Modifiers.OVERRIDE) != 0) {
-                               te.loc = loc;
-                               return te;
-                       }
-
-                       ConstructedType ct = te as ConstructedType;
-                       if ((ct != null) && !ct.CheckConstraints (ec))
-                               return null;
-
                        te.loc = loc;
                        return te;
                }
@@ -301,13 +303,24 @@ namespace Mono.CSharp {
 
                }
 
+               protected void Error_CannotAssign (string to, string roContext)
+               {
+                       Report.Error (1656, loc, "Cannot assign to `{0}' because it is a `{1}'",
+                               to, roContext);
+               }
+
+               public static void Error_VoidInvalidInTheContext (Location loc)
+               {
+                       Report.Error (1547, loc, "Keyword `void' cannot be used in this context");
+               }
+
                public virtual void Error_ValueCannotBeConverted (Location loc, Type target, bool expl)
                {
-                       if (Type.Name == target.Name){
+                       if (Type.FullName == target.FullName){
                                Report.ExtraInformation (loc,
                                        String.Format (
                                        "The type {0} has two conflicting definitions, one comes from {1} and the other from {2}",
-                                       Type.Name, Type.Assembly.FullName, target.Assembly.FullName));
+                                       Type.FullName, Type.Assembly.FullName, target.Assembly.FullName));
                                                         
                        }
 
@@ -382,23 +395,22 @@ namespace Mono.CSharp {
                        if ((flags & ResolveFlags.MaskExprClass) == ResolveFlags.Type) 
                                return ResolveAsTypeStep (ec, false);
 
-                       bool old_do_flow_analysis = ec.DoFlowAnalysis;
-                       bool old_omit_struct_analysis = ec.OmitStructFlowAnalysis;
+                       bool do_flow_analysis = ec.DoFlowAnalysis;
+                       bool omit_struct_analysis = ec.OmitStructFlowAnalysis;
                        if ((flags & ResolveFlags.DisableFlowAnalysis) != 0)
-                               ec.DoFlowAnalysis = false;
+                               do_flow_analysis = false;
                        if ((flags & ResolveFlags.DisableStructFlowAnalysis) != 0)
-                               ec.OmitStructFlowAnalysis = true;
+                               omit_struct_analysis = true;
 
                        Expression e;
-                       if (this is SimpleName) {
-                               bool intermediate = (flags & ResolveFlags.Intermediate) == ResolveFlags.Intermediate;
-                               e = ((SimpleName) this).DoResolve (ec, intermediate);
+                       using (ec.WithFlowAnalysis (do_flow_analysis, omit_struct_analysis)) {
+                               if (this is SimpleName) {
+                                       bool intermediate = (flags & ResolveFlags.Intermediate) == ResolveFlags.Intermediate;
+                                       e = ((SimpleName) this).DoResolve (ec, intermediate);
+                               } else {
+                                       e = DoResolve (ec);
+                               }
                        }
-                       else 
-                               e = DoResolve (ec);
-
-                       ec.DoFlowAnalysis = old_do_flow_analysis;
-                       ec.OmitStructFlowAnalysis = old_omit_struct_analysis;
 
                        if (e == null)
                                return null;
@@ -442,7 +454,12 @@ namespace Mono.CSharp {
                        if (c != null)
                                return c;
 
-                       Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError ());
+                       Type constant_type = null;
+                       if (mc is MemberBase) {
+                               constant_type = ((MemberBase)mc).MemberType;
+                       }
+
+                       Const.Error_ExpressionMustBeConstant (constant_type, loc, mc.GetSignatureForError ());
                        return null;
                }
 
@@ -652,14 +669,49 @@ namespace Mono.CSharp {
                        if (mi == null)
                                return null;
 
-                       int count = mi.Length;
+                       if (mi.Length > 1) {
+                               bool is_interface = qualifier_type != null && qualifier_type.IsInterface;
+                               MemberInfo non_method = null;
+                               ArrayList methods = new ArrayList (2);
+
+                               foreach (MemberInfo m in mi) {
+                                       if (m is MethodBase) {
+                                               methods.Add (m);
+                                               continue;
+                                       }
+
+                                       if (non_method == null) {
+                                               non_method = m;
+                                               continue;
+                                       }
+
+                                       if (!is_interface)
+                                               continue;
+
+                                       Report.SymbolRelatedToPreviousError (m);
+                                       Report.SymbolRelatedToPreviousError (non_method);
+                                       Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
+                                               TypeManager.GetFullNameSignature (m), TypeManager.GetFullNameSignature (non_method));
+                                       return null;
+                               }
+
+                               if (non_method != null && is_interface) {
+                                       MethodBase method = (MethodBase)methods[0];
+                                       Report.SymbolRelatedToPreviousError (method);
+                                       Report.SymbolRelatedToPreviousError (non_method);
+                                       Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
+                                               TypeManager.CSharpSignature (method), TypeManager.GetFullNameSignature (non_method));
+                               }
+
+                               if (methods.Count == 0)
+                                       return new MethodGroupExpr (mi, loc);
+
+                               return new MethodGroupExpr (methods, loc);
+                       }
 
                        if (mi [0] is MethodBase)
                                return new MethodGroupExpr (mi, loc);
 
-                       if (count > 1)
-                               return null;
-
                        return ExprClassFromMemberInfo (container_type, mi [0], loc);
                }
 
@@ -762,6 +814,7 @@ namespace Mono.CSharp {
                                                // then we are in this situation.
                                                Error_CannotAccessProtected (loc, m, qualifier_type, container_type);
                                        } else {
+                                               Report.SymbolRelatedToPreviousError (m);
                                                ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (m));
                                        }
                                }
@@ -769,9 +822,14 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       MemberInfo[] lookup = TypeManager.MemberLookup (queried_type, null, queried_type,
-                                                                       AllMemberTypes, AllBindingFlags |
-                                                                       BindingFlags.NonPublic, name, null);
+                       MemberInfo[] lookup = null;
+                       if (queried_type == null) {
+                               class_name = "global::";
+                       } else {
+                               lookup = TypeManager.MemberLookup (queried_type, null, queried_type,
+                                       AllMemberTypes, AllBindingFlags |
+                                       BindingFlags.NonPublic, name, null);
+                       }
 
                        if (lookup == null) {
                                if (!complain_if_none_found)
@@ -808,6 +866,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
+                       Report.SymbolRelatedToPreviousError (lookup [0]);
                        ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (lookup [0]));
                }
 
@@ -1084,22 +1143,20 @@ namespace Mono.CSharp {
                {
                        Expression target;
                        
-                       bool old_checked = ec.CheckState;
-                       ec.CheckState = true;
-                       
-                       target = Convert.ImplicitConversion (ec, source, TypeManager.int32_type, loc);
-                       if (target == null){
-                               target = Convert.ImplicitConversion (ec, source, TypeManager.uint32_type, loc);
-                               if (target == null){
+                       using (ec.With (EmitContext.Flags.CheckState, true)) {
+                               target = Convert.ImplicitConversion (ec, source, TypeManager.int32_type, loc);
+                               if (target == null)
+                                       target = Convert.ImplicitConversion (ec, source, TypeManager.uint32_type, loc);
+                               if (target == null)
                                        target = Convert.ImplicitConversion (ec, source, TypeManager.int64_type, loc);
-                                       if (target == null){
-                                               target = Convert.ImplicitConversion (ec, source, TypeManager.uint64_type, loc);
-                                               if (target == null)
-                                                       source.Error_ValueCannotBeConverted (loc, TypeManager.int32_type, false);
-                                       }
+                               if (target == null)
+                                       target = Convert.ImplicitConversion (ec, source, TypeManager.uint64_type, loc);
+
+                               if (target == null) {
+                                       source.Error_ValueCannotBeConverted (loc, TypeManager.int32_type, false);
+                                       return null;
                                }
-                       } 
-                       ec.CheckState = old_checked;
+                       }
 
                        //
                        // Only positive constants are allowed at compile time
@@ -1554,7 +1611,7 @@ namespace Mono.CSharp {
                        ILGenerator ig = ec.ig;
                        
                        base.Emit (ec);
-                       if (t.IsGenericParameter)
+                       if (t.IsGenericParameter || t.IsGenericType && t.IsValueType)
                                ig.Emit (OpCodes.Unbox_Any, t);
                        else {
                                ig.Emit (OpCodes.Unbox, t);
@@ -1917,14 +1974,10 @@ namespace Mono.CSharp {
                                Report.Error (236, l,
                                        "A field initializer cannot reference the nonstatic field, method, or property `{0}'",
                                        name);
-                       else {
-                               if (name.LastIndexOf ('.') > 0)
-                                       name = name.Substring (name.LastIndexOf ('.') + 1);
-
+                       else
                                Report.Error (
                                        120, l, "`{0}': An object reference is required for the nonstatic field, method or property",
                                        name);
-                       }
                }
 
                public bool IdenticalNameAndTypeName (EmitContext ec, Expression resolved_to, Location loc)
@@ -2004,7 +2057,7 @@ namespace Mono.CSharp {
 
                public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
                {
-                       FullNamedExpression fne = ec.DeclContainer.LookupGeneric (Name, loc);
+                       FullNamedExpression fne = ec.GenericDeclContainer.LookupGeneric (Name, loc);
                        if (fne != null)
                                return fne.ResolveAsTypeStep (ec, silent);
 
@@ -2113,6 +2166,13 @@ namespace Mono.CSharp {
                        if (current_block != null){
                                LocalInfo vi = current_block.GetLocalInfo (Name);
                                if (vi != null){
+                                       if (Arguments != null) {
+                                               Report.Error (307, loc,
+                                                             "The variable `{0}' cannot be used with type arguments",
+                                                             Name);
+                                               return null;
+                                       }
+
                                        LocalVariableReference var = new LocalVariableReference (ec.CurrentBlock, Name, loc);
                                        if (right_side != null) {
                                                return var.ResolveLValue (ec, right_side, loc);
@@ -2126,6 +2186,13 @@ namespace Mono.CSharp {
 
                                ParameterReference pref = current_block.Toplevel.GetParameterReference (Name, loc);
                                if (pref != null) {
+                                       if (Arguments != null) {
+                                               Report.Error (307, loc,
+                                                             "The variable `{0}' cannot be used with type arguments",
+                                                             Name);
+                                               return null;
+                                       }
+
                                        if (right_side != null)
                                                return pref.ResolveLValue (ec, right_side, loc);
                                        else
@@ -2176,8 +2243,14 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (e is TypeExpr)
-                               return e;
+                       if (e is TypeExpr) {
+                               if (Arguments == null)
+                                       return e;
+
+                               ConstructedType ct = new ConstructedType (
+                                       (FullNamedExpression) e, Arguments, loc);
+                               return ct.ResolveAsTypeStep (ec, false);
+                       }
 
                        if (e is MemberExpr) {
                                MemberExpr me = (MemberExpr) e;
@@ -2699,7 +2772,7 @@ namespace Mono.CSharp {
                                return;
 
                        if (InstanceExpression == EmptyExpression.Null) {
-                               SimpleName.Error_ObjectRefRequired (ec, loc, Name);
+                               SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
                                return;
                        }
                                
@@ -3070,7 +3143,7 @@ namespace Mono.CSharp {
                                        // This can happen when referencing an instance field using
                                        // a fully qualified type expression: TypeName.InstanceField = xxx
                                        // 
-                                       SimpleName.Error_ObjectRefRequired (ec, loc, FieldInfo.Name);
+                                       SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
                                        return null;
                                }
 
@@ -3079,12 +3152,11 @@ namespace Mono.CSharp {
                                // "a.b" is initialized, not whether the whole struct "a" is initialized.
 
                                if (lvalue_instance) {
-                                       bool old_do_flow_analysis = ec.DoFlowAnalysis;
-                                       ec.DoFlowAnalysis = false;
-                                       Expression right_side =
-                                               out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
-                                       InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side, loc);
-                                       ec.DoFlowAnalysis = old_do_flow_analysis;
+                                       using (ec.With (EmitContext.Flags.DoFlowAnalysis, false)) {
+                                               Expression right_side =
+                                                       out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
+                                               InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side, loc);
+                                       }
                                } else {
                                        ResolveFlags rf = ResolveFlags.VariableOrValue | ResolveFlags.DisableFlowAnalysis;
                                        InstanceExpression = InstanceExpression.Resolve (ec, rf);
@@ -3333,23 +3405,23 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (FieldInfo is FieldBuilder){
-                               FieldBase f = TypeManager.GetField (FieldInfo);
-                               if (f != null){
-                                       if ((f.ModFlags & Modifiers.VOLATILE) != 0)
-                                               ig.Emit (OpCodes.Volatile);
+                       FieldBase f = TypeManager.GetField (FieldInfo);
+                       if (f != null){
+                               if ((f.ModFlags & Modifiers.VOLATILE) != 0)
+                                       ig.Emit (OpCodes.Volatile);
                                        
-                                       f.SetAssigned ();
-                               }
-                       } 
+                               f.SetAssigned ();
+                       }
 
                        if (is_static)
                                ig.Emit (OpCodes.Stsfld, FieldInfo);
                        else 
                                ig.Emit (OpCodes.Stfld, FieldInfo);
                        
-                       if (temp != null)
+                       if (temp != null) {
                                temp.Emit (ec);
+                               temp.Release (ec);
+                       }
                }
 
                public override void Emit (EmitContext ec)
@@ -3360,22 +3432,20 @@ namespace Mono.CSharp {
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
                        ILGenerator ig = ec.ig;
-                       
-                       if (FieldInfo is FieldBuilder){
-                               FieldBase f = TypeManager.GetField (FieldInfo);
-                               if (f != null){
-                                       if ((f.ModFlags & Modifiers.VOLATILE) != 0){
-                                               Report.Warning (420, 1, loc, "`{0}': A volatile fields cannot be passed using a ref or out parameter",
+
+                       FieldBase f = TypeManager.GetField (FieldInfo);
+                       if (f != null){
+                               if ((f.ModFlags & Modifiers.VOLATILE) != 0){
+                                       Report.Warning (420, 1, loc, "`{0}': A volatile fields cannot be passed using a ref or out parameter",
                                                        f.GetSignatureForError ());
-                                               return;
-                                       }
-                                       
-                                       if ((mode & AddressOp.Store) != 0)
-                                               f.SetAssigned ();
-                                       if ((mode & AddressOp.Load) != 0)
-                                               f.SetMemberIsUsed ();
+                                       return;
                                }
-                       } 
+                                       
+                               if ((mode & AddressOp.Store) != 0)
+                                       f.SetAssigned ();
+                               if ((mode & AddressOp.Load) != 0)
+                                       f.SetMemberIsUsed ();
+                       }
 
                        //
                        // Handle initonly fields specially: make a copy and then
@@ -3565,7 +3635,7 @@ namespace Mono.CSharp {
                        }
 
                        if (InstanceExpression == null) {
-                               SimpleName.Error_ObjectRefRequired (ec, loc, PropertyInfo.Name);
+                               SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
                                return false;
                        }
 
@@ -3578,10 +3648,10 @@ namespace Mono.CSharp {
 
                        InstanceExpression.CheckMarshalByRefAccess ();
 
-                       if (must_do_cs1540_check && InstanceExpression != EmptyExpression.Null &&
-                           InstanceExpression.Type != ec.ContainerType &&
-                           ec.ContainerType.IsSubclassOf (PropertyInfo.DeclaringType) &&
-                           !InstanceExpression.Type.IsSubclassOf (ec.ContainerType)) {
+                       if (must_do_cs1540_check && (InstanceExpression != EmptyExpression.Null) &&
+                           !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.ContainerType) &&
+                           TypeManager.IsFamilyAccessible (ec.ContainerType, PropertyInfo.DeclaringType) &&
+                           !TypeManager.IsFamilyAccessible (InstanceExpression.Type, ec.ContainerType)) {
                                Error_CannotAccessProtected (loc, PropertyInfo, InstanceExpression.Type, ec.ContainerType);
                                return false;
                        }
@@ -3647,8 +3717,10 @@ namespace Mono.CSharp {
                                        Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because the get accessor is inaccessible",
                                                TypeManager.CSharpSignature (getter));
                                }
-                               else
+                               else {
+                                       Report.SymbolRelatedToPreviousError (getter);
                                        ErrorIsInaccesible (loc, TypeManager.CSharpSignature (getter));
+                               }
                                return null;
                        }
                        
@@ -3714,8 +3786,10 @@ namespace Mono.CSharp {
                                        Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible",
                                                TypeManager.CSharpSignature (setter));
                                }
-                               else
+                               else {
+                                       Report.SymbolRelatedToPreviousError (setter);
                                        ErrorIsInaccesible (loc, TypeManager.CSharpSignature (setter));
+                               }
                                return null;
                        }
                        
@@ -3803,8 +3877,10 @@ namespace Mono.CSharp {
                        
                        Invocation.EmitCall (ec, IsBase, IsStatic, InstanceExpression, setter, args, loc, false, prepared);
                        
-                       if (temp != null)
+                       if (temp != null) {
                                temp.Emit (ec);
+                               temp.Release (ec);
+                       }
                }
        }
 
@@ -3816,6 +3892,8 @@ namespace Mono.CSharp {
 
                bool is_static;
                MethodInfo add_accessor, remove_accessor;
+
+               internal static PtrHashtable AccessorTable = new PtrHashtable (); 
                
                public EventExpr (EventInfo ei, Location loc)
                {
@@ -3825,6 +3903,10 @@ namespace Mono.CSharp {
 
                        add_accessor = TypeManager.GetAddMethod (ei);
                        remove_accessor = TypeManager.GetRemoveMethod (ei);
+                       if (add_accessor != null)
+                               AccessorTable [add_accessor] = ei;
+                       if (remove_accessor != null)
+                               AccessorTable [remove_accessor] = ei;
                        
                        if (add_accessor.IsStatic || remove_accessor.IsStatic)
                                is_static = true;
@@ -3898,7 +3980,7 @@ namespace Mono.CSharp {
                        }
 
                        if (InstanceExpression == null) {
-                               SimpleName.Error_ObjectRefRequired (ec, loc, EventInfo.Name);
+                               SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
                                return false;
                        }
 
@@ -3913,6 +3995,7 @@ namespace Mono.CSharp {
                        if (must_do_cs1540_check && InstanceExpression != EmptyExpression.Null &&
                            InstanceExpression.Type != ec.ContainerType &&
                            ec.ContainerType.IsSubclassOf (InstanceExpression.Type)) {
+                               Report.SymbolRelatedToPreviousError (EventInfo);
                                ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo));
                                return false;
                        }
@@ -3930,6 +4013,7 @@ namespace Mono.CSharp {
                        bool must_do_cs1540_check;
                        if (!(IsAccessorAccessible (ec.ContainerType, add_accessor, out must_do_cs1540_check) &&
                              IsAccessorAccessible (ec.ContainerType, remove_accessor, out must_do_cs1540_check))) {
+                               Report.SymbolRelatedToPreviousError (EventInfo);
                                ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo));
                                return null;
                        }