// Loop on all interface methods...
int mcount = mono_class_get_method_count (ic);
for (im_index = 0; im_index < mcount; im_index++) {
- gboolean foundOverrideInClassOrParent = FALSE;
MonoMethod *im = ic->methods [im_index];
int im_slot = ic_offset + im->slot;
MonoMethod *override_im = (override_map != NULL) ? (MonoMethod *)g_hash_table_lookup (override_map, im) : NULL;
TRACE_INTERFACE_VTABLE (printf ("\tchecking iface method %s\n", mono_method_full_name (im,1)));
- int cm_index;
- MonoMethod *cm;
-
- // First look for a suitable method among the class methods
- for (l = virt_methods; l; l = l->next) {
- cm = (MonoMethod *)l->data;
- TRACE_INTERFACE_VTABLE (printf (" For slot %d ('%s'.'%s':'%s'), trying method '%s'.'%s':'%s'... [EXPLICIT IMPLEMENTATION = %d][SLOT IS NULL = %d]", im_slot, ic->name_space, ic->name, im->name, cm->klass->name_space, cm->klass->name, cm->name, interface_is_explicitly_implemented_by_class, (vtable [im_slot] == NULL)));
- if (check_interface_method_override (klass, im, cm, TRUE, interface_is_explicitly_implemented_by_class, (vtable [im_slot] == NULL))) {
- TRACE_INTERFACE_VTABLE (printf ("[check ok]: ASSIGNING"));
- vtable [im_slot] = cm;
- foundOverrideInClassOrParent = TRUE;
- /* Why do we need this? */
- if (cm->slot < 0) {
- cm->slot = im_slot;
- }
- if (conflict_map)
- g_hash_table_remove(conflict_map, im);
- }
- TRACE_INTERFACE_VTABLE (printf ("\n"));
- if (mono_class_has_failure (klass)) /*Might be set by check_interface_method_override*/
- goto fail;
- }
-
- // If the slot is still empty, look in all the inherited virtual methods...
- if ((vtable [im_slot] == NULL) && klass->parent != NULL) {
- MonoClass *parent = klass->parent;
- // Reverse order, so that last added methods are preferred
- for (cm_index = parent->vtable_size - 1; cm_index >= 0; cm_index--) {
- cm = parent->vtable [cm_index];
-
- TRACE_INTERFACE_VTABLE ((cm != NULL) && printf (" For slot %d ('%s'.'%s':'%s'), trying (ancestor) method '%s'.'%s':'%s'... ", im_slot, ic->name_space, ic->name, im->name, cm->klass->name_space, cm->klass->name, cm->name));
- if ((cm != NULL) && check_interface_method_override (klass, im, cm, FALSE, FALSE, TRUE)) {
- TRACE_INTERFACE_VTABLE (printf ("[everything ok]: ASSIGNING"));
+ if (override_im == NULL || (override_im && MONO_CLASS_IS_INTERFACE_INTERNAL(override_im->klass))) {
+ int cm_index;
+ MonoMethod *cm;
+
+ // First look for a suitable method among the class methods
+ for (l = virt_methods; l; l = l->next) {
+ cm = (MonoMethod *)l->data;
+ TRACE_INTERFACE_VTABLE (printf (" For slot %d ('%s'.'%s':'%s'), trying method '%s'.'%s':'%s'... [EXPLICIT IMPLEMENTATION = %d][SLOT IS NULL = %d]", im_slot, ic->name_space, ic->name, im->name, cm->klass->name_space, cm->klass->name, cm->name, interface_is_explicitly_implemented_by_class, (vtable [im_slot] == NULL)));
+ if (check_interface_method_override (klass, im, cm, TRUE, interface_is_explicitly_implemented_by_class, (vtable [im_slot] == NULL))) {
+ TRACE_INTERFACE_VTABLE (printf ("[check ok]: ASSIGNING"));
vtable [im_slot] = cm;
- foundOverrideInClassOrParent = TRUE;
/* Why do we need this? */
if (cm->slot < 0) {
cm->slot = im_slot;
if (mono_class_has_failure (klass)) /*Might be set by check_interface_method_override*/
goto fail;
}
- }
+
+ // If the slot is still empty, look in all the inherited virtual methods...
+ if ((vtable [im_slot] == NULL) && klass->parent != NULL) {
+ MonoClass *parent = klass->parent;
+ // Reverse order, so that last added methods are preferred
+ for (cm_index = parent->vtable_size - 1; cm_index >= 0; cm_index--) {
+ MonoMethod *cm = parent->vtable [cm_index];
+
+ TRACE_INTERFACE_VTABLE ((cm != NULL) && printf (" For slot %d ('%s'.'%s':'%s'), trying (ancestor) method '%s'.'%s':'%s'... ", im_slot, ic->name_space, ic->name, im->name, cm->klass->name_space, cm->klass->name, cm->name));
+ if ((cm != NULL) && check_interface_method_override (klass, im, cm, FALSE, FALSE, TRUE)) {
+ TRACE_INTERFACE_VTABLE (printf ("[everything ok]: ASSIGNING"));
+ vtable [im_slot] = cm;
+ /* Why do we need this? */
+ if (cm->slot < 0) {
+ cm->slot = im_slot;
+ }
+ break;
+ }
+ if (mono_class_has_failure (klass)) /*Might be set by check_interface_method_override*/
+ goto fail;
+ TRACE_INTERFACE_VTABLE ((cm != NULL) && printf ("\n"));
+ }
+ }
- if (vtable [im_slot] == NULL) {
- if (!(im->flags & METHOD_ATTRIBUTE_ABSTRACT)) {
- TRACE_INTERFACE_VTABLE (printf (" Using default iface method %s.\n", mono_method_full_name (im, 1)));
- vtable [im_slot] = im;
+ if (vtable [im_slot] == NULL) {
+ if (!(im->flags & METHOD_ATTRIBUTE_ABSTRACT)) {
+ TRACE_INTERFACE_VTABLE (printf (" Using default iface method %s.\n", mono_method_full_name (im, 1)));
+ vtable [im_slot] = im;
+ }
}
- }
-
- if (override_im != NULL && !foundOverrideInClassOrParent)
+ } else {
g_assert (vtable [im_slot] == override_im);
+ }
}
}
--- /dev/null
+using System;
+
+public interface I1
+{
+ int M1()
+ {
+ return 100;
+ }
+}
+
+public interface I2 : I1 { int I1.M1() { return 200; } }
+
+public interface I3 : I1 { int I1.M1() { return 300; } }
+
+public interface I4 : I1 { int I1.M1() { return 400; } }
+
+class Test10 : I1, I2, I3, I4 {
+ //void I1.M1() { System.Console.WriteLine("I1.I1.M1"); }
+ public int M1() { return 0; }
+}
+
+public interface I1t
+{
+ int M1t()
+ {
+ return 100;
+ }
+}
+
+public interface I2t : I1t { int I1t.M1t() { return 200; } }
+
+public interface I3t : I1t { int I1t.M1t() { return 300; } }
+
+public interface I4t : I1t { int I1t.M1t() { return 400; } }
+
+class Test10t : I1t, I2t, I3t, I4t
+{
+ int I1t.M1t() { return 0; }
+ public int M1t() { return 10; }
+}
+
+
+public interface IName
+{
+ string Name { get; }
+}
+public interface IOther<T>
+{
+ T other { get; }
+ string Name { get; }
+}
+public class Name1 : IName
+{
+ public string Name { get { return "ClassName"; } }
+ string IName.Name { get { return "InterfaceName"; } }
+}
+public class Name2 : IName, IOther<int>
+{
+ public string Name { get { return "ClassName"; } }
+ string IName.Name { get { return "InterfaceName"; } }
+ public int other { get { return 43; } }
+}
+
+public class Test
+{
+ public static int test_0_override()
+ {
+ var name1 = new Name1();
+ var name2 = new Name2();
+ IName iName1 = name1;
+ IName iName2 = name2;
+ if (!iName1.Name.Equals("InterfaceName"))
+ return 10;
+ if (!iName2.Name.Equals("InterfaceName"))
+ return 20;
+ if (!name1.Name.Equals("ClassName"))
+ return 30;
+ if (!name2.Name.Equals("ClassName"))
+ return 40;
+ return 0;
+ }
+
+ public static int test_0_dim_override()
+ {
+ I1 var = new Test10();
+ if (var.M1() != 0)
+ return var.M1();
+
+ I1t var2 = new Test10t();
+ return var2.M1t();
+ }
+
+ public static int Main (string[] args) {
+ return TestDriver.RunTests (typeof (Test), args);
+ }
+
+}