summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam S Fulton <wsf@fultondesigns.co.uk>2022-03-10 21:11:18 +0000
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2022-03-10 22:18:23 +0000
commit50518d4e77fec5dbb6c499fe599799891a29ba1a (patch)
treedb410e709e8d54f661ad9cb089113fc58e4b6d4b
parent8a8532d823d97b68a96da02f6c754a5ce5afb48f (diff)
downloadswig-50518d4e77fec5dbb6c499fe599799891a29ba1a.tar.gz
Using declarations, directors and overloaded methods
Language::unrollVirtualMethods was assuming that the using declaration would only introduce one method. Fix this by adding in all the overloaded methods from a base class. Affects code generation in C# and Java, but I was not able to construct a test that failed before this commit.
-rw-r--r--Examples/test-suite/csharp/director_using_member_scopes_runme.cs70
-rw-r--r--Examples/test-suite/director_using_member_scopes.i31
-rw-r--r--Examples/test-suite/java/director_using_member_scopes_runme.java64
-rw-r--r--Source/Modules/lang.cxx16
4 files changed, 168 insertions, 13 deletions
diff --git a/Examples/test-suite/csharp/director_using_member_scopes_runme.cs b/Examples/test-suite/csharp/director_using_member_scopes_runme.cs
new file mode 100644
index 000000000..8b979907f
--- /dev/null
+++ b/Examples/test-suite/csharp/director_using_member_scopes_runme.cs
@@ -0,0 +1,70 @@
+using System;
+
+namespace director_using_member_scopesNamespace {
+
+public class runme
+{
+ static void Main()
+ {
+ runme r = new runme();
+ r.run();
+ }
+
+ void run()
+ {
+ NativeWindowType nwt = new NativeWindowType();
+ {
+ MyApplicationContextSDL a = new MyApplicationContextSDL();
+
+ if (ApplicationContextBase.call_setWindowGrab(a, nwt, true) != 100)
+ throw new Exception("failed");
+
+ if (ApplicationContextSDL.call_setWindowGrab(a, nwt, true) != 100)
+ throw new Exception("failed");
+ }
+
+ {
+ MyACSDL a = new MyACSDL();
+
+ if (ACB.call_setWindowGrab(a, nwt, true) != 100)
+ throw new Exception("failed");
+ if (ACB.call_setWindowGrab(a, "hi", 0) != 200)
+ throw new Exception("failed");
+
+ if (ACSDL.call_setWindowGrab(a, nwt, true) != 100)
+ throw new Exception("failed");
+ if (ACSDL.call_setWindowGrab(a, "hi", 0) != 200)
+ throw new Exception("failed");
+ }
+ }
+}
+
+class MyApplicationContextSDL: ApplicationContextSDL
+{
+ public MyApplicationContextSDL() : base()
+ {
+ }
+
+ public override int setWindowGrab(NativeWindowType win, bool grab)
+ {
+ return 100;
+ }
+}
+
+class MyACSDL: ACSDL
+{
+ public MyACSDL() : base()
+ {
+ }
+
+ public override int setWindowGrab(NativeWindowType win, bool grab)
+ {
+ return 100;
+ }
+ public override int setWindowGrab(string s, int val)
+ {
+ return 200;
+ }
+}
+
+}
diff --git a/Examples/test-suite/director_using_member_scopes.i b/Examples/test-suite/director_using_member_scopes.i
index 02d4dc000..9e359539c 100644
--- a/Examples/test-suite/director_using_member_scopes.i
+++ b/Examples/test-suite/director_using_member_scopes.i
@@ -2,7 +2,7 @@
// Similar to using_member_scopes but for directors
-#if !defined(SWIGGO)
+#if !defined(SWIGGO) // TODO: fix Go crash
%feature("director");
// Python,Java,C# no diffs in generated code when adding in nodirector. Go not happy even without %nodirector.
@@ -18,13 +18,36 @@ namespace OgreBites
class ApplicationContextBase {
public:
virtual ~ApplicationContextBase() {}
- virtual void setWindowGrab(NativeWindowType* win, bool grab = true) {}
- void setWindowGrab(bool grab = true) {}
+ virtual int setWindowGrab(NativeWindowType* win, bool grab = true) { return 0; }
+ int setWindowGrab(bool grab = true) { return 5; }
+
+ static int call_setWindowGrab(ApplicationContextBase* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
};
class ApplicationContextSDL : public ApplicationContextBase {
public:
using ApplicationContextBase::setWindowGrab;
- void setWindowGrab(NativeWindowType* win, bool grab) {} // This should not be added again as it exists in base class
+ int setWindowGrab(NativeWindowType* win, bool grab) { return 10; } // This should not be added again as it exists in base class
+
+ static int call_setWindowGrab(ApplicationContextSDL* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
+ };
+
+ class ACB {
+ public:
+ virtual ~ACB() {}
+ virtual int setWindowGrab(NativeWindowType* win, bool grab = true) { return 0; }
+ virtual int setWindowGrab(const char *s, int val) { return 1; } // Additional method compared to ApplicationContextBase
+ int setWindowGrab(bool grab = true) { return 5; }
+
+ static int call_setWindowGrab(ACB* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
+ static int call_setWindowGrab(ACB* ptr, const char *s, int val) { return ptr->setWindowGrab(s, val); }
+ };
+ class ACSDL : public ACB {
+ public:
+ using ACB::setWindowGrab; // This introduces two methods, not one method like ApplicationContextSDL
+ int setWindowGrab(NativeWindowType* win, bool grab) { return 10; } // This should not be added again as it exists in base class
+
+ static int call_setWindowGrab(ACSDL* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
+ static int call_setWindowGrab(ACSDL* ptr, const char *s, int val) { return ptr->setWindowGrab(s, val); }
};
}
%}
diff --git a/Examples/test-suite/java/director_using_member_scopes_runme.java b/Examples/test-suite/java/director_using_member_scopes_runme.java
new file mode 100644
index 000000000..d500014e6
--- /dev/null
+++ b/Examples/test-suite/java/director_using_member_scopes_runme.java
@@ -0,0 +1,64 @@
+
+import director_using_member_scopes.*;
+
+public class director_using_member_scopes_runme {
+
+ static {
+ try {
+ System.loadLibrary("director_using_member_scopes");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) {
+ NativeWindowType nwt = new NativeWindowType();
+
+ {
+ director_using_member_scopes_MyApplicationContextSDL a = new director_using_member_scopes_MyApplicationContextSDL();
+
+ if (ApplicationContextBase.call_setWindowGrab(a, nwt, true) != 100)
+ throw new RuntimeException("failed");
+
+ if (ApplicationContextSDL.call_setWindowGrab(a, nwt, true) != 100)
+ throw new RuntimeException("failed");
+ }
+
+ {
+ director_using_member_scopes_MyACSDL a = new director_using_member_scopes_MyACSDL();
+
+ if (ACB.call_setWindowGrab(a, nwt, true) != 100)
+ throw new RuntimeException("failed");
+ if (ACB.call_setWindowGrab(a, "hi", 0) != 200)
+ throw new RuntimeException("failed");
+
+ if (ACSDL.call_setWindowGrab(a, nwt, true) != 100)
+ throw new RuntimeException("failed");
+ if (ACSDL.call_setWindowGrab(a, "hi", 0) != 200)
+ throw new RuntimeException("failed");
+ }
+ }
+}
+
+class director_using_member_scopes_MyApplicationContextSDL extends ApplicationContextSDL {
+ @Override
+ public int setWindowGrab(NativeWindowType win, boolean grab)
+ {
+ return 100;
+ }
+}
+
+class director_using_member_scopes_MyACSDL extends ACSDL {
+ @Override
+ public int setWindowGrab(NativeWindowType win, boolean grab)
+ {
+ return 100;
+ }
+
+ @Override
+ public int setWindowGrab(String s, int val)
+ {
+ return 200;
+ }
+}
diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx
index c9ab2e225..eb61752b8 100644
--- a/Source/Modules/lang.cxx
+++ b/Source/Modules/lang.cxx
@@ -1948,16 +1948,14 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int &virtual
// find the methods that need directors
String *classname = Getattr(n, "name");
- for (Node *ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
+ for (Node *ni = firstChild(n); ni; ni = nextSibling(ni)) {
/* we only need to check the virtual members */
- String *nodeType = Getattr(ni, "nodeType");
- int is_using = (Cmp(nodeType, "using") == 0);
- Node *nn = is_using ? firstChild(ni) : ni; /* assume there is only one child node for "using" nodes */
- if (is_using) {
- if (!nn)
- continue; // A using node with no added functions, or a using node with private access
- }
- unrollOneVirtualMethod(classname, nn, parent, vm, virtual_destructor, protectedbase);
+ if (Equal(nodeType(ni), "using")) {
+ for (Node *nn = firstChild(ni); nn; nn = Getattr(nn, "sym:nextSibling")) {
+ unrollOneVirtualMethod(classname, nn, parent, vm, virtual_destructor, protectedbase);
+ }
+ }
+ unrollOneVirtualMethod(classname, ni, parent, vm, virtual_destructor, protectedbase);
}
/*