Director code mods:
JNI field descriptors fix to use C++ type and correctly use the $javaclassname family of special variables. The real C++ type used everwhere in director code to fix numerous director bugs. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@6799 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
1813aaf607
commit
eb0eea2f85
1 changed files with 45 additions and 118 deletions
|
|
@ -2738,71 +2738,12 @@ class JAVA : public Language {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------
|
|
||||||
* Reduce and canonicalize the input type
|
|
||||||
*
|
|
||||||
* (scottm) There is probably a SWIG function to do this, but I
|
|
||||||
* haven't found it yet.
|
|
||||||
* (william) Rewriting this area based on substituteClassname()
|
|
||||||
* should work - using getProxyName() and getEnumName().
|
|
||||||
* --------------------------------------------------------------- */
|
|
||||||
|
|
||||||
Node *canonicalizeType(Node *n, String *classtype) {
|
|
||||||
String *reduced_type = SwigType_typedef_resolve_all(classtype);
|
|
||||||
String *base_type;
|
|
||||||
|
|
||||||
if (SwigType_isenum(reduced_type)) {
|
|
||||||
/* Enum handling code: Swig_typedef_resolve_all() will prefix an
|
|
||||||
* enumerated type with "enum ", leading to all kinds of headaches
|
|
||||||
* when above code is called. Need to call Swig_symbol_clookup
|
|
||||||
* with the unadorned enum name.
|
|
||||||
*/
|
|
||||||
base_type = classtype;
|
|
||||||
} else {
|
|
||||||
base_type = SwigType_base(reduced_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node *classnode = Swig_symbol_clookup(base_type, Getattr(n, "sym:symtab"));
|
|
||||||
|
|
||||||
if (classnode != NULL) {
|
|
||||||
/* This takes care of the case when there are forward declared
|
|
||||||
* classes that Language::classHandler() hasn't encountered yet.
|
|
||||||
*
|
|
||||||
* Swig_symbol_clookup() will find <<a node>> attached to
|
|
||||||
* the base_type name, and there will be a csym:nextSibling node
|
|
||||||
* chain. Most of the time, there **wont** be * a "class"-type
|
|
||||||
* node. Mostly, what I've seen are "constructor"-type nodes.
|
|
||||||
* Eventutally, however, a node is encountered with its
|
|
||||||
* sym:name set and this happens to be the right name.
|
|
||||||
*
|
|
||||||
* The worst that can happen here is that base_type is unchanged,
|
|
||||||
* which tends also to be the right thing to do.
|
|
||||||
*
|
|
||||||
* Dunno, this seems to work, so... contemplate what the "right"
|
|
||||||
* SWIG thing is to do...
|
|
||||||
*/
|
|
||||||
|
|
||||||
while (classnode && Getattr(classnode, "sym:name") == NULL) {
|
|
||||||
classnode = Getattr(classnode, "csym:nextSibling");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (base_type != classtype)
|
|
||||||
Delete(base_type);
|
|
||||||
Delete(reduced_type);
|
|
||||||
|
|
||||||
return classnode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------
|
/* ---------------------------------------------------------------
|
||||||
* Canonicalize the JNI field descriptor
|
* Canonicalize the JNI field descriptor
|
||||||
*
|
*
|
||||||
* Take the input type name, reduce the typedef to its fundamental
|
* Replace the $javapackage and $javaclassname family of special
|
||||||
* type if necessary, normalize its name.
|
* variables with the desired package and Java proxy name as
|
||||||
*
|
* required in the JNI field descriptors.
|
||||||
* See if the resulting typdef-reduced, normalized type name also
|
|
||||||
* has a "javapackage" typemap, and use it instead of the default
|
|
||||||
* package_path.
|
|
||||||
*
|
*
|
||||||
* !!SFM!! If $packagepath occurs in the field descriptor, but
|
* !!SFM!! If $packagepath occurs in the field descriptor, but
|
||||||
* package_path isn't set (length == 0), then strip it and the
|
* package_path isn't set (length == 0), then strip it and the
|
||||||
|
|
@ -2810,36 +2751,30 @@ class JAVA : public Language {
|
||||||
*
|
*
|
||||||
* --------------------------------------------------------------- */
|
* --------------------------------------------------------------- */
|
||||||
|
|
||||||
String *canonicalJNIFDesc(String *in_desc, Node *n, String *classtype) {
|
String *canonicalizeJNIDescriptor(String *descriptor_in, SwigType *type) {
|
||||||
Node *classnode = canonicalizeType(n, classtype);
|
|
||||||
String *name = (classnode ? Getattr(classnode, "name") : classtype);
|
|
||||||
String *symname = (classnode ? Getattr(classnode, "sym:name") : classtype);
|
|
||||||
Parm *tp = NewParm(name, (String *) empty_string);
|
|
||||||
String *pkg_path;
|
|
||||||
|
|
||||||
pkg_path = Swig_typemap_lookup_new("javapackage", tp, "", 0);
|
String *pkg_path = Swig_typemap_lookup_new("javapackage", type, "", 0);
|
||||||
Delete(tp);
|
|
||||||
|
|
||||||
if (pkg_path != NULL && Len(pkg_path) != 0) {
|
if (pkg_path && Len(pkg_path) != 0) {
|
||||||
Replaceall(pkg_path, ".", "/");
|
Replaceall(pkg_path, ".", "/");
|
||||||
} else
|
} else
|
||||||
pkg_path = package_path;
|
pkg_path = package_path;
|
||||||
|
|
||||||
String *mod_desc = Copy(in_desc);
|
String *descriptor_out = Copy(descriptor_in);
|
||||||
|
|
||||||
if (Len(pkg_path) > 0) {
|
if (Len(pkg_path) > 0) {
|
||||||
Replaceall(mod_desc, "$packagepath", pkg_path);
|
Replaceall(descriptor_out, "$packagepath", pkg_path);
|
||||||
} else {
|
} else {
|
||||||
Replaceall(mod_desc, "$packagepath/", empty_string);
|
Replaceall(descriptor_out, "$packagepath/", empty_string);
|
||||||
Replaceall(mod_desc, "$packagepath", empty_string);
|
Replaceall(descriptor_out, "$packagepath", empty_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
Replaceall(mod_desc, "$javaclassname", symname);
|
substituteClassname(type, descriptor_out);
|
||||||
|
|
||||||
if (pkg_path != package_path)
|
if (pkg_path != package_path)
|
||||||
Delete(pkg_path);
|
Delete(pkg_path);
|
||||||
|
|
||||||
return mod_desc;
|
return descriptor_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
@ -2859,20 +2794,20 @@ class JAVA : public Language {
|
||||||
String *classname = Getattr(parent, "sym:name");
|
String *classname = Getattr(parent, "sym:name");
|
||||||
String *name = Getattr(n, "name");
|
String *name = Getattr(n, "name");
|
||||||
String *symname = Getattr(n, "sym:name");
|
String *symname = Getattr(n, "sym:name");
|
||||||
String *type = Getattr(n, "type");
|
SwigType *type = Getattr(n, "type");
|
||||||
|
SwigType *returntype = Getattr(n,"returntype");
|
||||||
String *c_classname = NULL;
|
String *c_classname = NULL;
|
||||||
String *overloaded_name = getOverloadedName(n);
|
String *overloaded_name = getOverloadedName(n);
|
||||||
String *storage = Getattr(n, "storage");
|
String *storage = Getattr(n, "storage");
|
||||||
String *value = Getattr(n, "value");
|
String *value = Getattr(n, "value");
|
||||||
String *decl = Getattr(n, "decl");
|
String *decl = Getattr(n, "decl");
|
||||||
String *declaration = NewString("");
|
String *declaration = NewString("");
|
||||||
String *return_type = Copy(type);
|
|
||||||
String *tm;
|
String *tm;
|
||||||
Parm *p;
|
Parm *p;
|
||||||
int i, num_arguments, num_required;
|
int i, num_arguments, num_required;
|
||||||
Wrapper *w = NewWrapper();
|
Wrapper *w = NewWrapper();
|
||||||
ParmList *l = Getattr(n, "parms");
|
ParmList *l = Getattr(n, "parms");
|
||||||
bool is_void = !(Cmp(type, "void"));
|
bool is_void = !(Cmp(returntype, "void"));
|
||||||
String *qualified_return = NewString("");
|
String *qualified_return = NewString("");
|
||||||
bool pure_virtual = (!(Cmp(storage, "virtual")) && !(Cmp(value, "0")));
|
bool pure_virtual = (!(Cmp(storage, "virtual")) && !(Cmp(value, "0")));
|
||||||
int status = SWIG_OK;
|
int status = SWIG_OK;
|
||||||
|
|
@ -2884,7 +2819,7 @@ class JAVA : public Language {
|
||||||
String *classdesc = NewString("");
|
String *classdesc = NewString("");
|
||||||
String *jniret_desc = NewString("");
|
String *jniret_desc = NewString("");
|
||||||
String *classret_desc = NewString("");
|
String *classret_desc = NewString("");
|
||||||
String *jniret_type = NULL;
|
SwigType *jniret_type = NULL;
|
||||||
String *jupcall_args = NewString("swig_get_self()");
|
String *jupcall_args = NewString("swig_get_self()");
|
||||||
String *imclass_dmethod;
|
String *imclass_dmethod;
|
||||||
Wrapper *imw = NewWrapper();
|
Wrapper *imw = NewWrapper();
|
||||||
|
|
@ -2900,39 +2835,29 @@ class JAVA : public Language {
|
||||||
|
|
||||||
imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(classname, overloaded_name));
|
imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(classname, overloaded_name));
|
||||||
|
|
||||||
// Get the proper name for the parent node (should be a class... hint)
|
// Get the C++ name for the parent node (should be a class... hint)
|
||||||
|
|
||||||
c_classname = Getattr(parent, "name");
|
c_classname = Getattr(parent, "name");
|
||||||
if (!(Cmp(type, "class")))
|
if (!(Cmp(type, "class")))
|
||||||
c_classname = classname;
|
c_classname = classname;
|
||||||
|
|
||||||
/* Handle and form complete return type, including the modification
|
if (returntype) {
|
||||||
to a pointer, if return type is a reference. */
|
|
||||||
|
|
||||||
if (return_type) {
|
|
||||||
if (!is_void) {
|
if (!is_void) {
|
||||||
SwigType *t = Copy(decl);
|
|
||||||
SwigType *f = SwigType_pop_function(t);
|
|
||||||
|
|
||||||
SwigType_push(return_type, t);
|
qualified_return = SwigType_rcaststr(returntype, "result");
|
||||||
|
if (!SwigType_isclass(returntype)) {
|
||||||
Delete(f);
|
if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
|
||||||
Delete(t);
|
Wrapper_add_localv(w, "result", SwigType_lstr(returntype, "result"), NIL);
|
||||||
|
|
||||||
qualified_return = SwigType_rcaststr(return_type, "result");
|
|
||||||
if (!SwigType_isclass(return_type)) {
|
|
||||||
if (!(SwigType_ispointer(return_type) || SwigType_isreference(return_type))) {
|
|
||||||
Wrapper_add_localv(w, "result", SwigType_lstr(return_type, "result"), NIL);
|
|
||||||
} else {
|
} else {
|
||||||
/* initialize pointers to something sane. */
|
/* initialize pointers to something sane. */
|
||||||
Wrapper_add_localv(w, "result", SwigType_lstr(return_type, "result"), "= 0", NIL);
|
Wrapper_add_localv(w, "result", SwigType_lstr(returntype, "result"), "= 0", NIL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SwigType *vt;
|
SwigType *vt;
|
||||||
|
|
||||||
vt = cplus_value_type(return_type);
|
vt = cplus_value_type(returntype);
|
||||||
if (vt == NULL) {
|
if (vt == NULL) {
|
||||||
Wrapper_add_localv(w, "result", SwigType_lstr(return_type, "result"), NIL);
|
Wrapper_add_localv(w, "result", SwigType_lstr(returntype, "result"), NIL);
|
||||||
} else {
|
} else {
|
||||||
Wrapper_add_localv(w, "result", SwigType_lstr(vt, "result"), NIL);
|
Wrapper_add_localv(w, "result", SwigType_lstr(vt, "result"), NIL);
|
||||||
Delete(vt);
|
Delete(vt);
|
||||||
|
|
@ -2940,14 +2865,14 @@ class JAVA : public Language {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the intermediate class wrapper */
|
/* Create the intermediate class wrapper */
|
||||||
Parm *tp = NewParm(return_type, empty_str);
|
Parm *tp = NewParm(returntype, empty_str);
|
||||||
|
|
||||||
tm = Swig_typemap_lookup_new("jtype", tp, "", 0);
|
tm = Swig_typemap_lookup_new("jtype", tp, "", 0);
|
||||||
if (tm != NULL) {
|
if (tm != NULL) {
|
||||||
Printf(imw->def, "public static %s %s(%s self", tm, imclass_dmethod, classname);
|
Printf(imw->def, "public static %s %s(%s self", tm, imclass_dmethod, classname);
|
||||||
} else {
|
} else {
|
||||||
Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number,
|
Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number,
|
||||||
"No jtype typemap defined for %s\n", SwigType_str(t,0));
|
"No jtype typemap defined for %s\n", SwigType_str(returntype,0));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
Printf(imw->def, "public static void %s(%s self", imclass_dmethod, classname);
|
Printf(imw->def, "public static void %s(%s self", imclass_dmethod, classname);
|
||||||
|
|
@ -2955,7 +2880,7 @@ class JAVA : public Language {
|
||||||
/* Get the JNI field descriptor for this return type, add the JNI field descriptor
|
/* Get the JNI field descriptor for this return type, add the JNI field descriptor
|
||||||
to jniret_desc */
|
to jniret_desc */
|
||||||
|
|
||||||
Parm *retpm = NewParm(return_type, empty_str);
|
Parm *retpm = NewParm(returntype, empty_str);
|
||||||
|
|
||||||
if ((jniret_type = Swig_typemap_lookup_new("jni", retpm, "", 0)) != NULL) {
|
if ((jniret_type = Swig_typemap_lookup_new("jni", retpm, "", 0)) != NULL) {
|
||||||
String *jdesc;
|
String *jdesc;
|
||||||
|
|
@ -2971,7 +2896,7 @@ class JAVA : public Language {
|
||||||
&& (jdesc = Getattr(tp, "tmap:directorin:descriptor")) != NULL) {
|
&& (jdesc = Getattr(tp, "tmap:directorin:descriptor")) != NULL) {
|
||||||
String *jnidesc_canon;
|
String *jnidesc_canon;
|
||||||
|
|
||||||
jnidesc_canon = canonicalJNIFDesc(jdesc, n, jniret_type);
|
jnidesc_canon = canonicalizeJNIDescriptor(jdesc, Getattr(tp,"type"));
|
||||||
Append(jniret_desc, jnidesc_canon);
|
Append(jniret_desc, jnidesc_canon);
|
||||||
Delete(jnidesc_canon);
|
Delete(jnidesc_canon);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2983,19 +2908,22 @@ class JAVA : public Language {
|
||||||
Delete(tp);
|
Delete(tp);
|
||||||
} else {
|
} else {
|
||||||
Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number,
|
Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number,
|
||||||
"No jni typemap defined for %s\n", SwigType_str(type,0));
|
"No jni typemap defined for %s\n", SwigType_str(returntype,0));
|
||||||
output_director = false;
|
output_director = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String *jdesc;
|
String *jdesc;
|
||||||
|
|
||||||
if ((tm = Swig_typemap_lookup_new("directorin", retpm, "", 0)) != NULL
|
SwigType *virtualtype = Getattr(n,"virtual:type");
|
||||||
&& (jdesc = Getattr(retpm, "tmap:directorin:descriptor")) != NULL) {
|
SwigType *adjustedreturntype = virtualtype ? virtualtype : returntype;
|
||||||
|
Parm *adjustedreturntypeparm = NewParm(adjustedreturntype, empty_str);
|
||||||
|
|
||||||
|
if ((tm = Swig_typemap_lookup_new("directorin", adjustedreturntypeparm, "", 0)) != NULL
|
||||||
|
&& (jdesc = Getattr(adjustedreturntypeparm, "tmap:directorin:descriptor")) != NULL) {
|
||||||
String *jnidesc_canon;
|
String *jnidesc_canon;
|
||||||
|
|
||||||
// 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
|
// 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 *virtualtype = Getattr(n,"virtual:type");
|
jnidesc_canon = canonicalizeJNIDescriptor(jdesc, adjustedreturntype);
|
||||||
jnidesc_canon = canonicalJNIFDesc(jdesc, n, virtualtype ? virtualtype : return_type);
|
|
||||||
Append(classret_desc, jnidesc_canon);
|
Append(classret_desc, jnidesc_canon);
|
||||||
Delete(jnidesc_canon);
|
Delete(jnidesc_canon);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3004,6 +2932,7 @@ class JAVA : public Language {
|
||||||
output_director = false;
|
output_director = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Delete(adjustedreturntypeparm);
|
||||||
Delete(retpm);
|
Delete(retpm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3069,14 +2998,14 @@ class JAVA : public Language {
|
||||||
|
|
||||||
/* Start the Java field descriptor for the intermediate class's upcall (insert self object) */
|
/* Start the Java field descriptor for the intermediate class's upcall (insert self object) */
|
||||||
{
|
{
|
||||||
Parm *tp = NewParm(classname, empty_str);
|
Parm *tp = NewParm(c_classname, empty_str);
|
||||||
String *jdesc;
|
String *jdesc;
|
||||||
|
|
||||||
if ((tm = Swig_typemap_lookup_new("directorin", tp, "", 0)) != NULL
|
if ((tm = Swig_typemap_lookup_new("directorin", tp, "", 0)) != NULL
|
||||||
&& (jdesc = Getattr(tp, "tmap:directorin:descriptor")) != NULL) {
|
&& (jdesc = Getattr(tp, "tmap:directorin:descriptor")) != NULL) {
|
||||||
String *jni_canon;
|
String *jni_canon;
|
||||||
|
|
||||||
jni_canon = canonicalJNIFDesc(jdesc, n, classname);
|
jni_canon = canonicalizeJNIDescriptor(jdesc, Getattr(tp,"type"));
|
||||||
Append(jnidesc, jni_canon);
|
Append(jnidesc, jni_canon);
|
||||||
Delete(jni_canon);
|
Delete(jni_canon);
|
||||||
Delete(tm);
|
Delete(tm);
|
||||||
|
|
@ -3130,7 +3059,7 @@ class JAVA : public Language {
|
||||||
&& (cdesc = Getattr(p, "tmap:directorin:descriptor")) != NULL) {
|
&& (cdesc = Getattr(p, "tmap:directorin:descriptor")) != NULL) {
|
||||||
String *jni_canon;
|
String *jni_canon;
|
||||||
|
|
||||||
jni_canon = canonicalJNIFDesc(jdesc, n, c_param_type);
|
jni_canon = canonicalizeJNIDescriptor(jdesc, Getattr(tp,"type"));
|
||||||
Append(jnidesc, jni_canon);
|
Append(jnidesc, jni_canon);
|
||||||
Delete(jni_canon);
|
Delete(jni_canon);
|
||||||
|
|
||||||
|
|
@ -3162,7 +3091,7 @@ class JAVA : public Language {
|
||||||
} else
|
} else
|
||||||
Printv(imcall_args, ln, NIL);
|
Printv(imcall_args, ln, NIL);
|
||||||
|
|
||||||
jni_canon = canonicalJNIFDesc(cdesc, n, pt);
|
jni_canon = canonicalizeJNIDescriptor(cdesc, Getattr(p,"type"));
|
||||||
Append(classdesc, jni_canon);
|
Append(classdesc, jni_canon);
|
||||||
Delete(jni_canon);
|
Delete(jni_canon);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3265,18 +3194,16 @@ class JAVA : public Language {
|
||||||
String *upcall = NewStringf("self.%s(%s)", symname, imcall_args);
|
String *upcall = NewStringf("self.%s(%s)", symname, imcall_args);
|
||||||
|
|
||||||
if (!is_void) {
|
if (!is_void) {
|
||||||
Parm *tp = NewParm(return_type, empty_str);
|
Parm *tp = NewParm(returntype, empty_str);
|
||||||
String *base_type = SwigType_base(return_type);
|
|
||||||
|
|
||||||
tm = Swig_typemap_lookup_new("javadirectorout", tp, "", 0);
|
tm = Swig_typemap_lookup_new("javadirectorout", tp, "", 0);
|
||||||
if (tm != NULL) {
|
if (tm != NULL) {
|
||||||
substituteClassname(base_type, tm);
|
substituteClassname(returntype, tm);
|
||||||
Replaceall(tm, "$javacall", upcall);
|
Replaceall(tm, "$javacall", upcall);
|
||||||
|
|
||||||
Printf(imw->code, "return %s;\n", tm);
|
Printf(imw->code, "return %s;\n", tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
Delete(base_type);
|
|
||||||
Delete(tm);
|
Delete(tm);
|
||||||
Delete(tp);
|
Delete(tp);
|
||||||
} else
|
} else
|
||||||
|
|
@ -3305,7 +3232,7 @@ class JAVA : public Language {
|
||||||
if (!is_void) {
|
if (!is_void) {
|
||||||
String *jresult_str = NewString("jresult");
|
String *jresult_str = NewString("jresult");
|
||||||
String *result_str = NewString("result");
|
String *result_str = NewString("result");
|
||||||
Parm *tp = NewParm(return_type, result_str);
|
Parm *tp = NewParm(returntype, result_str);
|
||||||
|
|
||||||
/* Copy jresult into result... */
|
/* Copy jresult into result... */
|
||||||
if ((tm = Swig_typemap_lookup_new("in", tp, result_str, w))) {
|
if ((tm = Swig_typemap_lookup_new("in", tp, result_str, w))) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue