Fixes for the family of %interface macros for overloaded methods
When C++ methods are not able to be overloaded in a derived class, such as when they differ by just const, or the target language parameters types are identical even when the C++ parameter types are different, SWIG will ignore one of the overloaded methods with a warning. A %ignore is required to explicitly ignore one of the overloaded methods to avoid the warning message. Methods added in the derived classes due to one of the %interface macros are now similarly ignored/not added to the derived class. The adding of additional methods into the parse tree is now more robust and complete resulting in support for %feature and %rename for the added methods. Closes #1277
This commit is contained in:
parent
77853770bd
commit
b6ece11fc1
12 changed files with 259 additions and 15 deletions
|
|
@ -7,6 +7,23 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||||
Version 4.1.0 (in progress)
|
Version 4.1.0 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2022-03-12: wsfulton
|
||||||
|
#1277 Fixes for the family of %interface macros, %interface,
|
||||||
|
%interface_impl and %interface_custom fixes for overloaded methods
|
||||||
|
in an inheritance chain.
|
||||||
|
|
||||||
|
When C++ methods are not able to be overloaded in a derived class,
|
||||||
|
such as when they differ by just const, or the target language
|
||||||
|
parameters types are identical even when the C++ parameter types
|
||||||
|
are different, SWIG will ignore one of the overloaded methods with
|
||||||
|
a warning. A %ignore is required to explicitly ignore one of the
|
||||||
|
overloaded methods to avoid the warning message. Methods added
|
||||||
|
in the derived classes due to one of the %interface macros are now
|
||||||
|
similarly ignored/not added to the derived class.
|
||||||
|
|
||||||
|
The methods added to the derived classes can now also be modified
|
||||||
|
via %feature and %rename.
|
||||||
|
|
||||||
2022-03-08: olly
|
2022-03-08: olly
|
||||||
#1006 SWIG now copes with an interface filename specified on the
|
#1006 SWIG now copes with an interface filename specified on the
|
||||||
command line which contains a closing parenthesis `)`, and more
|
command line which contains a closing parenthesis `)`, and more
|
||||||
|
|
@ -626,7 +643,6 @@ Version 4.1.0 (in progress)
|
||||||
|
|
||||||
%typemap(csinterfacemodifiers) X "internal interface"
|
%typemap(csinterfacemodifiers) X "internal interface"
|
||||||
|
|
||||||
|
|
||||||
2020-09-24: geefr
|
2020-09-24: geefr
|
||||||
[C#] #1868 Fix wchar_t* csvarout typemap for member variable wrappers.
|
[C#] #1868 Fix wchar_t* csvarout typemap for member variable wrappers.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3434,9 +3434,11 @@ Consider the following C++ code:
|
||||||
namespace Space {
|
namespace Space {
|
||||||
struct Base1 {
|
struct Base1 {
|
||||||
virtual void Method1();
|
virtual void Method1();
|
||||||
|
virtual Base1();
|
||||||
};
|
};
|
||||||
struct Base2 {
|
struct Base2 {
|
||||||
virtual void Method2();
|
virtual void Method2();
|
||||||
|
virtual Base2();
|
||||||
};
|
};
|
||||||
struct Derived : Base1, Base2 {
|
struct Derived : Base1, Base2 {
|
||||||
};
|
};
|
||||||
|
|
@ -3453,7 +3455,7 @@ SWIG generates a warning for the above code:
|
||||||
|
|
||||||
<div class="shell">
|
<div class="shell">
|
||||||
<pre>
|
<pre>
|
||||||
example.i:10: Warning 813: Warning for Derived, base Base2 ignored.
|
example.i:12: Warning 813: Warning for Derived, base Base2 ignored.
|
||||||
Multiple inheritance is not supported in Java.
|
Multiple inheritance is not supported in Java.
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3506,7 +3508,7 @@ public class Base1SwigImpl implements Base1 {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
In fact any class deriving from <tt>Base</tt> will now implement the interface instead of
|
In fact any class using <tt>Base</tt> as an immediate base class will now implement the interface instead of
|
||||||
deriving from it (or ignoring the base in the case of multiple base classes).
|
deriving from it (or ignoring the base in the case of multiple base classes).
|
||||||
Hence the <tt>Derived</tt> proxy class will now implement both bases:
|
Hence the <tt>Derived</tt> proxy class will now implement both bases:
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -3535,6 +3537,15 @@ public class Derived implements Base1, Base2 {
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The proxy class has methods added to it, from the implemented bases, so that
|
||||||
|
the underlying C++ implementation can be called.
|
||||||
|
In the example above, <tt>Method1</tt> and <tt>Method2</tt> have been added from the implemented bases.
|
||||||
|
If a method is ignored in the base, such as via <tt>%ignore</tt>, then that method
|
||||||
|
will be excluded from the interface and there will not be an additional method
|
||||||
|
added to the proxy class implementing that interface.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Wherever a class marked as an interface is used, such as the <tt>UseBases</tt> method in the example,
|
Wherever a class marked as an interface is used, such as the <tt>UseBases</tt> method in the example,
|
||||||
the interface name is used as the type in the Java layer:
|
the interface name is used as the type in the Java layer:
|
||||||
|
|
|
||||||
|
|
@ -308,6 +308,7 @@ CPP_TEST_CASES += \
|
||||||
multiple_inheritance_abstract \
|
multiple_inheritance_abstract \
|
||||||
multiple_inheritance_interfaces \
|
multiple_inheritance_interfaces \
|
||||||
multiple_inheritance_nspace \
|
multiple_inheritance_nspace \
|
||||||
|
multiple_inheritance_overload \
|
||||||
multiple_inheritance_shared_ptr \
|
multiple_inheritance_shared_ptr \
|
||||||
name_cxx \
|
name_cxx \
|
||||||
name_warnings \
|
name_warnings \
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using multiple_inheritance_overloadNamespace;
|
||||||
|
|
||||||
|
public class multiple_inheritance_overload_runme {
|
||||||
|
|
||||||
|
public static void check(bool fail, String msg) {
|
||||||
|
if (fail)
|
||||||
|
throw new Exception(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Main() {
|
||||||
|
int i = 0;
|
||||||
|
Base b1 = new Derived();
|
||||||
|
check(b1.Method(i) != 0, "b1.Method failed");
|
||||||
|
check(b1.MethodForRenaming(i) != 0, "b1.MethodForRenaming failed");
|
||||||
|
check(b1.MethodForRenamingConst(i) != 1, "b1.MethodForRenamingConst failed");
|
||||||
|
check(b1.MethodWarningSuppressed(i) != 0, "b1.MethodWarningSuppressed failed");
|
||||||
|
check(b1.NotVirtualMethod(i) != 0, "b1.NotVirtualMethod failed");
|
||||||
|
check(b1.SimilarOverloadedMethod(i) != 0, "b1.NotVirtualMethod failed");
|
||||||
|
|
||||||
|
Derived d1 = new Derived();
|
||||||
|
check(d1.Method(i) != 0, "d1.Method failed");
|
||||||
|
check(d1.MethodForRenaming(i) != 0, "d1.MethodForRenaming failed");
|
||||||
|
check(d1.MethodForRenamingConst(i) != 1, "d1.MethodForRenamingConst failed");
|
||||||
|
check(d1.MethodWarningSuppressed(i) != 0, "d1.MethodWarningSuppressed failed");
|
||||||
|
check(d1.NotVirtualMethod(i) != 0, "d1.NotVirtualMethod failed");
|
||||||
|
check(d1.SimilarOverloadedMethod(i) != 0, "d1.NotVirtualMethod failed");
|
||||||
|
|
||||||
|
check(d1.AnotherMethod(i) != 0, "d1.AnotherMethod failed");
|
||||||
|
|
||||||
|
Base db1 = BaseSwigImpl.inout(d1);
|
||||||
|
check(db1.Method(i) != 0, "db1.Method failed");
|
||||||
|
check(db1.MethodForRenaming(i) != 0, "db1.MethodForRenaming failed");
|
||||||
|
check(db1.MethodForRenamingConst(i) != 1, "db1.MethodForRenamingConst failed");
|
||||||
|
check(db1.MethodWarningSuppressed(i) != 0, "db1.MethodWarningSuppressed failed");
|
||||||
|
check(db1.NotVirtualMethod(i) != 0, "db1.NotVirtualMethod failed");
|
||||||
|
check(db1.SimilarOverloadedMethod(i) != 0, "db1.NotVirtualMethod failed");
|
||||||
|
|
||||||
|
MoreDerived m1 = new MoreDerived();
|
||||||
|
check(m1.Method(i) != 0, "m1.Method failed");
|
||||||
|
check(m1.MethodForRenaming(i) != 0, "m1.MethodForRenaming failed");
|
||||||
|
check(m1.MethodForRenamingConst(i) != 1, "m1.MethodForRenamingConst failed");
|
||||||
|
check(m1.MethodWarningSuppressed(i) != 0, "m1.MethodWarningSuppressed failed");
|
||||||
|
check(m1.NotVirtualMethod(i) != 0, "m1.NotVirtualMethod failed");
|
||||||
|
check(m1.SimilarOverloadedMethod(i) != 0, "m1.NotVirtualMethod failed");
|
||||||
|
|
||||||
|
check(m1.AnotherMethod(i) != 0, "m1.AnotherMethod failed");
|
||||||
|
|
||||||
|
Base mb2 = BaseSwigImpl.inout(m1);
|
||||||
|
check(mb2.Method(i) != 0, "mb2.Method failed");
|
||||||
|
check(mb2.MethodForRenaming(i) != 0, "mb2.MethodForRenaming failed");
|
||||||
|
check(mb2.MethodForRenamingConst(i) != 1, "mb2.MethodForRenamingConst failed");
|
||||||
|
check(mb2.MethodWarningSuppressed(i) != 0, "mb2.MethodWarningSuppressed failed");
|
||||||
|
check(mb2.NotVirtualMethod(i) != 0, "mb2.NotVirtualMethod failed");
|
||||||
|
check(mb2.SimilarOverloadedMethod(i) != 0, "mb2.NotVirtualMethod failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
import multiple_inheritance_overload.*;
|
||||||
|
|
||||||
|
public class multiple_inheritance_overload_runme {
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("multiple_inheritance_overload");
|
||||||
|
} 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 check(boolean fail, String msg) {
|
||||||
|
if (fail)
|
||||||
|
throw new RuntimeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String argv[]) {
|
||||||
|
int i = 0;
|
||||||
|
Base b1 = new Derived();
|
||||||
|
check(b1.Method(i) != 0, "b1.Method failed");
|
||||||
|
check(b1.MethodForRenaming(i) != 0, "b1.MethodForRenaming failed");
|
||||||
|
check(b1.MethodForRenamingConst(i) != 1, "b1.MethodForRenamingConst failed");
|
||||||
|
check(b1.MethodWarningSuppressed(i) != 0, "b1.MethodWarningSuppressed failed");
|
||||||
|
check(b1.NotVirtualMethod(i) != 0, "b1.NotVirtualMethod failed");
|
||||||
|
check(b1.SimilarOverloadedMethod(i) != 0, "b1.NotVirtualMethod failed");
|
||||||
|
|
||||||
|
Derived d1 = new Derived();
|
||||||
|
check(d1.Method(i) != 0, "d1.Method failed");
|
||||||
|
check(d1.MethodForRenaming(i) != 0, "d1.MethodForRenaming failed");
|
||||||
|
check(d1.MethodForRenamingConst(i) != 1, "d1.MethodForRenamingConst failed");
|
||||||
|
check(d1.MethodWarningSuppressed(i) != 0, "d1.MethodWarningSuppressed failed");
|
||||||
|
check(d1.NotVirtualMethod(i) != 0, "d1.NotVirtualMethod failed");
|
||||||
|
check(d1.SimilarOverloadedMethod(i) != 0, "d1.NotVirtualMethod failed");
|
||||||
|
|
||||||
|
check(d1.AnotherMethod(i) != 0, "d1.AnotherMethod failed");
|
||||||
|
|
||||||
|
Base db1 = BaseSwigImpl.inout(d1);
|
||||||
|
check(db1.Method(i) != 0, "db1.Method failed");
|
||||||
|
check(db1.MethodForRenaming(i) != 0, "db1.MethodForRenaming failed");
|
||||||
|
check(db1.MethodForRenamingConst(i) != 1, "db1.MethodForRenamingConst failed");
|
||||||
|
check(db1.MethodWarningSuppressed(i) != 0, "db1.MethodWarningSuppressed failed");
|
||||||
|
check(db1.NotVirtualMethod(i) != 0, "db1.NotVirtualMethod failed");
|
||||||
|
check(db1.SimilarOverloadedMethod(i) != 0, "db1.NotVirtualMethod failed");
|
||||||
|
|
||||||
|
MoreDerived m1 = new MoreDerived();
|
||||||
|
check(m1.Method(i) != 0, "m1.Method failed");
|
||||||
|
check(m1.MethodForRenaming(i) != 0, "m1.MethodForRenaming failed");
|
||||||
|
check(m1.MethodForRenamingConst(i) != 1, "m1.MethodForRenamingConst failed");
|
||||||
|
check(m1.MethodWarningSuppressed(i) != 0, "m1.MethodWarningSuppressed failed");
|
||||||
|
check(m1.NotVirtualMethod(i) != 0, "m1.NotVirtualMethod failed");
|
||||||
|
check(m1.SimilarOverloadedMethod(i) != 0, "m1.NotVirtualMethod failed");
|
||||||
|
|
||||||
|
check(m1.AnotherMethod(i) != 0, "m1.AnotherMethod failed");
|
||||||
|
|
||||||
|
Base mb2 = BaseSwigImpl.inout(m1);
|
||||||
|
check(mb2.Method(i) != 0, "mb2.Method failed");
|
||||||
|
check(mb2.MethodForRenaming(i) != 0, "mb2.MethodForRenaming failed");
|
||||||
|
check(mb2.MethodForRenamingConst(i) != 1, "mb2.MethodForRenamingConst failed");
|
||||||
|
check(mb2.MethodWarningSuppressed(i) != 0, "mb2.MethodWarningSuppressed failed");
|
||||||
|
check(mb2.NotVirtualMethod(i) != 0, "mb2.NotVirtualMethod failed");
|
||||||
|
check(mb2.SimilarOverloadedMethod(i) != 0, "mb2.NotVirtualMethod failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
|
SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
|
||||||
|
|
||||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
|
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
|
||||||
%include "swiginterface.i"
|
%include <swiginterface.i>
|
||||||
%interface_impl(Space::ABase1)
|
%interface_impl(Space::ABase1)
|
||||||
%interface_impl(Space::CBase1)
|
%interface_impl(Space::CBase1)
|
||||||
%interface_impl(Space::CBase2)
|
%interface_impl(Space::CBase2)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
|
SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
|
||||||
|
|
||||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
|
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
|
||||||
%include "swiginterface.i"
|
%include <swiginterface.i>
|
||||||
%interface_custom("A", "IA", IA)
|
%interface_custom("A", "IA", IA)
|
||||||
%interface_custom("B", "IB", IB)
|
%interface_custom("B", "IB", IB)
|
||||||
%interface_custom("%(strip:[I])s", "I%s", IC) // same as %interface_custom("C", "IC", IC)
|
%interface_custom("%(strip:[I])s", "I%s", IC) // same as %interface_custom("C", "IC", IC)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
|
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
|
||||||
%include "swiginterface.i"
|
%include <swiginterface.i>
|
||||||
%interface(Space::ABase1)
|
%interface(Space::ABase1)
|
||||||
%interface(Space::CBase1)
|
%interface(Space::CBase1)
|
||||||
%interface(Space::CBase2)
|
%interface(Space::CBase2)
|
||||||
|
|
|
||||||
67
Examples/test-suite/multiple_inheritance_overload.i
Normal file
67
Examples/test-suite/multiple_inheritance_overload.i
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
%module(ruby_minherit="1") multiple_inheritance_overload
|
||||||
|
|
||||||
|
%warnfilter(SWIGWARN_D_MULTIPLE_INHERITANCE,
|
||||||
|
SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
|
||||||
|
|
||||||
|
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
|
||||||
|
%include <swiginterface.i>
|
||||||
|
%interface_impl(Space::Base);
|
||||||
|
%interface_impl(Space::AnotherBase);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
%ignore AnotherSpace::AnotherBase::AnotherMethod(int i) const;
|
||||||
|
%ignore Space::Base::Method(int i) const;
|
||||||
|
%ignore Space::Base::NotVirtualMethod(int i) const;
|
||||||
|
%ignore Space::Base::SimilarOverloadedMethod(unsigned short i);
|
||||||
|
%rename(MethodForRenamingConst) Space::Base::MethodForRenaming(int i) const;
|
||||||
|
|
||||||
|
// Different overloaded warning filters needed for scripting languages (eg Python) and for statically typed languages (eg C#).
|
||||||
|
%warnfilter(509, 516) Space::Base::MethodWarningSuppressed(int i) const;
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
namespace AnotherSpace {
|
||||||
|
class AnotherBase {
|
||||||
|
public:
|
||||||
|
virtual int AnotherMethod(int i) { return 0; }
|
||||||
|
virtual int AnotherMethod(int i) const { return 1; }
|
||||||
|
virtual ~AnotherBase() {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Space {
|
||||||
|
class Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual int Method(int i) { return 0; }
|
||||||
|
virtual int Method(int i) const { return 1; }
|
||||||
|
virtual int MethodForRenaming(int i) { return 0; }
|
||||||
|
virtual int MethodForRenaming(int i) const { return 1; }
|
||||||
|
virtual int MethodWarningSuppressed(int i) { return 0; }
|
||||||
|
virtual int MethodWarningSuppressed(int i) const { return 1; }
|
||||||
|
int NotVirtualMethod(int i) { return 0; }
|
||||||
|
int NotVirtualMethod(int i) const { return 1; }
|
||||||
|
|
||||||
|
typedef int Integer;
|
||||||
|
|
||||||
|
// int and unsigned short are wrapped with a Java int and so would be automatically ignored with a warning
|
||||||
|
virtual int SimilarOverloadedMethod(Integer i) { return 0; }
|
||||||
|
virtual int SimilarOverloadedMethod(unsigned short i) { return 1; }
|
||||||
|
virtual ~Base() {}
|
||||||
|
static Base *inout(Base *p) { return p; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Derived : public Base, public AnotherSpace::AnotherBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int member_var;
|
||||||
|
};
|
||||||
|
class MoreDerived : public Derived {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace OtherSpace {
|
||||||
|
class OtherDerived : public Space::Base
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
@ -48,7 +48,7 @@
|
||||||
%shared_ptr(Space::Bottom2)
|
%shared_ptr(Space::Bottom2)
|
||||||
%shared_ptr(Space::Bottom3)
|
%shared_ptr(Space::Bottom3)
|
||||||
|
|
||||||
%include "swiginterface.i"
|
%include <swiginterface.i>
|
||||||
SWIG_SHARED_PTR_INTERFACE_TYPEMAPS(, Space::ABase1)
|
SWIG_SHARED_PTR_INTERFACE_TYPEMAPS(, Space::ABase1)
|
||||||
SWIG_SHARED_PTR_INTERFACE_TYPEMAPS(, Space::CBase1)
|
SWIG_SHARED_PTR_INTERFACE_TYPEMAPS(, Space::CBase1)
|
||||||
SWIG_SHARED_PTR_INTERFACE_TYPEMAPS(, Space::CBase2)
|
SWIG_SHARED_PTR_INTERFACE_TYPEMAPS(, Space::CBase2)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance or %interface */
|
SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance or %interface */
|
||||||
|
|
||||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
|
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
|
||||||
%include "swiginterface.i"
|
%include <swiginterface.i>
|
||||||
%interface(IA)
|
%interface(IA)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "swigmod.h"
|
#include "swigmod.h"
|
||||||
|
#include "cparse.h"
|
||||||
|
|
||||||
static bool interface_feature_enabled = false;
|
static bool interface_feature_enabled = false;
|
||||||
|
|
||||||
|
|
@ -38,11 +39,19 @@ static List *collect_interface_methods(Node *n) {
|
||||||
if (Cmp(nodeType(child), "cdecl") == 0) {
|
if (Cmp(nodeType(child), "cdecl") == 0) {
|
||||||
if (GetFlag(child, "feature:ignore") || Getattr(child, "interface:owner"))
|
if (GetFlag(child, "feature:ignore") || Getattr(child, "interface:owner"))
|
||||||
continue; // skip methods propagated to bases
|
continue; // skip methods propagated to bases
|
||||||
Node *m = Copy(child);
|
if (!checkAttribute(child, "kind", "function"))
|
||||||
set_nextSibling(m, NIL);
|
continue;
|
||||||
set_previousSibling(m, NIL);
|
if (checkAttribute(child, "storage", "static"))
|
||||||
Setattr(m, "interface:owner", cls);
|
continue; // accept virtual methods, non-virtual methods too... mmm??. Warn that the interface class has something that is not a virtual method?
|
||||||
Append(methods, m);
|
Node *nn = copyNode(child);
|
||||||
|
Setattr(nn, "interface:owner", cls);
|
||||||
|
ParmList *parms = CopyParmList(Getattr(child, "parms"));
|
||||||
|
Setattr(nn, "parms", parms);
|
||||||
|
Delete(parms);
|
||||||
|
ParmList *throw_parm_list = Getattr(child, "throws");
|
||||||
|
if (throw_parm_list)
|
||||||
|
Setattr(nn, "throws", CopyParmList(throw_parm_list));
|
||||||
|
Append(methods, nn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -164,8 +173,25 @@ void Swig_interface_propagate_methods(Node *n) {
|
||||||
}
|
}
|
||||||
Delete(this_decl_resolved);
|
Delete(this_decl_resolved);
|
||||||
if (!identically_overloaded_method) {
|
if (!identically_overloaded_method) {
|
||||||
// TODO: Fix if the method is overloaded with different arguments / has default args
|
// Add method copied from base class to this derived class
|
||||||
appendChild(n, mi.item);
|
Node *cn = mi.item;
|
||||||
|
Delattr(cn, "sym:overname");
|
||||||
|
String *prefix = Getattr(n, "name");
|
||||||
|
String *name = Getattr(cn, "name");
|
||||||
|
String *decl = Getattr(cn, "decl");
|
||||||
|
String *oldname = Getattr(cn, "sym:name");
|
||||||
|
|
||||||
|
String *symname = Swig_name_make(cn, prefix, name, decl, oldname);
|
||||||
|
if (Strcmp(symname, "$ignore") != 0) {
|
||||||
|
Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
|
||||||
|
Node *on = Swig_symbol_add(symname, cn);
|
||||||
|
assert(on == cn);
|
||||||
|
|
||||||
|
// Features from the copied base class method are already present, now add in features specific to the added method in the derived class
|
||||||
|
Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
|
||||||
|
Swig_symbol_setscope(oldscope);
|
||||||
|
appendChild(n, cn);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Delete(mi.item);
|
Delete(mi.item);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue