2003-04-17 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / interface.cs
index 58323c0bd2f964901069e08a829a6a4bebc040fb..f47a91c35f8d9f6c860ba1cea92ac17fc38baee5 100755 (executable)
@@ -7,7 +7,7 @@
 //
 // (C) 2001 Ximian, Inc (http://www.ximian.com)
 //
-
+#define CACHE
 using System.Collections;
 using System;
 using System.IO;
@@ -19,7 +19,7 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Interfaces
        /// </summary>
-       public class Interface : DeclSpace {
+       public class Interface : DeclSpace, IMemberContainer {
                const MethodAttributes interface_method_attributes =
                        MethodAttributes.Public |
                        MethodAttributes.Abstract |
@@ -44,9 +44,17 @@ namespace Mono.CSharp {
 
                ArrayList method_builders;
                ArrayList property_builders;
+               ArrayList event_builders;
                
                Attributes OptAttributes;
 
+               public string IndexerName;
+
+               IMemberContainer parent_container;
+               MemberCache member_cache;
+
+               bool members_defined;
+
                // These will happen after the semantic analysis
                
                // Hashtable defined_indexers;
@@ -71,6 +79,7 @@ namespace Mono.CSharp {
                        
                        method_builders = new ArrayList ();
                        property_builders = new ArrayList ();
+                       event_builders = new ArrayList ();
                }
 
                public AdditionResult AddMethod (InterfaceMethod imethod)
@@ -221,9 +230,22 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public MethodInfo [] GetMethods ()
+               //
+               // This might trigger a definition of the methods.  This happens only
+               // with Attributes, as Attribute classes are processed before interfaces.
+               // Ideally, we should make everything just define recursively in terms
+               // of its dependencies.
+               //
+               public MethodInfo [] GetMethods (TypeContainer container)
                {
-                       int n = method_builders.Count;
+                       int n = 0;
+                       
+                       if (!members_defined){
+                               if (DefineMembers (container))
+                                       n = method_builders.Count;
+                       } else
+                               n = method_builders.Count;
+                       
                        MethodInfo [] mi = new MethodInfo [n];
                        
                        method_builders.CopyTo (mi, 0);
@@ -232,7 +254,8 @@ namespace Mono.CSharp {
                }
 
                // Hack around System.Reflection as found everywhere else
-               public MemberInfo [] FindMembers (MemberTypes mt, BindingFlags bf, MemberFilter filter, object criteria)
+               public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
+                                                       MemberFilter filter, object criteria)
                {
                        ArrayList members = new ArrayList ();
 
@@ -248,35 +271,39 @@ namespace Mono.CSharp {
                                                members.Add (pb);
                        }
 
-                       if ((bf & BindingFlags.DeclaredOnly) == 0){
-                               MemberInfo [] parent_mi;
+                       if ((mt & MemberTypes.Event) != 0) {
+                               foreach (MyEventBuilder eb in event_builders)
+                                       if (filter (eb, criteria))
+                                               members.Add (eb);
+                       }
+
+                       if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
+                               MemberList parent_mi;
                                
                                parent_mi = TypeContainer.FindMembers (
                                        TypeBuilder.BaseType, mt, bf, filter, criteria);
 
-                               if (parent_mi != null)
-                                       members.AddRange (parent_mi);
+                               members.AddRange (parent_mi);
                        }
-                       
-                       // The rest of the cases, if any, are unhandled at present.
 
-                       int count = members.Count;
+                       return new MemberList (members);
+               }
 
-                       if (count > 0) {
-                               MemberInfo [] mi = new MemberInfo [count];
-                               members.CopyTo (mi, 0);
-                               return mi;
+               public override MemberCache MemberCache {
+                       get {
+                               return member_cache;
                        }
-
-                       return null;
                }
 
                //
                // Populates the methods in the interface
                //
-               void PopulateMethod (InterfaceMethod im)
+               void PopulateMethod (TypeContainer parent, DeclSpace decl_space, InterfaceMethod im)
                {
-                       Type return_type = RootContext.LookupType (this, im.ReturnType, false, im.Location);
+                       Type return_type = im.ReturnType.Type;
+                       if (return_type == null)
+                               return_type = this.ResolveType (im.ReturnType, false, im.Location);
+                       
                        Type [] arg_types = im.ParameterTypes (this);
                        MethodBuilder mb;
                        Parameter [] p;
@@ -288,6 +315,9 @@ namespace Mono.CSharp {
                        if (return_type.IsPointer && !UnsafeOK (this))
                                return;
 
+                       if (arg_types == null)
+                               return;
+
                        foreach (Type t in arg_types){
 
                                if (t == null)
@@ -305,7 +335,7 @@ namespace Mono.CSharp {
                                return_type, arg_types);
 
                        InternalParameters ip = new InternalParameters (arg_types, im.Parameters);
-                       
+
                        if (!RegisterMethod (mb, ip, arg_types)) {
                                Error111 (im);
                                return;
@@ -323,16 +353,26 @@ namespace Mono.CSharp {
                                if (i != arg_types.Length)
                                        Console.WriteLine ("Implement the type definition for params");
                        }
+
+                       EmitContext ec = new EmitContext (parent, decl_space, Location, null,
+                                                         return_type, ModFlags, false);
+
+                       if (im.OptAttributes != null)
+                               Attribute.ApplyAttributes (ec, mb, im, im.OptAttributes);
                }
 
                //
                // Populates the properties in the interface
                //
-               void PopulateProperty (InterfaceProperty ip)
+               void PopulateProperty (TypeContainer parent, DeclSpace decl_space, InterfaceProperty ip)
                {
                        PropertyBuilder pb;
                        MethodBuilder get = null, set = null;
-                       Type prop_type = RootContext.LookupType (this, ip.Type, false, ip.Location);
+                       ip.Type = this.ResolveTypeExpr (ip.Type, false, ip.Location);
+                       if (ip.Type == null)
+                               return;
+                       
+                       Type prop_type = ip.Type.Type;
                        Type [] setter_args = new Type [1];
 
                        if (prop_type == null)
@@ -361,7 +401,7 @@ namespace Mono.CSharp {
                                //
                                Type [] null_types = null;
                                InternalParameters inp = new InternalParameters
-                                       (null_types, Parameters.GetEmptyReadOnlyParameters ());
+                                       (null_types, Parameters.EmptyReadOnlyParameters);
                                
                                if (!RegisterMethod (get, inp, null)) {
                                        Error111 (ip);
@@ -395,6 +435,12 @@ namespace Mono.CSharp {
                                }
                        }
 
+                       EmitContext ec = new EmitContext (parent, decl_space, Location, null,
+                                                         null, ModFlags, false);
+
+                       if (ip.OptAttributes != null)
+                               Attribute.ApplyAttributes (ec, pb, ip, ip.OptAttributes);
+
                        TypeManager.RegisterProperty (pb, get, set);
                        property_builders.Add (pb);
                }
@@ -402,21 +448,85 @@ namespace Mono.CSharp {
                //
                // Populates the events in the interface
                //
-               void PopulateEvent (InterfaceEvent ie)
+               void PopulateEvent (TypeContainer parent, DeclSpace decl_space, InterfaceEvent ie)
                {
                        //
                        // FIXME: We need to do this after delegates have been
                        // declared or we declare them recursively.
                        //
+                       MyEventBuilder eb;
+                       MethodBuilder add = null, remove = null;
+                       ie.Type = this.ResolveTypeExpr (ie.Type, false, ie.Location);
+                       if (ie.Type == null)
+                               return;
+                       
+                       Type event_type = ie.Type.Type;
+
+                       if (event_type == null)
+                               return;
+
+                       if (event_type.IsPointer && !UnsafeOK (this))
+                               return;
+
+                       Type [] parameters = new Type [1];
+                       parameters [0] = event_type;
+
+                       eb = new MyEventBuilder (null, TypeBuilder, ie.Name,
+                                                EventAttributes.None, event_type);
+
+                       //
+                       // Now define the accessors
+                       //
+                       string add_name = "add_" + ie.Name;
+                       
+                       add = TypeBuilder.DefineMethod (
+                               add_name, property_attributes, null, parameters);
+                       add.DefineParameter (1, ParameterAttributes.None, "value");
+                       eb.SetAddOnMethod (add);
+
+                       string remove_name = "remove_" + ie.Name;
+                       remove = TypeBuilder.DefineMethod (
+                               remove_name, property_attributes, null, parameters);
+                       remove.DefineParameter (1, ParameterAttributes.None, "value");
+                       eb.SetRemoveOnMethod (remove);
+
+                       Parameter [] parms = new Parameter [1];
+                       parms [0] = new Parameter (ie.Type, "value", Parameter.Modifier.NONE, null);
+                       InternalParameters ip = new InternalParameters (
+                               this, new Parameters (parms, null, Location.Null));
+
+                       if (!RegisterMethod (add, ip, parameters)) {
+                               Error111 (ie);
+                               return;
+                       }
+                       
+                       if (!RegisterMethod (remove, ip, parameters)) {
+                               Error111 (ie);
+                               return;
+                       }
+
+                       EmitContext ec = new EmitContext (parent, decl_space, Location, null,
+                                                         null, ModFlags, false);
+
+
+                       if (ie.OptAttributes != null)
+                               Attribute.ApplyAttributes (ec, eb, ie, ie.OptAttributes);
+
+                       TypeManager.RegisterEvent (eb, add, remove);
+                       event_builders.Add (eb);
                }
 
                //
                // Populates the indexers in the interface
                //
-               void PopulateIndexer (InterfaceIndexer ii)
+               void PopulateIndexer (TypeContainer parent, DeclSpace decl_space, InterfaceIndexer ii)
                {
                        PropertyBuilder pb;
-                       Type prop_type = RootContext.LookupType (this, ii.Type, false, ii.Location);
+                       ii.Type = this.ResolveTypeExpr (ii.Type, false, ii.Location);
+                       if (ii.Type == null)
+                               return;
+                       
+                       Type prop_type = ii.Type.Type;
                        Type [] arg_types = ii.ParameterTypes (this);
                        Type [] value_arg_types;
 
@@ -446,16 +556,24 @@ namespace Mono.CSharp {
                                value_arg_types [1] = prop_type;
                        }
 
+                       EmitContext ec = new EmitContext (parent, decl_space, Location, null,
+                                                         null, ModFlags, false);
+
+                       IndexerName = Attribute.ScanForIndexerName (ec, ii.OptAttributes);
+                       if (IndexerName == null)
+                               IndexerName = "Item";
+                       
                        pb = TypeBuilder.DefineProperty (
-                               "Item", PropertyAttributes.None,
+                               IndexerName, PropertyAttributes.None,
                                prop_type, arg_types);
-
+                       
+                       MethodBuilder set_item = null, get_item = null;
                        if (ii.HasGet){
-                               MethodBuilder get_item;
                                Parameter [] p = ii.Parameters.FixedParameters;
                                
                                get_item = TypeBuilder.DefineMethod (
-                                       "get_Item", property_attributes, prop_type, arg_types);
+                                       "get_" + IndexerName, property_attributes,
+                                       prop_type, arg_types);
                                pb.SetGetMethod (get_item);
                                //
                                // HACK because System.Reflection.Emit is lame
@@ -478,18 +596,24 @@ namespace Mono.CSharp {
 
                        if (ii.HasSet){
                                Parameter [] p = ii.Parameters.FixedParameters;
-                               MethodBuilder set_item;
+                               Parameter [] pv;
                                int i = 0;
                                
+                               pv = new Parameter [p.Length + 1];
+                               p.CopyTo (pv, 0);
+                               pv [p.Length] = new Parameter (ii.Type, "value", Parameter.Modifier.NONE, null);
+                               Parameters value_params = new Parameters (pv, null, Location.Null);
+                               value_params.GetParameterInfo (decl_space);
+                               
                                set_item = TypeBuilder.DefineMethod (
-                                       "set_Item", property_attributes,
+                                       "set_" + IndexerName, property_attributes,
                                        TypeManager.void_type, value_arg_types);
                                pb.SetSetMethod (set_item);
                                //
                                // HACK because System.Reflection.Emit is lame
                                //
                                InternalParameters ip = new InternalParameters (
-                                       value_arg_types, ii.Parameters);
+                                       value_arg_types, value_params);
                                if (!RegisterMethod (set_item, ip, value_arg_types)) {
                                        Error111 (ii);
                                        return;
@@ -504,6 +628,11 @@ namespace Mono.CSharp {
                                
                                set_item.DefineParameter (i + 1, ParameterAttributes.None, "value");
                        }
+
+                       if (ii.OptAttributes != null)
+                               Attribute.ApplyAttributes (ec, pb, ii, ii.OptAttributes);
+
+                       property_builders.Add (pb);
                }
 
                /// <summary>
@@ -538,137 +667,31 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               //
-               // Returns the Type that represents the interface whose name
-               // is `name'.
-               //
-               
-               Type LookupInterfaceByName (string ns, string name, out bool error)
+               Type GetInterfaceTypeByName (string name)
                {
-                       Interface parent;
-                       Type t;
+                       Type t = FindType (Location, name);
 
-                       error = false;
-                       name = TypeContainer.MakeFQN (ns, name);
-                       t = TypeManager.LookupType (name);
-                       
-                       if (t != null) {
-                               if (t.IsInterface)
-                                       return t;
-                               
-                               string cause;
-                               
-                               if (t.IsValueType)
-                                       cause = "is a struct";
-                               else if (t.IsClass) 
-                                       cause = "is a class";
-                               else
-                                       cause = "Should not happen.";
-
-                               error = true;
-                               Report.Error (527, Location, "`"+name+"' " + cause +
-                                             ", need an interface instead");
-                               
+                       if (t == null) {
+                               Report.Error (246, Location, "The type or namespace `" + name +
+                                             "' could not be found");
                                return null;
                        }
-
-                       Tree tree = RootContext.Tree;
-                       parent = (Interface) tree.Interfaces [name];
-                       if (parent == null)
-                               return null;
                        
-                       t = parent.DefineInterface ();
-                       if (t == null){
-                               Report.Error (529,
-                                             "Inherited interface `"+name+"' is circular");
-                               error = true;
-                               return null;
-                       }
-
-                       return t;
-               }
-
-               Type GetInterfaceTypeByName (string name)
-               {
-                       //
-                       // For the case the type we are looking for is nested within this one
-                       // or is in any base class
-                       //
-                       DeclSpace containing_ds = this;
-                       bool error = false;
-                       Type t;
-                       
-                       while (containing_ds != null){
-                               Type current_type = containing_ds.TypeBuilder;
-
-                               while (current_type != null) {
-                                       string pre = current_type.FullName;
-                                       
-                                       t = LookupInterfaceByName (pre, name, out error);
-                                       if (error)
-                                               return null;
+                       if (t.IsInterface)
+                               return t;
                                
-                                       if (t != null) 
-                                               return t;
-
-                                       current_type = current_type.BaseType;
-                               }
-                               containing_ds = containing_ds.Parent;
-                       }
-
-                       //
-                       // Attempt to lookup the class on our namespace and all it's implicit parents
-                       //
-                       for (string ns = Namespace.Name; ns != null; ns = RootContext.ImplicitParent (ns)){
-                               t = LookupInterfaceByName (ns, name, out error);
-                               if (error)
-                                       return null;
-                               if (t != null)
-                                       return t;
-                       }
-
-                       //
-                       // Attempt to do a direct unqualified lookup
-                       //
-                       t = LookupInterfaceByName ("", name, out error);
-                       if (error)
-                               return null;
+                       string cause;
                        
-                       if (t != null)
-                               return t;
+                       if (t.IsValueType)
+                               cause = "is a struct";
+                       else if (t.IsClass) 
+                               cause = "is a class";
+                       else
+                               cause = "Should not happen.";
+                       
+                       Report.Error (527, Location, "`"+name+"' " + cause +
+                                     ", need an interface instead");
                        
-                       //
-                       // Attempt to lookup the class on any of the `using'
-                       // namespaces
-                       //
-
-                       for (Namespace ns = Namespace; ns != null; ns = ns.Parent){
-                               t = LookupInterfaceByName (ns.Name, name, out error);
-                               if (error)
-                                       return null;
-
-                               if (t != null)
-                                       return t;
-
-                               //
-                               // Now check the using clause list
-                               //
-                               ArrayList using_list = ns.UsingTable;
-                               
-                               if (using_list == null)
-                                       continue;
-
-                               foreach (string n in using_list){
-                                       t = LookupInterfaceByName (n, name, out error);
-                                       if (error)
-                                               return null;
-
-                                       if (t != null)
-                                               return t;
-                               }
-                       }
-
-                       Report.Error (246, Location, "Can not find type `"+name+"'");
                        return null;
                }
                
@@ -692,29 +715,37 @@ namespace Mono.CSharp {
 
                        foreach (string name in Bases){
                                Type t;
-                               
+
                                t = GetInterfaceTypeByName (name);
                                if (t == null){
                                        error = true;
                                        return null;
                                }
-                               
+
+                               if (!Parent.AsAccessible (t, ModFlags))
+                                       Report.Error (61, Location,
+                                                     "Inconsistent accessibility: base interface `" +
+                                                     TypeManager.CSharpName (t) + "' is less " +
+                                                     "accessible than interface `" +
+                                                     Name + "'");
+
                                tbases [i++] = t;
                        }
                        
-                       return tbases;
+                       return TypeManager.ExpandInterfaces (tbases);
                }
                
                //
                // <summary>
                //  Defines the Interface in the appropriate ModuleBuilder or TypeBuilder
                // </summary>
+               //
                // TODO:
                //   Rework the way we recurse, because for recursive
                //   definitions of interfaces (A:B and B:A) we report the
                //   error twice, rather than once.  
                
-               public TypeBuilder DefineInterface ()
+               public override TypeBuilder DefineType ()
                {
                        Type [] ifaces;
                        bool error;
@@ -733,7 +764,7 @@ namespace Mono.CSharp {
                                return null;
 
                        if (IsTopLevel) {
-                               ModuleBuilder builder = RootContext.ModuleBuilder;
+                               ModuleBuilder builder = CodeGen.ModuleBuilder;
 
                                TypeBuilder = builder.DefineType (
                                        Name,
@@ -753,47 +784,109 @@ namespace Mono.CSharp {
                                TypeContainer tc = TypeManager.LookupTypeContainer (builder);
                                tc.RegisterOrder (this);
                        }
-                       
-                       TypeManager.AddUserInterface (Name, TypeBuilder, this);
+
+                       TypeManager.AddUserInterface (Name, TypeBuilder, this, ifaces);
                        InTransit = false;
-                       
+
                        return TypeBuilder;
                }
+
+               //
+               // Defines the indexers, and also verifies that the IndexerNameAttribute in the
+               // interface is consistent.  Either it is `Item' or it is the name defined by all the
+               // indexers with the `IndexerName' attribute.
+               //
+               // Turns out that the IndexerNameAttribute is applied to each indexer,
+               // but it is never emitted, instead a DefaultName attribute is attached
+               // to the interface
+               //
+               void DefineIndexers (TypeContainer parent)
+               {
+                       string interface_indexer_name = null;
+
+                       foreach (InterfaceIndexer ii in defined_indexer){
+
+                               PopulateIndexer (parent, this, ii);
+
+                               if (interface_indexer_name == null){
+                                       interface_indexer_name = IndexerName;
+                                       continue;
+                               }
+                               
+                               if (IndexerName == interface_indexer_name)
+                                       continue;
+                               
+                               Report.Error (
+                                       668, "Two indexers have different names, " +
+                                       " you should use the same name for all your indexers");
+                       }
+                       if (interface_indexer_name == null)
+                               interface_indexer_name = "Item";
+                       IndexerName = interface_indexer_name;
+               }
                
                /// <summary>
                ///   Performs semantic analysis, and then generates the IL interfaces
                /// </summary>
-               public override bool Define (TypeContainer parent)
+               public override bool DefineMembers (TypeContainer parent)
                {
+                       if (members_defined)
+                               return true;
+                       
                        if (!SemanticAnalysis ())
                                return false;
 
+                       
                        if (defined_method != null){
                                foreach (InterfaceMethod im in defined_method)
-                                       PopulateMethod (im);
+                                       PopulateMethod (parent, this, im);
                        }
 
                        if (defined_properties != null){
                                foreach (InterfaceProperty ip in defined_properties)
-                                       PopulateProperty (ip);
+                                       PopulateProperty (parent, this, ip);
                        }
 
                        if (defined_events != null)
                                foreach (InterfaceEvent ie in defined_events)
-                                       PopulateEvent (ie);
+                                       PopulateEvent (parent, this, ie);
 
                        if (defined_indexer != null) {
-                               foreach (InterfaceIndexer ii in defined_indexer)
-                                       PopulateIndexer (ii);
+                               DefineIndexers (parent);
+
+                               CustomAttributeBuilder cb = EmitDefaultMemberAttr (
+                                       parent, IndexerName, ModFlags, Location);
+                               if (cb != null)
+                                       TypeBuilder.SetCustomAttribute (cb);
+                       }
 
-                               CustomAttributeBuilder cb = EmitDefaultMemberAttr (parent, ModFlags, Location);
-                               TypeBuilder.SetCustomAttribute (cb);
+#if CACHE
+                       if (TypeBuilder.BaseType != null)
+                               parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
+
+                       member_cache = new MemberCache (this);
+#endif
+                       members_defined = true;
+                       return true;
+               }
+
+               /// <summary>
+               ///   Applies all the attributes.
+               /// </summary>
+               public override bool Define (TypeContainer parent)
+               {
+                       if (OptAttributes != null) {
+                               EmitContext ec = new EmitContext (parent, this, Location, null, null,
+                                                                 ModFlags, false);
+                               Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes);
                        }
-                       
+
                        return true;
                }
 
-               public static CustomAttributeBuilder EmitDefaultMemberAttr (TypeContainer parent, int flags,
+               public static CustomAttributeBuilder EmitDefaultMemberAttr (TypeContainer parent,
+                                                                           string name,
+                                                                           int flags,
                                                                            Location loc)
                {
                        EmitContext ec = new EmitContext (parent, loc, null, null, flags);
@@ -812,13 +905,73 @@ namespace Mono.CSharp {
 
                        MethodBase constructor = mg.Methods [0];
 
-                       string [] vals = { "Item" };
+                       string [] vals = { name };
 
-                       CustomAttributeBuilder cb = new CustomAttributeBuilder ((ConstructorInfo) constructor, vals);
+                       CustomAttributeBuilder cb = null;
+                       try {
+                               cb = new CustomAttributeBuilder ((ConstructorInfo) constructor, vals);
+                       } catch {
+                               Report.Warning (-100, "Can not set the indexer default member attribute");
+                       }
 
                        return cb;
                }
 
+               //
+               // IMemberContainer
+               //
+
+               string IMemberContainer.Name {
+                       get {
+                               return Name;
+                       }
+               }
+
+               Type IMemberContainer.Type {
+                       get {
+                               return TypeBuilder;
+                       }
+               }
+
+               IMemberContainer IMemberContainer.Parent {
+                       get {
+                               return parent_container;
+                       }
+               }
+
+               MemberCache IMemberContainer.MemberCache {
+                       get {
+                               return member_cache;
+                       }
+               }
+
+               bool IMemberContainer.IsInterface {
+                       get {
+                               return true;
+                       }
+               }
+
+               MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
+               {
+                       // Interfaces only contain instance members.
+                       if ((bf & BindingFlags.Instance) == 0)
+                               return MemberList.Empty;
+                       if ((bf & BindingFlags.Public) == 0)
+                               return MemberList.Empty;
+
+                       ArrayList members = new ArrayList ();
+
+                       if ((mt & MemberTypes.Method) != 0)
+                               members.AddRange (method_builders);
+
+                       if ((mt & MemberTypes.Property) != 0)
+                               members.AddRange (property_builders);
+
+                       if ((mt & MemberTypes.Event) != 0)
+                               members.AddRange (event_builders);
+
+                       return new MemberList (members);
+               }
        }
 
        public class InterfaceMemberBase {
@@ -837,11 +990,10 @@ namespace Mono.CSharp {
        public class InterfaceProperty : InterfaceMemberBase {
                public readonly bool HasSet;
                public readonly bool HasGet;
-               public readonly string Type;
-               public readonly string type;
                public readonly Location Location;
+               public Expression Type;
                
-               public InterfaceProperty (string type, string name,
+               public InterfaceProperty (Expression type, string name,
                                          bool is_new, bool has_get, bool has_set,
                                          Attributes attrs, Location loc)
                        : base (name, is_new, attrs)
@@ -854,21 +1006,24 @@ namespace Mono.CSharp {
        }
 
        public class InterfaceEvent : InterfaceMemberBase {
-               public readonly string Type;
+               public readonly Location Location;
+               public Expression Type;
                
-               public InterfaceEvent (string type, string name, bool is_new, Attributes attrs)
+               public InterfaceEvent (Expression type, string name, bool is_new, Attributes attrs,
+                                      Location loc)
                        : base (name, is_new, attrs)
                {
                        Type = type;
+                       Location = loc;
                }
        }
        
        public class InterfaceMethod : InterfaceMemberBase {
-               public readonly string     ReturnType;
+               public Expression ReturnType;
                public readonly Parameters Parameters;
                public readonly Location Location;
                
-               public InterfaceMethod (string return_type, string name, bool is_new, Parameters args,
+               public InterfaceMethod (Expression return_type, string name, bool is_new, Parameters args,
                                        Attributes attrs, Location l)
                        : base (name, is_new, attrs)
                {
@@ -882,7 +1037,11 @@ namespace Mono.CSharp {
                /// </summary>
                public string GetSignature (DeclSpace ds)
                {
-                       Type ret = RootContext.LookupType (ds, ReturnType, false, Location);
+                       ReturnType = ds.ResolveTypeExpr (ReturnType, false, Location);
+                       if (ReturnType == null)
+                               return null;
+                       
+                       Type ret = ReturnType.Type;
                        string args = Parameters.GetSignature (ds);
 
                        if ((ret == null) || (args == null))
@@ -900,10 +1059,10 @@ namespace Mono.CSharp {
        public class InterfaceIndexer : InterfaceMemberBase {
                public readonly bool HasGet, HasSet;
                public readonly Parameters Parameters;
-               public readonly string Type;
                public readonly Location Location;
+               public Expression Type;
                
-               public InterfaceIndexer (string type, Parameters args, bool do_get, bool do_set,
+               public InterfaceIndexer (Expression type, Parameters args, bool do_get, bool do_set,
                                         bool is_new, Attributes attrs, Location loc)
                        : base ("", is_new, attrs)
                {