diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2022-03-10 21:11:18 +0000 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2022-03-10 22:18:23 +0000 |
commit | 50518d4e77fec5dbb6c499fe599799891a29ba1a (patch) | |
tree | db410e709e8d54f661ad9cb089113fc58e4b6d4b | |
parent | 8a8532d823d97b68a96da02f6c754a5ce5afb48f (diff) | |
download | swig-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.cs | 70 | ||||
-rw-r--r-- | Examples/test-suite/director_using_member_scopes.i | 31 | ||||
-rw-r--r-- | Examples/test-suite/java/director_using_member_scopes_runme.java | 64 | ||||
-rw-r--r-- | Source/Modules/lang.cxx | 16 |
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); } /* |