interfaces (1)
This commit is contained in:
parent
481ed3c578
commit
0898d6435d
1 changed files with 127 additions and 46 deletions
|
|
@ -51,6 +51,7 @@ class CSHARP: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
|
||||||
|
|
@ -121,6 +122,7 @@ public:
|
||||||
imclass_name(NULL),
|
imclass_name(NULL),
|
||||||
module_class_name(NULL),
|
module_class_name(NULL),
|
||||||
imclass_class_code(NULL),
|
imclass_class_code(NULL),
|
||||||
|
interface_class_code(NULL),
|
||||||
proxy_class_def(NULL),
|
proxy_class_def(NULL),
|
||||||
proxy_class_code(NULL),
|
proxy_class_code(NULL),
|
||||||
module_class_code(NULL),
|
module_class_code(NULL),
|
||||||
|
|
@ -1577,7 +1579,39 @@ public:
|
||||||
}
|
}
|
||||||
return Language::pragmaDirective(n);
|
return Language::pragmaDirective(n);
|
||||||
}
|
}
|
||||||
|
String* getQualifiedInterfaceName(Node* n)
|
||||||
|
{
|
||||||
|
// TODO: qualified interface name //getProxyName(Getattr(base.item, "name"))
|
||||||
|
return Getattr(n, "feature:interface:name");
|
||||||
|
}
|
||||||
|
void addInterfaceNameAndUpcasts(String* interface_list, String* interface_upcasts, Iterator base, String* c_baseclass, String* c_classname) {
|
||||||
|
String* iname = getQualifiedInterfaceName(base.item);
|
||||||
|
if (Len(interface_list))
|
||||||
|
Append(interface_list, ", ");
|
||||||
|
Append(interface_list, iname);
|
||||||
|
|
||||||
|
Printf(interface_upcasts, " [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]\n");
|
||||||
|
String* upcast_name = 0;
|
||||||
|
if (String* cptr_func = Getattr(base.item, "feature:interface:cptr"))
|
||||||
|
upcast_name = NewStringf("%s.%s", iname, cptr_func);
|
||||||
|
else
|
||||||
|
upcast_name = NewStringf("%s.GetCPtr", iname);
|
||||||
|
Printf(interface_upcasts, " IntPtr %s()", 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 %s.%s(swigCPtr.Handle); }\n", imclass_name, upcast_method );
|
||||||
|
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);
|
||||||
|
}
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* emitProxyClassDefAndCPPCasts()
|
* emitProxyClassDefAndCPPCasts()
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
@ -1587,6 +1621,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;
|
||||||
|
|
||||||
|
|
@ -1605,6 +1641,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, c_baseclass, 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));
|
||||||
|
|
@ -1613,14 +1653,14 @@ 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, c_baseclass, 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_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
|
||||||
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));
|
||||||
"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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1647,6 +1687,9 @@ public:
|
||||||
|
|
||||||
// Pure C# interfaces
|
// Pure C# interfaces
|
||||||
const String *pure_interfaces = typemapLookup(n, derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE);
|
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
|
// Start writing the proxy class
|
||||||
Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements
|
Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements
|
||||||
"\n", NIL);
|
"\n", NIL);
|
||||||
|
|
@ -1658,8 +1701,8 @@ public:
|
||||||
|
|
||||||
Printv(proxy_class_def, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
|
Printv(proxy_class_def, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
|
||||||
" $csclassname", // Class name and base class
|
" $csclassname", // Class name and base class
|
||||||
(*Char(wanted_base) || *Char(pure_interfaces)) ? " : " : "", wanted_base, (*Char(wanted_base) && *Char(pure_interfaces)) ? // Interfaces
|
(*Char(wanted_base) || *Char(interface_list)) ? " : " : "", wanted_base, (*Char(wanted_base) && *Char(interface_list)) ? // Interfaces
|
||||||
", " : "", pure_interfaces, " {", derived ? typemapLookup(n, "csbody_derived", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF) : // main body of class
|
", " : "", 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
|
typemapLookup(n, "csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
|
||||||
NIL);
|
NIL);
|
||||||
|
|
||||||
|
|
@ -1704,6 +1747,8 @@ public:
|
||||||
Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n",
|
Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n",
|
||||||
NIL);
|
NIL);
|
||||||
}
|
}
|
||||||
|
if (*Char(interface_upcasts))
|
||||||
|
Printv(proxy_class_def, interface_upcasts, NIL);
|
||||||
|
|
||||||
if (feature_director) {
|
if (feature_director) {
|
||||||
// Generate director connect method
|
// Generate director connect method
|
||||||
|
|
@ -1785,6 +1830,7 @@ public:
|
||||||
Delete(director_connect_method_name);
|
Delete(director_connect_method_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Delete(interface_list);
|
||||||
Delete(attributes);
|
Delete(attributes);
|
||||||
Delete(destruct);
|
Delete(destruct);
|
||||||
|
|
||||||
|
|
@ -1838,6 +1884,38 @@ public:
|
||||||
Delete(baseclass);
|
Delete(baseclass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void emitInterfaceDeclaration(Node* n, String* iname, File* f_interface)
|
||||||
|
{
|
||||||
|
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 (!base_iname) {
|
||||||
|
Swig_error(Getfile(n), Getline(n), "interface %s has a base interface %s w/o name attribute", iname, Getattr(base.item, "name"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
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, " IntPtr %s();\n", cptr_func);
|
||||||
|
else
|
||||||
|
Printf(f_interface, " IntPtr GetCPtr();\n");
|
||||||
|
}
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
* classHandler()
|
* classHandler()
|
||||||
* ---------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
@ -1846,6 +1924,9 @@ public:
|
||||||
|
|
||||||
String *nspace = getNSpace();
|
String *nspace = getNSpace();
|
||||||
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"));
|
||||||
|
|
||||||
|
|
@ -1883,18 +1964,32 @@ public:
|
||||||
}
|
}
|
||||||
Append(filenames_list, Copy(filen));
|
Append(filenames_list, Copy(filen));
|
||||||
Delete(filen);
|
Delete(filen);
|
||||||
filen = NULL;
|
|
||||||
|
|
||||||
// Start writing out the proxy class file
|
// Start writing out the proxy class file
|
||||||
emitBanner(f_proxy);
|
emitBanner(f_proxy);
|
||||||
|
|
||||||
addOpenNamespace(nspace, f_proxy);
|
addOpenNamespace(nspace, f_proxy);
|
||||||
|
|
||||||
Clear(proxy_class_def);
|
Clear(proxy_class_def);
|
||||||
Clear(proxy_class_code);
|
Clear(proxy_class_code);
|
||||||
|
|
||||||
destructor_call = NewString("");
|
destructor_call = NewStringEmpty();
|
||||||
proxy_class_constants_code = NewString("");
|
proxy_class_constants_code = NewStringEmpty();
|
||||||
|
if (Getattr(n, "feature:interface")) {
|
||||||
|
interface_class_code = NewStringEmpty();
|
||||||
|
String* iname = Copy(Getattr(n, "feature:interface:name"));
|
||||||
|
if (!iname)
|
||||||
|
iname = NewStringf("I%s", proxy_class_name);
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Language::classHandler(n);
|
Language::classHandler(n);
|
||||||
|
|
@ -1934,41 +2029,16 @@ public:
|
||||||
Printf(f_proxy, "}\n");
|
Printf(f_proxy, "}\n");
|
||||||
addCloseNamespace(nspace, f_proxy);
|
addCloseNamespace(nspace, f_proxy);
|
||||||
Delete(f_proxy);
|
Delete(f_proxy);
|
||||||
f_proxy = NULL;
|
if (f_interface) {
|
||||||
|
Printv(f_interface, interface_class_code, "}\n", NIL);
|
||||||
/* Output the downcast method, if necessary. Note: There's no other really
|
addCloseNamespace(nspace, f_interface);
|
||||||
good place to put this code, since Abstract Base Classes (ABCs) can and should have
|
Delete(f_interface);
|
||||||
downcasts, making the constructorHandler() a bad place (because ABCs don't get to
|
|
||||||
have constructors emitted.) */
|
|
||||||
if (GetFlag(n, "feature:javadowncast")) {
|
|
||||||
String *downcast_method = Swig_name_member(getNSpace(), proxy_class_name, "SWIGDowncast");
|
|
||||||
String *wname = Swig_name_wrapper(downcast_method);
|
|
||||||
|
|
||||||
String *norm_name = SwigType_namestr(Getattr(n, "name"));
|
|
||||||
|
|
||||||
Printf(imclass_class_code, " public final static native %s %s(long cPtrBase, boolean cMemoryOwn);\n", proxy_class_name, downcast_method);
|
|
||||||
|
|
||||||
Wrapper *dcast_wrap = NewWrapper();
|
|
||||||
|
|
||||||
Printf(dcast_wrap->def, "SWIGEXPORT jobject SWIGSTDCALL %s(JNIEnv *jenv, jclass jcls, jlong jCPtrBase, jboolean cMemoryOwn) {", wname);
|
|
||||||
Printf(dcast_wrap->code, " Swig::Director *director = (Swig::Director *) 0;\n");
|
|
||||||
Printf(dcast_wrap->code, " jobject jresult = (jobject) 0;\n");
|
|
||||||
Printf(dcast_wrap->code, " %s *obj = *((%s **)&jCPtrBase);\n", norm_name, norm_name);
|
|
||||||
Printf(dcast_wrap->code, " if (obj) director = dynamic_cast<Swig::Director *>(obj);\n");
|
|
||||||
Printf(dcast_wrap->code, " if (director) jresult = director->swig_get_self(jenv);\n");
|
|
||||||
Printf(dcast_wrap->code, " return jresult;\n");
|
|
||||||
Printf(dcast_wrap->code, "}\n");
|
|
||||||
|
|
||||||
Wrapper_print(dcast_wrap, f_wrappers);
|
|
||||||
DelWrapper(dcast_wrap);
|
|
||||||
|
|
||||||
Delete(norm_name);
|
|
||||||
Delete(wname);
|
|
||||||
Delete(downcast_method);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emitDirectorExtraMethods(n);
|
emitDirectorExtraMethods(n);
|
||||||
|
|
||||||
|
Delete(interface_class_code);
|
||||||
|
interface_class_code = old_interface_class_code;
|
||||||
Delete(csclazzname);
|
Delete(csclazzname);
|
||||||
Delete(proxy_class_name);
|
Delete(proxy_class_name);
|
||||||
proxy_class_name = NULL;
|
proxy_class_name = NULL;
|
||||||
|
|
@ -2053,6 +2123,7 @@ public:
|
||||||
String *pre_code = NewString("");
|
String *pre_code = NewString("");
|
||||||
String *post_code = NewString("");
|
String *post_code = NewString("");
|
||||||
String *terminator_code = NewString("");
|
String *terminator_code = NewString("");
|
||||||
|
bool is_interface = Getattr(parentNode(n), "feature:interface") != 0 && !static_flag;
|
||||||
|
|
||||||
if (!proxy_flag)
|
if (!proxy_flag)
|
||||||
return;
|
return;
|
||||||
|
|
@ -2136,6 +2207,9 @@ public:
|
||||||
if (static_flag)
|
if (static_flag)
|
||||||
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)
|
||||||
|
|
@ -2215,10 +2289,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);
|
||||||
|
|
||||||
Delete(arg);
|
Delete(arg);
|
||||||
Delete(param_type);
|
Delete(param_type);
|
||||||
|
|
@ -2228,6 +2307,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 PInvoke function (in intermediary class) to type used in C# wrapper function (in proxy class)
|
// 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))) {
|
if ((tm = Swig_typemap_lookup("csout", n, "", 0))) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue