process protected/private bases, support/ignore multi-inheritance directors
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@6734 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
0c80869369
commit
acb5bc3e48
1 changed files with 146 additions and 69 deletions
|
|
@ -277,6 +277,8 @@ Language::Language() :
|
||||||
default. Each language that need it, has to define it.
|
default. Each language that need it, has to define it.
|
||||||
*/
|
*/
|
||||||
director_prot_ctor_code = 0;
|
director_prot_ctor_code = 0;
|
||||||
|
director_multiple_inheritance = 1;
|
||||||
|
director_language = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Language::~Language() {
|
Language::~Language() {
|
||||||
|
|
@ -729,7 +731,7 @@ int Language::cDeclaration(Node *n) {
|
||||||
if (!isfriend ) {
|
if (!isfriend ) {
|
||||||
/* we check what director needs. If the method is pure virtual,
|
/* we check what director needs. If the method is pure virtual,
|
||||||
it is always needed. */
|
it is always needed. */
|
||||||
if (!(is_member_director(CurrentClass,n) && need_nonpublic_member(n)))
|
if (!(directorsEnabled() && is_member_director(CurrentClass,n) && need_nonpublic_member(n)))
|
||||||
return SWIG_NOWRAP;
|
return SWIG_NOWRAP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1515,22 +1517,50 @@ int Language::classDirectorDefaultConstructor(Node *n) {
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
* Language::unrollVirtualMethods()
|
* Language::unrollVirtualMethods()
|
||||||
* ---------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------- */
|
||||||
|
static
|
||||||
|
String *vtable_method_id(Node *n)
|
||||||
|
{
|
||||||
|
String *nodeType = Getattr(n, "nodeType");
|
||||||
|
int is_destructor = (Cmp(nodeType, "destructor") == 0);
|
||||||
|
if (is_destructor) return 0;
|
||||||
|
String *name = Getattr(n, "name");
|
||||||
|
String *decl = Getattr(n, "decl");
|
||||||
|
String *local_decl = SwigType_typedef_resolve_all(decl);
|
||||||
|
Node *method_id = NewStringf("%s|%s", name, local_decl);
|
||||||
|
Delete(local_decl);
|
||||||
|
return method_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int Language::unrollVirtualMethods(Node *n,
|
int Language::unrollVirtualMethods(Node *n,
|
||||||
Node *parent,
|
Node *parent,
|
||||||
Hash *vm,
|
Hash *vm,
|
||||||
int default_director,
|
int default_director,
|
||||||
int &virtual_destructor) {
|
int &virtual_destructor,
|
||||||
|
int protectedbase) {
|
||||||
Node *ni;
|
Node *ni;
|
||||||
String *nodeType;
|
String *nodeType;
|
||||||
String *classname;
|
String *classname;
|
||||||
String *decl;
|
String *decl;
|
||||||
|
bool first_base = false;
|
||||||
// recurse through all base classes to build the vtable
|
// recurse through all base classes to build the vtable
|
||||||
List* bl = Getattr(n, "bases");
|
List* bl = Getattr(n, "bases");
|
||||||
if (bl) {
|
if (bl) {
|
||||||
Iterator bi;
|
Iterator bi;
|
||||||
for (bi = First(bl); bi.item; bi = Next(bi)) {
|
for (bi = First(bl); bi.item; bi = Next(bi)) {
|
||||||
|
if (first_base && !director_multiple_inheritance) break;
|
||||||
unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor);
|
unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor);
|
||||||
|
first_base = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// recurse through all protected base classes to build the vtable, as needed
|
||||||
|
bl = Getattr(n, "protectedbases");
|
||||||
|
if (bl) {
|
||||||
|
Iterator bi;
|
||||||
|
for (bi = First(bl); bi.item; bi = Next(bi)) {
|
||||||
|
if (first_base && !director_multiple_inheritance) break;
|
||||||
|
unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor, 1);
|
||||||
|
first_base = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// find the methods that need directors
|
// find the methods that need directors
|
||||||
|
|
@ -1545,11 +1575,11 @@ int Language::unrollVirtualMethods(Node *n,
|
||||||
decl = Getattr(ni, "decl");
|
decl = Getattr(ni, "decl");
|
||||||
/* extra check for function type and proper access */
|
/* extra check for function type and proper access */
|
||||||
if (SwigType_isfunction(decl)
|
if (SwigType_isfunction(decl)
|
||||||
&& (is_public(n) || need_nonpublic_member(n))
|
&& (((!protectedbase || dirprot_mode()) && is_public(ni))
|
||||||
&& (is_public(ni) || need_nonpublic_member(ni))) {
|
|| need_nonpublic_member(ni))) {
|
||||||
String *name = Getattr(ni, "name");
|
String *name = Getattr(ni, "name");
|
||||||
String *local_decl = SwigType_typedef_resolve_all(decl);
|
Node *method_id = is_destructor ?
|
||||||
Node *method_id = is_destructor ? NewStringf("~destructor") : NewStringf("%s|%s", name, local_decl);
|
NewStringf("~destructor") : vtable_method_id(ni);
|
||||||
/* Make sure that the new method overwrites the existing: */
|
/* Make sure that the new method overwrites the existing: */
|
||||||
Hash *exists_item = Getattr(vm, method_id);
|
Hash *exists_item = Getattr(vm, method_id);
|
||||||
if (exists_item) {
|
if (exists_item) {
|
||||||
|
|
@ -1564,7 +1594,8 @@ int Language::unrollVirtualMethods(Node *n,
|
||||||
Hash *item = NewHash();
|
Hash *item = NewHash();
|
||||||
Setattr(item, "fqName", fqname);
|
Setattr(item, "fqName", fqname);
|
||||||
Node *m = Copy(ni);
|
Node *m = Copy(ni);
|
||||||
String *mname = NewStringf("%s::%s", Getattr(parent,"name"), name);
|
String *mname = NewStringf("%s::%s", Getattr(parent,"name"),name);
|
||||||
|
/* apply the features of the original method found in the base class */
|
||||||
Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m,"decl"), m);
|
Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m,"decl"), m);
|
||||||
Setattr(item, "methodNode", m);
|
Setattr(item, "methodNode", m);
|
||||||
Setattr(vm, method_id, item);
|
Setattr(vm, method_id, item);
|
||||||
|
|
@ -1572,7 +1603,6 @@ int Language::unrollVirtualMethods(Node *n,
|
||||||
Delete(fqname);
|
Delete(fqname);
|
||||||
Delete(item);
|
Delete(item);
|
||||||
Delete(method_id);
|
Delete(method_id);
|
||||||
Delete(local_decl);
|
|
||||||
}
|
}
|
||||||
if (is_destructor) {
|
if (is_destructor) {
|
||||||
virtual_destructor = 1;
|
virtual_destructor = 1;
|
||||||
|
|
@ -1592,39 +1622,16 @@ int Language::unrollVirtualMethods(Node *n,
|
||||||
for (k = First(vm); k.key; k = Next(k)) {
|
for (k = First(vm); k.key; k = Next(k)) {
|
||||||
Node *m = Getattr(k.item, "methodNode");
|
Node *m = Getattr(k.item, "methodNode");
|
||||||
/* retrieve the director features */
|
/* retrieve the director features */
|
||||||
int mdir = checkAttribute(m, "feature:director", "1") || director_mode;
|
int mdir = checkAttribute(m, "feature:director", "1");
|
||||||
int mndir = checkAttribute(m, "feature:nodirector", "1");
|
int mndir = checkAttribute(m, "feature:nodirector", "1");
|
||||||
/* 'nodirector' has precedence over 'director' */
|
/* 'nodirector' has precedence over 'director' */
|
||||||
int dir = (mdir || mndir) ? (mdir && !mndir) : 1;
|
int dir = (mdir || mndir) ? (mdir && !mndir) : 1;
|
||||||
/* check if the method was found only in a base class */
|
/* check if the method was found only in a base class */
|
||||||
Node *p = Getattr(m, "parentNode");
|
Node *p = Getattr(m, "parentNode");
|
||||||
if (p != n) {
|
if (p != n) {
|
||||||
/* check for my own features to take precedence, ie, if I only
|
|
||||||
found Base::method(), look for MySelf::method() features.
|
|
||||||
|
|
||||||
The problem is that MySelf::method() is not declared in the
|
|
||||||
MySelf class, and appears here through derivation:
|
|
||||||
|
|
||||||
%feature("nodirector") Base::method();
|
|
||||||
%feature("director") MySelf::method();
|
|
||||||
|
|
||||||
struct Base {
|
|
||||||
virtual ~Base();
|
|
||||||
virtual int method();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MySelf : Base {
|
|
||||||
};
|
|
||||||
|
|
||||||
*** Ask David, this is not working now!!! *****
|
|
||||||
|
|
||||||
This is now just giving back the Base::method() features,
|
|
||||||
maybe we need to look directly in the feature hash
|
|
||||||
table?...
|
|
||||||
*/
|
|
||||||
Node *c = Copy(m);
|
Node *c = Copy(m);
|
||||||
Setattr(c, "parentNode", n);
|
Setattr(c, "parentNode", n);
|
||||||
int cdir = checkAttribute(c, "feature:director", "1") || director_mode;
|
int cdir = checkAttribute(c, "feature:director", "1");
|
||||||
int cndir = checkAttribute(c, "feature:nodirector", "1");
|
int cndir = checkAttribute(c, "feature:nodirector", "1");
|
||||||
dir = (cdir || cndir) ? (cdir && !cndir) : dir;
|
dir = (cdir || cndir) ? (cdir && !cndir) : dir;
|
||||||
Delete(c);
|
Delete(c);
|
||||||
|
|
@ -1637,7 +1644,7 @@ int Language::unrollVirtualMethods(Node *n,
|
||||||
Delattr(vm, k.key);
|
Delattr(vm, k.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -1696,16 +1703,21 @@ int Language::classDirectorConstructors(Node *n) {
|
||||||
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
|
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
|
||||||
nodeType = Getattr(ni, "nodeType");
|
nodeType = Getattr(ni, "nodeType");
|
||||||
if (!Cmp(nodeType, "constructor")) {
|
if (!Cmp(nodeType, "constructor")) {
|
||||||
|
Parm *parms = Getattr(ni,"parms");
|
||||||
if (is_public(ni)) {
|
if (is_public(ni)) {
|
||||||
/* emit public constructor */
|
/* emit public constructor */
|
||||||
classDirectorConstructor(ni);
|
classDirectorConstructor(ni);
|
||||||
constructor = 1;
|
constructor = 1;
|
||||||
|
if (default_ctor)
|
||||||
|
default_ctor = !ParmList_numrequired(parms);
|
||||||
} else {
|
} else {
|
||||||
/* emit protected constructor if needed */
|
/* emit protected constructor if needed */
|
||||||
if (need_nonpublic_ctor(ni)) {
|
if (need_nonpublic_ctor(ni)) {
|
||||||
classDirectorConstructor(ni);
|
classDirectorConstructor(ni);
|
||||||
constructor = 1;
|
constructor = 1;
|
||||||
protected_ctor = 1;
|
protected_ctor = 1;
|
||||||
|
if (default_ctor)
|
||||||
|
default_ctor = !ParmList_numrequired(parms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1840,6 +1852,11 @@ int Language::classDirector(Node *n) {
|
||||||
"Director base class %s has no virtual destructor.\n",
|
"Director base class %s has no virtual destructor.\n",
|
||||||
classtype);
|
classtype);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
since now %feature("nodirector") is working, we check
|
||||||
|
that the director is really not abstract.
|
||||||
|
*/
|
||||||
|
|
||||||
Setattr(n, "vtable", vtable);
|
Setattr(n, "vtable", vtable);
|
||||||
classDirectorInit(n);
|
classDirectorInit(n);
|
||||||
classDirectorConstructors(n);
|
classDirectorConstructors(n);
|
||||||
|
|
@ -1913,19 +1930,21 @@ int Language::classDeclaration(Node *n) {
|
||||||
InClass = 1;
|
InClass = 1;
|
||||||
CurrentClass = n;
|
CurrentClass = n;
|
||||||
|
|
||||||
Abstract = abstractClassTest(n);
|
|
||||||
|
|
||||||
/* Call classHandler() here */
|
/* Call classHandler() here */
|
||||||
if (!ImportMode) {
|
if (!ImportMode) {
|
||||||
int ndir = checkAttribute(n, "feature:director", "1") || director_mode;
|
int ndir = checkAttribute(n, "feature:director", "1");
|
||||||
int nndir = checkAttribute(n, "feature:nodirector", "1");
|
int nndir = checkAttribute(n, "feature:nodirector", "1");
|
||||||
/* 'nodirector' has precedence over 'director' */
|
/* 'nodirector' has precedence over 'director' */
|
||||||
int dir = (ndir || nndir) ? (ndir && !nndir) : 0;
|
int dir = (ndir || nndir) ? (ndir && !nndir) : 0;
|
||||||
if (directorsEnabled() && dir) {
|
if (directorsEnabled() && dir) {
|
||||||
classDirector(n);
|
classDirector(n);
|
||||||
}
|
}
|
||||||
|
/* check for abstract after resolving directors */
|
||||||
|
Abstract = abstractClassTest(n);
|
||||||
classHandler(n);
|
classHandler(n);
|
||||||
} else {
|
} else {
|
||||||
|
Abstract = abstractClassTest(n);
|
||||||
Language::classHandler(n);
|
Language::classHandler(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1992,6 +2011,7 @@ int Language::classHandler(Node *n) {
|
||||||
bool hasDirector = Swig_directorclass(n) ? true : false;
|
bool hasDirector = Swig_directorclass(n) ? true : false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Emit all of the class members */
|
/* Emit all of the class members */
|
||||||
emit_children(n);
|
emit_children(n);
|
||||||
|
|
||||||
|
|
@ -2011,7 +2031,7 @@ int Language::classHandler(Node *n) {
|
||||||
if (!ImportMode && (GenerateDefault && !Getattr(n,"feature:nodefault"))) {
|
if (!ImportMode && (GenerateDefault && !Getattr(n,"feature:nodefault"))) {
|
||||||
if (!Getattr(n,"has_constructor") && !Getattr(n,"allocate:has_constructor") && (Getattr(n,"allocate:default_constructor"))) {
|
if (!Getattr(n,"has_constructor") && !Getattr(n,"allocate:has_constructor") && (Getattr(n,"allocate:default_constructor"))) {
|
||||||
/* Note: will need to change this to support different kinds of classes */
|
/* Note: will need to change this to support different kinds of classes */
|
||||||
if (!Abstract || hasDirector) {
|
if (!Abstract) {
|
||||||
Node *cn = makeConstructor(CurrentClass);
|
Node *cn = makeConstructor(CurrentClass);
|
||||||
constructorHandler(cn);
|
constructorHandler(cn);
|
||||||
Delete(cn);
|
Delete(cn);
|
||||||
|
|
@ -2098,6 +2118,7 @@ int Language::constructorDeclaration(Node *n) {
|
||||||
}
|
}
|
||||||
/* Only create a constructor if the class is not abstract */
|
/* Only create a constructor if the class is not abstract */
|
||||||
|
|
||||||
|
|
||||||
if (!Abstract) {
|
if (!Abstract) {
|
||||||
Node *over;
|
Node *over;
|
||||||
over = Swig_symbol_isoverloaded(n);
|
over = Swig_symbol_isoverloaded(n);
|
||||||
|
|
@ -2143,22 +2164,51 @@ int Language::constructorDeclaration(Node *n) {
|
||||||
* Language::constructorHandler()
|
* Language::constructorHandler()
|
||||||
* ---------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static String*
|
||||||
|
get_director_ctor_code(Node *n, String *director_ctor_code,
|
||||||
|
String *director_prot_ctor_code,
|
||||||
|
List*& abstract )
|
||||||
|
{
|
||||||
|
String *director_ctor = director_ctor_code;
|
||||||
|
int use_director = Swig_directorclass(n);
|
||||||
|
if (use_director) {
|
||||||
|
Node *pn = Swig_methodclass(n);
|
||||||
|
abstract = Getattr(pn,"abstract");
|
||||||
|
if (director_prot_ctor_code) {
|
||||||
|
int is_notabstract = Getattr(pn,"feature:notabstract") ? 1 : 0;
|
||||||
|
int is_abstract = abstract && !is_notabstract;
|
||||||
|
if (is_protected(n) || is_abstract) {
|
||||||
|
director_ctor = director_prot_ctor_code;
|
||||||
|
Delattr(pn,"abstract");
|
||||||
|
} else {
|
||||||
|
if (is_notabstract) {
|
||||||
|
Delattr(pn,"abstract");
|
||||||
|
} else {
|
||||||
|
abstract = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return director_ctor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
Language::constructorHandler(Node *n) {
|
Language::constructorHandler(Node *n) {
|
||||||
Swig_require("constructorHandler",n,"?name","*sym:name","?type","?parms",NIL);
|
Swig_require("constructorHandler",n,"?name","*sym:name","?type","?parms",NIL);
|
||||||
String *symname = Getattr(n,"sym:name");
|
String *symname = Getattr(n,"sym:name");
|
||||||
String *mrename = Swig_name_construct(symname);
|
String *mrename = Swig_name_construct(symname);
|
||||||
String *director_ctor = director_ctor_code;
|
List *abstract = 0;
|
||||||
if (director_prot_ctor_code) {
|
String *director_ctor = get_director_ctor_code(n, director_ctor_code,
|
||||||
if (is_protected(n) || Getattr(Swig_methodclass(n),"abstract")) {
|
director_prot_ctor_code,
|
||||||
director_ctor = director_prot_ctor_code;
|
abstract);
|
||||||
}
|
Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor,
|
||||||
}
|
CPlusPlus, Getattr(n, "template") ? 0 :Extend);
|
||||||
Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 :Extend);
|
|
||||||
Setattr(n,"sym:name", mrename);
|
Setattr(n,"sym:name", mrename);
|
||||||
functionWrapper(n);
|
functionWrapper(n);
|
||||||
Delete(mrename);
|
Delete(mrename);
|
||||||
Swig_restore(n);
|
Swig_restore(n);
|
||||||
|
if (abstract) Setattr(Swig_methodclass(n),"abstract",abstract);
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2171,18 +2221,17 @@ Language::copyconstructorHandler(Node *n) {
|
||||||
Swig_require("copyconstructorHandler",n,"?name","*sym:name","?type","?parms", NIL);
|
Swig_require("copyconstructorHandler",n,"?name","*sym:name","?type","?parms", NIL);
|
||||||
String *symname = Getattr(n,"sym:name");
|
String *symname = Getattr(n,"sym:name");
|
||||||
String *mrename = Swig_name_copyconstructor(symname);
|
String *mrename = Swig_name_copyconstructor(symname);
|
||||||
String *director_ctor = director_ctor_code;
|
List *abstract = 0;
|
||||||
if (director_prot_ctor_code) {
|
String *director_ctor = get_director_ctor_code(n, director_ctor_code,
|
||||||
if (is_protected(n) || Getattr(Swig_methodclass(n),"abstract")) {
|
director_prot_ctor_code,
|
||||||
director_ctor = director_prot_ctor_code;
|
abstract);
|
||||||
}
|
|
||||||
}
|
|
||||||
Swig_ConstructorToFunction(n,ClassType, none_comparison, director_ctor,
|
Swig_ConstructorToFunction(n,ClassType, none_comparison, director_ctor,
|
||||||
CPlusPlus, Getattr(n,"template") ? 0 : Extend);
|
CPlusPlus, Getattr(n,"template") ? 0 : Extend);
|
||||||
Setattr(n,"sym:name", mrename);
|
Setattr(n,"sym:name", mrename);
|
||||||
functionWrapper(n);
|
functionWrapper(n);
|
||||||
Delete(mrename);
|
Delete(mrename);
|
||||||
Swig_restore(n);
|
Swig_restore(n);
|
||||||
|
if (abstract) Setattr(Swig_methodclass(n),"abstract",abstract);
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2576,7 +2625,7 @@ void Language::allow_directors(int val) {
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int Language::directorsEnabled() const {
|
int Language::directorsEnabled() const {
|
||||||
return (directors || director_mode) && CPlusPlus;
|
return director_language && CPlusPlus && (directors || director_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
|
|
@ -2731,33 +2780,61 @@ String * Language::getClassType() const {
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Language::abstractClassTest()
|
* Language::abstractClassTest()
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
//#define SWIG_DEBUG
|
||||||
int Language::abstractClassTest(Node *n) {
|
int Language::abstractClassTest(Node *n) {
|
||||||
/* check for non public operator new */
|
/* check for non public operator new */
|
||||||
|
if (Getattr(n,"feature:notabstract")) return 0;
|
||||||
if (Getattr(n,"allocate:nonew")) return 1;
|
if (Getattr(n,"allocate:nonew")) return 1;
|
||||||
/* now check for the rest */
|
/* now check for the rest */
|
||||||
List *abstract = Getattr(n,"abstract");
|
List *abstract = Getattr(n,"abstract");
|
||||||
if (!abstract) return 0;
|
if (!abstract) return 0;
|
||||||
|
int labs = Len(abstract);
|
||||||
|
#ifdef SWIG_DEBUG
|
||||||
|
List *bases = Getattr(n,"allbases");
|
||||||
|
Printf(stderr,"testing %s %d %d\n",Getattr(n,"name"),labs,Len(bases));
|
||||||
|
#endif
|
||||||
|
if (!labs) return 0; /*strange, but need to be fixed */
|
||||||
if (abstract && !directorsEnabled()) return 1;
|
if (abstract && !directorsEnabled()) return 1;
|
||||||
if (Cmp(Getattr(n, "feature:director"), "1")) return 1;
|
if (!Getattr(n,"feature:director")) return 1;
|
||||||
/*
|
|
||||||
since now %feature("noabstract") is working, we check
|
Node *dirabstract = 0;
|
||||||
that the director is really not abstract.
|
Node *vtable = Getattr(n, "vtable");
|
||||||
*/
|
if (vtable) {
|
||||||
int dirabstract = 0;
|
#ifdef SWIG_DEBUG
|
||||||
for (int i = 0; i < Len(abstract); i++) {
|
Printf(stderr,"vtable %s %d %d\n",Getattr(n,"name"),Len(vtable),labs);
|
||||||
Node *nn = Getitem(abstract,i);
|
#endif
|
||||||
if (!is_member_director(n,nn)) {
|
for (int i = 0; i < labs; i++) {
|
||||||
dirabstract = 1;
|
Node *ni = Getitem(abstract,i);
|
||||||
|
Node *method_id = vtable_method_id(ni);
|
||||||
|
if (!method_id) continue;
|
||||||
|
Hash *exists_item = Getattr(vtable, method_id);
|
||||||
|
#ifdef SWIG_DEBUG
|
||||||
|
Printf(stderr,"method %s %d\n",method_id,exists_item ? 1 : 0);
|
||||||
|
#endif
|
||||||
|
Delete(method_id);
|
||||||
|
if (!exists_item) {
|
||||||
|
dirabstract = ni;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (dirabstract) {
|
||||||
|
if (is_public(dirabstract)) {
|
||||||
|
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT,Getfile(n),Getline(n),
|
||||||
|
"Director class '%s' is abstract, abstract method '%s' is not accesible, maybe due to multiple inheritance or 'nodirector' feature\n",
|
||||||
|
SwigType_namestr(Getattr(n,"name")),
|
||||||
|
Getattr(dirabstract,"name"));
|
||||||
|
} else {
|
||||||
|
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT,Getfile(n),Getline(n),
|
||||||
|
"Director class '%s' is abstract, abstract method '%s' is private\n",
|
||||||
|
SwigType_namestr(Getattr(n,"name")),
|
||||||
|
Getattr(dirabstract,"name"));
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
if (dirabstract) {
|
return dirabstract ? 1 : 0;
|
||||||
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT,Getfile(n),Getline(n),
|
|
||||||
"Director class '%s' is abstract\n",
|
|
||||||
SwigType_namestr(Getattr(n,"name")));
|
|
||||||
}
|
|
||||||
|
|
||||||
return dirabstract;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Language::setSubclassInstanceCheck(String *nc) {
|
void Language::setSubclassInstanceCheck(String *nc) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue