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:
commit
abccc13a4a
11 changed files with 1166 additions and 39 deletions
|
|
@ -282,6 +282,8 @@ CPP_TEST_CASES += \
|
|||
minherit2 \
|
||||
mixed_types \
|
||||
multiple_inheritance \
|
||||
multiple_inheritance_abstract \
|
||||
multiple_inheritance_interfaces \
|
||||
name_cxx \
|
||||
name_warnings \
|
||||
namespace_class \
|
||||
|
|
|
|||
|
|
@ -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 = \
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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"});
|
||||
}
|
||||
}
|
||||
315
Examples/test-suite/multiple_inheritance_abstract.i
Normal file
315
Examples/test-suite/multiple_inheritance_abstract.i
Normal 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();
|
||||
}
|
||||
|
||||
%}
|
||||
28
Examples/test-suite/multiple_inheritance_interfaces.i
Normal file
28
Examples/test-suite/multiple_inheritance_interfaces.i
Normal 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 {};
|
||||
%}
|
||||
32
Lib/csharp/feature_interface.i
Normal file
32
Lib/csharp/feature_interface.i
Normal 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
|
||||
|
||||
31
Lib/java/feature_interface.i
Normal file
31
Lib/java/feature_interface.i
Normal 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
|
||||
|
||||
|
|
@ -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))) {
|
||||
|
|
|
|||
|
|
@ -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))) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue