//
// Author:
// Miguel de Icaza (miguel@gnu.org)
+// Anirban Bhattacharjee (banirban@novell.com)
//
// Licensed under the terms of the GNU GPL
//
using System.Reflection;
using System.Reflection.Emit;
-namespace Mono.CSharp {
+namespace Mono.MonoBASIC {
struct TypeAndMethods {
public Type type;
// 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;
}
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;
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;
// TypeBuilder.
//
ifaces = type_builder.GetInterfaces ();
+
#if DEBUG
{
Type x = type_builder;
}
}
#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
/// <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);
}
/// 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>
// 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
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
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>
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;