**** Merged from MCS ****
authorMartin Baulig <martin@novell.com>
Thu, 20 May 2004 12:08:02 +0000 (12:08 -0000)
committerMartin Baulig <martin@novell.com>
Thu, 20 May 2004 12:08:02 +0000 (12:08 -0000)
svn path=/trunk/mcs/; revision=27742

mcs/gmcs/ChangeLog
mcs/gmcs/attribute.cs
mcs/gmcs/class.cs
mcs/gmcs/codegen.cs
mcs/gmcs/cs-parser.jay
mcs/gmcs/decl.cs
mcs/gmcs/delegate.cs
mcs/gmcs/enum.cs
mcs/gmcs/parameter.cs
mcs/gmcs/report.cs

index 86a64f64efb69fecf0661f0447b1cf04ba1ed0ca..2d66e08cc31b278d0fc02eba48130990107a3888 100755 (executable)
@@ -1,3 +1,32 @@
+2004-05-18  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #52585 (Implemented explicit attribute declaration)
+
+       * attribute.cs:
+       (Attributable.ValidAttributeTargets): New abstract method. It gets
+       list of valid attribute targets for explicit target declaration.
+       (Attribute.Target): It holds target itself.
+       (AttributeSection): Removed.
+       (Attribute.CheckTargets): New method. It checks whether attribute
+       target is valid for the current element.
+
+       * class.cs:
+       (EventProperty): New class. For events that are declared like
+       property (with add and remove accessors).
+       (EventField): New class. For events that are declared like field.
+       class.cs
+
+       * cs-parser.jay: Implemented explicit attribute target declaration.
+
+       * class.cs, decl.cs, delegate.cs, enum.cs, parameter.cs:        
+       Override ValidAttributeTargets.
+
+       * parameter.cs:
+       (ReturnParameter): Class for applying custom attributes on 
+       the return type.
+       (ParameterAtribute): New class. Class for applying custom
+       attributes on the parameter type.
+
 2004-05-17  Miguel de Icaza  <miguel@ximian.com>
 
        * class.cs (MemberBase.DoDefine): Pass UNSAFE on interface
        parameter.
        Fixes #56442.
 
+2004-04-08  Martin Baulig  <martin@ximian.com>
+
+       Merged latest changes into gmcs.  Please keep this comment in
+       here, it makes it easier for me to see what changed in MCS since
+       the last time I merged.
+
 2004-04-16  Raja R Harinath  <rharinath@novell.com>
 
        * class.cs (TypeContainer.AddIndexer): Use
index f207f19f733b781044e487adbf8964e2dec19987..a69963be6a0edfc303d603460bba41b0828c554b 100644 (file)
@@ -33,6 +33,8 @@ namespace Mono.CSharp {
                public Attributable(Attributes attrs)\r
                {\r
                        attributes = attrs;\r
+                       if (attributes != null)\r
+                               attributes.CheckTargets (ValidAttributeTargets);\r
                }\r
 \r
                public Attributes OptAttributes \r
@@ -56,10 +58,15 @@ namespace Mono.CSharp {
                public abstract AttributeTargets AttributeTargets { get; }\r
 \r
                public abstract bool IsClsCompliaceRequired (DeclSpace ds);\r
-       };\r
 \r
+               /// <summary>\r
+               /// Gets list of valid attribute targets for explicit target declaration\r
+               /// </summary>\r
+               protected abstract string[] ValidAttributeTargets { get; }\r
+       };\r
 \r
        public class Attribute {\r
+               public readonly string Target;\r
                public readonly string    Name;\r
                public readonly ArrayList Arguments;\r
 \r
@@ -90,11 +97,12 @@ namespace Mono.CSharp {
 \r
                static PtrHashtable usage_attr_cache = new PtrHashtable ();\r
 \r
-               public Attribute (string name, ArrayList args, Location loc)\r
+               public Attribute (string target, string name, ArrayList args, Location loc)\r
                {\r
                        Name = name;\r
                        Arguments = args;\r
                        Location = loc;\r
+                       Target = target;\r
                }\r
 \r
                void Error_InvalidNamedArgument (string name)\r
@@ -127,7 +135,8 @@ namespace Mono.CSharp {
                /// <summary>\r
                 ///   Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.\r
                 /// </summary>\r
-               private Type CheckAttributeType (EmitContext ec, bool complain) {\r
+               protected virtual Type CheckAttributeType (EmitContext ec, bool complain)\r
+               {\r
                        TypeExpr t1 = RootContext.LookupType (ec.DeclSpace, Name, true, Location);\r
                        // FIXME: Shouldn't do this for quoted attributes: [@A]\r
                        TypeExpr t2 = RootContext.LookupType (ec.DeclSpace, Name + "Attribute", true, Location);\r
@@ -638,47 +647,44 @@ namespace Mono.CSharp {
                        if (opt_attrs.AttributeSections == null)\r
                                return null;\r
 \r
-                       foreach (AttributeSection asec in opt_attrs.AttributeSections) {\r
-                               if (asec.Attributes == null)\r
-                                       continue;\r
-\r
-                               foreach (Attribute a in asec.Attributes){\r
-                                       if (a.ResolveType (ec, true) == null)\r
-                                               return null;\r
+                       foreach (Attribute a in opt_attrs.AttributeSections) {\r
+                               if (a.ResolveType (ec, true) == null)\r
+                                       return null;\r
 \r
-                                       if (a.Type != TypeManager.indexer_name_type)\r
-                                               continue;\r
+                               if (a.Type != TypeManager.indexer_name_type)\r
+                                       continue;\r
 \r
-                                       //\r
-                                       // So we have found an IndexerName, pull the data out.\r
-                                       //\r
-                                       if (a.Arguments == null || a.Arguments [0] == null){\r
-                                               Error_AttributeConstructorMismatch (a.Location);\r
-                                               return null;\r
-                                       }\r
-                                       ArrayList pos_args = (ArrayList) a.Arguments [0];\r
-                                       if (pos_args.Count == 0){\r
-                                               Error_AttributeConstructorMismatch (a.Location);\r
-                                               return null;\r
-                                       }\r
+                               //\r
+                               // So we have found an IndexerName, pull the data out.\r
+                               //\r
+                               if (a.Arguments == null || a.Arguments [0] == null){\r
+                                       Error_AttributeConstructorMismatch (a.Location);\r
+                                       return null;\r
+                               }\r
+                               ArrayList pos_args = (ArrayList) a.Arguments [0];\r
+                               if (pos_args.Count == 0){\r
+                                       Error_AttributeConstructorMismatch (a.Location);\r
+                                       return null;\r
+                               }\r
                                        \r
-                                       Argument arg = (Argument) pos_args [0];\r
-                                       if (!arg.Resolve (ec, a.Location))\r
-                                               return null;\r
+                               Argument arg = (Argument) pos_args [0];\r
+                               if (!arg.Resolve (ec, a.Location))\r
+                                       return null;\r
                                        \r
-                                       Expression e = arg.Expr;\r
-                                       if (!(e is StringConstant)){\r
-                                               Error_AttributeConstructorMismatch (a.Location);\r
-                                               return null;\r
-                                       }\r
+                               Expression e = arg.Expr;\r
+                               if (!(e is StringConstant)){\r
+                                       Error_AttributeConstructorMismatch (a.Location);\r
+                                       return null;\r
+                               }\r
 \r
-                                       //\r
-                                       // Remove the attribute from the list\r
-                                       //\r
-                                       asec.Attributes.Remove (a);\r
+                               //\r
+                               // Remove the attribute from the list\r
+                               //\r
 \r
-                                       return (((StringConstant) e).Value);\r
-                               }\r
+                               //TODO: It is very close to hack and it can crash here\r
+                               opt_attrs.AttributeSections.Remove (a);\r
+\r
+                               return (((StringConstant) e).Value);\r
                        }\r
                        return null;\r
                }\r
@@ -834,7 +840,7 @@ namespace Mono.CSharp {
                /// <summary>\r
                /// Emit attribute for Attributable symbol\r
                /// </summary>\r
-               public void Emit (EmitContext ec, Attributable ias, ListDictionary emitted_attr, string target)\r
+               public void Emit (EmitContext ec, Attributable ias, ListDictionary emitted_attr)\r
                {\r
                        CustomAttributeBuilder cb = Resolve (ec);\r
                        if (cb == null) \r
@@ -849,11 +855,11 @@ namespace Mono.CSharp {
                        ias.ApplyAttributeBuilder (this, cb);\r
 \r
                        string emitted = emitted_attr [Type] as string;\r
-                       if (target != null && emitted == target && !usage_attr.AllowMultiple) {\r
+                       if (Target != null && emitted == Target && !usage_attr.AllowMultiple) {\r
                                Report.Error (579, Location, "Duplicate '" + Name + "' attribute");\r
                        }\r
 \r
-                       emitted_attr [Type] = target;\r
+                       emitted_attr [Type] = Target;\r
 \r
                        // Here we are testing attribute arguments for array usage (error 3016)\r
                        if (ias.IsClsCompliaceRequired (ec.DeclSpace)) {\r
@@ -1063,82 +1069,80 @@ namespace Mono.CSharp {
                }\r
        }\r
        \r
-       /// <summary>\r
        /// For global attributes (assembly, module) we need special handling.\r
        /// Attributes can be located in the several files\r
        /// </summary>\r
-       public class GlobalAttributeSection: AttributeSection\r
+       public class GlobalAttribute: Attribute\r
        {\r
                public readonly NamespaceEntry ns;\r
 \r
-               public GlobalAttributeSection (TypeContainer container, AttributeSection attrsec):\r
-                       base (attrsec.Target, attrsec.Attributes)\r
+               public GlobalAttribute (TypeContainer container, string target, string name, ArrayList args, Location loc):\r
+                       base (target, name, args, loc)\r
                {\r
                        ns = container.NamespaceEntry;\r
                }\r
 \r
-               public override void Emit(EmitContext ec, Attributable ias, ListDictionary ld)\r
+               protected override Type CheckAttributeType (EmitContext ec, bool complain)\r
                {\r
                        ec.DeclSpace.NamespaceEntry = ns;\r
-                       base.Emit (ec, ias, ld);\r
-               }\r
-\r
-               public override Attribute Search(Type t, EmitContext ec)\r
-               {\r
-                       ec.DeclSpace.NamespaceEntry = ns;\r
-                       return base.Search (t, ec);\r
+                       return base.CheckAttributeType (ec, complain);\r
                }\r
        }\r
 \r
-       public class AttributeSection {\r
-               public readonly string    Target;\r
-               public readonly ArrayList Attributes;\r
-               \r
-               public AttributeSection (string target, ArrayList attrs)\r
+       public class Attributes {\r
+               public ArrayList AttributeSections;\r
+\r
+               public Attributes (Attribute a)\r
                {\r
-                       Target = target;\r
-                       Attributes = attrs;\r
+                       AttributeSections = new ArrayList ();\r
+                       AttributeSections.Add (a);\r
                }\r
 \r
-               public virtual void Emit (EmitContext ec, Attributable ias, ListDictionary ld)\r
+               public Attributes (ArrayList attrs)\r
                {\r
-                       foreach (Attribute a in Attributes) {\r
-                               a.Emit (ec, ias, ld, Target);\r
-                       }\r
+                       AttributeSections = attrs;\r
                }\r
 \r
-               public virtual Attribute Search (Type t, EmitContext ec)\r
+               public void AddAttributes (ArrayList attrs)\r
                {\r
-                       foreach (Attribute a in Attributes) {\r
-                               if (a.ResolveType (ec, false) == t)\r
-                                       return a;\r
-                       }\r
-                       return null;\r
+                       AttributeSections.AddRange (attrs);\r
                }\r
-       }\r
 \r
-       public class Attributes {\r
-               public ArrayList AttributeSections;\r
-\r
-               public Attributes (AttributeSection a)\r
+               /// <summary>\r
+               /// Checks whether attribute target is valid for the current element\r
+               /// </summary>\r
+               public void CheckTargets (string[] possible_targets)\r
                {\r
-                       AttributeSections = new ArrayList ();\r
-                       AttributeSections.Add (a);\r
+                       foreach (Attribute a in AttributeSections) {\r
+                               if (a.Target == null)\r
+                                       continue;\r
 \r
-               }\r
+                               bool valid_target = false;\r
+                               for (int i = 0; i < possible_targets.Length; ++i) {\r
+                                       if (a.Target == possible_targets [i]) {\r
+                                               valid_target = true;\r
+                                               break;\r
+                                       }\r
+                               }\r
 \r
-               public void AddAttributeSection (AttributeSection a)\r
-               {\r
-                       if (a != null && !AttributeSections.Contains (a))\r
-                               AttributeSections.Add (a);\r
+                               if (valid_target)\r
+                                       continue;\r
+\r
+                               StringBuilder sb = new StringBuilder ();\r
+                               foreach (string s in possible_targets) {\r
+                                       sb.Append (s);\r
+                                       sb.Append (", ");\r
+                               }\r
+                               sb.Remove (sb.Length - 2, 2);\r
+                               Report.Error_T (657, a.Location, a.Target, sb.ToString ());\r
+                       }\r
                }\r
 \r
                public Attribute Search (Type t, EmitContext ec)\r
                {\r
-                       foreach (AttributeSection attr_section in AttributeSections){\r
-                               Attribute a = attr_section.Search (t, ec);\r
-                               if (a != null)\r
-                                       return a;\r
+                       foreach (Attribute attr_section in AttributeSections) {\r
+                               if (attr_section.ResolveType (ec, false) == t)\r
+                                       return attr_section;\r
                        }\r
                        return null;\r
                }\r
@@ -1147,8 +1151,8 @@ namespace Mono.CSharp {
                {\r
                        ListDictionary ld = new ListDictionary ();\r
 \r
-                       foreach (AttributeSection attr_section in AttributeSections) {\r
-                               attr_section.Emit (ec, ias, ld);\r
+                       foreach (Attribute a in AttributeSections) {\r
+                               a.Emit (ec, ias, ld);\r
                        }\r
                }\r
 \r
index 2942c0b7286850da9c3573a5e6403bbd28247deb..198e547b317127d3b1d70f10ade8038913641ba9 100755 (executable)
@@ -2662,6 +2662,8 @@ namespace Mono.CSharp {
                // Whether this is an operator method.
                public bool IsOperator;
 
+               static string[] attribute_targets = new string [] { "method", "return" };
+
                public MethodCore (DeclSpace ds, Expression type, int mod, int allowed_mod,
                                   bool is_interface, MemberName name, Attributes attrs,
                                   Parameters parameters, Location loc)
@@ -2782,6 +2784,12 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               protected override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+
                protected override bool VerifyClsCompliance (DeclSpace ds)
                {
                        if (!base.VerifyClsCompliance (ds)) {
@@ -2894,6 +2902,7 @@ namespace Mono.CSharp {
        public class Method : MethodCore, IIteratorContainer, IMethodData {
                public MethodBuilder MethodBuilder;
                public MethodData MethodData;
+               ReturnParameter return_attributes;
 
                /// <summary>
                ///   Modifiers allowed in a class declaration
@@ -2990,6 +2999,14 @@ namespace Mono.CSharp {
 
                public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
                {
+                       if (a.Target == "return") {
+                               if (return_attributes == null)
+                                       return_attributes = new ReturnParameter (MethodBuilder, Location);
+
+                               return_attributes.ApplyAttributeBuilder (a, cb);
+                               return;
+                       }
+
                        if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
                                MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
                        }
@@ -3525,8 +3542,7 @@ namespace Mono.CSharp {
                                ec.IsStatic = false;
                        }
 
-                       Parameters.LabelParameters (ec, ConstructorBuilder,
-                                                    OptAttributes, Location);
+                       Parameters.LabelParameters (ec, ConstructorBuilder, Location);
                        
                        SymbolWriter sw = CodeGen.SymbolWriter;
                        bool generate_debugging = false;
@@ -3744,26 +3760,21 @@ namespace Mono.CSharp {
                        if ((opt_attrs == null) || (opt_attrs.AttributeSections == null))
                                return true;
 
-                       foreach (AttributeSection asec in opt_attrs.AttributeSections) {
-                               if (asec.Attributes == null)
-                                       continue;
-                                       
-                               foreach (Attribute a in asec.Attributes) {
-                                       Type attr_type = a.ResolveType (ec, true);
-                                       if (attr_type == TypeManager.conditional_attribute_type) {
-                                               if (!ApplyConditionalAttribute (a))
-                                                       return false;
-                                       } else if (attr_type == TypeManager.obsolete_attribute_type) {
-                                               if (!ApplyObsoleteAttribute (a))
-                                                       return false;
-                                       } else if (attr_type == TypeManager.dllimport_type) {
-                                               if (!is_method) {
-                                                       Attribute.Error_AttributeNotValidForElement (a, method.Location);
-                                                       return false;
-                                               }
-                                               if (!ApplyDllImportAttribute (a))
-                                                       return false;
+                       foreach (Attribute a in opt_attrs.AttributeSections) {
+                               Type attr_type = a.ResolveType (ec, true);
+                               if (attr_type == TypeManager.conditional_attribute_type) {
+                                       if (!ApplyConditionalAttribute (a))
+                                               return false;
+                               } else if (attr_type == TypeManager.obsolete_attribute_type) {
+                                       if (!ApplyObsoleteAttribute (a))
+                                               return false;
+                               } else if (attr_type == TypeManager.dllimport_type) {
+                                       if (!is_method) {
+                                               Attribute.Error_AttributeNotValidForElement (a, method.Location);
+                                               return false;
                                        }
+                                       if (!ApplyDllImportAttribute (a))
+                                               return false;
                                }
                        }
 
@@ -4113,7 +4124,7 @@ namespace Mono.CSharp {
                                OptAttributes.Emit (ec, kind);
 
                        if (member is MethodCore)
-                               ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder,OptAttributes, loc);
+                               ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
                         
                        SymbolWriter sw = CodeGen.SymbolWriter;
                        Block block = method.Block;
@@ -4641,6 +4652,8 @@ namespace Mono.CSharp {
                [Flags]
                public enum Status : byte { ASSIGNED = 1, USED = 2 }
 
+               static string[] attribute_targets = new string [] { "field" };
+
                //
                // The constructor is only exposed to our children
                //
@@ -4735,6 +4748,12 @@ namespace Mono.CSharp {
                        return TypeManager.GetFullNameSignature (FieldBuilder);
                }
 
+               protected override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+
                protected override bool VerifyClsCompliance (DeclSpace ds)
                {
                        if (!base.VerifyClsCompliance (ds))
@@ -4909,6 +4928,8 @@ namespace Mono.CSharp {
 
                public class GetMethod: PropertyMethod
                {
+                       static string[] attribute_targets = new string [] { "method", "return" };
+
                        public GetMethod (MethodCore method, Accessor accessor):
                                base (method, accessor)
                        {
@@ -4935,14 +4956,37 @@ namespace Mono.CSharp {
                                        return method.MemberType;
                                }
                        }
+
+                       protected override string[] ValidAttributeTargets {
+                               get {
+                                       return attribute_targets;
+                               }
+                       }
                }
 
                public class SetMethod: PropertyMethod {
+
+                       static string[] attribute_targets = new string [] { "method", "param", "return" };
+                       ParameterAtribute param_attr;
+
                        public SetMethod (MethodCore method, Accessor accessor):
                                base (method, accessor)
                        {
                        }
 
+                       public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+                       {
+                               if (a.Target == "param") {
+                                       if (param_attr == null)
+                                               param_attr = new ParameterAtribute (method_data.MethodBuilder);
+
+                                       param_attr.ApplyAttributeBuilder (a, cb);
+                                       return;
+                               }
+
+                               base.ApplyAttributeBuilder (a, cb);
+                       }
+
                        protected virtual InternalParameters GetParameterInfo (TypeContainer container)
                        {
                                Parameter [] parms = new Parameter [1];
@@ -4978,13 +5022,23 @@ namespace Mono.CSharp {
                                        return TypeManager.void_type;
                                }
                        }
+
+                       protected override string[] ValidAttributeTargets {
+                               get {
+                                       return attribute_targets;
+                               }
+                       }
                }
 
+               static string[] attribute_targets = new string [] { "property" };
+
                public abstract class PropertyMethod: Attributable, IMethodData {
                        protected readonly MethodCore method;
                        protected MethodData method_data;
                        Block block;
 
+                       ReturnParameter return_attributes;
+
                        public PropertyMethod (MethodCore method, Accessor accessor):
                                base (accessor.Attributes)
                        {
@@ -5035,6 +5089,14 @@ namespace Mono.CSharp {
 
                        public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
                        {
+                               if (a.Target == "return") {
+                                       if (return_attributes == null)
+                                               return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
+
+                                       return_attributes.ApplyAttributeBuilder (a, cb);
+                                       return;
+                               }
+
                                method_data.MethodBuilder.SetCustomAttribute (cb);
                        }
 
@@ -5265,6 +5327,12 @@ namespace Mono.CSharp {
 
                        base.Emit (tc);
                }
+
+               protected override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
        }
                        
        public class Property : PropertyBase, IIteratorContainer {
@@ -5522,9 +5590,71 @@ namespace Mono.CSharp {
                }
        }
        
-       public class Event : FieldBase {
+       /// <summary>
+       /// For case when event is declared like property (with add and remove accessors).
+       /// </summary>
+       public class EventProperty: Event {
 
-               sealed class AddDelegateMethod: DelegateMethod
+               static string[] attribute_targets = new string [] { "event", "property" };
+
+               public EventProperty (DeclSpace ds, Expression type, int mod_flags,
+                                     bool is_iface, MemberName name, Object init,
+                                     Attributes attrs, Accessor add, Accessor remove,
+                                     Location loc)
+                       : base (ds, type, mod_flags, is_iface, name, init, attrs, loc)
+               {
+                       Add = new AddDelegateMethod (this, add);
+                       Remove = new RemoveDelegateMethod (this, remove);
+               }
+
+               protected override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+       }
+
+       /// <summary>
+       /// Event is declared like field.
+       /// </summary>
+       public class EventField: Event {
+
+               static string[] attribute_targets = new string [] { "method", "field", "event" };
+
+               public EventField (DeclSpace ds, Expression type, int mod_flags, bool is_iface,
+                                  MemberName name, Object init, Attributes attrs, Location loc)
+                       : base (ds, type, mod_flags, is_iface, name, init, attrs, loc)
+               {
+                       Add = new AddDelegateMethod (this);
+                       Remove = new RemoveDelegateMethod (this);
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Target == "field") {
+                               FieldBuilder.SetCustomAttribute (cb);
+                               return;
+                       }
+
+                       if (a.Target == "method") {
+                               AddBuilder.SetCustomAttribute (cb);
+                               RemoveBuilder.SetCustomAttribute (cb);
+                               return;
+                       }
+
+                       base.ApplyAttributeBuilder (a, cb);
+               }
+
+               protected override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+       }
+
+       public abstract class Event : FieldBase {
+
+               protected sealed class AddDelegateMethod: DelegateMethod
                {
                        public AddDelegateMethod (Event method):
                                base (method)
@@ -5550,7 +5680,7 @@ namespace Mono.CSharp {
 
                }
 
-               sealed class RemoveDelegateMethod: DelegateMethod
+               protected sealed class RemoveDelegateMethod: DelegateMethod
                {
                        public RemoveDelegateMethod (Event method):
                                base (method)
@@ -5581,6 +5711,10 @@ namespace Mono.CSharp {
                        protected readonly Event method;
                        protected MethodData method_data;
                        Block block;
+                       ReturnParameter return_attributes;
+                       ParameterAtribute param_attr;
+
+                       static string[] attribute_targets = new string [] { "method", "param", "return" };
 
                        public DelegateMethod (Event method):
                                base (null)
@@ -5597,6 +5731,22 @@ namespace Mono.CSharp {
 
                        public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
                        {
+                               if (a.Target == "return") {
+                                       if (return_attributes == null)
+                                               return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
+
+                                       return_attributes.ApplyAttributeBuilder (a, cb);
+                                       return;
+                               }
+
+                               if (a.Target == "param") {
+                                       if (param_attr == null)
+                                               param_attr = new ParameterAtribute (method_data.MethodBuilder);
+
+                                       param_attr.ApplyAttributeBuilder (a, cb);
+                                       return;
+                               }
+
                                method_data.MethodBuilder.SetCustomAttribute (cb);
                        }
 
@@ -5690,13 +5840,18 @@ namespace Mono.CSharp {
 
                        public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
                        {
-                               return new EmitContext (tc, method.ds, method.Location, ig, ReturnType, method.ModFlags, false);
+                               return new EmitContext (tc, method.ds, Location, ig, ReturnType, method.ModFlags, false);
                        }
 
                        public abstract string MethodName { get; }
 
                        #endregion
 
+                       protected override string[] ValidAttributeTargets {
+                               get {
+                                       return attribute_targets;
+                               }
+                       }
                }
 
 
@@ -5716,27 +5871,13 @@ namespace Mono.CSharp {
                const int AllowedInterfaceModifiers =
                        Modifiers.NEW;
 
-               readonly DelegateMethod Add, Remove;
+               protected DelegateMethod Add, Remove;
                public MyEventBuilder     EventBuilder;
                public MethodBuilder AddBuilder, RemoveBuilder;
                public DeclSpace ds;
 
                MethodData AddData, RemoveData;
                
-               public Event (DeclSpace ds, Expression type, int mod_flags, bool is_iface,
-                             MemberName name, Object init, Attributes attrs, Accessor add,
-                             Accessor remove, Location loc)
-                       : base (type, mod_flags,
-                               is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
-                               name, init, attrs, loc)
-               {
-                       IsInterface = is_iface;
-                       this.ds = ds;
-
-                       Add = new AddDelegateMethod (this, add);
-                       Remove = new RemoveDelegateMethod (this, remove);
-               }
-
                public Event (DeclSpace ds, Expression type, int mod_flags, bool is_iface,
                              MemberName name, Object init, Attributes attrs, Location loc)
                        : base (type, mod_flags,
@@ -5745,9 +5886,6 @@ namespace Mono.CSharp {
                {
                        IsInterface = is_iface;
                        this.ds = ds;
-
-                       Add = new AddDelegateMethod (this);
-                       Remove = new RemoveDelegateMethod (this);
                }
 
                public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
@@ -5848,7 +5986,6 @@ namespace Mono.CSharp {
 
                        base.Emit (tc);
                }
-               
        }
 
        //
@@ -6186,6 +6323,8 @@ namespace Mono.CSharp {
                public string MethodName;
                public Method OperatorMethod;
 
+               static string[] attribute_targets = new string [] { "param" };
+
                public Operator (OpType type, Expression ret_type, int mod_flags,
                                 Expression arg1type, string arg1name,
                                 Expression arg2type, string arg2name,
@@ -6453,6 +6592,12 @@ namespace Mono.CSharp {
                                        param_types [0], param_types [1]);
                }
 
+               protected override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+
                public void SetYields ()
                {
                        ModFlags |= Modifiers.METHOD_YIELDS;
index 6c5a3816181121762a9edb64e17a525ccbd04a5e..5c913992c4c3e452fbf4853a9568056fcc61f930 100755 (executable)
@@ -765,19 +765,23 @@ namespace Mono.CSharp {
 
 
        public abstract class CommonAssemblyModulClass: Attributable {
+               static string[] attribute_targets = new string [] { "assembly", "module" };
 
                protected CommonAssemblyModulClass ():
                        base (null)
                {
                }
 
-               public void AddAttribute (AttributeSection attr)
+               // TODO: The error can be reported more than once
+               public void AddAttributes (ArrayList attrs)
                {
                        if (OptAttributes == null) {
-                               OptAttributes = new Attributes (attr);
+                               OptAttributes = new Attributes (attrs);
+                               OptAttributes.CheckTargets (ValidAttributeTargets);
                                return;
                        }
-                       OptAttributes.AddAttributeSection (attr);
+                       OptAttributes.AddAttributes (attrs);
+                       OptAttributes.CheckTargets (ValidAttributeTargets);
                }
 
                public virtual void Emit (TypeContainer tc) 
@@ -801,6 +805,12 @@ namespace Mono.CSharp {
                        }
                        return a;
                }
+
+               protected override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
        }
 
        public class AssemblyClass: CommonAssemblyModulClass {
@@ -844,11 +854,11 @@ namespace Mono.CSharp {
                public AssemblyName GetAssemblyName (string name, string output) 
                {
                        if (OptAttributes != null) {
-                               foreach (AttributeSection asect in OptAttributes.AttributeSections) {
-                                       if (asect.Target != "assembly")
+                               foreach (Attribute a in OptAttributes.AttributeSections) {
+                                       if (a.Target != "assembly")
                                                continue;
                                        // strongname attributes don't support AllowMultiple
-                                       Attribute a = (Attribute) asect.Attributes [0];
+                                       //Attribute a = (Attribute) asect.Attributes [0];
                                        switch (a.Name) {
                                                case "AssemblyKeyFile":
                                                        if (RootContext.StrongNameKeyFile != null) {
@@ -973,7 +983,6 @@ namespace Mono.CSharp {
        public class ModuleClass: CommonAssemblyModulClass {
                // TODO: make it private and move all builder based methods here
                public ModuleBuilder Builder;
-            
                bool m_module_is_unsafe;
 
                public ModuleClass (bool is_unsafe)
index 65086e37a5baff94fdd2781ef483f5a6fe2ecbe2..e554eb0cb7a17f0aa5c576ec6698977dd256cd8b 100755 (executable)
@@ -97,6 +97,13 @@ namespace Mono.CSharp
                /// The current file.
                ///
                SourceFile file;
+               
+               
+               /// Current attribute target
+               string current_attr_target;
+               
+               /// assembly and module attribute definition is enabled
+               bool global_attrs_enabled = true;
 %}
 
 %token EOF
@@ -343,15 +350,8 @@ using_namespace_directive
 namespace_declaration
        : opt_attributes NAMESPACE namespace_name
        {
-               Attributes attrs = (Attributes) $1;
-
-               if (attrs != null) {
-                       foreach (AttributeSection asec in attrs.AttributeSections)
-                               if (asec.Target == "assembly")
-                                       CodeGen.Assembly.AddAttribute (new GlobalAttributeSection (current_container, asec));
-                               else
-                                       Report.Error(1518, Lexer.Location,
-                                       "Attributes cannot be applied to namespaces."
+               if ($1 != null) {
+                       Report.Error(1518, Lexer.Location, "Attributes cannot be applied to namespaces."
                                        + " Expected class, delegate, enum, interface, or struct");
                }
 
@@ -466,66 +466,87 @@ type_declaration
 
 opt_attributes
         : /* empty */
-       | attribute_sections { $$ = $1; }
+         {
+               global_attrs_enabled = false;
+               $$ = null;
+      }
+       | attribute_sections
+         { 
+               global_attrs_enabled = false;
+               $$ = $1;
+         }
         ;
  
+
 attribute_sections
        : attribute_section
           {
-               AttributeSection sect = (AttributeSection) $1;
+               ArrayList sect = (ArrayList) $1;
 
-               if (sect.Target == "assembly") {
-                       CodeGen.Assembly.AddAttribute (new GlobalAttributeSection (current_container, sect));
+               if (global_attrs_enabled) {
+                       if (current_attr_target == "module") {
+                               CodeGen.Module.AddAttributes (sect);
                        $$ = null;
-               }
-               else if (sect.Target == "module") {
-                       CodeGen.Module.AddAttribute (new GlobalAttributeSection (current_container, sect));
+                       } else if (current_attr_target == "assembly") {
+                               CodeGen.Assembly.AddAttributes (sect);
                        $$ = null;
+                       } else {
+
+                               // Because we don't know if target should be on assembly or type
+                               // we add it to both. This leads error CS0657 is reported twice
+                               // for this case but it is better than mistification.
+                               CodeGen.Assembly.AddAttributes (sect);
+                               $$ = new Attributes (sect);
                }
-               else
+               } else {
                        $$ = new Attributes (sect);
           }
+               current_attr_target = null;
+      }
        | attribute_sections attribute_section
          {
                Attributes attrs = $1 as Attributes;
-               AttributeSection sect = (AttributeSection) $2;
+               ArrayList sect = (ArrayList) $2;
 
-               if (sect.Target == "assembly") {
-                       CodeGen.Assembly.AddAttribute (new GlobalAttributeSection (current_container, sect));
-               }
-               else if (sect.Target == "module") {
-                       CodeGen.Module.AddAttribute (new GlobalAttributeSection (current_container, sect));
+               if (global_attrs_enabled) {
+                       if (current_attr_target == "module") {
+                               CodeGen.Module.AddAttributes (sect);
+                               $$ = null;
+                       } else if (current_attr_target == "assembly") {
+                               CodeGen.Assembly.AddAttributes (sect);
+                               $$ = null;
+                       } else {
+                               if (attrs == null)
+                                       attrs = new Attributes (sect);
+                               else
+                                       attrs.AddAttributes (sect);                     
                }
-               else {
+               else {
                        if (attrs == null)
                                attrs = new Attributes (sect);
                        else
-                       attrs.AddAttributeSection (sect);
+                               attrs.AddAttributes (sect);
                }
-               
                $$ = attrs;
+               current_attr_target = null;
          }
        ;
 
 attribute_section
        : OPEN_BRACKET attribute_target_specifier attribute_list opt_comma CLOSE_BRACKET
          {
-               string target = null;
-               
-               if ($2 != null)
-                       target = (string) $2;
-               
-               $$ = new AttributeSection (target, (ArrayList) $3);
+               $$ = $3;
          }
         | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET
          {
-               $$ = new AttributeSection (null, (ArrayList) $2);
+               $$ = $2;
          }
        ;
  
 attribute_target_specifier
        : attribute_target COLON
          {
+               current_attr_target = (string)$1;
                $$ = $1;
          }
        ;
@@ -568,7 +589,13 @@ attribute
                //
                // Attributes need a string, not an expression: generic types will fail here.
                //
-               $$ = new Attribute (((Expression) $1).ToString (), (ArrayList) $3, (Location) $2);
+               if (current_attr_target == "assembly" || current_attr_target == "module")
+                       $$ = new GlobalAttribute (current_container, current_attr_target,
+                                                 ((Expression) $1).ToString (),
+                                                 (ArrayList) $3, (Location) $2);
+               else
+                       $$ = new Attribute (current_attr_target, ((Expression) $1).ToString (),
+                                           (ArrayList) $3, (Location) $2);
          }
        ;
 
@@ -1392,9 +1419,9 @@ interface_accessors
 interface_event_declaration
        : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
          {
-               $$ = new Event (current_container, (Expression) $4, (int) $2, true,
-                                new MemberName ((string) $5), null,
-                               (Attributes) $1, lexer.Location);
+               $$ = new EventField (current_container, (Expression) $4, (int) $2, true,
+                                    new MemberName ((string) $5), null,
+                                    (Attributes) $1, lexer.Location);
          }
        | opt_attributes opt_new EVENT type error {
                CheckIdentifierToken (yyToken);
@@ -1704,9 +1731,10 @@ event_declaration
 
                        MemberName name = new MemberName (var.identifier);
 
-                       Event e = new Event (current_container, (Expression) $4, (int) $2,
-                                            false, name, var.expression_or_array_initializer,
-                                            (Attributes) $1, lexer.Location);
+                       Event e = new EventField (current_container, (Expression) $4, (int) $2,
+                                                 false, name,
+                                                 var.expression_or_array_initializer,
+                                                 (Attributes) $1, lexer.Location);
 
                        CheckDef (current_container.AddEvent (e), e.Name, e.Location);
                                       
@@ -1741,9 +1769,10 @@ event_declaration
 
                MemberName name = type_name.GetMemberName ();
 
-               Event e = new Event (current_container, (Expression) $4, (int) $2, false,
-                                    name, null, (Attributes) $1, (Accessor) pair.First,
-                                    (Accessor) pair.Second, loc);
+               Event e = new EventProperty (current_container, (Expression) $4, (int) $2,
+                                            false, name, null, (Attributes) $1,
+                                            (Accessor) pair.First, (Accessor) pair.Second,
+                                            loc);
                
                CheckDef (current_container.AddEvent (e), e.Name, loc);
                implicit_value_parameter_type = null;
index 97903704bd005f14ab6dd130da7dc7c1ea8d751c..c2f326f79101f2924c067d1ae9151a87fac499dc 100755 (executable)
@@ -542,6 +542,8 @@ namespace Mono.CSharp {
 
                TypeContainer parent;
 
+               static string[] attribute_targets = new string [] { "type" };
+
                public DeclSpace (NamespaceEntry ns, TypeContainer parent, MemberName name,
                                  Attributes attrs, Location l)
                        : base (name, attrs, l)
@@ -1572,6 +1574,12 @@ namespace Mono.CSharp {
                                return new TypeExpression (TypeBuilder, Location);
                        }
                }
+
+               protected override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
        }
 
        /// <summary>
index c91efce4cf76c4e0e9ddc6d8e247cb893cd62f77..ac5fde42e9404158252e3740718af721ade4b1e7 100644 (file)
@@ -35,8 +35,11 @@ namespace Mono.CSharp {
                Type [] param_types;\r
                Type ret_type;\r
 \r
+               static string[] attribute_targets = new string [] { "type", "return" };\r
+\r
                Expression instance_expr;\r
                MethodBase delegate_method;\r
+               ReturnParameter return_attributes;\r
        \r
                const int AllowedModifiers =\r
                        Modifiers.NEW |\r
@@ -59,6 +62,19 @@ namespace Mono.CSharp {
                        Parameters      = param_list;\r
                }\r
 \r
+               public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)\r
+               {\r
+                       if (a.Target == "return") {\r
+                               if (return_attributes == null)\r
+                                       return_attributes = new ReturnParameter (InvokeBuilder, Location);\r
+\r
+                               return_attributes.ApplyAttributeBuilder (a, cb);\r
+                               return;\r
+                       }\r
+\r
+                       base.ApplyAttributeBuilder (a, cb);\r
+               }\r
+\r
                public override TypeBuilder DefineType ()\r
                {\r
                        if (TypeBuilder != null)\r
@@ -378,12 +394,19 @@ namespace Mono.CSharp {
                {\r
                        if (OptAttributes != null) {\r
                                EmitContext ec = new EmitContext (tc, this, Location, null, null, ModFlags, false);\r
+                               Parameters.LabelParameters (ec, InvokeBuilder, Location);\r
                                OptAttributes.Emit (ec, this);\r
                        }\r
 \r
                        base.Emit (tc);\r
                }\r
 \r
+               protected override string[] ValidAttributeTargets {\r
+                       get {\r
+                               return attribute_targets;\r
+                       }\r
+               }\r
+\r
                //TODO: duplicate\r
                protected override bool VerifyClsCompliance (DeclSpace ds)\r
                {\r
index 3e2f787fcf03d0efd1ec311559858dd8466bb34c..2c76438a76ab6095819301d264a61affce1dad2c 100755 (executable)
@@ -21,6 +21,8 @@ namespace Mono.CSharp {
                Enum parent;
                Location loc;
 
+               static string[] attribute_targets = new string [] { "field" };
+
                public FieldBuilder builder;
 
                public EnumMember (string name, Enum parent, Location loc, Attributes attrs):
@@ -71,6 +73,11 @@ namespace Mono.CSharp {
                                OptAttributes.Emit (ec, this); 
                }
 
+               protected override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
        }
 
        /// <summary>
index 9be72aeb12dffa56e70869e1c808e0c3e87f72c6..c0900b3608df39240933ba355ee680408010d4ff 100755 (executable)
@@ -47,13 +47,30 @@ namespace Mono.CSharp {
                {
                        return false;
                                }
-
        }
 
+       /// <summary>
+       /// Class for applying custom attributes on the return type
+       /// </summary>
        public class ReturnParameter: ParameterBase {
-               public ReturnParameter (Attributes attrs):
-                       base (attrs)
+               public ReturnParameter (MethodBuilder mb, Location location):
+                       base (null)
                {
+                       try {
+                               builder = mb.DefineParameter (0, ParameterAttributes.None, "");                 
+                       }
+                       catch (ArgumentOutOfRangeException) {
+                               Report.Warning_T (-28, location);
+                       }
+               }
+
+               public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+               {
+                       // This occurs after Warning -28
+                       if (builder == null)
+                               return;
+
+                       base.ApplyAttributeBuilder (a, cb);
                }
 
                public override AttributeTargets AttributeTargets {
@@ -62,20 +79,44 @@ namespace Mono.CSharp {
                        }
                }
 
-               public void DefineParameter (EmitContext ec, MethodBuilder mb, Location loc)
+               /// <summary>
+               /// Is never called
+               /// </summary>
+               protected override string[] ValidAttributeTargets {
+                       get {
+                               return null;
+                       }
+               }
+       }
+
+       /// <summary>
+       /// Class for applying custom attributes on the parameter type.
+       /// ! Now it works only with 1st parameter (for properties and events)
+       /// </summary>
+       public class ParameterAtribute: ParameterBase {
+               public ParameterAtribute (MethodBuilder mb):
+                       base (null)
                {
-                       try {
-                               builder = mb.DefineParameter (0, ParameterAttributes.None, "");                         
-                               OptAttributes.Emit (ec, this);
-                       } catch (ArgumentOutOfRangeException) {
-                               Report.Warning (
-                                       -24, loc,
-                                       ".NET SDK 1.0 does not permit setting custom attributes" +
-                                       " on the return type of a method");
+                       builder = mb.DefineParameter (1, ParameterAttributes.None, "");                 
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Parameter;
                        }
                }
+
+               /// <summary>
+               /// Is never called
+               /// </summary>
+               protected override string[] ValidAttributeTargets {
+                       get {
+                               return null;
+                       }
+       }
        }
 
+
        /// <summary>
        ///   Represents a single method parameter
        /// </summary>
@@ -92,6 +133,8 @@ namespace Mono.CSharp {
                        ISBYREF = 8
                }
 
+               static string[] attribute_targets = new string [] { "param" };
+
                public readonly Expression TypeName;
                public readonly Modifier ModFlags;
                public readonly string Name;
@@ -228,6 +271,12 @@ namespace Mono.CSharp {
                                }
                        }
                }
+
+               protected override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
        }
 
        /// <summary>
@@ -538,7 +587,6 @@ namespace Mono.CSharp {
                //
                public void LabelParameters (EmitContext ec,
                        MethodBase builder,
-                       Attributes method_attrs,
                        Location loc) {
                        //
                        // Define each type attribute (in/out/ref) and
@@ -573,34 +621,6 @@ namespace Mono.CSharp {
                                
                                pb.SetCustomAttribute (a);
                        }
-
-                       //
-                       // And now for the return type attribute decoration
-                       //
-                               
-                       if (mb == null || method_attrs == null)
-                               return;
-
-                       Attributes ret_attrs = null;
-                       foreach (AttributeSection asec in method_attrs.AttributeSections) {
-
-                               if (asec.Target != "return")
-                                       continue;
-
-                               if (ret_attrs == null)
-                                       ret_attrs = new Attributes (asec);
-                               else
-                                       ret_attrs.AddAttributeSection (asec);
-                       }
-
-                       if (ret_attrs != null) {
-                               ReturnParameter ret = new ReturnParameter (ret_attrs);
-                               ret.DefineParameter (ec, mb, loc);
-                       }
                }
-
        }
 }
-               
-       
-
index c33d935c68a63f5ef0c3c22036c128951c4aaee7..096f17e031579d988c440ce6bfda4615bb86a8ee 100644 (file)
@@ -88,6 +88,7 @@ namespace Mono.CSharp {
                static string GetErrorMsg (int error_no)
                {
                        switch (error_no) {
+                               case 0657: return "'{0}' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are '{1}'";
                                case 3001: return "Argument type '{0}' is not CLS-compliant";
                                case 3002: return "Return type of '{0}' is not CLS-compliant";
                                case 3003: return "Type of '{0}' is not CLS-compliant";
@@ -109,6 +110,7 @@ namespace Mono.CSharp {
                {
                        switch (warn_no) {
                                case -24: return new WarningData (1, "The Microsoft Runtime cannot set this marshal info. Please use the Mono runtime instead.");
+                               case -28: return new WarningData (1, "The Microsoft .NET Runtime 1.x does not permit setting custom attributes on the return type");
                                case 3012: return new WarningData (1, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
                                case 3019: return new WarningData (2, "CLS compliance checking will not be performed on '{0}' because it is private or internal");
                        }