diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 760f5e357..2c6e0464b 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -258,6 +258,7 @@ CPP_TEST_CASES += \ mixed_types \ multiple_inheritance \ multiple_inheritance_abstract \ + multiple_inheritance_interfaces \ name_cxx \ name_warnings \ namespace_class \ diff --git a/Examples/test-suite/java/multiple_inheritance_interfaces_runme.java b/Examples/test-suite/java/multiple_inheritance_interfaces_runme.java new file mode 100644 index 000000000..0d3a7106c --- /dev/null +++ b/Examples/test-suite/java/multiple_inheritance_interfaces_runme.java @@ -0,0 +1,61 @@ +import multiple_inheritance_interfaces.*; +import java.util.Arrays; + +public class multiple_inheritance_interfaces_runme { + + static { + try { + System.loadLibrary("multiple_inheritance_interfaces"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + private static void checkBaseAndInterfaces(Class cls, boolean interfaceExpected, String base, String[] interfaces) { + String[] expectedInterfaces = new String[interfaces.length]; + for (int i=0; i %s\n", interface_list); Delete(keys); } diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 9508bc28a..da39d6f65 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -3630,21 +3630,38 @@ static void collect_interface_methods(Node *n, List *methods) { } } +/* ----------------------------------------------------------------------------- + * collect_interface_bases + * ----------------------------------------------------------------------------- */ + static void collect_interface_bases(Hash *bases, Node *n) { if (Getattr(n, "feature:interface")) { String *name = Getattr(n, "feature:interface:name"); - if (Getattr(bases, name)) - return; - Setattr(bases, name, n); + if (!Getattr(bases, name)) + Setattr(bases, name, n); } + if (List *baselist = Getattr(n, "bases")) { - for (Iterator base = First(baselist); base.item; base = Next(base)) - if (!GetFlag(base.item, "feature:ignore")) - collect_interface_bases(bases, base.item); + for (Iterator base = First(baselist); base.item; base = Next(base)) { + if (!GetFlag(base.item, "feature:ignore")) { + if (Getattr(base.item, "feature:interface")) + collect_interface_bases(bases, base.item); + } + } } } -static void Swig_collect_interface_bases(Node *n) { +/* ----------------------------------------------------------------------------- + * collect_and_set_interface_bases() + * + * Create a hash containing all the classes up the inheritance hierarchy + * marked with feature:interface (including this class n). + * Stops going up the inheritance chain as soon as a class is found without + * feature:interface. + * The idea is to find all the base interfaces that a class must implement. + * ----------------------------------------------------------------------------- */ + +static void collect_and_set_interface_bases(Node *n) { Hash *interface_bases = NewHash(); collect_interface_bases(interface_bases, n); if (Len(interface_bases) == 0) @@ -3655,7 +3672,7 @@ static void Swig_collect_interface_bases(Node *n) { // Append all the interface methods not implemented in the current class, so that it would not be abstract void Swig_propagate_interface_methods(Node *n) { - Swig_collect_interface_bases(n); + collect_and_set_interface_bases(n); List *methods = NewList(); collect_interface_methods(n, methods); bool is_interface = Getattr(n, "feature:interface") != 0;