mirror of https://github.com/swig/swig
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.
This commit is contained in:
parent
8a8532d823
commit
50518d4e77
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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); }
|
||||
};
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
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, nn, parent, vm, virtual_destructor, protectedbase);
|
||||
unrollOneVirtualMethod(classname, ni, parent, vm, virtual_destructor, protectedbase);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue