diff options
author | Vladimir Kalinin <vkalinin@opendesign.com> | 2013-05-21 03:49:52 +0400 |
---|---|---|
committer | Vladimir Kalinin <vkalinin@opendesign.com> | 2013-05-21 03:49:52 +0400 |
commit | a61b45d1a2b9c796b6693fc2352d00bc49ea88a0 (patch) | |
tree | 509666ecdf963bbc161a7b8b9d825df96f8667ae | |
parent | 9c0ceb2adf178f0c5233459d4f6cc62f82782082 (diff) | |
download | swig-a61b45d1a2b9c796b6693fc2352d00bc49ea88a0.tar.gz |
propagate non-abstract "interface" base methods (3)
-rw-r--r-- | Source/Modules/csharp.cxx | 56 | ||||
-rw-r--r-- | Source/Modules/lang.cxx | 55 |
2 files changed, 58 insertions, 53 deletions
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 52b8371af..89722cf8a 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -19,6 +19,8 @@ /* Hash type used for upcalls from C/C++ */ typedef DOH UpcallData; +void Swig_propagate_interface_methods(Node *n); + class CSHARP:public Language { static const char *usage; const String *empty_string; @@ -1930,58 +1932,6 @@ public: 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() * ---------------------------------------------------------------------- */ @@ -2040,7 +1990,7 @@ public: destructor_call = NewStringEmpty(); proxy_class_constants_code = NewStringEmpty(); - propagateInterfaceMethods(n); + Swig_propagate_interface_methods(n); if (Getattr(n, "feature:interface")) { interface_class_code = NewStringEmpty(); String* iname = Getattr(n, "feature:interface:name"); diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index eb7d49480..78e959bfc 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -3603,3 +3603,58 @@ Language *Language::instance() { Hash *Language::getClassHash() const { 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); +} |