From: zhiyang j. <ja...@gm...> - 2008-08-10 08:31:07
|
Index: /home/jazy/workspace/SWIG/Examples/test-suite/common.mk =================================================================== --- /home/jazy/workspace/SWIG/Examples/test-suite/common.mk (revision 10659) +++ /home/jazy/workspace/SWIG/Examples/test-suite/common.mk (working copy) @@ -221,6 +221,7 @@ minherit2 \ mixed_types \ multiple_inheritance \ + multiple_inheritance_abstract \ name_cxx \ name_warnings \ namespace_class \ Index: /home/jazy/workspace/SWIG/Examples/test-suite/java/multiple_inheritance_abstract_runme.java =================================================================== --- /home/jazy/workspace/SWIG/Examples/test-suite/java/multiple_inheritance_abstract_runme.java (revision 0) +++ /home/jazy/workspace/SWIG/Examples/test-suite/java/multiple_inheritance_abstract_runme.java (revision 0) @@ -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");*/ + +} +} Index: /home/jazy/workspace/SWIG/Examples/test-suite/multiple_inheritance_abstract.i =================================================================== --- /home/jazy/workspace/SWIG/Examples/test-suite/multiple_inheritance_abstract.i (revision 0) +++ /home/jazy/workspace/SWIG/Examples/test-suite/multiple_inheritance_abstract.i (revision 0) @@ -0,0 +1,105 @@ +%module multiple_inheritance_abstract + +%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, + SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, + SWIGWARN_PHP4_MULTIPLE_INHERITANCE) Derived1; /* C#, Java, Php4 multiple inheritance */ + +%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, + SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, + SWIGWARN_PHP4_MULTIPLE_INHERITANCE) Derived2; /* C#, Java, Php4 multiple inheritance */ +%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, + SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, + SWIGWARN_PHP4_MULTIPLE_INHERITANCE) Derived3; /* C#, Java, Php4 multiple inheritance */ +%feature("interface") ABase1; +%feature("interface") CBase1; +%feature("interface") 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(); +} + +%} Property changes on: /home/jazy/workspace/SWIG/Examples/test-suite/multiple_inheritance_abstract.i ___________________________________________________________________ Name: svn:executable + * Index: /home/jazy/workspace/SWIG/Lib/java/java.swg =================================================================== --- /home/jazy/workspace/SWIG/Lib/java/java.swg (revision 10659) +++ /home/jazy/workspace/SWIG/Lib/java/java.swg (working copy) @@ -967,9 +967,10 @@ jdoubleArray, jobjectArray "$javainput" -%typemap(javain) SWIGTYPE "$&javaclassname.getCPtr($javainput)" -%typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "$javaclassname.getCPtr($javainput)" - +/*%typemap(javain) SWIGTYPE "$&javaclassname.getCPtr($javainput)" +%typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "$javaclassname.getCPtr($javainput)"*/ +%typemap(javain) SWIGTYPE "(($javainput!=null)?$javainput.getCPtr():0)" +%typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "(($javainput!=null)?$javainput.getCPtr():0)" /* The javaout typemap is used for converting function return types from the return type * used in the JNI class to the type returned by the proxy, module or type wrapper class. */ %typemap(javaout) bool, const bool &, @@ -1030,7 +1031,8 @@ %typemap(jni) SWIGTYPE *& "jlong" %typemap(jtype) SWIGTYPE *& "long" %typemap(jstype) SWIGTYPE *& "$*javaclassname" -%typemap(javain) SWIGTYPE *& "$*javaclassname.getCPtr($javainput)" +/*%typemap(javain) SWIGTYPE *& "$*javaclassname.getCPtr($javainput)"*/ +%typemap(javain) SWIGTYPE *& "(($javainput!=null)?$javainput.getCPtr():0)" %typemap(javaout) SWIGTYPE *& { long cPtr = $jnicall; return (cPtr == 0) ? null : new $*javaclassname(cPtr, $owner); @@ -1064,8 +1066,11 @@ swigCPtr = cPtr; } - CPTR_VISIBILITY static long getCPtr($javaclassname obj) { +/* CPTR_VISIBILITY long getCPtr($javaclassname obj) { return (obj == null) ? 0 : obj.swigCPtr; + }*/ + public long getCPtr() { + return swigCPtr; } %} @@ -1072,15 +1077,23 @@ // Derived proxy classes %typemap(javabody_derived) TYPENAME %{ private long swigCPtr; - + protected boolean swigCMemOwn; + //private long swigPPtr; PTRCTOR_VISIBILITY $javaclassname(long cPtr, boolean cMemoryOwn) { - super($imclassname.SWIG$javaclassnameUpcast(cPtr), cMemoryOwn); + //super($imclassname.SWIG$javaclassnameUpcast(cPtr), cMemoryOwn); + //swigPPtr=$imclassname.SWIG$javaclassnameUpcast(cPtr); swigCPtr = cPtr; } - CPTR_VISIBILITY static long getCPtr($javaclassname obj) { + /*CPTR_VISIBILITY static long getCPtr($javaclassname obj) { return (obj == null) ? 0 : obj.swigCPtr; + }*/ + public long getCPtr() { + return swigCPtr; } + /* public long getPPtr(){ + return swigPPtr; + }*/ %} %enddef @@ -1101,8 +1114,11 @@ swigCPtr = 0; } - protected static long getCPtr($javaclassname obj) { + /* protected static long getCPtr($javaclassname obj) { return (obj == null) ? 0 : obj.swigCPtr; + }*/ + public long getCPtr() { + return swigCPtr; } %} @@ -1160,7 +1176,8 @@ $jnicall; } swigCPtr = 0; - super.delete(); + //super.delete(); + // swigPPtr=0; } %typemap(directordisconnect, methodname="swigDirectorDisconnect") SWIGTYPE %{ Index: /home/jazy/workspace/SWIG/Source/CParse/parser.y =================================================================== --- /home/jazy/workspace/SWIG/Source/CParse/parser.y (revision 10659) +++ /home/jazy/workspace/SWIG/Source/CParse/parser.y (working copy) @@ -3189,8 +3189,8 @@ nscope_inner = 0; } } - Setattr($$,"name",$3); - + Setattr($$,"name",$3); + /*Printf(stdout,"the cpares features are %s\n.",Getattr(Swig_cparse_features(),"feature:interface"));*/ Delete(class_rename); class_rename = make_name($$,$3,0); Classprefix = NewString($3); @@ -3223,6 +3223,13 @@ if (bases) { Iterator s; for (s = First(bases); s.item; s = Next(s)) { + /*set the Derived class has a interface base feature*/ + if(GetFlag(s.item,"feature:interface")){ + String* interface=NewStringf("feature:interface:%s",Getattr(s.item,"name")); + SetFlag($$,interface); + Delete(interface); + } + Symtab *st = Getattr(s.item,"symtab"); if (st) { Setfile(st,Getfile(s.item)); Index: /home/jazy/workspace/SWIG/Source/Modules/java.cxx =================================================================== --- /home/jazy/workspace/SWIG/Source/Modules/java.cxx (revision 10659) +++ /home/jazy/workspace/SWIG/Source/Modules/java.cxx (working copy) @@ -32,7 +32,8 @@ File *f_directors; File *f_directors_h; List *filenames_list; - + List *interfaces_list; //list to save interfaces + bool proxy_flag; // Flag for generating proxy classes bool nopgcpp_flag; // Flag for suppressing the premature garbage collection prevention parameter bool native_function_flag; // Flag for when wrapping a native function @@ -70,7 +71,7 @@ String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code String *imclass_directors; // Intermediate class director code String *destructor_call; //C++ destructor call if any - + String *interface_code; // C++ base class from %feature("interface") // Director method stuff: List *dmethods_seq; Hash *dmethods_table; @@ -106,6 +107,7 @@ f_directors(NULL), f_directors_h(NULL), filenames_list(NULL), + interfaces_list(NULL), proxy_flag(true), nopgcpp_flag(false), native_function_flag(false), @@ -141,6 +143,7 @@ imclass_cppcasts_code(NULL), imclass_directors(NULL), destructor_call(NULL), + interface_code(NULL), dmethods_seq(NULL), dmethods_table(NULL), n_dmethods(0), @@ -167,7 +170,18 @@ } return NULL; } - + /*isInterface() + * Test wheather "name" is a interface in "l" + */ +bool isInterface(List* l,String* name){ + Iterator i; + for(i=First(l);i.item;i=Next(i)){ + if(Cmp(name,i.item)==0){ + return true; + } + } + return false; +} /* ----------------------------------------------------------------------------- * makeValidJniName() * ----------------------------------------------------------------------------- */ @@ -195,7 +209,7 @@ return dirclassname; } - + /* ------------------------------------------------------------ * main() * ------------------------------------------------------------ */ @@ -327,7 +341,7 @@ swig_types_hash = NewHash(); filenames_list = NewList(); - + interfaces_list=NewList(); // Make the intermediary class and module class names. The intermediary class name can be set in the module directive. if (!imclass_name) { imclass_name = NewStringf("%sJNI", Getattr(n, "name")); @@ -343,6 +357,7 @@ imclass_class_code = NewString(""); proxy_class_def = NewString(""); proxy_class_code = NewString(""); + interface_code=NewString(""); module_class_constants_code = NewString(""); imclass_baseclass = NewString(""); imclass_interfaces = NewString(""); @@ -596,6 +611,8 @@ proxy_class_def = NULL; Delete(proxy_class_code); proxy_class_code = NULL; + Delete(interface_code); + interface_code=NULL; Delete(module_class_constants_code); module_class_constants_code = NULL; Delete(imclass_baseclass); @@ -1552,14 +1569,18 @@ String *baseclass = NULL; String *c_baseclassname = NULL; String *typemap_lookup_type = Getattr(n, "classtypeobj"); + String *interface=NewStringf(""); bool feature_director = Swig_directorclass(n) ? true : false; - + bool isExtend=true; //wheather the keyword extend is needed // Inheritance from pure Java classes Node *attributes = NewHash(); - const String *pure_baseclass = typemapLookup("javabase", typemap_lookup_type, WARN_NONE, attributes); + const String *pure_baseclass = typemapLookup("javabase", typemap_lookup_type, WARN_NONE, attributes); bool purebase_replace = GetFlag(attributes, "tmap:javabase:replace") ? true : false; Delete(attributes); - + //the interface itself is the base of the classes like SWIGTYEP_XXX + if(GetFlag(n,"feature:interface")){ + Printf(interface,"%s",Getattr(n,"name")); + } // C++ inheritance if (!purebase_replace) { List *baselist = Getattr(n, "bases"); @@ -1570,6 +1591,17 @@ } if (base.item) { c_baseclassname = Getattr(base.item, "name"); + + //we get the fist base class from here + String* aFeature=NewStringf("feature:interface:%s",c_baseclassname); + if(GetFlag(n,aFeature)){ + isExtend=false; + Printf(interface,"%s",c_baseclassname); + if(Next(base).item&&!GetFlag(Next(base).item,"feature:ignore")){ + Printf(interface,","); + } + } + Delete(aFeature); baseclass = Copy(getProxyName(c_baseclassname)); if (baseclass) c_baseclass = SwigType_namestr(Getattr(base.item, "name")); @@ -1576,10 +1608,20 @@ base = Next(base); /* Warn about multiple inheritance for additional base class(es) */ while (base.item) { + //add other interfaces into string "interface" + aFeature=NewStringf("feature:interface:%s",Getattr(base.item, "name")); if (GetFlag(base.item, "feature:ignore")) { base = Next(base); continue; + }else{ + if(GetFlag(n,aFeature)){ + Printf(interface,"%s",Getattr(base.item, "name")); + if(Next(base).item&&!GetFlag(Next(base).item,"feature:ignore")){ + Printf(interface,","); + } } + } + Delete(aFeature); String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0); String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0); Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, input_file, line_number, @@ -1585,6 +1627,8 @@ Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, input_file, line_number, "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", proxyclassname, baseclassname); base = Next(base); + + } } } @@ -1591,8 +1635,11 @@ } bool derived = baseclass && getProxyName(c_baseclassname); + if(!isExtend){ + baseclass=NULL; + + } const String *wanted_base = baseclass ? baseclass : pure_baseclass; - if (purebase_replace) { wanted_base = pure_baseclass; derived = false; @@ -1610,8 +1657,9 @@ Printv(proxy_class_def, typemapLookup("javaimports", typemap_lookup_type, WARN_NONE), // Import statements "\n", typemapLookup("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("javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class + (*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(pure_interfaces)||(Cmp(interface,"")) ? + " implements " : "",interface,*Char(pure_interfaces)?",":"", pure_interfaces, // Pure Java interfaces + " {", derived ? typemapLookup("javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class typemapLookup("javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class NIL); @@ -1673,6 +1721,7 @@ Delete(destruct_jnicall); Delete(release_jnicall); Delete(take_jnicall); + Delete(interface); } Delete(attributes); @@ -1683,8 +1732,17 @@ "\n", NIL); // Substitute various strings into the above template - Replaceall(proxy_class_code, "$javaclassname", proxy_class_name); - Replaceall(proxy_class_def, "$javaclassname", proxy_class_name); + if(GetFlag(n,"feature:interface")){ + String* mangleName=NewStringf("SWIGTYPE_%s",proxy_class_name); + Replaceall(proxy_class_code, "$javaclassname", mangleName); + Replaceall(proxy_class_def, "$javaclassname", mangleName); + Delete(mangleName); + }else{ + Replaceall(proxy_class_code, "$javaclassname", proxy_class_name); + Replaceall(proxy_class_def, "$javaclassname", proxy_class_name); + } + + Replaceall(proxy_class_def, "$module", module_class_name); Replaceall(proxy_class_code, "$module", module_class_name); @@ -1740,8 +1798,15 @@ Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name); SWIG_exit(EXIT_FAILURE); } - - String *filen = NewStringf("%s%s.java", SWIG_output_directory(), proxy_class_name); + + String *filen=NULL; + //add the class name declared by %feauture("interface") into interfaces_list + if(GetFlag(n,"feature:interface")){ + Append(interfaces_list,Getattr(n,"name")); + filen = NewStringf("SWIGTYPE_%s%s.java", SWIG_output_directory(), proxy_class_name); + }else{ + filen = NewStringf("%s%s.java", SWIG_output_directory(), proxy_class_name); + } f_proxy = NewFile(filen, "w"); if (!f_proxy) { FileErrorDisplay(filen); @@ -1759,7 +1824,7 @@ Clear(proxy_class_def); Clear(proxy_class_code); - + Clear(interface_code); destructor_call = NewString(""); proxy_class_constants_code = NewString(""); } @@ -1812,7 +1877,22 @@ Wrapper_print(dcast_wrap, f_wrappers); DelWrapper(dcast_wrap); } - + //if the class is declared as interface in SWIG,generate a java interface + if(GetFlag(n,"feature:interface")){ + String *interfaceName=NewStringf("%s%s.java",SWIG_output_directory(),proxy_class_name); + File* f_interface= NewFile(interfaceName, "w"); + emitBanner(f_interface); + if (Len(package) > 0) + Printf(f_interface, "package %s;\n", package); + Printf(f_interface,"public interface %s%s",SWIG_output_directory(),proxy_class_name); + Printf(f_interface,"{\n"); + Printv(f_interface,interface_code, NIL); + // add two common methods in java interface + Printf(f_interface,"long getCPtr();\n"); + Printf(f_interface,"void delete();\n"); + Printf(f_interface,"}"); + Delete(interfaceName); + } emitDirectorExtraMethods(n); Delete(proxy_class_name); @@ -1822,7 +1902,9 @@ Delete(proxy_class_constants_code); proxy_class_constants_code = NULL; } - + + + return SWIG_OK; } @@ -1884,6 +1966,7 @@ void proxyClassFunctionHandler(Node *n) { SwigType *t = Getattr(n, "type"); ParmList *l = Getattr(n, "parms"); + String* storage=Getattr(n,"storage"); String *intermediary_function_name = Getattr(n, "imfuncname"); String *proxy_function_name = Getattr(n, "proxyfuncname"); String *tm; @@ -1895,7 +1978,9 @@ bool setter_flag = false; String *pre_code = NewString(""); String *post_code = NewString(""); - + + String *interfaceBody=NewString(""); + if (!proxy_flag) return; @@ -1924,7 +2009,8 @@ // Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type SwigType *covariant = Getattr(n, "covariant"); substituteClassname(covariant ? covariant : t, tm); - Printf(return_type, "%s", tm); + + Printf(return_type, "%s", tm); if (covariant) Swig_warning(WARN_JAVA_COVARIANT_RET, input_file, line_number, "Covariant return types not supported in Java. Proxy method will return %s.\n", SwigType_str(covariant, 0)); @@ -1941,10 +2027,14 @@ const String *methodmods = Getattr(n, "feature:java:methodmodifiers"); methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); Printf(function_code, " %s ", methodmods); + if (static_flag) Printf(function_code, "static "); Printf(function_code, "%s %s(", return_type, proxy_function_name); - + // extract virtual function return type for java interface + if(Cmp(storage,"virtual")==0){ + Printf(interfaceBody, "%s %s(", return_type, proxy_function_name); + } Printv(imcall, imclass_name, ".$imfuncname(", NIL); if (!static_flag) { Printf(imcall, "swigCPtr"); @@ -1994,7 +2084,7 @@ /* Get the Java parameter type */ if ((tm = Getattr(p, "tmap:jstype"))) { substituteClassname(pt, tm); - Printf(param_type, "%s", tm); + Printf(param_type, "%s", tm); } else { Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt, 0)); } @@ -2031,10 +2121,17 @@ } /* Add parameter to proxy function */ - if (gencomma >= 2) + if (gencomma >= 2){ Printf(function_code, ", "); + if(Cmp(storage,"virtual")==0){ + Printf(interfaceBody, ", "); + } + } gencomma = 2; Printf(function_code, "%s %s", param_type, arg); + // extract virtual function param type for java interface + if(Cmp(storage,"virtual")==0) + Printf(interfaceBody, "%s %s", param_type, arg); if (prematureGarbageCollectionPreventionParameter(pt, p)) { String *pgcppname = Getattr(p, "tmap:javain:pgcppname"); @@ -2056,7 +2153,9 @@ Printf(imcall, ")"); Printf(function_code, ")"); - + if(Cmp(storage,"virtual")==0){ + Printf(interfaceBody,")"); + } // 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))) { addThrows(n, "tmap:javaout", n); @@ -2081,7 +2180,7 @@ Replaceall(tm, "$owner", "true"); else Replaceall(tm, "$owner", "false"); - substituteClassname(t, tm); + substituteClassnameJavaout(t, tm); // For director methods: generate code to selectively make a normal polymorphic call or // an explicit method call - needed to prevent infinite recursion calls in director methods. @@ -2112,11 +2211,20 @@ } else { Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0)); } - + generateThrowsClause(n, function_code); + + Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string); + if(Cmp(storage,"virtual")==0){ + Printf(interfaceBody,";\n"); + } + Printv(proxy_class_code, function_code, NIL); - + //add the interface body into interface_code + if(Cmp(storage,"virtual")==0){ + Printv(interface_code, interfaceBody, NIL); + } Delete(pre_code); Delete(post_code); Delete(function_code); @@ -2122,6 +2230,7 @@ Delete(function_code); Delete(return_type); Delete(imcall); + Delete(interfaceBody); } /* ---------------------------------------------------------------------- @@ -2158,8 +2267,13 @@ tm = Getattr(n, "tmap:jtype"); // typemaps were attached earlier to the node Printf(im_return_type, "%s", tm); - - Printf(function_code, " %s %s(", methodmods, proxy_class_name); + if(!isInterface(interfaces_list,proxy_class_name)){ + Printf(function_code, " %s %s(", methodmods, proxy_class_name); + }else{ + //if the class is a interface in java,we also need the concrete class with another name + String* ctorName=NewStringf("SWIGTYPE_%s",proxy_class_name); + Printf(function_code, " %s %s(", methodmods, ctorName); + } Printf(helper_code, " static private %s SwigConstruct%s(", im_return_type, proxy_class_name); Printv(imcall, imclass_name, ".", mangled_overname, "(", NIL); @@ -2266,9 +2380,14 @@ generateThrowsClause(n, function_code); /* Insert the javaconstruct typemap, doing the replacement for $directorconnect, as needed */ + Hash *attributes = NewHash(); - String *construct_tm = Copy(typemapLookup("javaconstruct", Getattr(n, "name"), - WARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF, attributes)); + + + String * construct_tm = Copy(typemapLookup("javaconstruct", Getattr(n,"name"), + WARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF, attributes)); + + if (construct_tm) { if (!feature_director) { Replaceall(construct_tm, "$directorconnect", ""); @@ -2303,16 +2422,18 @@ Printv(helper_code, " return ", imcall, ";", NIL); } Printf(helper_code, "\n }\n"); - String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", proxy_class_name, proxy_class_name, helper_args); + String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", proxy_class_name, proxy_class_name, helper_args); + Printv(proxy_class_code, helper_code, "\n", NIL); Replaceall(function_code, "$imcall", helper_name); + Delete(helper_name); } else { Replaceall(function_code, "$imcall", imcall); + } Printv(proxy_class_code, function_code, "\n", NIL); - Delete(helper_args); Delete(im_return_type); Delete(pre_code); @@ -2433,7 +2554,7 @@ /* Get return types */ if ((tm = Swig_typemap_lookup("jstype", n, "", 0))) { substituteClassname(t, tm); - Printf(return_type, "%s", tm); + Printf(return_type, "%s", tm); } else { Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 0)); } @@ -2480,7 +2601,7 @@ /* Get the Java parameter type */ if ((tm = Getattr(p, "tmap:jstype"))) { substituteClassname(pt, tm); - Printf(param_type, "%s", tm); + Printf(param_type, "%s", tm); } else { Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt, 0)); } @@ -2566,7 +2687,7 @@ Replaceall(tm, "$owner", "true"); else Replaceall(tm, "$owner", "false"); - substituteClassname(t, tm); + substituteClassnameJavaout(t, tm); Replaceall(tm, "$jnicall", imcall); } else { Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0)); @@ -2727,6 +2848,42 @@ return substitution_performed; } + /* + * substituteClassnameJavaout() + * almost same as substituteClassname(),it is used replace the $javaclassname in javaout + * when the SwigType is declared as interface through %feature("interface") + */ + bool substituteClassnameJavaout(SwigType *pt, String *tm, bool jnidescriptor = false) { + bool substitution_performed = false; + SwigType *type = Copy(SwigType_typedef_resolve_all(pt)); + SwigType *strippedtype = SwigType_strip_qualifiers(type); + + if (Strstr(tm, "$javaclassname")) { + SwigType *classnametype = Copy(strippedtype); + substituteClassnameSpecialVariableJavaout(classnametype, tm, "$javaclassname", jnidescriptor); + substitution_performed = true; + Delete(classnametype); + } + if (Strstr(tm, "$*javaclassname")) { + SwigType *classnametype = Copy(strippedtype); + Delete(SwigType_pop(classnametype)); + substituteClassnameSpecialVariableJavaout(classnametype, tm, "$*javaclassname", jnidescriptor); + substitution_performed = true; + Delete(classnametype); + } + if (Strstr(tm, "$&javaclassname")) { + SwigType *classnametype = Copy(strippedtype); + SwigType_add_pointer(classnametype); + substituteClassnameSpecialVariableJavaout(classnametype, tm, "$&javaclassname", jnidescriptor); + substitution_performed = true; + Delete(classnametype); + } + + Delete(strippedtype); + Delete(type); + + return substitution_performed; + } /* ----------------------------------------------------------------------------- * substituteClassnameSpecialVariable() * ----------------------------------------------------------------------------- */ @@ -2740,8 +2897,12 @@ Replaceall(tm, classnamespecialvariable, NewStringf("int")); } else { String *classname = getProxyName(classnametype); + if (classname) { - Replaceall(tm, classnamespecialvariable, classname); // getProxyName() works for pointers to classes too + + Replaceall(tm, classnamespecialvariable, classname); // getProxyName() works for pointers to classes too + + } else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved. String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype)); Replaceall(tm, classnamespecialvariable, descriptor); @@ -2752,7 +2913,39 @@ } } } +/* + * substituteClassnameSpecialVariableJavaout + */ + void substituteClassnameSpecialVariableJavaout(SwigType *classnametype, String *tm, const char *classnamespecialvariable, bool jnidescriptor) { + if (SwigType_isenum(classnametype)) { + String *enumname = getEnumName(classnametype, jnidescriptor); + if (enumname) + Replaceall(tm, classnamespecialvariable, enumname); + else + Replaceall(tm, classnamespecialvariable, NewStringf("int")); + } else { + String *classname = getProxyName(classnametype); + + if (classname) { + + if(!isInterface(interfaces_list,classname)){ + Replaceall(tm, classnamespecialvariable, classname); // getProxyName() works for pointers to classes too + + }else{ + classname=NewStringf("SWIGTYPE_%s",classname); + Replaceall(tm, classnamespecialvariable, classname); + } + + } else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved. + String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype)); + Replaceall(tm, classnamespecialvariable, descriptor); + // Add to hash table so that the type wrapper classes can be created later + Setattr(swig_types_hash, descriptor, classnametype); + Delete(descriptor); + } + } + } /* ----------------------------------------------------------------------------- * makeParameterName() * |