Directors are output in the order in which they are declared in the C++ class rather than in some pseudo-random order.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@9391 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2006-10-03 22:44:12 +00:00
commit 79eb884747

View file

@ -1710,7 +1710,7 @@ String *vtable_method_id(Node *n)
* ---------------------------------------------------------------------- */ * ---------------------------------------------------------------------- */
int Language::unrollVirtualMethods(Node *n, int Language::unrollVirtualMethods(Node *n,
Node *parent, Node *parent,
Hash *vm, List *vm,
int default_director, int default_director,
int &virtual_destructor, int &virtual_destructor,
int protectedbase) { int protectedbase) {
@ -1750,20 +1750,21 @@ int Language::unrollVirtualMethods(Node *n,
if ((Cmp(nodeType, "cdecl") == 0)|| is_destructor) { if ((Cmp(nodeType, "cdecl") == 0)|| is_destructor) {
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) && (((!protectedbase || dirprot_mode()) && is_public(ni)) || need_nonpublic_member(ni))) {
&& (((!protectedbase || dirprot_mode()) && is_public(ni))
|| need_nonpublic_member(ni))) {
String *name = Getattr(ni, "name"); String *name = Getattr(ni, "name");
Node *method_id = is_destructor ? Node *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(ni);
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); int len = Len(vm);
if (exists_item) { const int DO_NOT_REPLACE = -1;
/* maybe we should check for precedence here, ie, only int replace = DO_NOT_REPLACE;
delete the previous method if 'n' is derived from the for (int i=0; i<len; i++) {
previous method parent node. This is almost always true, Node *item = Getitem(vm,i);
so by now, we just delete the entry. */ String *check_vmid = Getattr(item, "vmid");
Delattr(vm, method_id);
if (Strcmp(method_id, check_vmid) == 0) {
replace = i;
break;
}
} }
/* filling a new method item */ /* filling a new method item */
String *fqdname = NewStringf("%s::%s", classname, name); String *fqdname = NewStringf("%s::%s", classname, name);
@ -1784,11 +1785,13 @@ int Language::unrollVirtualMethods(Node *n,
/* apply the features of the original method found in the base class */ /* 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(item, "vmid", method_id);
if (replace == DO_NOT_REPLACE)
Append(vm, item);
else
Setitem(vm, replace, item);
Delete(mname); Delete(mname);
Delete(fqdname);
Delete(item);
Delete(method_id);
} }
if (is_destructor) { if (is_destructor) {
virtual_destructor = 1; virtual_destructor = 1;
@ -1804,9 +1807,10 @@ int Language::unrollVirtualMethods(Node *n,
an the recursive loop!. an the recursive loop!.
*/ */
if (n == parent) { if (n == parent) {
Iterator k; int len = Len(vm);
for (k = First(vm); k.key; k = Next(k)) { for (int i=0; i<len; i++) {
Node *m = Getattr(k.item, "methodNode"); Node *item = Getitem(vm,i);
Node *m = Getattr(item, "methodNode");
/* retrieve the director features */ /* retrieve the director features */
int mdir = GetFlag(m, "feature:director"); int mdir = GetFlag(m, "feature:director");
int mndir = GetFlag(m, "feature:nodirector"); int mndir = GetFlag(m, "feature:nodirector");
@ -1827,7 +1831,7 @@ int Language::unrollVirtualMethods(Node *n,
if (mndir) Delattr(m, "feature:nodirector"); if (mndir) Delattr(m, "feature:nodirector");
} else { } else {
/* or just delete from the vm, since is not a director method */ /* or just delete from the vm, since is not a director method */
Delattr(vm, k.key); Delitem(vm, i);
} }
} }
} }
@ -1947,15 +1951,12 @@ int Language::classDirectorConstructors(Node *n) {
int Language::classDirectorMethods(Node *n) { int Language::classDirectorMethods(Node *n) {
Node *vtable = Getattr(n, "vtable"); Node *vtable = Getattr(n, "vtable");
Node *item;
Iterator k;
for (k = First(vtable); k.key; k = Next(k)) { int len = Len(vtable);
item = k.item; for (int i=0; i<len; i++) {
Node *item = Getitem(vtable,i);
String *method = Getattr(item, "methodNode"); String *method = Getattr(item, "methodNode");
String *fqdname = Getattr(item, "fqdname"); String *fqdname = Getattr(item, "fqdname");
// if (GetFlag(method,"feature:ignore"))
// continue;
if (GetFlag(method, "feature:nodirector")) if (GetFlag(method, "feature:nodirector"))
continue; continue;
@ -2027,7 +2028,7 @@ int Language::classDirector(Node *n) {
Setattr(module, "wrap:directormap", directormap); Setattr(module, "wrap:directormap", directormap);
} }
} }
Hash* vtable = NewHash(); List* vtable = NewList();
int virtual_destructor = 0; int virtual_destructor = 0;
unrollVirtualMethods(n, n, vtable, 0, virtual_destructor); unrollVirtualMethods(n, n, vtable, 0, virtual_destructor);
if (virtual_destructor || Len(vtable) > 0) { if (virtual_destructor || Len(vtable) > 0) {
@ -2366,16 +2367,15 @@ int Language::classHandler(Node *n) {
/* Emit additional protected virtual methods - only needed if the language module /* Emit additional protected virtual methods - only needed if the language module
* codes logic in the C++ layer instead of the director proxy class method - primarily * codes logic in the C++ layer instead of the director proxy class method - primarily
* to catch public use of protected methods by the sripting languages. */ * to catch public use of protected methods by the scripting languages. */
if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) { if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) {
Node *vtable = Getattr(n, "vtable"); Node *vtable = Getattr(n, "vtable");
String* symname = Getattr(n, "sym:name"); String* symname = Getattr(n, "sym:name");
Node *item;
Iterator k;
AccessMode old_mode = cplus_mode; AccessMode old_mode = cplus_mode;
cplus_mode = PROTECTED; cplus_mode = PROTECTED;
for (k = First(vtable); k.key; k = Next(k)) { int len = Len(vtable);
item = k.item; for (int i=0; i<len; i++) {
Node *item = Getitem(vtable,i);
Node *method = Getattr(item, "methodNode"); Node *method = Getattr(item, "methodNode");
SwigType *type = Getattr(method,"nodeType"); SwigType *type = Getattr(method,"nodeType");
if (Strcmp(type,"cdecl") !=0 ) if (Strcmp(type,"cdecl") !=0 )
@ -3200,14 +3200,15 @@ int Language::abstractClassTest(Node *n) {
Node *ni = Getitem(abstract,i); Node *ni = Getitem(abstract,i);
Node *method_id = vtable_method_id(ni); Node *method_id = vtable_method_id(ni);
if (!method_id) continue; if (!method_id) continue;
Hash *exists_item = Getattr(vtable, method_id); bool exists_item = false;
#ifdef SWIG_DEBUG int len = Len(vtable);
Printf(stderr,"method %s %d\n",method_id,exists_item ? 1 : 0); for (int i=0; i<len; i++) {
#endif Node *item = Getitem(vtable,i);
Delete(method_id); String *check_item = Getattr(item, "vmid");
if (!exists_item) { if (Strcmp(method_id, check_item) == 0) {
dirabstract = ni; exists_item = true;
break; break;
}
} }
} }
if (dirabstract) { if (dirabstract) {