Merge branch 'interfaces' into interfaces2

* interfaces:
  Remove unnecessary interfaces for concrete classes
  cosmetic code formatting changes
  Correct interface name attributes that are internal
  interface macro changes to support templates
  Test non-virtual method in Derived classes
  interface tests for a most derived class inheriting the interfaces further up the chain
  Rename GetCPtr/getCPtr to SWIGInterfaceUpcast
  interface feature support for const ref pointers (used by the STL)
  Interface feature support for arrays
  More interface feature testing for return values
  interface feature support for passing by value
  interface feature support for references
  Multiple inheritance parameters as pointers testing
  Simplify multiple_inheritance_abstract Java runtime test
  Warning fixes
  Rename test functions in multiple_inheritance_abstract testcase
  Formatting fixes in generated code for interface feature
  Cosmetic spacing changes in test case
  interface feature typemap corrections to handle NULL pointers
  interface test added
  javadirectorin fix
  interface implementation visibility
  interface inheritance (2)
  interface inheritance (1)
  feature:interface ported to Java
  propagate non-abstract "interface" base methods (3)
  propagate non-abstract "interface" base methods (2)
  propagate non-abstract "interface" base methods (1)
  namespace support added GetCPtr now returns HandleRef "feature:interface:name" is now mandatory attribute
  interfaces (1)
  interfaces (1)

Conflicts:
	Source/Modules/csharp.cxx
	Source/Modules/java.cxx
This commit is contained in:
William S Fulton 2016-02-11 19:37:31 +00:00
commit abccc13a4a
11 changed files with 1166 additions and 39 deletions

View file

@ -282,6 +282,8 @@ CPP_TEST_CASES += \
minherit2 \
mixed_types \
multiple_inheritance \
multiple_inheritance_abstract \
multiple_inheritance_interfaces \
name_cxx \
name_warnings \
namespace_class \

View file

@ -38,7 +38,8 @@ CPP_TEST_CASES = \
java_prepost \
java_throws \
java_typemaps_proxy \
java_typemaps_typewrapper
java_typemaps_typewrapper \
multiple_inheritance_abstract
# li_boost_intrusive_ptr
CPP11_TEST_CASES = \

View file

@ -0,0 +1,253 @@
import multiple_inheritance_abstract.*;
public class multiple_inheritance_abstract_runme {
static {
try {
System.loadLibrary("multiple_inheritance_abstract");
} 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);
}
}
//Test base class as a parameter in java
int jcbase1b(CBase1 cb1){
return cb1.cbase1y();
}
int jabase1(ABase1 ab1){
return ab1.abase1();
}
int jcbase2(CBase2 cb2){
return cb2.cbase2();
}
public static void check(boolean fail, String msg) {
if (fail)
throw new RuntimeException(msg);
}
public static void main(String argv[]) {
//Test Derived1
Derived1 d1=new Derived1();
check(d1.cbase1y()!=3, "Derived1::cbase1y() failed in multiple_inheritance_abstract");
check(d1.cbase2()!=4, "Derived1::cbase2() failed in multiple_inheritance_abstract");
//Test Derived2
Derived2 d2=new Derived2();
check(d2.cbase1y()!=6, "Derived2::cbase1y() failed in multiple_inheritance_abstract");
check(d2.abase1()!=5, "Derived2::abase1() failed in multiple_inheritance_abstract");
//Test Derived3
Derived3 d3=new Derived3();
check(d3.cbase1y()!=7, "Derived3::cbase1y() failed in multiple_inheritance_abstract");
check(d3.cbase2()!=8, "Derived3::cbase2() failed in multiple_inheritance_abstract");
check(d3.abase1()!=9, "Derived3::abase1() failed in multiple_inheritance_abstract");
//Test Bottom1
Bottom1 b1=new Bottom1();
check(b1.cbase1y()!=103, "Bottom1::cbase1y() failed");
check(b1.cbase2()!=104, "Bottom1::cbase2() failed");
//Test Bottom2
Bottom2 b2=new Bottom2();
check(b2.cbase1y()!=206, "Bottom2::cbase1y() failed");
check(b2.abase1()!=205, "Bottom2::abase1() failed");
//Test Bottom3
Bottom3 b3=new Bottom3();
check(b3.cbase1y()!=307, "Bottom3::cbase1y() failed");
check(b3.cbase2()!=308, "Bottom3::cbase2() failed");
check(b3.abase1()!=309, "Bottom3::abase1() failed");
//Test interfaces from c++ classes
CBase1 cb1=new SWIGTYPE_CBase1();
CBase2 cb2=new SWIGTYPE_CBase2();
check(cb1.cbase1y()!=1, "CBase1::cbase1y() failed in multiple_inheritance_abstract");
check(cb2.cbase2()!=2, "CBase2::cbase2() failed in multiple_inheritance_abstract");
//Test abstract class as return value
ABase1 ab1=d3.clone();
check(ab1.abase1()!=9, "Derived3::abase1() through ABase1 failed in multiple_inheritance_abstract");
//Test concrete base class as return value
CBase1 cb6=d2.clone();
CBase2 cb7=d1.clone();
check(cb6.cbase1y()!=6, "Derived2::cbase1y() through CBase1 failed in multiple_inheritance_abstract");
check(cb7.cbase2()!=4, "Derived1:cbase2() through ABase1 failed in multiple_inheritance_abstract");
//Test multi inheritance
CBase1 cb3=new Derived1();
CBase1 cb4=new Derived3();
CBase2 cb5=new Derived3();
ABase1 ab6=new Derived2();
check(cb3.cbase1y()!=3, "Derived1::cbase1y() through CBase1 failed in multiple_inheritance_abstract");
check(cb4.cbase1y()!=7, "Derived3::cbase1y() through CBase1 failed in multiple_inheritance_abstract");
check(cb5.cbase2()!=8, "Derived3::cbase2() through CBase2 failed in multiple_inheritance_abstract");
check(ab6.abase1()!=5, "Derived2::abase1() through ABase1 failed in multiple_inheritance_abstract");
//Test base classes as parameter in java
multiple_inheritance_abstract_runme mhar=new multiple_inheritance_abstract_runme();
check(mhar.jcbase1b(d1)!=3, "jcbase1b() through Derived1 as parameter failed in multiple_inheritance_abstract");
check(mhar.jcbase1b(d2)!=6, "jcbase1b() through Derived2 as parameter failed in multiple_inheritance_abstract");
check(mhar.jcbase1b(d3)!=7, "jcbase1b() through Derived3 as parameter failed in multiple_inheritance_abstract");
check(mhar.jcbase2(d1)!=4, "jcbase2() through Derived1 as parameter failed in multiple_inheritance_abstract");
check(mhar.jcbase2(d3)!=8, "jcbase2() through Derived3 as parameter failed in multiple_inheritance_abstract");
check(mhar.jabase1(d2)!=5, "jabase1() through Derived2 as parameter failed in multiple_inheritance_abstract");
check(mhar.jabase1(d3)!=9, "jabase1() through Derived3 as parameter failed in multiple_inheritance_abstract");
//Value parameters
//Test CBase1 CBase2 as parameters (note slicing for Derived and Bottom classes)
check(multiple_inheritance_abstract.InputValCBase1(d1)!=1, "InputValCBase1(), Derived1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputValCBase1(d2)!=1, "InputValCBase1(), Derived2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputValCBase1(d3)!=1, "InputValCBase1(), Derived3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputValCBase2(d3)!=2, "InputValCBase2(), Derived3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputValCBase2(d1)!=2, "InputValCBase2(), Derived1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputValCBase1(cb1)!=1, "InputValCBase1(), CBase1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputValCBase2(cb2)!=2, "InputValCBase2(), CBase2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputValCBase1(b1)!=1, "InputValCBase1(), Bottom1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputValCBase1(b2)!=1, "InputValCBase1(), Bottom2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputValCBase1(b3)!=1, "InputValCBase1(), Bottom3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputValCBase2(b3)!=2, "InputValCBase2(), Bottom3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputValCBase2(b1)!=2, "InputValCBase2(), Bottom1 as a parameter failed in multiple_inheritance_abstract");
//Pointer parameters
//Test ABase1 as a parameter
check(multiple_inheritance_abstract.InputPtrABase1(d2)!=5, "InputPtrABase1() through Derived2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrABase1(d3)!=9, "InputPtrABase1() through Derived3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrABase1(b2)!=205, "InputPtrABase1() through Bottom2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrABase1(b3)!=309, "InputPtrABase1() through Bottom3 as a parameter failed in multiple_inheritance_abstract");
//Test CBase1 CBase2 as parameters
check(multiple_inheritance_abstract.InputPtrCBase1(d1)!=3, "InputPtrCBase1(), Derived1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrCBase1(d2)!=6, "InputPtrCBase1(), Derived2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrCBase1(d3)!=7, "InputPtrCBase1(), Derived3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrCBase2(d3)!=8, "InputPtrCBase2(), Derived3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrCBase2(d1)!=4, "InputPtrCBase2(), Derived1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrCBase1(cb1)!=1, "InputPtrCBase1(), CBase1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrCBase2(cb2)!=2, "InputPtrCBase2(), CBase2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrCBase1(b1)!=103, "InputPtrCBase1(), Bottom1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrCBase1(b2)!=206, "InputPtrCBase1(), Bottom2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrCBase1(b3)!=307, "InputPtrCBase1(), Bottom3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrCBase2(b3)!=308, "InputPtrCBase2(), Bottom3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputPtrCBase2(b1)!=104, "InputPtrCBase2(), Bottom1 as a parameter failed in multiple_inheritance_abstract");
//Reference parameters
//Test ABase1 as a parameter
check(multiple_inheritance_abstract.InputRefABase1(d2)!=5, "InputRefABase1() through Derived2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefABase1(d3)!=9, "InputRefABase1() through Derived3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefABase1(b2)!=205, "InputRefABase1() through Bottom2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefABase1(b3)!=309, "InputRefABase1() through Bottom3 as a parameter failed in multiple_inheritance_abstract");
//Test CBase1 CBase2 as parameters
check(multiple_inheritance_abstract.InputRefCBase1(d1)!=3, "InputRefCBase1(), Derived1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefCBase1(d2)!=6, "InputRefCBase1(), Derived2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefCBase1(d3)!=7, "InputRefCBase1(), Derived3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefCBase2(d3)!=8, "InputRefCBase2(), Derived3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefCBase2(d1)!=4, "InputRefCBase2(), Derived1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefCBase1(cb1)!=1, "InputRefCBase1(), CBase1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefCBase2(cb2)!=2, "InputRefCBase2(), CBase2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefCBase1(b1)!=103, "InputRefCBase1(), Bottom1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefCBase1(b2)!=206, "InputRefCBase1(), Bottom2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefCBase1(b3)!=307, "InputRefCBase1(), Bottom3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefCBase2(b3)!=308, "InputRefCBase2(), Bottom3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputRefCBase2(b1)!=104, "InputRefCBase2(), Bottom1 as a parameter failed in multiple_inheritance_abstract");
//Const reference pointer parameters
//Test ABase1 as a parameter
check(multiple_inheritance_abstract.InputCPtrRefABase1(d2)!=5, "InputCPtrRefABase1() through Derived2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefABase1(d3)!=9, "InputCPtrRefABase1() through Derived3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefABase1(b2)!=205, "InputCPtrRefABase1() through Bottom2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefABase1(b3)!=309, "InputCPtrRefABase1() through Bottom3 as a parameter failed in multiple_inheritance_abstract");
//Test CBase1 CBase2 as parameters
check(multiple_inheritance_abstract.InputCPtrRefCBase1(d1)!=3, "InputCPtrRefCBase1(), Derived1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefCBase1(d2)!=6, "InputCPtrRefCBase1(), Derived2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefCBase1(d3)!=7, "InputCPtrRefCBase1(), Derived3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefCBase2(d3)!=8, "InputCPtrRefCBase2(), Derived3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefCBase2(d1)!=4, "InputCPtrRefCBase2(), Derived1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefCBase1(cb1)!=1, "InputCPtrRefCBase1(), CBase1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefCBase2(cb2)!=2, "InputCPtrRefCBase2(), CBase2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefCBase1(b1)!=103, "InputCPtrRefCBase1(), Bottom1 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefCBase1(b2)!=206, "InputCPtrRefCBase1(), Bottom2 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefCBase1(b3)!=307, "InputCPtrRefCBase1(), Bottom3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefCBase2(b3)!=308, "InputCPtrRefCBase2(), Bottom3 as a parameter failed in multiple_inheritance_abstract");
check(multiple_inheritance_abstract.InputCPtrRefCBase2(b1)!=104, "InputCPtrRefCBase2(), Bottom1 as a parameter failed in multiple_inheritance_abstract");
//Derived classes as parameters
check(multiple_inheritance_abstract.InputValDerived1(d1)!=3+4, "InputValDerived1() failed");
check(multiple_inheritance_abstract.InputValDerived2(d2)!=6+5, "InputValDerived2() failed");
check(multiple_inheritance_abstract.InputValDerived3(d3)!=7+8+9, "InputValDerived3() failed");
check(multiple_inheritance_abstract.InputRefDerived1(d1)!=3+4, "InputRefDerived1() failed");
check(multiple_inheritance_abstract.InputRefDerived2(d2)!=6+5, "InputRefDerived2() failed");
check(multiple_inheritance_abstract.InputRefDerived3(d3)!=7+8+9, "InputRefDerived3() failed");
check(multiple_inheritance_abstract.InputPtrDerived1(d1)!=3+4, "InputPtrDerived1() failed");
check(multiple_inheritance_abstract.InputPtrDerived2(d2)!=6+5, "InputPtrDerived2() failed");
check(multiple_inheritance_abstract.InputPtrDerived3(d3)!=7+8+9, "InputPtrDerived3() failed");
check(multiple_inheritance_abstract.InputCPtrRefDerived1(d1)!=3+4, "InputCPtrRefDerived1() failed");
check(multiple_inheritance_abstract.InputCPtrRefDerived2(d2)!=6+5, "InputCPtrRefDerived2() failed");
check(multiple_inheritance_abstract.InputCPtrRefDerived3(d3)!=7+8+9, "InputCPtrRefDerived3() failed");
//Bottom classes as Derived parameters
check(multiple_inheritance_abstract.InputValDerived1(b1)!=3+4, "InputValDerived1() failed");
check(multiple_inheritance_abstract.InputValDerived2(b2)!=6+5, "InputValDerived2() failed");
check(multiple_inheritance_abstract.InputValDerived3(b3)!=7+8+9, "InputValDerived3() failed");
check(multiple_inheritance_abstract.InputRefDerived1(b1)!=103+104, "InputRefDerived1() failed");
check(multiple_inheritance_abstract.InputRefDerived2(b2)!=206+205, "InputRefDerived2() failed");
check(multiple_inheritance_abstract.InputRefDerived3(b3)!=307+308+309, "InputRefDerived3() failed");
check(multiple_inheritance_abstract.InputPtrDerived1(b1)!=103+104, "InputPtrDerived1() failed");
check(multiple_inheritance_abstract.InputPtrDerived2(b2)!=206+205, "InputPtrDerived2() failed");
check(multiple_inheritance_abstract.InputPtrDerived3(b3)!=307+308+309, "InputPtrDerived3() failed");
check(multiple_inheritance_abstract.InputCPtrRefDerived1(b1)!=103+104, "InputCPtrRefDerived1() failed");
check(multiple_inheritance_abstract.InputCPtrRefDerived2(b2)!=206+205, "InputCPtrRefDerived2() failed");
check(multiple_inheritance_abstract.InputCPtrRefDerived3(b3)!=307+308+309, "InputCPtrRefDerived3() failed");
//Bottom classes as Bottom parameters
check(multiple_inheritance_abstract.InputValBottom1(b1)!=103+104, "InputValBottom1() failed");
check(multiple_inheritance_abstract.InputValBottom2(b2)!=206+205, "InputValBottom2() failed");
check(multiple_inheritance_abstract.InputValBottom3(b3)!=307+308+309, "InputValBottom3() failed");
check(multiple_inheritance_abstract.InputRefBottom1(b1)!=103+104, "InputRefBottom1() failed");
check(multiple_inheritance_abstract.InputRefBottom2(b2)!=206+205, "InputRefBottom2() failed");
check(multiple_inheritance_abstract.InputRefBottom3(b3)!=307+308+309, "InputRefBottom3() failed");
check(multiple_inheritance_abstract.InputPtrBottom1(b1)!=103+104, "InputPtrBottom1() failed");
check(multiple_inheritance_abstract.InputPtrBottom2(b2)!=206+205, "InputPtrBottom2() failed");
check(multiple_inheritance_abstract.InputPtrBottom3(b3)!=307+308+309, "InputPtrBottom3() failed");
check(multiple_inheritance_abstract.InputCPtrRefBottom1(b1)!=103+104, "InputCPtrRefBottom1() failed");
check(multiple_inheritance_abstract.InputCPtrRefBottom2(b2)!=206+205, "InputCPtrRefBottom2() failed");
check(multiple_inheritance_abstract.InputCPtrRefBottom3(b3)!=307+308+309, "InputCPtrRefBottom3() failed");
// Return pointers
check(multiple_inheritance_abstract.MakePtrDerived1_CBase1().cbase1y()!=3, "MakePtrDerived1_CBase1 failed");
check(multiple_inheritance_abstract.MakePtrDerived1_CBase2().cbase2()!=4, "MakePtrDerived1_CBase2 failed");
check(multiple_inheritance_abstract.MakePtrDerived2_CBase1().cbase1y()!=6, "MakePtrDerived2_CBase1 failed");
check(multiple_inheritance_abstract.MakePtrDerived2_ABase1().abase1()!=5, "MakePtrDerived2_ABase1 failed");
check(multiple_inheritance_abstract.MakePtrDerived3_ABase1().abase1()!=9, "MakePtrDerived3_ABase1 failed");
check(multiple_inheritance_abstract.MakePtrDerived3_CBase1().cbase1y()!=7, "MakePtrDerived3_CBase1 failed");
check(multiple_inheritance_abstract.MakePtrDerived3_CBase2().cbase2()!=8, "MakePtrDerived3_CBase2 failed");
// Return references
check(multiple_inheritance_abstract.MakeRefDerived1_CBase1().cbase1y()!=3, "MakeRefDerived1_CBase1 failed");
check(multiple_inheritance_abstract.MakeRefDerived1_CBase2().cbase2()!=4, "MakeRefDerived1_CBase2 failed");
check(multiple_inheritance_abstract.MakeRefDerived2_CBase1().cbase1y()!=6, "MakeRefDerived2_CBase1 failed");
check(multiple_inheritance_abstract.MakeRefDerived2_ABase1().abase1()!=5, "MakeRefDerived2_ABase1 failed");
check(multiple_inheritance_abstract.MakeRefDerived3_ABase1().abase1()!=9, "MakeRefDerived3_ABase1 failed");
check(multiple_inheritance_abstract.MakeRefDerived3_CBase1().cbase1y()!=7, "MakeRefDerived3_CBase1 failed");
check(multiple_inheritance_abstract.MakeRefDerived3_CBase2().cbase2()!=8, "MakeRefDerived3_CBase2 failed");
// Return by value (sliced objects)
check(multiple_inheritance_abstract.MakeValDerived1_CBase1().cbase1y()!=1, "MakeValDerived1_CBase1 failed");
check(multiple_inheritance_abstract.MakeValDerived1_CBase2().cbase2()!=2, "MakeValDerived1_CBase2 failed");
check(multiple_inheritance_abstract.MakeValDerived2_CBase1().cbase1y()!=1, "MakeValDerived2_CBase1 failed");
check(multiple_inheritance_abstract.MakeValDerived3_CBase1().cbase1y()!=1, "MakeValDerived3_CBase1 failed");
check(multiple_inheritance_abstract.MakeValDerived3_CBase2().cbase2()!=2, "MakeValDerived3_CBase2 failed");
}
}

View file

@ -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<interfaces.length; ++i)
expectedInterfaces[i] = "interface multiple_inheritance_interfaces." + interfaces[i];
Class[] actualInterfaces = cls.getInterfaces();
String expectedInterfacesString = Arrays.toString(expectedInterfaces);
String actualInterfacesString = Arrays.toString(actualInterfaces);
if (!expectedInterfacesString.equals(actualInterfacesString))
throw new RuntimeException("Expected interfaces for " + cls.getName() + ": \n" + expectedInterfacesString + "\n" + "Actual interfaces: \n" + actualInterfacesString);
String expectedBaseString = null;
if (interfaceExpected) {
// expecting an interface
if (!cls.isInterface())
throw new RuntimeException(cls.getName() + " should be an interface but is not");
expectedBaseString = base.isEmpty() ? "" : "multiple_inheritance_interfaces." + base;
} else {
// expecting a class
if (cls.isInterface())
throw new RuntimeException(cls.getName() + " is an interface but it should not be");
expectedBaseString = base.isEmpty() ? "java.lang.Object" : "multiple_inheritance_interfaces." + base;
}
String actualBaseString = cls.getSuperclass() == null ? "" : cls.getSuperclass().getName();
if (!expectedBaseString.equals(actualBaseString))
throw new RuntimeException("Expected base for " + cls.getName() + ": [" + expectedBaseString + "]" + " Actual base: [" + actualBaseString + "]");
}
public static void main(String argv[]) {
checkBaseAndInterfaces(IA.class, true, "", new String[] {});
checkBaseAndInterfaces(IB.class, true, "", new String[] {});
checkBaseAndInterfaces(IC.class, true, "", new String[] {"IA", "IB"});
checkBaseAndInterfaces(A.class, false, "", new String[] {"IA"});
checkBaseAndInterfaces(B.class, false, "", new String[] {"IB"});
checkBaseAndInterfaces(C.class, false, "", new String[] {"IA", "IB", "IC"});
checkBaseAndInterfaces(D.class, false, "", new String[] {"IA", "IB", "IC"});
checkBaseAndInterfaces(E.class, false, "D", new String[] {});
checkBaseAndInterfaces(IJ.class, true, "", new String[] {});
checkBaseAndInterfaces(IK.class, true, "", new String[] {"IJ"});
checkBaseAndInterfaces(IL.class, true, "", new String[] {"IK"});
checkBaseAndInterfaces(J.class, false, "", new String[] {"IJ"});
checkBaseAndInterfaces(K.class, false, "", new String[] {"IJ", "IK"});
checkBaseAndInterfaces(L.class, false, "", new String[] {"IJ", "IK", "IL"});
checkBaseAndInterfaces(M.class, false, "", new String[] {"IJ", "IK", "IL"});
}
}

View file

@ -0,0 +1,315 @@
%module multiple_inheritance_abstract
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
%include "feature_interface.i"
DECLARE_INTERFACE_RENAME(ABase1, SWIGTYPE_ABase1, ABase1)
DECLARE_INTERFACE_RENAME(CBase1, SWIGTYPE_CBase1, CBase1)
DECLARE_INTERFACE_RENAME(CBase2, SWIGTYPE_CBase2, CBase2)
#endif
%inline %{
struct CBase1 {
virtual void cbase1x() {
return;
}
virtual int cbase1y() {
return 1;
}
int cbase1z() {
return 10;
}
virtual ~CBase1() {
}
};
struct CBase2 {
virtual int cbase2() {
return 2;
}
virtual ~CBase2() {
}
};
struct ABase1 {
virtual int abase1() = 0;
virtual ~ABase1() {
}
};
struct Derived1 : CBase2, CBase1 {
virtual void cbase1x() {
return;
}
virtual int cbase1y() {
return 3;
}
virtual int cbase2() {
return 4;
}
virtual CBase2 *clone() {
return new Derived1(*this);
}
void derived1() {
}
};
struct Derived2 : CBase1, ABase1 {
virtual void cbase1x() {
return;
}
virtual int cbase1y() {
return 6;
}
virtual int abase1() {
return 5;
}
virtual CBase1 *clone() {
return new Derived2(*this);
}
void derived2() {
}
};
struct Derived3 : ABase1, CBase1, CBase2 {
virtual int cbase1y() {
return 7;
}
virtual int cbase2() {
return 8;
}
virtual int abase1() {
return 9;
}
virtual void cbase1x() {
}
virtual ABase1 *clone() {
return new Derived3(*this);
}
void derived3() {
}
};
struct Bottom1 : Derived1 {
virtual void cbase1x() {
return;
}
virtual int cbase1y() {
return 103;
}
virtual int cbase2() {
return 104;
}
};
struct Bottom2 : Derived2 {
virtual int cbase1y() {
return 206;
}
virtual int abase1() {
return 205;
}
};
struct Bottom3 : Derived3 {
virtual int cbase1y() {
return 307;
}
virtual int cbase2() {
return 308;
}
virtual int abase1() {
return 309;
}
};
// Base classes as input
int InputValCBase1(CBase1 cb1) {
return cb1.cbase1y();
}
int InputValCBase2(CBase2 cb2) {
return cb2.cbase2();
}
int InputPtrABase1(ABase1 *pab1) {
return pab1->abase1();
}
int InputPtrCBase1(CBase1 *pcb1) {
return pcb1->cbase1y();
}
int InputPtrCBase2(CBase2 *pcb2) {
return pcb2->cbase2();
}
int InputRefABase1(ABase1 &rab1) {
return rab1.abase1();
}
int InputRefCBase1(CBase1 &rcb1) {
return rcb1.cbase1y();
}
int InputRefCBase2(CBase2 &rcb2) {
return rcb2.cbase2();
}
int InputCPtrRefABase1(ABase1 *const& pab1) {
return pab1->abase1();
}
int InputCPtrRefCBase1(CBase1 *const& pcb1) {
return pcb1->cbase1y();
}
int InputCPtrRefCBase2(CBase2 *const& pcb2) {
return pcb2->cbase2();
}
// Derived classes as input
int InputValDerived1(Derived1 d) {
return d.cbase1y() + d.cbase2();
}
int InputValDerived2(Derived2 d) {
return d.cbase1y() + d.abase1();
}
int InputValDerived3(Derived3 d) {
return d.cbase1y() + d.cbase2() + d.abase1();
}
int InputRefDerived1(Derived1 &d) {
return d.cbase1y() + d.cbase2();
}
int InputRefDerived2(Derived2 &d) {
return d.cbase1y() + d.abase1();
}
int InputRefDerived3(Derived3 &d) {
return d.cbase1y() + d.cbase2() + d.abase1();
}
int InputPtrDerived1(Derived1 *d) {
return d->cbase1y() + d->cbase2();
}
int InputPtrDerived2(Derived2 *d) {
return d->cbase1y() + d->abase1();
}
int InputPtrDerived3(Derived3 *d) {
return d->cbase1y() + d->cbase2() + d->abase1();
}
int InputCPtrRefDerived1(Derived1 *const& d) {
return d->cbase1y() + d->cbase2();
}
int InputCPtrRefDerived2(Derived2 *const& d) {
return d->cbase1y() + d->abase1();
}
int InputCPtrRefDerived3(Derived3 *const& d) {
return d->cbase1y() + d->cbase2() + d->abase1();
}
// Bottom classes as input
int InputValBottom1(Bottom1 d) {
return d.cbase1y() + d.cbase2();
}
int InputValBottom2(Bottom2 d) {
return d.cbase1y() + d.abase1();
}
int InputValBottom3(Bottom3 d) {
return d.cbase1y() + d.cbase2() + d.abase1();
}
int InputRefBottom1(Bottom1 &d) {
return d.cbase1y() + d.cbase2();
}
int InputRefBottom2(Bottom2 &d) {
return d.cbase1y() + d.abase1();
}
int InputRefBottom3(Bottom3 &d) {
return d.cbase1y() + d.cbase2() + d.abase1();
}
int InputPtrBottom1(Bottom1 *d) {
return d->cbase1y() + d->cbase2();
}
int InputPtrBottom2(Bottom2 *d) {
return d->cbase1y() + d->abase1();
}
int InputPtrBottom3(Bottom3 *d) {
return d->cbase1y() + d->cbase2() + d->abase1();
}
int InputCPtrRefBottom1(Bottom1 *const& d) {
return d->cbase1y() + d->cbase2();
}
int InputCPtrRefBottom2(Bottom2 *const& d) {
return d->cbase1y() + d->abase1();
}
int InputCPtrRefBottom3(Bottom3 *const& d) {
return d->cbase1y() + d->cbase2() + d->abase1();
}
// Return pointers
CBase1 *MakePtrDerived1_CBase1() {
return new Derived1();
}
CBase2 *MakePtrDerived1_CBase2() {
return new Derived1();
}
CBase1 *MakePtrDerived2_CBase1() {
return new Derived2();
}
ABase1 *MakePtrDerived2_ABase1() {
return new Derived2();
}
ABase1 *MakePtrDerived3_ABase1() {
return new Derived3();
}
CBase1 *MakePtrDerived3_CBase1() {
return new Derived3();
}
CBase2 *MakePtrDerived3_CBase2() {
return new Derived3();
}
// Return references
CBase1 &MakeRefDerived1_CBase1() {
static Derived1 d;
return d;
}
CBase2 &MakeRefDerived1_CBase2() {
static Derived1 d;
return d;
}
CBase1 &MakeRefDerived2_CBase1() {
static Derived2 d;
return d;
}
ABase1 &MakeRefDerived2_ABase1() {
static Derived2 d;
return d;
}
ABase1 &MakeRefDerived3_ABase1() {
static Derived3 d;
return d;
}
CBase1 &MakeRefDerived3_CBase1() {
static Derived3 d;
return d;
}
CBase2 &MakeRefDerived3_CBase2() {
static Derived3 d;
return d;
}
// Return by value (sliced objects)
CBase1 MakeValDerived1_CBase1() {
return Derived1();
}
CBase2 MakeValDerived1_CBase2() {
return Derived1();
}
CBase1 MakeValDerived2_CBase1() {
return Derived2();
}
CBase1 MakeValDerived3_CBase1() {
return Derived3();
}
CBase2 MakeValDerived3_CBase2() {
return Derived3();
}
%}

View file

@ -0,0 +1,28 @@
%module multiple_inheritance_interfaces
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
%include "feature_interface.i"
DECLARE_INTERFACE_RENAME(IA, A, IA)
DECLARE_INTERFACE_RENAME(IB, B, IB)
DECLARE_INTERFACE_RENAME(IC, C, IC)
#endif
%inline %{
struct IA { virtual void ia() {} };
struct IB { virtual void ib() {} };
struct IC : IA, IB {};
struct D : IC {};
struct E : D {};
%}
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
DECLARE_INTERFACE_RENAME(IJ, J, IJ)
DECLARE_INTERFACE_RENAME(IK, K, IK)
DECLARE_INTERFACE_RENAME(IL, L, IL)
#endif
%inline %{
struct IJ { virtual void ij() {} };
struct IK : IJ {};
struct IL : IK {};
struct M : IL {};
%}

View file

@ -0,0 +1,32 @@
%define DECLARE_INTERFACE_(INTERFACE, IMPL, CTYPE...)
%feature("interface", name = "INTERFACE", cptr = "SWIGInterfaceUpcast") CTYPE;
%typemap(cstype) CTYPE, CTYPE *, CTYPE [], CTYPE &, CTYPE *const& "INTERFACE"
%typemap(csin) CTYPE, CTYPE & "$csinput.SWIGInterfaceUpcast()"
%typemap(csin) CTYPE *, CTYPE *const&, CTYPE [] "$csinput == null ? new HandleRef(null, IntPtr.Zero) : $csinput.SWIGInterfaceUpcast()"
%typemap(csout, excode=SWIGEXCODE) CTYPE {
IMPL ret = new IMPL($imcall, true);$excode
return (INTERFACE)ret;
}
%typemap(csout, excode=SWIGEXCODE) CTYPE & {
IMPL ret = new IMPL($imcall, $owner);$excode
return (INTERFACE)ret;
}
%typemap(csout, excode=SWIGEXCODE) CTYPE *, CTYPE *const&, CTYPE [] {
IntPtr cPtr = $imcall;
IMPL ret = (cPtr == IntPtr.Zero) ? null : new IMPL(cPtr, $owner);$excode
return (INTERFACE)ret;
}
%typemap(csdirectorin) CTYPE, CTYPE & "(INTERFACE)new IMPL($iminput, false)"
%typemap(csdirectorin) CTYPE *, CTYPE *const&, CTYPE [] "($iminput == IntPtr.Zero) ? null : (INTERFACE)new IMPL($iminput, false)"
%typemap(csdirectorout) CTYPE, CTYPE *, CTYPE *const&, CTYPE [], CTYPE & "$cscall.SWIGInterfaceUpcast()"
%enddef
%define DECLARE_INTERFACE_RENAME(INTERFACE, IMPL, CTYPE...)
%rename (IMPL) CTYPE;
DECLARE_INTERFACE_(INTERFACE, IMPL, CTYPE)
%enddef
%define DECLARE_INTERFACE(INTERFACE, CTYPE...)
DECLARE_INTERFACE_(INTERFACE, CTYPE, CTYPE)
%enddef

View file

@ -0,0 +1,31 @@
%define DECLARE_INTERFACE_(INTERFACE, IMPL, CTYPE...)
%feature("interface", name = "INTERFACE", cptr = #INTERFACE ## "_SWIGInterfaceUpcast") CTYPE;
%typemap(jtype, nopgcpp="1") CTYPE, CTYPE *, CTYPE *const&, CTYPE [], CTYPE & "long"
%typemap(jstype) CTYPE, CTYPE *, CTYPE *const&, CTYPE [], CTYPE & "INTERFACE"
%typemap(javain) CTYPE, CTYPE & "$javainput." ## #INTERFACE ## "_SWIGInterfaceUpcast()"
%typemap(javain) CTYPE *, CTYPE *const&, CTYPE [] "($javainput == null) ? 0 : $javainput." ## #INTERFACE ## "_SWIGInterfaceUpcast()"
%typemap(javaout) CTYPE {
return (INTERFACE)new IMPL($jnicall, true);
}
%typemap(javaout) CTYPE & {
return (INTERFACE)new IMPL($jnicall, $owner);
}
%typemap(javaout) CTYPE *, CTYPE *const&, CTYPE [] {
long cPtr = $jnicall;
return (cPtr == 0) ? null : (INTERFACE)new IMPL(cPtr, $owner);
}
%typemap(javadirectorin) CTYPE, CTYPE & "(INTERFACE)new IMPL($jniinput, false)"
%typemap(javadirectorin) CTYPE *, CTYPE *const&, CTYPE [] "($jniinput == 0) ? null : (INTERFACE)new IMPL($jniinput, false)"
%typemap(javadirectorout) CTYPE, CTYPE *, CTYPE *const&, CTYPE [], CTYPE & "$javacall." ## #INTERFACE ## "_SWIGInterfaceUpcast()"
SWIG_JAVABODY_PROXY(public, protected, CTYPE)
%enddef
%define DECLARE_INTERFACE_RENAME(INTERFACE, IMPL, CTYPE...)
%rename (IMPL) CTYPE;
DECLARE_INTERFACE_(INTERFACE, IMPL, CTYPE)
%enddef
%define DECLARE_INTERFACE(INTERFACE, CTYPE...)
DECLARE_INTERFACE_(INTERFACE, CTYPE, CTYPE)
%enddef

View file

@ -18,6 +18,8 @@
/* Hash type used for upcalls from C/C++ */
typedef DOH UpcallData;
// helper function used in feature:interface implementation
void Swig_propagate_interface_methods(Node *n);
class CSHARP:public Language {
static const char *usage;
@ -52,6 +54,7 @@ class CSHARP:public Language {
String *imclass_class_code; // intermediary class code
String *proxy_class_def;
String *proxy_class_code;
String *interface_class_code; // if %feature("interface") was declared for a class, here goes the interface declaration
String *module_class_code;
String *proxy_class_name; // proxy class name
String *full_imclass_name; // fully qualified intermediary class name when using nspace feature, otherwise same as imclass_name
@ -126,6 +129,7 @@ public:
imclass_class_code(NULL),
proxy_class_def(NULL),
proxy_class_code(NULL),
interface_class_code(NULL),
module_class_code(NULL),
proxy_class_name(NULL),
full_imclass_name(NULL),
@ -1643,6 +1647,62 @@ public:
return Language::pragmaDirective(n);
}
String *getQualifiedInterfaceName(Node *n) {
String *ret = Getattr(n, "interface:qname");
if (!ret) {
String *nspace = Getattr(n, "sym:nspace");
String *iname = Getattr(n, "feature:interface:name");
if (nspace) {
if (namespce)
ret = NewStringf("%s.%s.%s", namespce, nspace, iname);
else
ret = NewStringf("%s.%s", nspace, iname);
} else {
ret = Copy(iname);
}
Setattr(n, "interface:qname", ret);
}
return ret;
}
void addInterfaceNameAndUpcasts(String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) {
List *keys = Keys(base_list);
for (Iterator it = First(keys); it.item; it = Next(it)) {
Node *base = Getattr(base_list, it.item);
String *c_baseclass = SwigType_namestr(Getattr(base, "name"));
String *iname = getQualifiedInterfaceName(base);
if (Len(interface_list))
Append(interface_list, ", ");
Append(interface_list, iname);
Printf(interface_upcasts, "\n");
Printf(interface_upcasts, " [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]\n");
String *upcast_name = 0;
if (String *cptr_func = Getattr(base, "feature:interface:cptr"))
upcast_name = NewStringf("%s.%s", iname, cptr_func);
else
upcast_name = NewStringf("%s.SWIGInterfaceUpcast", iname);
Printf(interface_upcasts, " HandleRef %s() {\n", upcast_name);
Replaceall(upcast_name, ".", "_");
String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, upcast_name);
String *wname = Swig_name_wrapper(upcast_method);
Printf(interface_upcasts, " return new HandleRef((%s)this, %s.%s(swigCPtr.Handle));\n", iname, imclass_name, upcast_method);
Printf(interface_upcasts, " }\n");
Printv(imclass_cppcasts_code, "\n [DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
Printf(imclass_cppcasts_code, " public static extern IntPtr %s(IntPtr jarg1);\n", upcast_method);
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
Printv(upcasts_code,
"SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n",
" return (", c_baseclass, " *)jarg1;\n"
"}\n", "\n", NIL);
Delete(upcast_name);
Delete(wname);
Delete(upcast_method);
Delete(c_baseclass);
}
Delete(keys);
}
/* -----------------------------------------------------------------------------
* emitProxyClassDefAndCPPCasts()
* ----------------------------------------------------------------------------- */
@ -1652,6 +1712,8 @@ public:
String *c_baseclass = NULL;
String *baseclass = NULL;
String *c_baseclassname = NULL;
String *interface_list = NewStringEmpty();
String *interface_upcasts = NewStringEmpty();
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
bool feature_director = Swig_directorclass(n) ? true : false;
bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
@ -1668,9 +1730,8 @@ public:
List *baselist = Getattr(n, "bases");
if (baselist) {
Iterator base = First(baselist);
while (base.item && GetFlag(base.item, "feature:ignore")) {
base = Next(base);
}
while (base.item && (GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface")))
base = Next(base);
if (base.item) {
c_baseclassname = Getattr(base.item, "name");
baseclass = Copy(getProxyName(c_baseclassname));
@ -1679,19 +1740,20 @@ public:
base = Next(base);
/* Warn about multiple inheritance for additional base class(es) */
while (base.item) {
if (GetFlag(base.item, "feature:ignore")) {
base = Next(base);
continue;
}
String *proxyclassname = Getattr(n, "classtypeobj");
String *baseclassname = Getattr(base.item, "name");
Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
"Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname));
if (!GetFlag(base.item, "feature:ignore") && !Getattr(base.item, "feature:interface")) {
String *proxyclassname = Getattr(n, "classtypeobj");
String *baseclassname = Getattr(base.item, "name");
Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
"Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname));
}
base = Next(base);
}
}
}
}
Hash *interface_bases = Getattr(n, "interface:bases");
if (interface_bases)
addInterfaceNameAndUpcasts(interface_list, interface_upcasts, interface_bases, c_classname);
bool derived = baseclass && getProxyName(c_baseclassname);
if (derived && purebase_notderived)
@ -1713,6 +1775,9 @@ public:
// Pure C# interfaces
const String *pure_interfaces = typemapLookup(n, derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE);
if (*Char(interface_list) && *Char(pure_interfaces))
Append(interface_list, ", ");
Append(interface_list, pure_interfaces);
// Start writing the proxy class
if (!has_outerclass)
Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements
@ -1725,8 +1790,8 @@ public:
Printv(proxy_class_def, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
" $csclassname", // Class name and base class
(*Char(wanted_base) || *Char(pure_interfaces)) ? " : " : "", wanted_base, (*Char(wanted_base) && *Char(pure_interfaces)) ? // Interfaces
", " : "", pure_interfaces, " {", derived ? typemapLookup(n, "csbody_derived", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF) : // main body of class
(*Char(wanted_base) || *Char(interface_list)) ? " : " : "", wanted_base, (*Char(wanted_base) && *Char(interface_list)) ? // Interfaces
", " : "", interface_list, " {", derived ? typemapLookup(n, "csbody_derived", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF) : // main body of class
typemapLookup(n, "csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
NIL);
@ -1771,6 +1836,8 @@ public:
Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n",
NIL);
}
if (*Char(interface_upcasts))
Printv(proxy_class_def, interface_upcasts, NIL);
if (feature_director) {
// Generate director connect method
@ -1852,6 +1919,8 @@ public:
Delete(director_connect_method_name);
}
Delete(interface_upcasts);
Delete(interface_list);
Delete(attributes);
Delete(destruct);
@ -1899,12 +1968,40 @@ public:
Delete(baseclass);
}
void emitInterfaceDeclaration(Node *n, String *iname, File *f_interface) {
Printv(f_interface, typemapLookup(n, "csimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL);
Printf(f_interface, "public interface %s", iname);
if (List *baselist = Getattr(n, "bases")) {
String *bases = 0;
for (Iterator base = First(baselist); base.item; base = Next(base)) {
if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface"))
continue; // TODO: warn about skipped non-interface bases
String *base_iname = Getattr(base.item, "feature:interface:name");
if (!bases)
bases = NewStringf(" : %s", base_iname);
else {
Append(bases, ", ");
Append(bases, base_iname);
}
}
if (bases) {
Printv(f_interface, bases, NIL);
Delete(bases);
}
}
Printf(f_interface, " {\n");
Printf(f_interface, " [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]\n");
if (String *cptr_func = Getattr(n, "feature:interface:cptr"))
Printf(f_interface, " HandleRef %s();\n", cptr_func);
else
Printf(f_interface, " HandleRef SWIGInterfaceUpcast();\n");
}
/* ----------------------------------------------------------------------
* classHandler()
* ---------------------------------------------------------------------- */
virtual int classHandler(Node *n) {
String *nspace = getNSpace();
File *f_proxy = NULL;
// save class local variables
@ -1915,6 +2012,9 @@ public:
String *old_proxy_class_def = proxy_class_def;
String *old_proxy_class_code = proxy_class_code;
bool has_outerclass = Getattr(n, "nested:outer") && !GetFlag(n, "feature:flatnested");
File *f_interface = NULL;
String *old_interface_class_code = interface_class_code;
interface_class_code = 0;
if (proxy_flag) {
proxy_class_name = NewString(Getattr(n, "sym:name"));
@ -1963,10 +2063,36 @@ public:
}
else
++nesting_depth;
proxy_class_def = NewString("");
proxy_class_code = NewString("");
destructor_call = NewString("");
proxy_class_constants_code = NewString("");
// Start writing out the proxy class file
emitBanner(f_proxy);
addOpenNamespace(nspace, f_proxy);
Clear(proxy_class_def);
Clear(proxy_class_code);
destructor_call = NewStringEmpty();
proxy_class_constants_code = NewStringEmpty();
Swig_propagate_interface_methods(n);
if (Getattr(n, "feature:interface")) {
interface_class_code = NewStringEmpty();
String *iname = Getattr(n, "feature:interface:name");
if (!iname) {
Swig_error(Getfile(n), Getline(n), "Interface %s has no name attribute", proxy_class_name);
SWIG_exit(EXIT_FAILURE);
}
filen = NewStringf("%s%s.cs", output_directory, iname);
f_interface = NewFile(filen, "w", SWIG_output_files());
if (!f_interface) {
FileErrorDisplay(filen);
SWIG_exit(EXIT_FAILURE);
}
Append(filenames_list, filen); // file name ownership goes to the list
emitBanner(f_interface);
addOpenNamespace(nspace, f_interface);
emitInterfaceDeclaration(n, iname, f_interface);
}
Delete(output_directory);
}
Language::classHandler(n);
@ -2056,10 +2182,17 @@ public:
Delete(norm_name);
Delete(wname);
Delete(downcast_method);
if (f_interface) {
Printv(f_interface, interface_class_code, "}\n", NIL);
addCloseNamespace(nspace, f_interface);
Delete(f_interface);
}
emitDirectorExtraMethods(n);
Delete(interface_class_code);
interface_class_code = old_interface_class_code;
Delete(csclazzname);
Delete(proxy_class_name);
proxy_class_name = old_proxy_class_name;
@ -2145,6 +2278,8 @@ public:
String *pre_code = NewString("");
String *post_code = NewString("");
String *terminator_code = NewString("");
bool is_interface = Getattr(parentNode(n), "feature:interface") != 0
&& !static_flag && Getattr(n, "interface:owner") == 0;
if (!proxy_flag)
return;
@ -2217,8 +2352,10 @@ public:
Printf(function_code, " %s ", methodmods);
if (!is_smart_pointer()) {
// Smart pointer classes do not mirror the inheritance hierarchy of the underlying pointer type, so no virtual/override/new required.
if (Getattr(n, "override"))
Printf(function_code, "override ");
if (Node *base = Getattr(n, "override")) {
if (!Getattr(parentNode(base), "feature:interface"))
Printf(function_code, "override ");
}
else if (checkAttribute(n, "storage", "virtual"))
Printf(function_code, "virtual ");
if (Getattr(n, "hides"))
@ -2228,6 +2365,9 @@ public:
if (static_flag)
Printf(function_code, "static ");
Printf(function_code, "%s %s(", return_type, proxy_function_name);
if (is_interface)
Printf(interface_class_code, " %s %s(", return_type, proxy_function_name);
Printv(imcall, full_imclass_name, ".$imfuncname(", NIL);
if (!static_flag)
@ -2307,10 +2447,15 @@ public:
}
/* Add parameter to proxy function */
if (gencomma >= 2)
if (gencomma >= 2) {
Printf(function_code, ", ");
if (is_interface)
Printf(interface_class_code, ", ");
}
gencomma = 2;
Printf(function_code, "%s %s", param_type, arg);
if (is_interface)
Printf(interface_class_code, "%s %s", param_type, arg);
Delete(arg);
Delete(param_type);
@ -2320,6 +2465,8 @@ public:
Printf(imcall, ")");
Printf(function_code, ")");
if (is_interface)
Printf(interface_class_code, ");\n");
// Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in proxy class)
if ((tm = Swig_typemap_lookup("csout", n, "", 0))) {

View file

@ -18,6 +18,8 @@
/* Hash type used for upcalls from C/C++ */
typedef DOH UpcallData;
// helper function used in feature:interface implementation
void Swig_propagate_interface_methods(Node *n);
class JAVA:public Language {
static const char *usage;
@ -53,6 +55,7 @@ class JAVA:public Language {
String *imclass_class_code; // intermediary class code
String *proxy_class_def;
String *proxy_class_code;
String *interface_class_code; // if %feature("interface") was declared for a class, here goes the interface declaration
String *module_class_code;
String *proxy_class_name; // proxy class name
String *full_proxy_class_name;// fully qualified proxy class name when using nspace feature, otherwise same as proxy_class_name
@ -125,6 +128,7 @@ public:
imclass_class_code(NULL),
proxy_class_def(NULL),
proxy_class_code(NULL),
interface_class_code(NULL),
module_class_code(NULL),
proxy_class_name(NULL),
full_proxy_class_name(NULL),
@ -1288,8 +1292,10 @@ public:
// Add extra indentation
Replaceall(enum_code, "\n", "\n ");
Replaceall(enum_code, " \n", "\n");
Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL);
if (GetFlag(getCurrentClass(), "feature:interface"))
Printv(interface_class_code, " ", enum_code, "\n\n", NIL);
else
Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL);
} else {
// Global enums are defined in their own file
String *output_directory = outputDirectory(nspace);
@ -1723,6 +1729,71 @@ public:
return Language::pragmaDirective(n);
}
String *getQualifiedInterfaceName(Node *n) {
String *ret = Getattr(n, "interface:qname");
if (!ret) {
String *nspace = Getattr(n, "sym:nspace");
String *symname = Getattr(n, "feature:interface:name");
if (nspace) {
if (package)
ret = NewStringf("%s.%s.%s", package, nspace, symname);
else
ret = NewStringf("%s.%s", nspace, symname);
} else {
if (package)
ret = NewStringf("%s.%s", package, symname);
else
ret = Copy(symname);
}
Setattr(n, "interface:qname", ret);
}
return ret;
}
void addInterfaceNameAndUpcasts(String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) {
// Printf(stdout, "addInterfaceNameAndUpcasts %s base_list", c_classname);
List *keys = Keys(base_list);
for (Iterator it = First(keys); it.item; it = Next(it)) {
Node *base = Getattr(base_list, it.item);
String *c_baseclass = SwigType_namestr(Getattr(base, "name"));
String *iname = Getattr(base, "feature:interface:name");
if (Len(interface_list))
Append(interface_list, ", ");
Append(interface_list, iname);
String *upcast_name = 0;
if (String *cptr_func = Getattr(base, "feature:interface:cptr"))
upcast_name = NewStringf("%s", cptr_func);
else
upcast_name = NewStringf("%s_SWIGInterfaceUpcast", iname);
Printf(interface_upcasts, "\n");
Printf(interface_upcasts, " public long %s() {\n", upcast_name);
Replaceall(upcast_name, ".", "_");
String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, upcast_name);
String *jniname = makeValidJniName(upcast_method);
String *wname = Swig_name_wrapper(jniname);
Printf(interface_upcasts, " return %s.%s(swigCPtr);\n", imclass_name, upcast_method);
Printf(interface_upcasts, " }\n");
Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method);
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
Printv(upcasts_code,
"SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
" jlong baseptr = 0;\n"
" (void)jenv;\n"
" (void)jcls;\n"
" *(", c_baseclass, " **)&baseptr = *(", c_classname, " **)&jarg1;\n"
" return baseptr;\n"
"}\n", "\n", NIL);
Delete(upcast_name);
Delete(wname);
Delete(jniname);
Delete(upcast_method);
Delete(c_baseclass);
}
// Printf(stdout, " => %s\n", interface_list);
Delete(keys);
}
/* -----------------------------------------------------------------------------
* emitProxyClassDefAndCPPCasts()
* ----------------------------------------------------------------------------- */
@ -1732,6 +1803,8 @@ public:
String *c_baseclass = NULL;
String *baseclass = NULL;
String *c_baseclassname = NULL;
String *interface_list = NewStringEmpty();
String *interface_upcasts = NewStringEmpty();
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
bool feature_director = Swig_directorclass(n) ? true : false;
bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
@ -1748,9 +1821,8 @@ public:
List *baselist = Getattr(n, "bases");
if (baselist) {
Iterator base = First(baselist);
while (base.item && GetFlag(base.item, "feature:ignore")) {
while (base.item && (GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface")))
base = Next(base);
}
if (base.item) {
c_baseclassname = Getattr(base.item, "name");
baseclass = Copy(getProxyName(c_baseclassname));
@ -1759,20 +1831,22 @@ public:
base = Next(base);
/* Warn about multiple inheritance for additional base class(es) */
while (base.item) {
if (GetFlag(base.item, "feature:ignore")) {
base = Next(base);
continue;
}
String *proxyclassname = Getattr(n, "classtypeobj");
String *baseclassname = Getattr(base.item, "name");
Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
"Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname));
if (!GetFlag(base.item, "feature:ignore") && !Getattr(base.item, "feature:interface")) {
String *proxyclassname = Getattr(n, "classtypeobj");
String *baseclassname = Getattr(base.item, "name");
Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
"Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname));
}
base = Next(base);
}
}
}
}
Hash *interface_bases = Getattr(n, "interface:bases");
if (interface_bases)
addInterfaceNameAndUpcasts(interface_list, interface_upcasts, interface_bases, c_classname);
bool derived = baseclass && getProxyName(c_baseclassname);
if (derived && purebase_notderived)
pure_baseclass = empty_string;
@ -1793,7 +1867,9 @@ public:
// Pure Java interfaces
const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
if (*Char(interface_list) && *Char(pure_interfaces))
Append(interface_list, ", ");
Append(interface_list, pure_interfaces);
// Start writing the proxy class
if (!has_outerclass) // Import statements
Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE),"\n", NIL);
@ -1801,8 +1877,8 @@ public:
Printv(proxy_class_def, "static ", NIL); // C++ nested classes correspond to static java classes
Printv(proxy_class_def, typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
" $javaclassname", // Class name and bases
(*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(pure_interfaces) ? // Pure Java interfaces
" implements " : "", pure_interfaces, " {", derived ? typemapLookup(n, "javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class
(*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(interface_list) ? // Pure Java interfaces
" implements " : "", interface_list, " {", derived ? typemapLookup(n, "javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class
typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class
NIL);
@ -1845,6 +1921,8 @@ public:
if (*Char(destruct))
Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " void ", destruct_methodname, "()", destructor_throws_clause, " ", destruct, "\n", NIL);
}
if (*Char(interface_upcasts))
Printv(proxy_class_def, interface_upcasts, NIL);
/* Insert directordisconnect typemap, if this class has directors enabled */
/* Also insert the swigTakeOwnership and swigReleaseOwnership methods */
@ -1866,6 +1944,8 @@ public:
Delete(take_jnicall);
}
Delete(interface_upcasts);
Delete(interface_list);
Delete(attributes);
Delete(destruct);
@ -1920,12 +2000,48 @@ public:
Delete(baseclass);
}
void emitInterfaceDeclaration(Node *n, String *iname, File *f_interface, String *nspace) {
if (package || nspace) {
Printf(f_interface, "package ");
if (package)
Printv(f_interface, package, nspace ? "." : "", NIL);
if (nspace)
Printv(f_interface, nspace, NIL);
Printf(f_interface, ";\n");
}
Printv(f_interface, typemapLookup(n, "javaimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL);
Printf(f_interface, "public interface %s", iname);
if (List *baselist = Getattr(n, "bases")) {
String *bases = 0;
for (Iterator base = First(baselist); base.item; base = Next(base)) {
if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface"))
continue; // TODO: warn about skipped non-interface bases
String *base_iname = Getattr(base.item, "feature:interface:name");
if (!bases)
bases = Copy(base_iname);
else {
Append(bases, ", ");
Append(bases, base_iname);
}
}
if (bases) {
Printv(f_interface, " extends ", bases, NIL);
Delete(bases);
}
}
Printf(f_interface, " {\n");
if (String *cptr_func = Getattr(n, "feature:interface:cptr"))
Printf(f_interface, " long %s();\n", cptr_func);
else
Printf(f_interface, " long %s_SWIGInterfaceUpcast();\n", iname);
}
/* ----------------------------------------------------------------------
* classHandler()
* ---------------------------------------------------------------------- */
virtual int classHandler(Node *n) {
File *f_proxy = NULL;
String *old_proxy_class_name = proxy_class_name;
String *old_full_proxy_class_name = full_proxy_class_name;
@ -1936,6 +2052,8 @@ public:
String *old_proxy_class_def = proxy_class_def;
String *old_proxy_class_code = proxy_class_code;
bool has_outerclass = Getattr(n, "nested:outer") && !GetFlag(n, "feature:flatnested");
File *f_interface = NULL;
interface_class_code = 0;
if (proxy_flag) {
proxy_class_name = NewString(Getattr(n, "sym:name"));
@ -2022,7 +2140,28 @@ public:
destructor_call = NewString("");
destructor_throws_clause = NewString("");
proxy_class_constants_code = NewString("");
Swig_propagate_interface_methods(n);
if (Getattr(n, "feature:interface")) {
interface_class_code = NewStringEmpty();
String *iname = Getattr(n, "feature:interface:name");
if (!iname) {
Swig_error(Getfile(n), Getline(n), "Interface %s has no name attribute", proxy_class_name);
SWIG_exit(EXIT_FAILURE);
}
filen = NewStringf("%s%s.java", output_directory, iname);
f_interface = NewFile(filen, "w", SWIG_output_files());
if (!f_interface) {
FileErrorDisplay(filen);
SWIG_exit(EXIT_FAILURE);
}
Append(filenames_list, filen); // file name ownership goes to the list
emitBanner(f_interface);
emitInterfaceDeclaration(n, iname, f_interface, nspace);
}
Delete(output_directory);
}
Language::classHandler(n);
if (proxy_flag) {
@ -2110,6 +2249,11 @@ public:
Delete(downcast_method);
}
if (f_interface) {
Printv(f_interface, interface_class_code, "}\n", NIL);
Delete(f_interface);
}
emitDirectorExtraMethods(n);
Delete(javaclazzname);
@ -2203,6 +2347,8 @@ public:
bool setter_flag = false;
String *pre_code = NewString("");
String *post_code = NewString("");
bool is_interface = Getattr(parentNode(n), "feature:interface") != 0
&& !static_flag && Getattr(n, "interface:owner") == 0;
if (!proxy_flag)
return;
@ -2252,6 +2398,9 @@ public:
if (static_flag)
Printf(function_code, "static ");
Printf(function_code, "%s %s(", return_type, proxy_function_name);
if (is_interface)
Printf(interface_class_code, " %s %s(", return_type, proxy_function_name);
Printv(imcall, full_imclass_name, ".$imfuncname(", NIL);
if (!static_flag) {
@ -2339,10 +2488,15 @@ public:
}
/* Add parameter to proxy function */
if (gencomma >= 2)
if (gencomma >= 2) {
Printf(function_code, ", ");
if (is_interface)
Printf(interface_class_code, ", ");
}
gencomma = 2;
Printf(function_code, "%s %s", param_type, arg);
if (is_interface)
Printf(interface_class_code, "%s %s", param_type, arg);
if (prematureGarbageCollectionPreventionParameter(pt, p)) {
String *pgcppname = Getattr(p, "tmap:javain:pgcppname");
@ -2364,6 +2518,8 @@ public:
Printf(imcall, ")");
Printf(function_code, ")");
if (is_interface)
Printf(interface_class_code, ");\n");
// Transform return type used in JNI function (in intermediary class) to type used in Java wrapper function (in proxy class)
if ((tm = Swig_typemap_lookup("javaout", n, "", 0))) {

View file

@ -3816,3 +3816,104 @@ Language *Language::instance() {
Hash *Language::getClassHash() const {
return classhash;
}
// 4 methods below are used in C# && Java module "feature:interface" implementation
//
// Collect all not abstract methods from the bases marked as "interface"
static void collect_interface_methods(Node *n, List *methods) {
if (Hash *bases = Getattr(n, "interface:bases")){
List *keys = Keys(bases);
for (Iterator base = First(keys); base.item; base = Next(base)) {
Node *cls = Getattr(bases, base.item);
if (cls == n)
continue;
for (Node *child = firstChild(cls); child; child = nextSibling(child)) {
if (strcmp(Char(nodeType(child)), "cdecl") == 0) {
if (GetFlag(child, "feature:ignore") || Getattr(child, "interface:owner"))
continue; // skip methods propagated to bases
Node *m = Copy(child);
set_nextSibling(m, NIL);
set_previousSibling(m, NIL);
Setattr(m, "interface:owner", cls);
Append(methods, m);
}
}
}
Delete(keys);
}
}
/* -----------------------------------------------------------------------------
* 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))
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")) {
if (Getattr(base.item, "feature:interface"))
collect_interface_bases(bases, base.item);
}
}
}
}
/* -----------------------------------------------------------------------------
* 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)
Delete(interface_bases);
else
Setattr(n, "interface:bases", interface_bases);
}
// 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) {
collect_and_set_interface_bases(n);
List *methods = NewList();
collect_interface_methods(n, methods);
bool is_interface = Getattr(n, "feature:interface") != 0;
for (Iterator mi = First(methods); mi.item; mi = Next(mi)) {
if (!is_interface && GetFlag(mi.item, "abstract"))
continue;
String *this_decl = Getattr(mi.item, "decl");
String *resolved_decl = SwigType_typedef_resolve_all(this_decl);
bool overloaded = false;
if (SwigType_isfunction(resolved_decl)) {
String *name = Getattr(mi.item, "name");
for (Node *child = firstChild(n); child; child = nextSibling(child)) {
if (Getattr(child, "interface:owner"))
break; // at the end of the list are newly appended methods
if (checkAttribute(child, "name", name)) {
String *decl = SwigType_typedef_resolve_all(Getattr(child, "decl"));
overloaded = Strcmp(decl, this_decl) == 0;
Delete(decl);
if (overloaded)
break;
}
}
}
Delete(resolved_decl);
if (!overloaded)
appendChild(n, mi.item);
else
Delete(mi.item);
}
Delete(methods);
}