interface inheritance (2)
This commit is contained in:
parent
5ccf08e3ec
commit
77bb7673ed
3 changed files with 85 additions and 71 deletions
|
|
@ -1599,35 +1599,40 @@ public:
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
void addInterfaceNameAndUpcasts(String* interface_list, String* interface_upcasts, Node* base, String* c_classname) {
|
void addInterfaceNameAndUpcasts(String* interface_list, String* interface_upcasts, Hash* base_list, String* c_classname) {
|
||||||
String* c_baseclass = SwigType_namestr(Getattr(base, "name"));
|
List* keys = Keys(base_list);
|
||||||
String* iname = getQualifiedInterfaceName(base);
|
for (Iterator it = First(keys); it.item; it = Next(it)) {
|
||||||
if (Len(interface_list))
|
Node* base = Getattr(base_list, it.item);
|
||||||
Append(interface_list, ", ");
|
String* c_baseclass = SwigType_namestr(Getattr(base, "name"));
|
||||||
Append(interface_list, iname);
|
String* iname = getQualifiedInterfaceName(base);
|
||||||
|
if (Len(interface_list))
|
||||||
|
Append(interface_list, ", ");
|
||||||
|
Append(interface_list, iname);
|
||||||
|
|
||||||
Printf(interface_upcasts, " [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]\n");
|
Printf(interface_upcasts, " [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]\n");
|
||||||
String* upcast_name = 0;
|
String* upcast_name = 0;
|
||||||
if (String* cptr_func = Getattr(base, "feature:interface:cptr"))
|
if (String* cptr_func = Getattr(base, "feature:interface:cptr"))
|
||||||
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, " public 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);
|
||||||
Printf(interface_upcasts, "{ return new HandleRef((%s)this, %s.%s(swigCPtr.Handle)); }\n", iname, imclass_name, upcast_method );
|
Printf(interface_upcasts, "{ return new HandleRef((%s)this, %s.%s(swigCPtr.Handle)); }\n", iname, imclass_name, upcast_method );
|
||||||
Printv(imclass_cppcasts_code, "\n [DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
|
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);
|
Printf(imclass_cppcasts_code, " public static extern IntPtr %s(IntPtr jarg1);\n", upcast_method);
|
||||||
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
|
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
|
||||||
Printv(upcasts_code,
|
Printv(upcasts_code,
|
||||||
"SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n",
|
"SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n",
|
||||||
" return (", c_baseclass, " *)jarg1;\n"
|
" return (", c_baseclass, " *)jarg1;\n"
|
||||||
"}\n", "\n", NIL);
|
"}\n", "\n", NIL);
|
||||||
Delete(upcast_name);
|
Delete(upcast_name);
|
||||||
Delete(wname);
|
Delete(wname);
|
||||||
Delete(upcast_method);
|
Delete(upcast_method);
|
||||||
Delete(c_baseclass);
|
Delete(c_baseclass);
|
||||||
|
}
|
||||||
|
Delete(keys);
|
||||||
}
|
}
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* emitProxyClassDefAndCPPCasts()
|
* emitProxyClassDefAndCPPCasts()
|
||||||
|
|
@ -1655,13 +1660,8 @@ public:
|
||||||
List *baselist = Getattr(n, "bases");
|
List *baselist = Getattr(n, "bases");
|
||||||
if (baselist) {
|
if (baselist) {
|
||||||
Iterator base = First(baselist);
|
Iterator base = First(baselist);
|
||||||
while (base.item && GetFlag(base.item, "feature:ignore")) {
|
while (base.item && (GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface")))
|
||||||
base = Next(base);
|
|
||||||
}
|
|
||||||
while (base.item && Getattr(base.item, "feature:interface")) {
|
|
||||||
addInterfaceNameAndUpcasts(interface_list, interface_upcasts, base.item, c_classname);
|
|
||||||
base = Next(base);
|
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));
|
||||||
|
|
@ -1670,9 +1670,7 @@ 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 (Getattr(base.item, "feature:interface")) {
|
if (!GetFlag(base.item, "feature:ignore") && !Getattr(base.item, "feature:interface")) {
|
||||||
addInterfaceNameAndUpcasts(interface_list, interface_upcasts, base.item, c_classname);
|
|
||||||
} 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),
|
||||||
|
|
@ -1682,10 +1680,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Getattr(n, "feature:interface")) {
|
|
||||||
addInterfaceNameAndUpcasts(interface_list, interface_upcasts, n, c_classname);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (Hash* interface_classes = Getattr(n, "feature:interface:bases"))
|
||||||
|
addInterfaceNameAndUpcasts(interface_list, interface_upcasts, interface_classes, c_classname);
|
||||||
|
|
||||||
bool derived = baseclass && getProxyName(c_baseclassname);
|
bool derived = baseclass && getProxyName(c_baseclassname);
|
||||||
if (derived && purebase_notderived)
|
if (derived && purebase_notderived)
|
||||||
|
|
@ -2144,7 +2141,8 @@ 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;
|
bool is_interface = Getattr(parentNode(n), "feature:interface") != 0
|
||||||
|
&& !static_flag && Getattr(n, "feature:interface:owner") == 0;
|
||||||
|
|
||||||
if (!proxy_flag)
|
if (!proxy_flag)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1763,20 +1763,6 @@ public:
|
||||||
Delete(c_baseclass);
|
Delete(c_baseclass);
|
||||||
}
|
}
|
||||||
Delete(keys);
|
Delete(keys);
|
||||||
Delete(base_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void collectInterfaceBases(Hash* bases, Node* n) {
|
|
||||||
if (Getattr(n, "feature:interface")) {
|
|
||||||
String* name = Getattr(n, "feature:interface:name");
|
|
||||||
if (Getattr(bases, name))
|
|
||||||
return;
|
|
||||||
Setattr(bases, name, n);
|
|
||||||
}
|
|
||||||
if (List *baselist = Getattr(n, "bases")) {
|
|
||||||
for (Iterator base = First(baselist); base.item; base = Next(base))
|
|
||||||
collectInterfaceBases(bases, base.item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
|
|
@ -1827,8 +1813,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
collectInterfaceBases(interface_classes, n);
|
if (Hash* interface_classes = Getattr(n, "feature:interface:bases"))
|
||||||
addInterfaceNameAndUpcasts(interface_list, interface_upcasts, interface_classes, c_classname);
|
addInterfaceNameAndUpcasts(interface_list, interface_upcasts, interface_classes, c_classname);
|
||||||
|
|
||||||
bool derived = baseclass && getProxyName(c_baseclassname);
|
bool derived = baseclass && getProxyName(c_baseclassname);
|
||||||
if (derived && purebase_notderived)
|
if (derived && purebase_notderived)
|
||||||
|
|
@ -2002,9 +1988,8 @@ public:
|
||||||
if (List *baselist = Getattr(n, "bases")) {
|
if (List *baselist = Getattr(n, "bases")) {
|
||||||
String* bases = 0;
|
String* bases = 0;
|
||||||
for (Iterator base = First(baselist); base.item; base = Next(base)) {
|
for (Iterator base = First(baselist); base.item; base = Next(base)) {
|
||||||
if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface")) {
|
if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface"))
|
||||||
continue; // TODO: warn about skipped non-interface bases
|
continue; // TODO: warn about skipped non-interface bases
|
||||||
}
|
|
||||||
String* base_iname = Getattr(base.item, "feature:interface:name");
|
String* base_iname = Getattr(base.item, "feature:interface:name");
|
||||||
if (!bases)
|
if (!bases)
|
||||||
bases = Copy(base_iname);
|
bases = Copy(base_iname);
|
||||||
|
|
@ -2271,7 +2256,8 @@ 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;
|
bool is_interface = Getattr(parentNode(n), "feature:interface") != 0
|
||||||
|
&& !static_flag && Getattr(n, "feature:interface:owner") == 0;
|
||||||
|
|
||||||
if (!proxy_flag)
|
if (!proxy_flag)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -3604,35 +3604,65 @@ Hash *Language::getClassHash() const {
|
||||||
return classhash;
|
return classhash;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2 methods below are used in C# && Java module "feature:interface" implementation
|
// 4 methods below are used in C# && Java module "feature:interface" implementation
|
||||||
//
|
//
|
||||||
// Collect all not abstract methods from the bases marked as "interface"
|
// Collect all not abstract methods from the bases marked as "interface"
|
||||||
void Swig_collect_non_abstract_methods(Node* n, List* methods) {
|
static void collect_interface_methods(Node* n, List* methods) {
|
||||||
if (List *baselist = Getattr(n, "bases")) {
|
if (Hash* bases = Getattr(n, "feature:interface:bases")){
|
||||||
for (Iterator base = First(baselist); base.item; base = Next(base)) {
|
List* keys = Keys(bases);
|
||||||
if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface"))
|
for (Iterator base = First(keys); base.item; base = Next(base)) {
|
||||||
|
Node* cls = Getattr(bases, base.item);
|
||||||
|
if (cls == n)
|
||||||
continue;
|
continue;
|
||||||
for (Node* child = firstChild(base.item); child; child = nextSibling(child)) {
|
for (Node* child = firstChild(cls); child; child = nextSibling(child)) {
|
||||||
if (strcmp(Char(nodeType(child)), "cdecl") == 0) {
|
if (strcmp(Char(nodeType(child)), "cdecl") == 0) {
|
||||||
if (GetFlag(child, "feature:ignore") || Getattr(child, "feature:interface:owner") || GetFlag(child, "abstract"))
|
if (GetFlag(child, "feature:ignore") || Getattr(child, "feature:interface:owner"))
|
||||||
continue; // skip methods propagated to bases and abstracts
|
continue; // skip methods propagated to bases
|
||||||
Node* m = Copy(child);
|
Node* m = Copy(child);
|
||||||
set_nextSibling(m, NIL);
|
set_nextSibling(m, NIL);
|
||||||
set_previousSibling(m, NIL);
|
set_previousSibling(m, NIL);
|
||||||
Setattr(m, "feature:interface:owner", base.item);
|
Setattr(m, "feature:interface:owner", cls);
|
||||||
Append(methods, m);
|
Append(methods, m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Swig_collect_non_abstract_methods(base.item, methods);
|
|
||||||
}
|
}
|
||||||
|
Delete(keys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void collect_interface_bases(Hash* bases, Node* n) {
|
||||||
|
if (Getattr(n, "feature:interface")) {
|
||||||
|
String* name = Getattr(n, "feature:interface:name");
|
||||||
|
if (Getattr(bases, name))
|
||||||
|
return;
|
||||||
|
Setattr(bases, name, n);
|
||||||
|
}
|
||||||
|
if (List *baselist = Getattr(n, "bases")) {
|
||||||
|
for (Iterator base = First(baselist); base.item; base = Next(base))
|
||||||
|
if (!GetFlag(base.item, "feature:ignore"))
|
||||||
|
collect_interface_bases(bases, base.item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Swig_collect_interface_bases(Node* n) {
|
||||||
|
Hash* interface_classes = NewHash();
|
||||||
|
collect_interface_bases(interface_classes, n);
|
||||||
|
if (Len(interface_classes) == 0)
|
||||||
|
Delete(interface_classes);
|
||||||
|
else
|
||||||
|
Setattr(n, "feature:interface:bases", interface_classes);
|
||||||
|
}
|
||||||
|
|
||||||
// Append all the interface methods not implemented in the current class, so that it would not be abstract
|
// Append all the interface methods not implemented in the current class, so that it would not be abstract
|
||||||
void Swig_propagate_interface_methods(Node *n)
|
void Swig_propagate_interface_methods(Node *n)
|
||||||
{
|
{
|
||||||
|
Swig_collect_interface_bases(n);
|
||||||
List* methods = NewList();
|
List* methods = NewList();
|
||||||
Swig_collect_non_abstract_methods(n, methods);
|
collect_interface_methods(n, methods);
|
||||||
|
bool is_interface = Getattr(n, "feature:interface") != 0;
|
||||||
for (Iterator mi = First(methods); mi.item; mi = Next(mi)) {
|
for (Iterator mi = First(methods); mi.item; mi = Next(mi)) {
|
||||||
|
if (!is_interface && GetFlag(mi.item, "abstract"))
|
||||||
|
continue;
|
||||||
String *this_decl = Getattr(mi.item, "decl");
|
String *this_decl = Getattr(mi.item, "decl");
|
||||||
String *resolved_decl = SwigType_typedef_resolve_all(this_decl);
|
String *resolved_decl = SwigType_typedef_resolve_all(this_decl);
|
||||||
bool overloaded = false;
|
bool overloaded = false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue