2005-05-31 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / mcs / enum.cs
old mode 100755 (executable)
new mode 100644 (file)
index b40a23e..f2ed451
@@ -24,23 +24,27 @@ namespace Mono.CSharp {
                public FieldBuilder builder;
                internal readonly Expression Type;
 
-               public EnumMember (Enum parent_enum, Expression expr, string name, Location loc, Attributes attrs):
-                       base (null, name, attrs, loc)
+               public EnumMember (Enum parent_enum, Expression expr, string name,
+                                  Location loc, Attributes attrs):
+                       base (null, new MemberName (name), attrs, loc)
                {
                        this.parent_enum = parent_enum;
                        this.ModFlags = parent_enum.ModFlags;
                        this.Type = expr;
                }
 
-               public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
                {
                        if (a.Type == TypeManager.marshal_as_attr_type) {
-                               UnmanagedMarshal marshal = a.GetMarshal ();
+                               UnmanagedMarshal marshal = a.GetMarshal (this);
                                if (marshal != null) {
                                        builder.SetMarshal (marshal);
-                                       return;
                                }
-                               Report.Warning (-24, a.Location, "The Microsoft Runtime cannot set this marshal info. Please use the Mono runtime instead.");
+                               return;
+                       }
+
+                       if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
+                               a.Error_InvalidSecurityParent ();
                                return;
                        }
 
@@ -68,8 +72,6 @@ namespace Mono.CSharp {
 
                public void Emit (EmitContext ec)
                {
-                       base.Emit ();
-
                        if (OptAttributes != null)
                                OptAttributes.Emit (ec, this); 
 
@@ -98,13 +100,17 @@ namespace Mono.CSharp {
                protected override void VerifyObsoleteAttribute()
                {
                }
+
+               public override string DocCommentHeader {
+                       get { return "F:"; }
+               }
        }
 
        /// <summary>
        ///   Enumeration container
        /// </summary>
        public class Enum : DeclSpace {
-               ArrayList ordered_enums;
+               public ArrayList ordered_enums;
                
                public Expression BaseType;
                
@@ -131,8 +137,8 @@ namespace Mono.CSharp {
                        Modifiers.INTERNAL |
                        Modifiers.PRIVATE;
 
-               public Enum (NamespaceEntry ns, TypeContainer parent, Expression type, int mod_flags,
-                            string name, Attributes attrs, Location l)
+               public Enum (NamespaceEntry ns, TypeContainer parent, Expression type,
+                            int mod_flags, MemberName name, Attributes attrs, Location l)
                        : base (ns, parent, name, attrs, l)
                {
                        this.BaseType = type;
@@ -150,7 +156,7 @@ namespace Mono.CSharp {
                ///   Adds @name to the enumeration space, with @expr
                ///   being its definition.  
                /// </summary>
-               public void AddEnumMember (string name, Expression expr, Location loc, Attributes opt_attrs)
+               public void AddEnumMember (string name, Expression expr, Location loc, Attributes opt_attrs, string documentation)
                {
                        if (name == "value__") {
                                Report.Error (76, loc, "An item in an enumeration can't have an identifier `value__'");
@@ -158,7 +164,8 @@ namespace Mono.CSharp {
                        }
 
                        EnumMember em = new EnumMember (this, expr, name, loc, opt_attrs);
-                       if (!AddToContainer (em, false, name, ""))
+                       em.DocComment = documentation;
+                       if (!AddToContainer (em, name))
                                return;
 
 
@@ -166,47 +173,14 @@ namespace Mono.CSharp {
                        ordered_enums.Add (name);
                        member_to_location.Add (name, loc);
                }
-
-               //
-               // This is used by corlib compilation: we map from our
-               // type to a type that is consumable by the DefineField
-               //
-               Type MapToInternalType (Type t)
-               {
-                       if (t == TypeManager.int32_type)
-                               return typeof (int);
-                       if (t == TypeManager.int64_type)
-                               return typeof (long);
-                       if (t == TypeManager.uint32_type)
-                               return typeof (uint);
-                       if (t == TypeManager.uint64_type)
-                               return typeof (ulong);
-                       if (t == TypeManager.float_type)
-                               return typeof (float);
-                       if (t == TypeManager.double_type)
-                               return typeof (double);
-                       if (t == TypeManager.byte_type)
-                               return typeof (byte);
-                       if (t == TypeManager.sbyte_type)
-                               return typeof (sbyte);
-                       if (t == TypeManager.char_type)
-                               return typeof (char);
-                       if (t == TypeManager.short_type)
-                               return typeof (short);
-                       if (t == TypeManager.ushort_type)
-                               return typeof (ushort);
-
-                       throw new Exception ();
-               }
                
                public override TypeBuilder DefineType ()
                {
                        if (TypeBuilder != null)
                                return TypeBuilder;
 
-                       TypeAttributes attr = Modifiers.TypeAttr (ModFlags, IsTopLevel);
-
-                       attr |= TypeAttributes.Class | TypeAttributes.Sealed;
+                       ec = new EmitContext (this, this, Location, null, null, ModFlags, false);
+                       ec.InEnumContext = true;
 
                        if (!(BaseType is TypeLookupExpression)) {
                                Report.Error (1008, Location,
@@ -215,7 +189,8 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       UnderlyingType = ResolveType (BaseType, false, Location);
+                       TypeExpr ute = ResolveBaseTypeExpr (BaseType, false, Location);
+                       UnderlyingType = ute.Type;
 
                        if (UnderlyingType != TypeManager.int32_type &&
                            UnderlyingType != TypeManager.uint32_type &&
@@ -238,14 +213,16 @@ namespace Mono.CSharp {
                                
                                ModuleBuilder builder = CodeGen.Module.Builder;
 
-                               TypeBuilder = builder.DefineType (Name, attr, TypeManager.enum_type);
+                               TypeBuilder = builder.DefineType (Name, TypeAttr, TypeManager.enum_type);
                        } else {
                                TypeBuilder builder = Parent.TypeBuilder;
 
                                TypeBuilder = builder.DefineNestedType (
-                                       Basename, attr, TypeManager.enum_type);
+                                       Basename, TypeAttr, TypeManager.enum_type);
                        }
 
+                       ec.ContainerType = TypeBuilder;
+
                        //
                        // Call MapToInternalType for corlib
                        //
@@ -471,19 +448,14 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               //
-               // Horrible, horrible.  But there is no other way we can pass the EmitContext
-               // to the recursive definition triggered by the evaluation of a forward
-               // expression
-               //
-               static EmitContext current_ec = null;
-               
                /// <summary>
                ///  This is used to lookup the value of an enum member. If the member is undefined,
                ///  it attempts to define it and return its value
                /// </summary>
-               public object LookupEnumValue (EmitContext ec, string name, Location loc)
+               public object LookupEnumValue (string name, Location loc)
                {
+                       if (ec == null)
+                               Report.Error (-1, loc, "Enum.LookupEnumValue () called too soon");
                        
                        object default_value = null;
                        Constant c = null;
@@ -524,14 +496,7 @@ namespace Mono.CSharp {
                                                Location m_loc = (Mono.CSharp.Location)
                                                        member_to_location [n];
                                                in_transit.Add (name, true);
-
-                                               EmitContext old_ec = current_ec;
-                                               current_ec = ec;
-                       
-                                               default_value = LookupEnumValue (ec, n, m_loc);
-
-                                               current_ec = old_ec;
-                                               
+                                               default_value = LookupEnumValue (n, m_loc);
                                                in_transit.Remove (name);
                                                if (default_value == null)
                                                        return null;
@@ -541,17 +506,9 @@ namespace Mono.CSharp {
                                }
                                
                        } else {
-                               bool old = ec.InEnumContext;
-                               ec.InEnumContext = true;
                                in_transit.Add (name, true);
-
-                               EmitContext old_ec = current_ec;
-                               current_ec = ec;
-                               val = val.Resolve (ec);
-                               current_ec = old_ec;
-                               
+                               val = val.Resolve (EmitContext);
                                in_transit.Remove (name);
-                               ec.InEnumContext = old;
 
                                if (val == null)
                                        return null;
@@ -616,9 +573,8 @@ namespace Mono.CSharp {
                        if (TypeBuilder == null)
                                return false;
 
-                       EmitContext ec = new EmitContext (this, this, Location, null,
-                                                         UnderlyingType, ModFlags, false);
-
+                       if (ec == null)
+                               throw new InternalErrorException ("Enum.Define () called too soon");
                        
                        object default_value = 0;
                        
@@ -633,7 +589,7 @@ namespace Mono.CSharp {
                                Location loc = (Mono.CSharp.Location) member_to_location [name];
 
                                if (this [name] != null) {
-                                       default_value = LookupEnumValue (ec, name, loc);
+                                       default_value = LookupEnumValue (name, loc);
 
                                        if (default_value == null)
                                                return true;
@@ -677,9 +633,6 @@ namespace Mono.CSharp {
 
                public override void Emit ()
                {
-                       EmitContext ec = new EmitContext (
-                               Parent, this, Location, null, null, ModFlags, false);
-
                        if (OptAttributes != null) {
                                OptAttributes.Emit (ec, this);
                        }
@@ -722,14 +675,6 @@ namespace Mono.CSharp {
                        return true;
                }
                
-               /// <summary>
-               /// Returns full enum name.
-               /// </summary>
-               string GetEnumeratorName (string valueName)
-               {
-                       return String.Concat (Name, ".", valueName);
-               }
-
                //
                // IMemberFinder
                //
@@ -739,10 +684,8 @@ namespace Mono.CSharp {
                        ArrayList members = new ArrayList ();
 
                        if ((mt & MemberTypes.Field) != 0) {
-                               if (criteria is string){
-                                       if (member_to_value [criteria] == null && current_ec != null){
-                                               LookupEnumValue (current_ec, (string) criteria, Location.Null);
-                                       }
+                               if (criteria is string && member_to_value [criteria] == null) {
+                                       LookupEnumValue ((string) criteria, Location.Null);
                                }
                                
                                foreach (FieldBuilder fb in field_builders)
@@ -778,9 +721,34 @@ namespace Mono.CSharp {
                        }
                }
 
+               protected override TypeAttributes TypeAttr {
+                       get {
+                               return Modifiers.TypeAttr (ModFlags, IsTopLevel) |
+                               TypeAttributes.Class | TypeAttributes.Sealed |
+                               base.TypeAttr;
+                       }
+               }
+
+
                protected override void VerifyObsoleteAttribute()
                {
                        // UnderlyingType is never obsolete
                }
+
+               //
+               // Generates xml doc comments (if any), and if required,
+               // handle warning report.
+               //
+               internal override void GenerateDocComment (DeclSpace ds)
+               {
+                       DocUtil.GenerateEnumDocComment (this, ds);
+               }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "T:"; }
+               }
        }
 }