2004-08-02 Martin Baulig <martin@ximian.com>
[mono.git] / mcs / gmcs / generic.cs
index 48d7810f89b25dce92ed89963cd3d38c463b5549..a055cb3b940d22198ec873232f44cf9ff5861cb7 100644 (file)
@@ -136,14 +136,6 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public TypeExpr[] InterfaceConstraints {
-                       get {
-                               TypeExpr[] ifaces = new TypeExpr [iface_constraints.Count];
-                               iface_constraints.CopyTo (ifaces, 0);
-                               return ifaces;
-                       }
-               }
-
                public bool ResolveTypes (EmitContext ec)
                {
                        iface_constraint_types = new Type [iface_constraints.Count];
@@ -295,12 +287,10 @@ namespace Mono.CSharp {
                public void Define (GenericTypeParameterBuilder type)
                {
                        this.type = type;
-                       TypeExpr[] ifaces = null;
-                       if (constraints != null) {
-                               ifaces = constraints.InterfaceConstraints;
+                       Type[] ifaces = null;
+                       if (constraints != null)
                                constraints.Define (type);
-                       }
-                       TypeManager.AddTypeParameter (type, this, ifaces);
+                       TypeManager.AddTypeParameter (type, this);
                }
 
                public bool DefineType (EmitContext ec)
@@ -315,6 +305,7 @@ namespace Mono.CSharp {
                                        type.SetBaseTypeConstraint (gc.ClassConstraint);
 
                                type.SetInterfaceConstraints (gc.InterfaceConstraints);
+                               TypeManager.RegisterBuilder (type, gc.InterfaceConstraints);
                        }
 
                        return true;
@@ -500,7 +491,7 @@ namespace Mono.CSharp {
                        bool ok = true;
 
                        atypes = new Type [count];
-                       
+
                        for (int i = 0; i < count; i++){
                                TypeExpr te = ds.ResolveTypeExpr (
                                        (Expression) args [i], false, Location);
@@ -603,6 +594,32 @@ namespace Mono.CSharp {
                        }
                }
 
+               protected bool CheckConstraint (EmitContext ec, Type ptype, Expression expr,
+                                               Type ctype)
+               {
+                       if (TypeManager.HasGenericArguments (ctype)) {
+                               Type[] types = TypeManager.GetTypeArguments (ctype);
+
+                               TypeArguments new_args = new TypeArguments (loc);
+
+                               for (int i = 0; i < types.Length; i++) {
+                                       Type t = types [i];
+
+                                       if (t.IsGenericParameter) {
+                                               int pos = t.GenericParameterPosition;
+                                               t = args.Arguments [pos];
+                                       }
+                                       new_args.Add (new TypeExpression (t, loc));
+                               }
+
+                               ctype = new ConstructedType (ctype, new_args, loc).ResolveType (ec);
+                               if (ctype == null)
+                                       return false;
+                       }
+
+                       return Convert.ImplicitStandardConversionExists (expr, ctype);
+               }
+
                protected bool CheckConstraints (EmitContext ec, int index)
                {
                        Type atype = atypes [index];
@@ -642,7 +659,7 @@ namespace Mono.CSharp {
                        // The class constraint comes next.
                        //
                        if ((parent != null) && (parent != TypeManager.object_type)) {
-                               if (!Convert.ImplicitStandardConversionExists (aexpr, parent)) {
+                               if (!CheckConstraint (ec, ptype, aexpr, parent)) {
                                        Report.Error (309, loc, "The type `{0}' must be " +
                                                      "convertible to `{1}' in order to " +
                                                      "use it as parameter `{2}' in the " +
@@ -655,12 +672,8 @@ namespace Mono.CSharp {
                        //
                        // Now, check the interface constraints.
                        //
-                       foreach (TypeExpr iface in TypeManager.GetInterfaces (ptype)) {
-                               Type itype = iface.ResolveType (ec);
-                               if (itype == null)
-                                       return false;
-
-                               if (!Convert.ImplicitStandardConversionExists (aexpr, itype)) {
+                       foreach (Type itype in TypeManager.GetInterfaces (ptype)) {
+                               if (!CheckConstraint (ec, ptype, aexpr, itype)) {
                                        Report.Error (309, loc, "The type `{0}' must be " +
                                                      "convertible to `{1}' in order to " +
                                                      "use it as parameter `{2}' in the " +
@@ -820,12 +833,6 @@ namespace Mono.CSharp {
                        get { return false; }
                }
 
-               public override TypeExpr[] GetInterfaces ()
-               {
-                       TypeExpr[] ifaces = TypeManager.GetInterfaces (gt);
-                       return ifaces;
-               }
-
                public override bool Equals (object obj)
                {
                        ConstructedType cobj = obj as ConstructedType;
@@ -840,7 +847,7 @@ namespace Mono.CSharp {
 
                public string Basename {
                        get {
-                               int pos = name.LastIndexOf ('!');
+                               int pos = name.LastIndexOf ('`');
                                if (pos >= 0)
                                        return name.Substring (0, pos);
                                else
@@ -867,18 +874,18 @@ namespace Mono.CSharp {
                        throw new Exception ();
                }
 
-               public override bool Define (TypeContainer parent)
+               public override bool Define ()
                {
                        for (int i = 0; i < TypeParameters.Length; i++)
-                               if (!TypeParameters [i].Resolve (parent))
+                               if (!TypeParameters [i].Resolve (Parent))
                                        return false;
 
                        return true;
                }
 
-               public bool Define (TypeContainer parent, MethodBuilder mb)
+               public bool Define (MethodBuilder mb)
                {
-                       if (!Define (parent))
+                       if (!Define ())
                                return false;
 
                        GenericTypeParameterBuilder[] gen_params;