2009-02-09 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / attribute.cs
index 3c4062789b50de51704fa9743306bc07701ac072..da6717218380af100ea14fe489e9feaa02be002f 100644 (file)
@@ -123,6 +123,14 @@ namespace Mono.CSharp {
                        this.nameEscaped = nameEscaped;
                }
 
+               public Attribute Clone ()
+               {
+                       Attribute a = new Attribute (ExplicitTarget, LeftExpr, Identifier, null, loc, nameEscaped);
+                       a.PosArguments = PosArguments;
+                       a.NamedArguments = NamedArguments;
+                       return a;
+               }
+
                static Attribute ()
                {
                        Reset ();
@@ -376,8 +384,8 @@ namespace Mono.CSharp {
                        if (ds == null)
                                ds = owner.ResolveContext.DeclContainer;
                        
-                       EmitContext ec = new EmitContext (owner.ResolveContext, ds, owner.ResolveContext.DeclContainer,
-                               Location, null, typeof (Attribute), owner.ResolveContext.DeclContainer.ModFlags, false);
+                       EmitContext ec = new EmitContext (owner.ResolveContext, ds, ds,
+                               Location, null, typeof (Attribute), ds.ModFlags, false);
                        ec.IsAnonymousMethodAllowed = false;
 
                        ConstructorInfo ctor = ResolveConstructor (ec);
@@ -449,13 +457,6 @@ namespace Mono.CSharp {
                                return null;
                        
                        ConstructorInfo constructor = (ConstructorInfo)mg;
-
-                       // TODO: move to OverloadResolve
-                       ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (constructor);
-                       if (oa != null && !Owner.ResolveContext.IsInObsoleteScope) {
-                               AttributeTester.Report_ObsoleteMessage (oa, mg.GetSignatureForError (), mg.Location);
-                       }
-
                        if (PosArguments == null) {
                                pos_values = EmptyObject;
                                return constructor;
@@ -524,7 +525,7 @@ namespace Mono.CSharp {
                                string member_name = (string) de.Key;
 
                                if (seen_names.Contains(member_name)) {
-                                       Report.Error(643, Location, "'" + member_name + "' duplicate named attribute argument");
+                                       Report.Error(643, Location, "'{0}' duplicate named attribute argument", member_name);
                                        return false;
                                }                               
                                seen_names.Add(member_name);
@@ -851,11 +852,11 @@ namespace Mono.CSharp {
                        // TODO: we can skip the first item
                        if (((IList) valid_targets).Contains (ExplicitTarget)) {
                                switch (ExplicitTarget) {
-                                       case "return": Target = AttributeTargets.ReturnValue; return true;
-                                       case "param": Target = AttributeTargets.Parameter; return true;
-                                       case "field": Target = AttributeTargets.Field; return true;
-                                       case "method": Target = AttributeTargets.Method; return true;
-                                       case "property": Target = AttributeTargets.Property; return true;
+                               case "return": Target = AttributeTargets.ReturnValue; return true;
+                               case "param": Target = AttributeTargets.Parameter; return true;
+                               case "field": Target = AttributeTargets.Field; return true;
+                               case "method": Target = AttributeTargets.Method; return true;
+                               case "property": Target = AttributeTargets.Property; return true;
                                }
                                throw new InternalErrorException ("Unknown explicit target: " + ExplicitTarget);
                        }
@@ -965,7 +966,7 @@ namespace Mono.CSharp {
                                                // TODO: pi can be null
                                                PropertyInfo pi = orig_assembly_type.GetProperty (emited_pi.Name);
 
-                                               object old_instance = pi.PropertyType.IsEnum ?
+                                               object old_instance = TypeManager.IsEnumType (pi.PropertyType) ?
                                                        System.Enum.ToObject (pi.PropertyType, prop_values_arr [i]) :
                                                        prop_values_arr [i];
 
@@ -981,15 +982,15 @@ namespace Mono.CSharp {
                        // IS is correct because for corlib we are using an instance from old corlib
                        if (!(perm is System.Security.CodeAccessPermission)) {
                                switch (action) {
-                                       case SecurityAction.Demand:
-                                               action = (SecurityAction)13;
-                                               break;
-                                       case SecurityAction.LinkDemand:
-                                               action = (SecurityAction)14;
-                                               break;
-                                       case SecurityAction.InheritanceDemand:
-                                               action = (SecurityAction)15;
-                                               break;
+                               case SecurityAction.Demand:
+                                       action = (SecurityAction)13;
+                                       break;
+                               case SecurityAction.LinkDemand:
+                                       action = (SecurityAction)14;
+                                       break;
+                               case SecurityAction.InheritanceDemand:
+                                       action = (SecurityAction)15;
+                                       break;
                                }
                        }
 
@@ -1129,6 +1130,19 @@ namespace Mono.CSharp {
                        return (CharSet)System.Enum.Parse (typeof (CharSet), pos_values [0].ToString ());
                }
 
+               public bool HasField (string fieldName)
+               {
+                       if (field_info_arr == null)
+                               return false;
+
+                       foreach (FieldInfo fi in field_info_arr) {
+                               if (fi.Name == fieldName)
+                                       return true;
+                       }
+
+                       return false;
+               }
+
                public bool IsInternalMethodImplAttribute {
                        get {
                                if (Type != TypeManager.methodimpl_attr_type)
@@ -1408,6 +1422,15 @@ namespace Mono.CSharp {
                                a.AttachTo (attributable);
                }
 
+               public Attributes Clone ()
+               {
+                       ArrayList al = new ArrayList (Attrs.Count);
+                       foreach (Attribute a in Attrs)
+                               al.Add (a.Clone ());
+
+                       return new Attributes (al);
+               }
+
                /// <summary>
                /// Checks whether attribute target is valid for the current element
                /// </summary>
@@ -1536,8 +1559,8 @@ namespace Mono.CSharp {
                                Type bType = types_b [i];
 
                                if (aType.IsArray && bType.IsArray) {
-                                       Type a_el_type = aType.GetElementType ();
-                                       Type b_el_type = bType.GetElementType ();
+                                       Type a_el_type = TypeManager.GetElementType (aType);
+                                       Type b_el_type = TypeManager.GetElementType (bType);
                                        if (aType.GetArrayRank () != bType.GetArrayRank () && a_el_type == b_el_type) {
                                                result = Result.RefOutArrayError;
                                                continue;
@@ -1571,7 +1594,7 @@ namespace Mono.CSharp {
                                return type_compliance == TRUE;
 
                        if (type.IsPointer) {
-                               analyzed_types.Add (type, null);
+                               analyzed_types.Add (type, FALSE);
                                return false;
                        }
 
@@ -1593,7 +1616,7 @@ namespace Mono.CSharp {
                public static IFixedBuffer GetFixedBuffer (FieldInfo fi)
                {
                        // Fixed buffer helper type is generated as value type
-                       if (!fi.FieldType.IsValueType)
+                       if (TypeManager.IsReferenceType (fi.FieldType))
                                return null;
 
                        FieldBase fb = TypeManager.GetField (fi);
@@ -1700,17 +1723,19 @@ namespace Mono.CSharp {
                        ObsoleteAttribute result = null;
                        if (TypeManager.HasElementType (type)) {
                                result = GetObsoleteAttribute (TypeManager.GetElementType (type));
-                       } else if (TypeManager.IsGenericParameter (type) || TypeManager.IsGenericType (type))
-                               return null;
-                       else {
+                       } else if (TypeManager.IsGenericParameter (type))
+                               result = null;  // TODO: throw new NotSupportedException ()
+                       else if (TypeManager.IsGenericType (type) && !TypeManager.IsGenericTypeDefinition (type)) {
+                               return GetObsoleteAttribute (TypeManager.DropGenericTypeArguments (type));
+                       } else {
                                DeclSpace type_ds = TypeManager.LookupDeclSpace (type);
 
                                // Type is external, we can get attribute directly
                                if (type_ds == null) {
                                        if (TypeManager.obsolete_attribute_type != null) {
-                                               object [] attribute = type.GetCustomAttributes (TypeManager.obsolete_attribute_type, false);
+                                               object[] attribute = type.GetCustomAttributes (TypeManager.obsolete_attribute_type, false);
                                                if (attribute.Length == 1)
-                                                       result = (ObsoleteAttribute) attribute [0];
+                                                       result = (ObsoleteAttribute) attribute[0];
                                        }
                                } else {
                                        result = type_ds.GetObsoleteAttribute ();