2005-07-13 Maverson Eduardo Schulze Rosa <maverson@gmail.com>
[mono.git] / mcs / mbas / pending.cs
index 82f8e3b84f67a9cc5961adf62d069ebbd656b50e..111b8d151f42d56df8e4b82d5813bdd72a9e3f69 100644 (file)
@@ -3,6 +3,7 @@
 //
 // Author:
 //   Miguel de Icaza (miguel@gnu.org)
+//   Anirban Bhattacharjee (banirban@novell.com)
 //
 // Licensed under the terms of the GNU GPL
 //
@@ -15,7 +16,7 @@ using System.Collections;
 using System.Reflection;
 using System.Reflection.Emit;
 
-namespace Mono.CSharp {
+namespace Mono.MonoBASIC {
 
        struct TypeAndMethods {
                public Type          type;
@@ -33,7 +34,7 @@ namespace Mono.CSharp {
 
                // If a method is defined here, then we always need to
                // create a proxy for it.  This is used when implementing
-               // an interface's indexer with a different IndexerName.
+               // an interface's indexer with a different DefaultPropName.
                public MethodInfo [] need_proxy;
        }
 
@@ -133,15 +134,14 @@ namespace Mono.CSharp {
                        if (ifaces != null){
                                foreach (Type t in ifaces){
                                        MethodInfo [] mi;
-
-                                       if (t is TypeBuilder){
+                                       /*if (t is TypeBuilder){
                                                Interface iface;
 
                                                iface = TypeManager.LookupInterface (t);
                                                
                                                mi = iface.GetMethods (container);
-                                       } else
-                                               mi = t.GetMethods ();
+                                       } else*/
+                                       mi = t.GetMethods ();
 
                                        int count = mi.Length;
                                        pending_implementations [i].type = t;
@@ -169,12 +169,12 @@ namespace Mono.CSharp {
                                abstract_methods.CopyTo (pending_implementations [i].methods, 0);
                                pending_implementations [i].found = new bool [count];
                                pending_implementations [i].args = new Type [count][];
-                               pending_implementations [i].type = type_builder;
+                               pending_implementations [i].type = type_builder.BaseType;
                                
                                int j = 0;
                                foreach (MemberInfo m in abstract_methods){
                                        MethodInfo mi = (MethodInfo) m;
-                                       
+
                                        Type [] types = TypeManager.GetArgumentTypes (mi);
                                        
                                        pending_implementations [i].args [j] = types;
@@ -206,6 +206,7 @@ namespace Mono.CSharp {
                        // TypeBuilder.
                        //
                        ifaces = type_builder.GetInterfaces ();
+
 #if DEBUG
                        {
                                Type x = type_builder;
@@ -221,9 +222,10 @@ namespace Mono.CSharp {
                                }
                        }
 #endif
-                                       
-                       icount = ifaces.Length;
 
+                       
+                       ifaces = TypeManager.ExpandInterfaces (ifaces);
+                       icount = ifaces.Length;
                        //
                        // If we are implementing an abstract class, and we are not
                        // ourselves abstract, and there are abstract methods (C# allows
@@ -260,12 +262,12 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Whether the specified method is an interface method implementation
                /// </summary>
-               public MethodInfo IsInterfaceMethod (Type t, string name, Type ret_type, Type [] args)
+               public MethodInfo IsAbstractMethod (Type t, string name, Type ret_type, Type [] args)
                {
                        return InterfaceMethod (t, name, ret_type, args, Operation.Lookup, null);
                }
 
-               public MethodInfo IsInterfaceIndexer (Type t, Type ret_type, Type [] args)
+               public MethodInfo IsAbstractIndexer (Type t, Type ret_type, Type [] args)
                {
                        return InterfaceMethod (t, null, ret_type, args, Operation.Lookup, null);
                }
@@ -295,7 +297,7 @@ namespace Mono.CSharp {
                ///   all the methods with the given signature.
                ///
                ///   The `MethodInfo need_proxy' is used when we're implementing an interface's
-               ///   indexer in a class.  If the new indexer's IndexerName does not match the one
+               ///   indexer in a class.  If the new indexer's DefaultPropName does not match the one
                ///   that was used in the interface, then we always need to create a proxy for it.
                ///
                /// </remarks>
@@ -364,8 +366,8 @@ namespace Mono.CSharp {
                                                // implementation and we can always clear the method.
                                                // `need_proxy' is not null if we're implementing an
                                                // interface indexer.  In this case, we need to create
-                                               // a proxy if the implementation's IndexerName doesn't
-                                               // match the IndexerName in the interface.
+                                               // a proxy if the implementation's DefaultPropName doesn't
+                                               // match the DefaultPropName in the interface.
                                                if ((t == null) && (need_proxy != null) && (name != m.Name))
                                                        tm.need_proxy [i] = need_proxy;
                                                else
@@ -433,6 +435,45 @@ namespace Mono.CSharp {
                        container.TypeBuilder.DefineMethodOverride (proxy, iface_method);
                }
                
+               static bool IsPropertyGetMethod (string m)
+               {
+                       return (m.Substring (0, 4) == "get_");  
+               }
+
+               static bool IsPropertySetMethod (string m)
+               {
+                       return (m.Substring (0, 4) == "set_");  
+               }
+
+               MethodInfo FindExplicitImplementation (string iface_name, string method_name)
+               {
+                       if (container.Properties != null) {
+                               foreach (Property p in container.Properties) 
+                               {
+                                       if (p.Implements != null) {                                     
+                                               if (IsPropertyGetMethod (method_name) && (container.Namespace.Name +  "." + p.Implements.ToString() == iface_name + "." + method_name.Substring(4))) 
+                                                               return p.PropertyBuilder.GetGetMethod(true);
+
+                                               if (IsPropertySetMethod (method_name) && (container.Namespace.Name +  "." + p.Implements.ToString() == iface_name + "." + method_name.Substring(4))) 
+                                                               return p.PropertyBuilder.GetSetMethod(true);
+                                       }
+                               }
+                       }
+
+                       if (container.Methods != null) 
+                       {
+                               foreach (Method m in container.Methods) 
+                               {
+                                       if (m.Implements != null) 
+                                       {                                       
+                                               if (container.Namespace.Name +  "." + m.Implements.ToString() == iface_name + "." + method_name)
+                                                       return (MethodInfo) m.MethodBuilder;
+                                       }
+                               }
+                       }
+                       return null;
+               }
+
                /// <summary>
                ///   This function tells whether one of our parent classes implements
                ///   the given method (which turns out, it is valid to have an interface
@@ -441,19 +482,27 @@ namespace Mono.CSharp {
                bool ParentImplements (Type iface_type, MethodInfo mi)
                {
                        MethodSignature ms;
+                       MethodInfo mr;
                        
                        Type [] args = TypeManager.GetArgumentTypes (mi);
+
                        ms = new MethodSignature (mi.Name, mi.ReturnType, args);
                        MemberList list = TypeContainer.FindMembers (
                                container.TypeBuilder.BaseType, MemberTypes.Method | MemberTypes.Property,
                                BindingFlags.Public | BindingFlags.Instance,
                                MethodSignature.method_signature_filter, ms);
 
-                       if (list.Count == 0)
-                               return false;
+                       if (list.Count == 0) 
+                       {
+                               mr = FindExplicitImplementation (iface_type.ToString(), mi.Name);
+                               if (mr == null)
+                                       return false;
+                       }
+                       else
+                               mr = (MethodInfo) list[0];
 
-                       DefineProxy (iface_type, (MethodInfo) list [0], mi, args);
-                       return true;
+                       DefineProxy (iface_type, mr, mi, args);
+                       return true;                                            
                }
 
                /// <summary>
@@ -498,9 +547,9 @@ namespace Mono.CSharp {
                                                        type.FullName + "." + mi.Name + "'" + extra);
                                        } else {
                                                Report.Error (
-                                                       534, container.Location,
+                                                       30610, container.Location,
                                                        "`" + container.Name + "' does not implement " +
-                                                       "inherited abstract member `" +
+                                                       "inherited 'MustOverride' member `" +
                                                        type.FullName + "." + mi.Name + "'");
                                        }
                                        errors = true;