feature:interface ported to Java
This commit is contained in:
parent
50685b512f
commit
766d55255b
7 changed files with 442 additions and 38 deletions
|
|
@ -34,7 +34,8 @@ CPP_TEST_CASES = \
|
||||||
java_prepost \
|
java_prepost \
|
||||||
java_throws \
|
java_throws \
|
||||||
java_typemaps_proxy \
|
java_typemaps_proxy \
|
||||||
java_typemaps_typewrapper
|
java_typemaps_typewrapper \
|
||||||
|
multiple_inheritance_abstract
|
||||||
# li_boost_intrusive_ptr
|
# li_boost_intrusive_ptr
|
||||||
|
|
||||||
include $(srcdir)/../common.mk
|
include $(srcdir)/../common.mk
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
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 jfoo1(CBase1 cb1){
|
||||||
|
return cb1.foo1();
|
||||||
|
}
|
||||||
|
int jbar1(ABase1 ab1){
|
||||||
|
return ab1.bar1();
|
||||||
|
}
|
||||||
|
int jfoo2(CBase2 cb2){
|
||||||
|
return cb2.foo2();
|
||||||
|
}
|
||||||
|
public static void main(String argv[]) {
|
||||||
|
//Test Derived1
|
||||||
|
Derived1 d1=new Derived1();
|
||||||
|
if(d1.foo1()!=3)
|
||||||
|
throw new RuntimeException("Derived1::foo1() failed in multiple_inheritance_abstract");
|
||||||
|
if(d1.foo2()!=4)
|
||||||
|
throw new RuntimeException("Derived::foo2() failed in multiple_inheritance_abstract");
|
||||||
|
//Test Derived2
|
||||||
|
Derived2 d2=new Derived2();
|
||||||
|
if(d2.foo1()!=6)
|
||||||
|
throw new RuntimeException("Derived2::foo1() failed in multiple_inheritance_abstract");
|
||||||
|
if(d2.bar1()!=5)
|
||||||
|
throw new RuntimeException("Derived2::bar1() failed in multiple_inheritance_abstract");
|
||||||
|
//Test Derived3
|
||||||
|
Derived3 d3=new Derived3();
|
||||||
|
if( d3.foo1()!=7)
|
||||||
|
throw new RuntimeException("Derived3::foo1() failed in multiple_inheritance_abstract");
|
||||||
|
if(d3.foo2()!=8)
|
||||||
|
throw new RuntimeException("Derived3::foo2() failed in multiple_inheritance_abstract");
|
||||||
|
if(d3.bar1()!=9)
|
||||||
|
throw new RuntimeException("Derived3::bar1() failed in multiple_inheritance_abstract");
|
||||||
|
//Test interfaces from c++ classes
|
||||||
|
CBase1 cb1=new SWIGTYPE_CBase1();
|
||||||
|
CBase2 cb2=new SWIGTYPE_CBase2();
|
||||||
|
if(cb1.foo1()!=1)
|
||||||
|
throw new RuntimeException("CBase1::foo1() failed in multiple_inheritance_abstract");
|
||||||
|
if(cb2.foo2()!=2)
|
||||||
|
throw new RuntimeException("CBase2::foo2() failed in multiple_inheritance_abstract");
|
||||||
|
//Test abstract class as return value
|
||||||
|
ABase1 ab1=d3.clone();
|
||||||
|
if( ab1.bar1()!=9)
|
||||||
|
throw new RuntimeException("Derived3::bar1() through ABase1 failed in multiple_inheritance_abstract");
|
||||||
|
//Test concrete base class as return value
|
||||||
|
CBase1 cb6=d2.clone();
|
||||||
|
CBase2 cb7=d1.clone();
|
||||||
|
if(cb6.foo1()!=6)
|
||||||
|
throw new RuntimeException("Derived2::foo1() through CBase1 failed in multiple_inheritance_abstract");
|
||||||
|
if(cb7.foo2()!=4)
|
||||||
|
throw new RuntimeException("Derived1:foo2() 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();
|
||||||
|
if(cb3.foo1()!=3)
|
||||||
|
throw new RuntimeException("Derived1::foo1()through CBase1 failed in multiple_inheritance_abstract");
|
||||||
|
if(cb4.foo1()!=7)
|
||||||
|
throw new RuntimeException("Derived3::foo1()through CBase1 failed in multiple_inheritance_abstract");
|
||||||
|
if(cb5.foo2()!=8)
|
||||||
|
throw new RuntimeException("Derived3::foo2()through CBase2 failed in multiple_inheritance_abstract");
|
||||||
|
if(ab6.bar1()!=5)
|
||||||
|
throw new RuntimeException("Derived2::bar1()through ABase1 failed in multiple_inheritance_abstract");
|
||||||
|
//Test base classes as parameter in java
|
||||||
|
multiple_inheritance_abstract_runme mhar=new multiple_inheritance_abstract_runme();
|
||||||
|
if(mhar.jfoo1(d1)!=3)
|
||||||
|
throw new RuntimeException("jfoo1()through Derived1 as parameter failed in multiple_inheritance_abstract");
|
||||||
|
if(mhar.jfoo1(d2)!=6)
|
||||||
|
throw new RuntimeException("jfoo1()through Derived2 as parameter failed in multiple_inheritance_abstract");
|
||||||
|
if(mhar.jfoo1(d3)!=7)
|
||||||
|
throw new RuntimeException("jfoo1()through Derived3 as parameter failed in multiple_inheritance_abstract");
|
||||||
|
if(mhar.jfoo2(d1)!=4)
|
||||||
|
throw new RuntimeException("jfoo2()through Derived1 as parameter failed in multiple_inheritance_abstract");
|
||||||
|
if(mhar.jfoo2(d3)!=8)
|
||||||
|
throw new RuntimeException("jfoo2()through Derived3 as parameter failed in multiple_inheritance_abstract");
|
||||||
|
if(mhar.jbar1(d2)!=5)
|
||||||
|
throw new RuntimeException("jbar1()through Derived2 as parameter failed in multiple_inheritance_abstract");
|
||||||
|
if(mhar.jbar1(d3)!=9)
|
||||||
|
throw new RuntimeException("jbar1()through Derived3 as parameter failed in multiple_inheritance_abstract");
|
||||||
|
/*//Test ABase1 as a parameter
|
||||||
|
if(multiple_inheritance_abstract.foo6(d2)!=5)
|
||||||
|
throw new RuntimeException("foo6() through Derived2 as a parameter failed in multiple_inheritance_abstract");
|
||||||
|
if(multiple_inheritance_abstract.foo6(d3)!=9)
|
||||||
|
throw new RuntimeException("foo6() through Derived3 as a parameter failed in multiple_inheritance_abstract");
|
||||||
|
//Test CBase1 CBase2 as parameters
|
||||||
|
if(multiple_inheritance_abstract.foo7(d3)!=7)
|
||||||
|
throw new RuntimeException("foo7() ,Derived3 as a parameter failed in multiple_inheritance_abstract");
|
||||||
|
if(multiple_inheritance_abstract.foo7(d1)!=3)
|
||||||
|
throw new RuntimeException("foo7() ,Derived1 as a parameter failed in multiple_inheritance_abstract");
|
||||||
|
if(multiple_inheritance_abstract.foo7(d2)!=6)
|
||||||
|
throw new RuntimeException("foo7() ,Derived3 as a parameter failed in multiple_inheritance_abstract");
|
||||||
|
if(multiple_inheritance_abstract.foo8(d3)!=4)
|
||||||
|
throw new RuntimeException("foo8() ,Derived3 as a parameter failed in multiple_inheritance_abstract");
|
||||||
|
if(multiple_inheritance_abstract.foo8(d1)!=8)
|
||||||
|
throw new RuntimeException("foo8() ,Derived1 as a parameter failed in multiple_inheritance_abstract");*/
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
96
Examples/test-suite/multiple_inheritance_abstract.i
Normal file
96
Examples/test-suite/multiple_inheritance_abstract.i
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
%module multiple_inheritance_abstract
|
||||||
|
|
||||||
|
%include "feature_interface.i"
|
||||||
|
DECLARE_INTERFACE_RENAME(ABase1, ABase1, SWIGTYPE_ABase1)
|
||||||
|
DECLARE_INTERFACE_RENAME(CBase1, CBase1, SWIGTYPE_CBase1)
|
||||||
|
DECLARE_INTERFACE_RENAME(CBase2, CBase2, SWIGTYPE_CBase2)
|
||||||
|
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct CBase1 {
|
||||||
|
virtual void foo9(){
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
virtual int foo1(){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int foo3(){
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
virtual ~CBase1(){
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct CBase2{
|
||||||
|
virtual int foo2(){
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
virtual ~CBase2(){
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct ABase1{
|
||||||
|
virtual int bar1()=0;
|
||||||
|
virtual ~ABase1(){
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Derived1 : CBase2,CBase1{
|
||||||
|
virtual int foo1(){
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
virtual void foo9(){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
virtual int foo2(){
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
virtual CBase2* clone(){
|
||||||
|
return new Derived1(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct Derived2:CBase1,ABase1{
|
||||||
|
virtual int bar1(){
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
virtual int foo1(){
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
virtual void foo9(){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
virtual CBase1* clone(){
|
||||||
|
return new Derived2(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct Derived3:ABase1,CBase1,CBase2{
|
||||||
|
virtual int foo1(){
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
virtual int foo2(){
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
virtual int bar1(){
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
virtual void foo9(){
|
||||||
|
}
|
||||||
|
virtual ABase1* clone(){
|
||||||
|
return new Derived3(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ABase1* foo4(Derived3 d){
|
||||||
|
return d.clone();
|
||||||
|
}
|
||||||
|
int foo5(CBase1 cb1,CBase2 cb2){
|
||||||
|
return cb1.foo1()+cb2.foo2();
|
||||||
|
}
|
||||||
|
int foo6(ABase1* pab1){
|
||||||
|
return pab1->bar1();
|
||||||
|
}
|
||||||
|
int foo7(CBase1* pcb1){
|
||||||
|
return pcb1->foo1();
|
||||||
|
}
|
||||||
|
int foo8(CBase2* pcb2){
|
||||||
|
return pcb2->foo2();
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
26
Lib/csharp/feature_interface.i
Normal file
26
Lib/csharp/feature_interface.i
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
%define DECLARE_INTERFACE_(CTYPE, INTERFACE, IMPL)
|
||||||
|
%feature("interface", name = "INTERFACE", cptr = "GetCPtr") CTYPE;
|
||||||
|
%typemap(cstype) CTYPE*, const CTYPE& "INTERFACE"
|
||||||
|
%typemap(csdirectorout) CTYPE*, const CTYPE& "$cscall.GetCPtr()"
|
||||||
|
%typemap(csdirectorin) CTYPE*, const CTYPE&
|
||||||
|
%{
|
||||||
|
(INTERFACE)new IMPL($iminput,false)
|
||||||
|
%}
|
||||||
|
%typemap(csin) CTYPE*, const CTYPE& "$csinput.GetCPtr()"
|
||||||
|
%typemap(csout, excode=SWIGEXCODE) CTYPE*, const CTYPE&
|
||||||
|
{
|
||||||
|
IMPL ret = new IMPL($imcall,true);
|
||||||
|
$excode
|
||||||
|
return (INTERFACE)ret;
|
||||||
|
}
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
%define DECLARE_INTERFACE_RENAME(CTYPE, INTERFACE, IMPL)
|
||||||
|
%rename (IMPL) CTYPE;
|
||||||
|
DECLARE_INTERFACE_(CTYPE, INTERFACE, IMPL)
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
%define DECLARE_INTERFACE(CTYPE, INTERFACE)
|
||||||
|
DECLARE_INTERFACE_(CTYPE, INTERFACE, CTYPE)
|
||||||
|
%enddef
|
||||||
|
|
||||||
28
Lib/java/feature_interface.i
Normal file
28
Lib/java/feature_interface.i
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
%define DECLARE_INTERFACE_(CTYPE, INTERFACE, IMPL)
|
||||||
|
%feature("interface", name = "INTERFACE", cptr = #INTERFACE ## "_getCPtr") CTYPE;
|
||||||
|
%typemap(jstype) CTYPE*, const CTYPE& "INTERFACE"
|
||||||
|
%typemap(jtype, nopgcpp="1") CTYPE*, const CTYPE& "long"
|
||||||
|
%typemap(javadirectorout) CTYPE*, const CTYPE& "$javacall." ## #INTERFACE ## "_getCPtr()"
|
||||||
|
%typemap(javadirectorin) CTYPE*, const CTYPE&
|
||||||
|
%{
|
||||||
|
long cPtr = $jniinput;
|
||||||
|
return (cPtr == 0) ? null : (INTERFACE)new IMPL(cPtr,false)
|
||||||
|
%}
|
||||||
|
%typemap(javain) CTYPE*, const CTYPE& "$javainput." ## #INTERFACE ## "_getCPtr()"
|
||||||
|
%typemap(javaout) CTYPE*, const CTYPE&
|
||||||
|
{
|
||||||
|
long cPtr = $jnicall;
|
||||||
|
return (cPtr == 0) ? null : (INTERFACE)new IMPL(cPtr,true);
|
||||||
|
}
|
||||||
|
SWIG_JAVABODY_PROXY(public, protected, CTYPE)
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
%define DECLARE_INTERFACE_RENAME(CTYPE, INTERFACE, IMPL)
|
||||||
|
%rename (IMPL) CTYPE;
|
||||||
|
DECLARE_INTERFACE_(CTYPE, INTERFACE, IMPL)
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
%define DECLARE_INTERFACE(CTYPE, INTERFACE)
|
||||||
|
DECLARE_INTERFACE_(CTYPE, INTERFACE, CTYPE)
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
/* Hash type used for upcalls from C/C++ */
|
/* Hash type used for upcalls from C/C++ */
|
||||||
typedef DOH UpcallData;
|
typedef DOH UpcallData;
|
||||||
|
// helper function used in feature:interface implementation
|
||||||
void Swig_propagate_interface_methods(Node *n);
|
void Swig_propagate_interface_methods(Node *n);
|
||||||
|
|
||||||
class CSHARP:public Language {
|
class CSHARP:public Language {
|
||||||
|
|
@ -82,7 +82,6 @@ class CSHARP:public Language {
|
||||||
String *director_method_types; // Director method types
|
String *director_method_types; // Director method types
|
||||||
String *director_connect_parms; // Director delegates parameter list for director connect call
|
String *director_connect_parms; // Director delegates parameter list for director connect call
|
||||||
String *destructor_call; //C++ destructor call if any
|
String *destructor_call; //C++ destructor call if any
|
||||||
String *interface_code;
|
|
||||||
|
|
||||||
// Director method stuff:
|
// Director method stuff:
|
||||||
List *dmethods_seq;
|
List *dmethods_seq;
|
||||||
|
|
@ -135,7 +134,6 @@ public:
|
||||||
variable_name(NULL),
|
variable_name(NULL),
|
||||||
proxy_class_constants_code(NULL),
|
proxy_class_constants_code(NULL),
|
||||||
module_class_constants_code(NULL),
|
module_class_constants_code(NULL),
|
||||||
interface_code(0),
|
|
||||||
enum_code(NULL),
|
enum_code(NULL),
|
||||||
dllimport(NULL),
|
dllimport(NULL),
|
||||||
namespce(NULL),
|
namespce(NULL),
|
||||||
|
|
@ -1585,16 +1583,19 @@ public:
|
||||||
}
|
}
|
||||||
String* getQualifiedInterfaceName(Node* n)
|
String* getQualifiedInterfaceName(Node* n)
|
||||||
{
|
{
|
||||||
String* ret;
|
String* ret = Getattr(n, "feature:interface:qname");
|
||||||
String *nspace = Getattr(n, "sym:nspace");
|
if (!ret) {
|
||||||
String *iname = Getattr(n, "feature:interface:name");
|
String *nspace = Getattr(n, "sym:nspace");
|
||||||
if (nspace) {
|
String *iname = Getattr(n, "feature:interface:name");
|
||||||
if (namespce)
|
if (nspace) {
|
||||||
ret = NewStringf("%s.%s.%s", namespce, nspace, iname);
|
if (namespce)
|
||||||
else
|
ret = NewStringf("%s.%s.%s", namespce, nspace, iname);
|
||||||
ret = NewStringf("%s.%s", nspace, iname);
|
else
|
||||||
} else {
|
ret = NewStringf("%s.%s", nspace, iname);
|
||||||
ret = Copy(iname);
|
} else {
|
||||||
|
ret = Copy(iname);
|
||||||
|
}
|
||||||
|
Setattr(n, "feature:interface:qname", ret);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -1611,7 +1612,7 @@ public:
|
||||||
upcast_name = NewStringf("%s.%s", iname, cptr_func);
|
upcast_name = NewStringf("%s.%s", iname, cptr_func);
|
||||||
else
|
else
|
||||||
upcast_name = NewStringf("%s.GetCPtr", iname);
|
upcast_name = NewStringf("%s.GetCPtr", iname);
|
||||||
Printf(interface_upcasts, " HandleRef %s()", upcast_name);
|
Printf(interface_upcasts, " public HandleRef %s()", upcast_name);
|
||||||
Replaceall(upcast_name, ".", "_");
|
Replaceall(upcast_name, ".", "_");
|
||||||
String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, upcast_name);
|
String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, upcast_name);
|
||||||
String *wname = Swig_name_wrapper(upcast_method);
|
String *wname = Swig_name_wrapper(upcast_method);
|
||||||
|
|
@ -1626,7 +1627,6 @@ public:
|
||||||
Delete(upcast_name);
|
Delete(upcast_name);
|
||||||
Delete(wname);
|
Delete(wname);
|
||||||
Delete(upcast_method);
|
Delete(upcast_method);
|
||||||
Delete(iname);
|
|
||||||
Delete(c_baseclass);
|
Delete(c_baseclass);
|
||||||
}
|
}
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
|
|
@ -1850,6 +1850,7 @@ public:
|
||||||
Delete(director_connect_method_name);
|
Delete(director_connect_method_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Delete(interface_upcasts);
|
||||||
Delete(interface_list);
|
Delete(interface_list);
|
||||||
Delete(attributes);
|
Delete(attributes);
|
||||||
Delete(destruct);
|
Delete(destruct);
|
||||||
|
|
@ -1939,9 +1940,6 @@ public:
|
||||||
* ---------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
virtual int classHandler(Node *n) {
|
virtual int classHandler(Node *n) {
|
||||||
String* old_interface_code = interface_code;
|
|
||||||
interface_code = NewStringEmpty();
|
|
||||||
bool isInterface = GetFlag(n, "feature:interface") != 0;
|
|
||||||
String *nspace = getNSpace();
|
String *nspace = getNSpace();
|
||||||
File *f_proxy = NULL;
|
File *f_proxy = NULL;
|
||||||
File *f_interface = NULL;
|
File *f_interface = NULL;
|
||||||
|
|
@ -1982,8 +1980,7 @@ public:
|
||||||
FileErrorDisplay(filen);
|
FileErrorDisplay(filen);
|
||||||
SWIG_exit(EXIT_FAILURE);
|
SWIG_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
Append(filenames_list, Copy(filen));
|
Append(filenames_list, filen);
|
||||||
Delete(filen);
|
|
||||||
|
|
||||||
// Start writing out the proxy class file
|
// Start writing out the proxy class file
|
||||||
emitBanner(f_proxy);
|
emitBanner(f_proxy);
|
||||||
|
|
@ -2013,6 +2010,7 @@ public:
|
||||||
addOpenNamespace(nspace, f_interface);
|
addOpenNamespace(nspace, f_interface);
|
||||||
emitInterfaceDeclaration(n, iname, f_interface);
|
emitInterfaceDeclaration(n, iname, f_interface);
|
||||||
}
|
}
|
||||||
|
Delete(output_directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
Language::classHandler(n);
|
Language::classHandler(n);
|
||||||
|
|
@ -2073,8 +2071,6 @@ public:
|
||||||
destructor_call = NULL;
|
destructor_call = NULL;
|
||||||
Delete(proxy_class_constants_code);
|
Delete(proxy_class_constants_code);
|
||||||
proxy_class_constants_code = NULL;
|
proxy_class_constants_code = NULL;
|
||||||
Delete(interface_code);
|
|
||||||
interface_code = old_interface_code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
/* Hash type used for upcalls from C/C++ */
|
/* Hash type used for upcalls from C/C++ */
|
||||||
typedef DOH UpcallData;
|
typedef DOH UpcallData;
|
||||||
|
// helper function used in feature:interface implementation
|
||||||
|
void Swig_propagate_interface_methods(Node *n);
|
||||||
|
|
||||||
class JAVA:public Language {
|
class JAVA:public Language {
|
||||||
static const char *usage;
|
static const char *usage;
|
||||||
|
|
@ -53,6 +55,7 @@ class JAVA:public Language {
|
||||||
String *imclass_class_code; // intermediary class code
|
String *imclass_class_code; // intermediary class code
|
||||||
String *proxy_class_def;
|
String *proxy_class_def;
|
||||||
String *proxy_class_code;
|
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 *module_class_code;
|
||||||
String *proxy_class_name; // proxy class name
|
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
|
String *full_proxy_class_name;// fully qualified proxy class name when using nspace feature, otherwise same as proxy_class_name
|
||||||
|
|
@ -124,6 +127,7 @@ public:
|
||||||
imclass_class_code(NULL),
|
imclass_class_code(NULL),
|
||||||
proxy_class_def(NULL),
|
proxy_class_def(NULL),
|
||||||
proxy_class_code(NULL),
|
proxy_class_code(NULL),
|
||||||
|
interface_class_code(NULL),
|
||||||
module_class_code(NULL),
|
module_class_code(NULL),
|
||||||
proxy_class_name(NULL),
|
proxy_class_name(NULL),
|
||||||
full_proxy_class_name(NULL),
|
full_proxy_class_name(NULL),
|
||||||
|
|
@ -1698,6 +1702,62 @@ public:
|
||||||
return Language::pragmaDirective(n);
|
return Language::pragmaDirective(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String* getQualifiedInterfaceName(Node* n)
|
||||||
|
{
|
||||||
|
String* ret = Getattr(n, "feature: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, "feature:interface:qname", ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void addInterfaceNameAndUpcasts(String* interface_list, String* interface_upcasts, Node* base, String* c_classname) {
|
||||||
|
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_getCPtr", iname);
|
||||||
|
Printf(interface_upcasts, " public long %s()", 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(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);
|
||||||
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* emitProxyClassDefAndCPPCasts()
|
* emitProxyClassDefAndCPPCasts()
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
@ -1707,6 +1767,8 @@ public:
|
||||||
String *c_baseclass = NULL;
|
String *c_baseclass = NULL;
|
||||||
String *baseclass = NULL;
|
String *baseclass = NULL;
|
||||||
String *c_baseclassname = NULL;
|
String *c_baseclassname = NULL;
|
||||||
|
String *interface_list = NewStringEmpty();
|
||||||
|
String *interface_upcasts = NewStringEmpty();
|
||||||
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
|
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
|
||||||
bool feature_director = Swig_directorclass(n) ? true : false;
|
bool feature_director = Swig_directorclass(n) ? true : false;
|
||||||
|
|
||||||
|
|
@ -1725,6 +1787,10 @@ public:
|
||||||
while (base.item && GetFlag(base.item, "feature:ignore")) {
|
while (base.item && GetFlag(base.item, "feature:ignore")) {
|
||||||
base = Next(base);
|
base = Next(base);
|
||||||
}
|
}
|
||||||
|
while (base.item && Getattr(base.item, "feature:interface")) {
|
||||||
|
addInterfaceNameAndUpcasts(interface_list, interface_upcasts, base.item, c_classname);
|
||||||
|
base = Next(base);
|
||||||
|
}
|
||||||
if (base.item) {
|
if (base.item) {
|
||||||
c_baseclassname = Getattr(base.item, "name");
|
c_baseclassname = Getattr(base.item, "name");
|
||||||
baseclass = Copy(getProxyName(c_baseclassname));
|
baseclass = Copy(getProxyName(c_baseclassname));
|
||||||
|
|
@ -1733,18 +1799,21 @@ public:
|
||||||
base = Next(base);
|
base = Next(base);
|
||||||
/* Warn about multiple inheritance for additional base class(es) */
|
/* Warn about multiple inheritance for additional base class(es) */
|
||||||
while (base.item) {
|
while (base.item) {
|
||||||
if (GetFlag(base.item, "feature:ignore")) {
|
if (Getattr(base.item, "feature:interface")) {
|
||||||
base = Next(base);
|
addInterfaceNameAndUpcasts(interface_list, interface_upcasts, base.item, c_classname);
|
||||||
continue;
|
} else if (!GetFlag(base.item, "feature:ignore")) {
|
||||||
}
|
String *proxyclassname = Getattr(n, "classtypeobj");
|
||||||
String *proxyclassname = Getattr(n, "classtypeobj");
|
String *baseclassname = Getattr(base.item, "name");
|
||||||
String *baseclassname = Getattr(base.item, "name");
|
Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
|
||||||
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));
|
||||||
"Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname));
|
}
|
||||||
base = Next(base);
|
base = Next(base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (Getattr(n, "feature:interface")) {
|
||||||
|
addInterfaceNameAndUpcasts(interface_list, interface_upcasts, n, c_classname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool derived = baseclass && getProxyName(c_baseclassname);
|
bool derived = baseclass && getProxyName(c_baseclassname);
|
||||||
|
|
@ -1767,13 +1836,15 @@ public:
|
||||||
|
|
||||||
// Pure Java interfaces
|
// Pure Java interfaces
|
||||||
const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
|
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
|
// Start writing the proxy class
|
||||||
Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE), // Import statements
|
Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE), // Import statements
|
||||||
"\n", typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
|
"\n", typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
|
||||||
" $javaclassname", // Class name and bases
|
" $javaclassname", // Class name and bases
|
||||||
(*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(pure_interfaces) ? // Pure Java interfaces
|
(*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(interface_list) ? // Pure Java interfaces
|
||||||
" implements " : "", pure_interfaces, " {", derived ? typemapLookup(n, "javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class
|
" 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
|
typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class
|
||||||
NIL);
|
NIL);
|
||||||
|
|
||||||
|
|
@ -1816,6 +1887,8 @@ public:
|
||||||
if (*Char(destruct))
|
if (*Char(destruct))
|
||||||
Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " void ", destruct_methodname, "()", destructor_throws_clause, " ", destruct, "\n", NIL);
|
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 */
|
/* Insert directordisconnect typemap, if this class has directors enabled */
|
||||||
/* Also insert the swigTakeOwnership and swigReleaseOwnership methods */
|
/* Also insert the swigTakeOwnership and swigReleaseOwnership methods */
|
||||||
|
|
@ -1837,6 +1910,8 @@ public:
|
||||||
Delete(take_jnicall);
|
Delete(take_jnicall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Delete(interface_upcasts);
|
||||||
|
Delete(interface_list);
|
||||||
Delete(attributes);
|
Delete(attributes);
|
||||||
Delete(destruct);
|
Delete(destruct);
|
||||||
|
|
||||||
|
|
@ -1897,13 +1972,53 @@ public:
|
||||||
Delete(baseclass);
|
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 = NewStringf(" : %s", 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_getCPtr();\n", iname);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
* classHandler()
|
* classHandler()
|
||||||
* ---------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
virtual int classHandler(Node *n) {
|
virtual int classHandler(Node *n) {
|
||||||
|
|
||||||
File *f_proxy = NULL;
|
File *f_proxy = NULL;
|
||||||
|
File *f_interface = NULL;
|
||||||
|
String *old_interface_class_code = interface_class_code;
|
||||||
|
interface_class_code = 0;
|
||||||
if (proxy_flag) {
|
if (proxy_flag) {
|
||||||
proxy_class_name = NewString(Getattr(n, "sym:name"));
|
proxy_class_name = NewString(Getattr(n, "sym:name"));
|
||||||
String *nspace = getNSpace();
|
String *nspace = getNSpace();
|
||||||
|
|
@ -1938,8 +2053,7 @@ public:
|
||||||
FileErrorDisplay(filen);
|
FileErrorDisplay(filen);
|
||||||
SWIG_exit(EXIT_FAILURE);
|
SWIG_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
Append(filenames_list, Copy(filen));
|
Append(filenames_list, filen);
|
||||||
Delete(filen);
|
|
||||||
filen = NULL;
|
filen = NULL;
|
||||||
|
|
||||||
// Start writing out the proxy class file
|
// Start writing out the proxy class file
|
||||||
|
|
@ -1960,6 +2074,24 @@ public:
|
||||||
destructor_call = NewString("");
|
destructor_call = NewString("");
|
||||||
destructor_throws_clause = NewString("");
|
destructor_throws_clause = NewString("");
|
||||||
proxy_class_constants_code = 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);
|
Delete(output_directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2030,6 +2162,11 @@ public:
|
||||||
Delete(downcast_method);
|
Delete(downcast_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (f_interface) {
|
||||||
|
Printv(f_interface, interface_class_code, "}\n", NIL);
|
||||||
|
Delete(f_interface);
|
||||||
|
}
|
||||||
|
|
||||||
emitDirectorExtraMethods(n);
|
emitDirectorExtraMethods(n);
|
||||||
|
|
||||||
Delete(javaclazzname);
|
Delete(javaclazzname);
|
||||||
|
|
@ -2119,6 +2256,7 @@ public:
|
||||||
bool setter_flag = false;
|
bool setter_flag = false;
|
||||||
String *pre_code = NewString("");
|
String *pre_code = NewString("");
|
||||||
String *post_code = NewString("");
|
String *post_code = NewString("");
|
||||||
|
bool is_interface = Getattr(parentNode(n), "feature:interface") != 0 && !static_flag;
|
||||||
|
|
||||||
if (!proxy_flag)
|
if (!proxy_flag)
|
||||||
return;
|
return;
|
||||||
|
|
@ -2169,6 +2307,9 @@ public:
|
||||||
Printf(function_code, "static ");
|
Printf(function_code, "static ");
|
||||||
Printf(function_code, "%s %s(", return_type, proxy_function_name);
|
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);
|
Printv(imcall, full_imclass_name, ".$imfuncname(", NIL);
|
||||||
if (!static_flag) {
|
if (!static_flag) {
|
||||||
Printf(imcall, "swigCPtr");
|
Printf(imcall, "swigCPtr");
|
||||||
|
|
@ -2255,10 +2396,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add parameter to proxy function */
|
/* Add parameter to proxy function */
|
||||||
if (gencomma >= 2)
|
if (gencomma >= 2) {
|
||||||
Printf(function_code, ", ");
|
Printf(function_code, ", ");
|
||||||
|
if (is_interface)
|
||||||
|
Printf(interface_class_code, ", ");
|
||||||
|
}
|
||||||
gencomma = 2;
|
gencomma = 2;
|
||||||
Printf(function_code, "%s %s", param_type, arg);
|
Printf(function_code, "%s %s", param_type, arg);
|
||||||
|
if (is_interface)
|
||||||
|
Printf(interface_class_code, "%s %s", param_type, arg);
|
||||||
|
|
||||||
if (prematureGarbageCollectionPreventionParameter(pt, p)) {
|
if (prematureGarbageCollectionPreventionParameter(pt, p)) {
|
||||||
String *pgcppname = Getattr(p, "tmap:javain:pgcppname");
|
String *pgcppname = Getattr(p, "tmap:javain:pgcppname");
|
||||||
|
|
@ -2280,6 +2426,8 @@ public:
|
||||||
|
|
||||||
Printf(imcall, ")");
|
Printf(imcall, ")");
|
||||||
Printf(function_code, ")");
|
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)
|
// 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))) {
|
if ((tm = Swig_typemap_lookup("javaout", n, "", 0))) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue