summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Kalinin <vkalinin@opendesign.com>2013-05-21 03:49:52 +0400
committerVladimir Kalinin <vkalinin@opendesign.com>2013-05-21 03:49:52 +0400
commita61b45d1a2b9c796b6693fc2352d00bc49ea88a0 (patch)
tree509666ecdf963bbc161a7b8b9d825df96f8667ae
parent9c0ceb2adf178f0c5233459d4f6cc62f82782082 (diff)
downloadswig-a61b45d1a2b9c796b6693fc2352d00bc49ea88a0.tar.gz
propagate non-abstract "interface" base methods (3)
-rw-r--r--Source/Modules/csharp.cxx56
-rw-r--r--Source/Modules/lang.cxx55
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);
+}