2003-07-16 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / mbas / attribute.cs
index edbccb5134c077b8d0bd248bc29629609c85fd04..bfe5a39da1d315cb6acddfeb61f9cb4724fc7f4d 100644 (file)
@@ -10,6 +10,7 @@
 //
 
 using System;
+using System.Diagnostics;
 using System.Collections;
 using System.Reflection;
 using System.Reflection.Emit;
@@ -145,10 +146,6 @@ namespace Mono.CSharp {
                        // First process positional arguments 
                        //
 
-                       if (Type.Name.IndexOf ("DefaultValue") != -1){
-                               Console.WriteLine ("HELLO");
-                       }
-                       
                        int i;
                        for (i = 0; i < pos_arg_count; i++) {
                                Argument a = (Argument) pos_args [i];
@@ -158,6 +155,7 @@ namespace Mono.CSharp {
                                        return null;
 
                                e = a.Expr;
+
                                if (e is Constant) {
                                        pos_values [i] = ((Constant) e).GetValue ();
                                } else if (e is TypeOf) {
@@ -228,7 +226,9 @@ namespace Mono.CSharp {
                                                                this.Inherited = (bool) o;
                                                }
                                                
-                                       } else { 
+                                       } else if (e is TypeOf) {
+                                               prop_values.Add (((TypeOf) e).TypeArg);
+                                       } else {
                                                Error_AttributeArgumentNotValid ();
                                                return null;
                                        }
@@ -251,7 +251,9 @@ namespace Mono.CSharp {
                                                object value = ((Constant) e).GetValue ();
                                                
                                                field_values.Add (value);
-                                       } else { 
+                                       } else if (e is TypeOf) {
+                                               field_values.Add (((TypeOf) e).TypeArg);
+                                       } else {
                                                Error_AttributeArgumentNotValid ();
                                                return null;
                                        }
@@ -276,6 +278,23 @@ namespace Mono.CSharp {
                                Error_AttributeConstructorMismatch (Location);
                                return null;
                        }
+
+                       //
+                       // Now we perform some checks on the positional args as they
+                       // cannot be null for a constructor which expects a parameter
+                       // of type object
+                       //
+
+                       ParameterData pd = Invocation.GetParameterData (constructor);
+
+                       for (int j = 0; j < pos_arg_count; ++j) {
+                               Argument a = (Argument) pos_args [j];
+                               
+                               if (a.Expr is NullLiteral && pd.ParameterType (j) == TypeManager.object_type) {
+                                       Error_AttributeArgumentNotValid ();
+                                       return null;
+                               }
+                       }
                        
                        PropertyInfo [] prop_info_arr = new PropertyInfo [prop_infos.Count];
                        FieldInfo [] field_info_arr = new FieldInfo [field_infos.Count];
@@ -293,6 +312,11 @@ namespace Mono.CSharp {
                                        (ConstructorInfo) constructor, pos_values,
                                        prop_info_arr, prop_values_arr,
                                        field_info_arr, field_values_arr); 
+
+                       } catch (NullReferenceException) {
+                               // 
+                               // Don't know what to do here
+                               //
                        } catch {
                                //
                                // Sample:
@@ -331,8 +355,10 @@ namespace Mono.CSharp {
                                }
                                        
                                foreach (System.Attribute tmp in attrs)
-                                       if (tmp is AttributeUsageAttribute) 
+                                       if (tmp is AttributeUsageAttribute) {
                                                targets = ((AttributeUsageAttribute) tmp).ValidOn;
+                                               break;
+                                       }
                        } else
                                targets = a.Targets;
 
@@ -539,10 +565,76 @@ namespace Mono.CSharp {
                        }
                        return null;
                }
-               
+
                //
-               // Applies the attributes to the `builder'.
+               // This pulls the condition name out of a Conditional attribute
+               //
+               public string Conditional_GetConditionName ()
+               {
+                       //
+                       // So we have a Conditional, pull the data out.
+                       //
+                       if (Arguments == null || Arguments [0] == null){
+                               Error_AttributeConstructorMismatch (Location);
+                               return null;
+                       }
+
+                       ArrayList pos_args = (ArrayList) Arguments [0];
+                       if (pos_args.Count != 1){
+                               Error_AttributeConstructorMismatch (Location);
+                               return null;
+                       }
+
+                       Argument arg = (Argument) pos_args [0]; 
+                       if (!(arg.Expr is StringConstant)){
+                               Error_AttributeConstructorMismatch (Location);
+                               return null;
+                       }
+
+                       return ((StringConstant) arg.Expr).Value;
+               }
+
+               //
+               // This pulls the obsolete message and error flag out of an Obsolete attribute
+               //
+               public string Obsolete_GetObsoleteMessage (out bool is_error)
+               {
+                       is_error = false;
+                       //
+                       // So we have an Obsolete, pull the data out.
+                       //
+                       if (Arguments == null || Arguments [0] == null)
+                               return "";
+
+                       ArrayList pos_args = (ArrayList) Arguments [0];
+                       if (pos_args.Count == 0)
+                               return "";
+                       else if (pos_args.Count > 2){
+                               Error_AttributeConstructorMismatch (Location);
+                               return null;
+                       }
+
+                       Argument arg = (Argument) pos_args [0]; 
+                       if (!(arg.Expr is StringConstant)){
+                               Error_AttributeConstructorMismatch (Location);
+                               return null;
+                       }
+
+                       if (pos_args.Count == 2){
+                               Argument arg2 = (Argument) pos_args [1];
+                               if (!(arg2.Expr is BoolConstant)){
+                                       Error_AttributeConstructorMismatch (Location);
+                                       return null;
+                               }
+                               is_error = ((BoolConstant) arg2.Expr).Value;
+                       }
+
+                       return ((StringConstant) arg.Expr).Value;
+               }
+
                //
+               // Applies the attributes to the `builder'.
+               //                                                                      
                public static void ApplyAttributes (EmitContext ec, object builder, object kind,
                                                    Attributes opt_attrs, Location loc)
                {
@@ -570,16 +662,17 @@ namespace Mono.CSharp {
                                                        return;
                                                }
 
-                                       if (kind is Method || kind is Operator || kind is InterfaceMethod) {
-
+                                       if (kind is Method || kind is Operator || kind is InterfaceMethod ||
+                                           kind is Accessor) {
                                                if (a.Type == TypeManager.methodimpl_attr_type) {
                                                        if (a.ImplOptions == MethodImplOptions.InternalCall)
-                                                               ((MethodBuilder) builder).SetImplementationFlags (
-                                                                          MethodImplAttributes.InternalCall |
-                                                                          MethodImplAttributes.Runtime);
-                                               } else if (a.Type != TypeManager.dllimport_type)
+                                                               ((MethodBuilder) builder).
+                                                               SetImplementationFlags (
+                                                                       MethodImplAttributes.InternalCall |
+                                                                       MethodImplAttributes.Runtime);
+                                               } else if (a.Type != TypeManager.dllimport_type){
                                                        ((MethodBuilder) builder).SetCustomAttribute (cb);
-
+                                               }
                                        } else if (kind is Constructor) {
                                                ((ConstructorBuilder) builder).SetCustomAttribute (cb);
                                        } else if (kind is Field) {
@@ -637,14 +730,30 @@ namespace Mono.CSharp {
                                                "\tMicrosoft .NET runtime");
                                                }
                                                
+                                       } else if (kind is Interface) {
+                                               Interface iface = (Interface) kind;
+
+                                               if ((a.Type == TypeManager.default_member_type) &&
+                                                   (iface.InterfaceIndexers != null)) {
+                                                       Report.Error (
+                                                               646, loc,
+                                                               "Cannot specify the DefaultMember attribute on" +
+                                                               " a type containing an indexer");
+                                                       return;
+                                               }
+
+                                               if (!CheckAttribute (a, kind)) {
+                                                       Error_AttributeNotValidForElement (a, loc);
+                                                       return;
+                                               }
+
+                                               ((TypeBuilder) builder).SetCustomAttribute (cb);
                                        } else if (kind is AssemblyBuilder){
                                                ((AssemblyBuilder) builder).SetCustomAttribute (cb);
                                        } else if (kind is ModuleBuilder) {
                                                ((ModuleBuilder) builder).SetCustomAttribute (cb);
                                        } else if (kind is FieldBuilder) {
                                                ((FieldBuilder) builder).SetCustomAttribute (cb);
-                                       } else if (kind is Accessor) {
-                                               ((MethodBuilder) builder).SetCustomAttribute (cb);
                                        } else
                                                throw new Exception ("Unknown kind: " + kind);
                                }
@@ -749,8 +858,11 @@ namespace Mono.CSharp {
                                }
                        }
 
+                       if (entry_point == null)
+                               entry_point = name;
+                       
                        MethodBuilder mb = builder.DefinePInvokeMethod (
-                               name, dll_name, flags | MethodAttributes.HideBySig,
+                               name, dll_name, entry_point, flags | MethodAttributes.HideBySig,
                                CallingConventions.Standard,
                                ret_type,
                                param_types,
@@ -761,8 +873,7 @@ namespace Mono.CSharp {
                                mb.SetImplementationFlags (MethodImplAttributes.PreserveSig);
                        
                        return mb;
-               }
-               
+               }                       
        }
        
        public class AttributeSection {
@@ -794,5 +905,22 @@ namespace Mono.CSharp {
                        if (a != null)
                                AttributeSections.Add (a);
                }
+               
+               public void AddAttributeSection (AttributeSection a)
+               {
+                       if (a != null && !AttributeSections.Contains (a))
+                               AttributeSections.Add (a);
+               }
+               
+               public bool Contains (Type t)
+               {
+                       foreach (AttributeSection attr_section in AttributeSections){
+                               foreach (Attribute a in attr_section.Attributes){
+                                       if (a.Type == t)
+                                               return true;
+                               }
+                       }
+                       return false;
+               }                       
        }
 }