propagate non-abstract "interface" base methods (3)
This commit is contained in:
parent
9c0ceb2adf
commit
a61b45d1a2
2 changed files with 58 additions and 53 deletions
|
|
@ -19,6 +19,8 @@
|
||||||
/* Hash type used for upcalls from C/C++ */
|
/* Hash type used for upcalls from C/C++ */
|
||||||
typedef DOH UpcallData;
|
typedef DOH UpcallData;
|
||||||
|
|
||||||
|
void Swig_propagate_interface_methods(Node *n);
|
||||||
|
|
||||||
class CSHARP:public Language {
|
class CSHARP:public Language {
|
||||||
static const char *usage;
|
static const char *usage;
|
||||||
const String *empty_string;
|
const String *empty_string;
|
||||||
|
|
@ -1930,58 +1932,6 @@ public:
|
||||||
Printf(f_interface, " HandleRef GetCPtr();\n");
|
Printf(f_interface, " HandleRef GetCPtr();\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect all not abstract methods from the bases marked as "interface"
|
|
||||||
void collectNonAbstractMethods(Node* n, List* methods) {
|
|
||||||
if (List *baselist = Getattr(n, "bases")) {
|
|
||||||
for (Iterator base = First(baselist); base.item; base = Next(base)) {
|
|
||||||
if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface"))
|
|
||||||
continue;
|
|
||||||
for (Node* child = firstChild(base.item); child; child = nextSibling(child)) {
|
|
||||||
if (strcmp(Char(nodeType(child)), "cdecl") == 0) {
|
|
||||||
if (GetFlag(child, "feature:ignore") || Getattr(child, "feature:interface:owner") || GetFlag(child, "abstract"))
|
|
||||||
continue; // skip methods propagated to bases and abstracts
|
|
||||||
Node* m = Copy(child);
|
|
||||||
set_nextSibling(m, NIL);
|
|
||||||
set_previousSibling(m, NIL);
|
|
||||||
Setattr(m, "feature:interface:owner", base.item);
|
|
||||||
Append(methods, m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
collectNonAbstractMethods(base.item, methods);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// append all the interface methods not implemented in the current class, so that it would not be abstract
|
|
||||||
void propagateInterfaceMethods(Node *n)
|
|
||||||
{
|
|
||||||
List* methods = NewList();
|
|
||||||
collectNonAbstractMethods(n, methods);
|
|
||||||
for (Iterator mi = First(methods); mi.item; mi = Next(mi)) {
|
|
||||||
String *this_decl = Getattr(mi.item, "decl");
|
|
||||||
String *resolved_decl = SwigType_typedef_resolve_all(this_decl);
|
|
||||||
bool overloaded = false;
|
|
||||||
if (SwigType_isfunction(resolved_decl)) {
|
|
||||||
String *name = Getattr(mi.item, "name");
|
|
||||||
for (Node* child = firstChild(n); child; child = nextSibling(child)) {
|
|
||||||
if (Getattr(child, "feature:interface:owner"))
|
|
||||||
break; // at the end of the list are newly appended methods
|
|
||||||
if (checkAttribute(child, "name", name)) {
|
|
||||||
String *decl = SwigType_typedef_resolve_all(Getattr(child, "decl"));
|
|
||||||
overloaded = Strcmp(decl, this_decl) == 0;
|
|
||||||
Delete(decl);
|
|
||||||
if (overloaded)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Delete(resolved_decl);
|
|
||||||
if (!overloaded)
|
|
||||||
appendChild(n, mi.item);
|
|
||||||
else
|
|
||||||
Delete(mi.item);
|
|
||||||
}
|
|
||||||
Delete(methods);
|
|
||||||
}
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
* classHandler()
|
* classHandler()
|
||||||
* ---------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
@ -2040,7 +1990,7 @@ public:
|
||||||
|
|
||||||
destructor_call = NewStringEmpty();
|
destructor_call = NewStringEmpty();
|
||||||
proxy_class_constants_code = NewStringEmpty();
|
proxy_class_constants_code = NewStringEmpty();
|
||||||
propagateInterfaceMethods(n);
|
Swig_propagate_interface_methods(n);
|
||||||
if (Getattr(n, "feature:interface")) {
|
if (Getattr(n, "feature:interface")) {
|
||||||
interface_class_code = NewStringEmpty();
|
interface_class_code = NewStringEmpty();
|
||||||
String* iname = Getattr(n, "feature:interface:name");
|
String* iname = Getattr(n, "feature:interface:name");
|
||||||
|
|
|
||||||
|
|
@ -3603,3 +3603,58 @@ Language *Language::instance() {
|
||||||
Hash *Language::getClassHash() const {
|
Hash *Language::getClassHash() const {
|
||||||
return classhash;
|
return classhash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2 methods below are used in C# && Java module "feature:interface" implementation
|
||||||
|
//
|
||||||
|
// Collect all not abstract methods from the bases marked as "interface"
|
||||||
|
void Swig_collect_non_abstract_methods(Node* n, List* methods) {
|
||||||
|
if (List *baselist = Getattr(n, "bases")) {
|
||||||
|
for (Iterator base = First(baselist); base.item; base = Next(base)) {
|
||||||
|
if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface"))
|
||||||
|
continue;
|
||||||
|
for (Node* child = firstChild(base.item); child; child = nextSibling(child)) {
|
||||||
|
if (strcmp(Char(nodeType(child)), "cdecl") == 0) {
|
||||||
|
if (GetFlag(child, "feature:ignore") || Getattr(child, "feature:interface:owner") || GetFlag(child, "abstract"))
|
||||||
|
continue; // skip methods propagated to bases and abstracts
|
||||||
|
Node* m = Copy(child);
|
||||||
|
set_nextSibling(m, NIL);
|
||||||
|
set_previousSibling(m, NIL);
|
||||||
|
Setattr(m, "feature:interface:owner", base.item);
|
||||||
|
Append(methods, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Swig_collect_non_abstract_methods(base.item, methods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
List* methods = NewList();
|
||||||
|
Swig_collect_non_abstract_methods(n, methods);
|
||||||
|
for (Iterator mi = First(methods); mi.item; mi = Next(mi)) {
|
||||||
|
String *this_decl = Getattr(mi.item, "decl");
|
||||||
|
String *resolved_decl = SwigType_typedef_resolve_all(this_decl);
|
||||||
|
bool overloaded = false;
|
||||||
|
if (SwigType_isfunction(resolved_decl)) {
|
||||||
|
String *name = Getattr(mi.item, "name");
|
||||||
|
for (Node* child = firstChild(n); child; child = nextSibling(child)) {
|
||||||
|
if (Getattr(child, "feature:interface:owner"))
|
||||||
|
break; // at the end of the list are newly appended methods
|
||||||
|
if (checkAttribute(child, "name", name)) {
|
||||||
|
String *decl = SwigType_typedef_resolve_all(Getattr(child, "decl"));
|
||||||
|
overloaded = Strcmp(decl, this_decl) == 0;
|
||||||
|
Delete(decl);
|
||||||
|
if (overloaded)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Delete(resolved_decl);
|
||||||
|
if (!overloaded)
|
||||||
|
appendChild(n, mi.item);
|
||||||
|
else
|
||||||
|
Delete(mi.item);
|
||||||
|
}
|
||||||
|
Delete(methods);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue