New tests.
[mono.git] / mcs / class / corlib / System.Reflection.Emit / DerivedTypes.cs
index 37237f7ec826326d4d287869cd9163b1343c8a3a..04e7f3c9d70bad3e9f9b29346ae445e6c632ea1b 100644 (file)
@@ -34,6 +34,7 @@ using System.Runtime.CompilerServices;
 using System.Globalization;
 using System.Runtime.InteropServices;
 using System.Runtime.Serialization;
+using System.Text;
 
 
 namespace System.Reflection.Emit
@@ -45,20 +46,22 @@ namespace System.Reflection.Emit
 
        internal abstract class DerivedType : Type
        {
+               internal Type elementType;
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                internal static extern void create_unmanaged_type (Type type);
-       
-       }
 
-       internal class ArrayType : DerivedType
-       {
-               Type elementType;
-               int rank;
-
-               internal ArrayType (Type elementType, int rank)
+               internal DerivedType (Type elementType)
                {
                        this.elementType = elementType;
-                       this.rank = rank;
+               }
+
+               internal abstract String FormatName (string elementName);
+
+               internal override bool IsCompilerContext {
+                       get {
+                               return elementType.IsCompilerContext;
+                       }
                }
 
                public override Type GetInterface (string name, bool ignoreCase)
@@ -157,7 +160,7 @@ namespace System.Reflection.Emit
 
                protected override bool IsArrayImpl ()
                {
-                       return true;
+                       return false;
                }
 
                protected override bool IsByRefImpl ()
@@ -204,12 +207,15 @@ namespace System.Reflection.Emit
                        return false;
                }
 
-               public override int GetArrayRank ()
+               public override bool IsAssignableFrom (Type c)
                {
-                       return rank;
+                       return false;
+               }
+
+               public override bool ContainsGenericParameters {
+                       get { return elementType.ContainsGenericParameters; }
                }
 
-#if NET_2_0
                //FIXME this should be handled by System.Type
                public override Type MakeGenericType (params Type[] typeArguments)
                {
@@ -218,7 +224,7 @@ namespace System.Reflection.Emit
 
                public override Type MakeArrayType ()
                {
-                       return MakeArrayType (1);
+                       return new ArrayType (this, 0);
                }
 
                public override Type MakeArrayType (int rank)
@@ -230,14 +236,17 @@ namespace System.Reflection.Emit
 
                public override Type MakeByRefType ()
                {
-                       create_unmanaged_type (this);
-                       return base.MakeByRefType ();
+                       return new ByRefType (this);
                }
 
                public override Type MakePointerType ()
                {
-                       create_unmanaged_type (this);
-                       return base.MakePointerType ();
+                       return new PointerType (this);
+               }
+
+               public override string ToString ()
+               {
+                       return FormatName (elementType.ToString ());
                }
 
                public override GenericParameterAttributes GenericParameterAttributes {
@@ -247,27 +256,30 @@ namespace System.Reflection.Emit
                public override StructLayoutAttribute StructLayoutAttribute {
                        get { throw new NotSupportedException (); }
                }
-#endif
 
                public override Assembly Assembly {
                        get { return elementType.Assembly; }
                }
 
                public override string AssemblyQualifiedName {
-                       get { return FullName + ", " + elementType.Assembly.FullName; }
+                       get {
+                               string fullName = FormatName (elementType.FullName);
+                               if (fullName == null)
+                                       return null;
+                               return fullName + ", " + elementType.Assembly.FullName;
+                       }
                }
 
-               public override Type BaseType {
-                       get { return typeof (System.Array); }
-               }
 
                public override string FullName {
                        get {
-                               //FIXME use a StringBuilder
-                               String commas = "";
-                               for (int i = 1; i < rank; ++i)
-                                       commas += ",";
-                               return String.Format("{0}[{1}]", elementType.FullName, commas);
+                               return FormatName (elementType.FullName);
+                       }
+               }
+
+               public override string Name {
+                       get {
+                               return FormatName (elementType.Name);
                        }
                }
 
@@ -288,7 +300,10 @@ namespace System.Reflection.Emit
                }
 
                public override Type UnderlyingSystemType {
-                       get { return this; }
+                       get {
+                               create_unmanaged_type (this);
+                               return this;
+                       }
                }
 
                //MemberInfo
@@ -306,15 +321,142 @@ namespace System.Reflection.Emit
                {
                        throw new NotSupportedException ();
                }
+       }
 
-               public override string Name {
-                       get {
-                               //FIXME use a StringBuilder
-                               String commas = "";
-                               for (int i = 1; i < rank; ++i)
-                                       commas += ",";
-                               return String.Format("{0}[{1}]", elementType.Name, commas);
-                       }
+       internal class ArrayType : DerivedType
+       {
+               int rank;
+
+               internal ArrayType (Type elementType, int rank) : base (elementType)
+               {
+                       this.rank = rank;
+               }
+
+               internal int GetEffectiveRank ()
+               {
+                       return rank;
+               }
+
+               internal override Type InternalResolve ()
+               {
+                       Type et = elementType.InternalResolve (); 
+                       if (rank == 0)
+                               return et.MakeArrayType ();                     
+                       return et.MakeArrayType (rank);
+               }
+
+               protected override bool IsArrayImpl ()
+               {
+                       return true;
+               }
+
+               public override int GetArrayRank ()
+               {
+                       return (rank == 0) ? 1 : rank;
+               }
+
+               public override Type BaseType {
+                       get { return typeof (System.Array); }
+               }
+
+               protected override TypeAttributes GetAttributeFlagsImpl ()
+               {
+                       if (IsCompilerContext)
+                               return (elementType.Attributes & TypeAttributes.VisibilityMask) | TypeAttributes.Sealed | TypeAttributes.Serializable;
+                       return elementType.Attributes;
+               }
+
+               internal override String FormatName (string elementName)
+               {
+                       if (elementName == null)
+                               return null;
+                       StringBuilder sb = new StringBuilder (elementName);
+                       sb.Append ("[");
+                       for (int i = 1; i < rank; ++i)
+                               sb.Append (",");
+                       if (rank == 1)
+                               sb.Append ("*");
+                       sb.Append ("]");
+                       return sb.ToString ();
+               }
+       }
+
+
+       internal class ByRefType : DerivedType
+       {
+               internal ByRefType (Type elementType) : base (elementType)
+               {
+               }
+
+               internal override Type InternalResolve ()
+               {
+                       return elementType.InternalResolve ().MakeByRefType (); 
+               }
+
+               protected override bool IsByRefImpl ()
+               {
+                       return true;
+               }
+
+               public override Type BaseType {
+                       get { return typeof (Array); }
+               }
+
+               internal override String FormatName (string elementName)
+               {
+                       if (elementName == null)
+                               return null;
+                       return elementName + "&";
+               }
+
+               public override Type MakeArrayType ()
+               {
+                       throw new ArgumentException ("Cannot create an array type of a byref type");
+               }
+
+               public override Type MakeArrayType (int rank)
+               {
+                       throw new ArgumentException ("Cannot create an array type of a byref type");
+               }
+
+               public override Type MakeByRefType ()
+               {
+                       throw new ArgumentException ("Cannot create a byref type of an already byref type");
+               }
+
+               public override Type MakePointerType ()
+               {
+                       throw new ArgumentException ("Cannot create a pointer type of a byref type");
+               }
+       }
+
+
+       internal class PointerType : DerivedType
+       {
+               internal PointerType (Type elementType) : base (elementType)
+               {
+               }
+
+               internal override Type InternalResolve ()
+               {
+                       return elementType.InternalResolve ().MakePointerType (); 
+               }
+
+               protected override bool IsPointerImpl ()
+               {
+                       return true;
+               }
+
+               public override Type BaseType {
+                       get { return typeof(Array); }
+               }
+
+               internal override String FormatName (string elementName)
+               {
+                       if (elementName == null)
+                               return null;
+                       return elementName + "*";
                }
        }
+
 }