diff -x '*.pyc' -C3 src.orig/ClassExporter.py src/ClassExporter.py *** src.orig/ClassExporter.py 2003-06-12 12:11:36.000000000 -0400 --- src/ClassExporter.py 2003-06-13 16:01:56.000000000 -0400 *************** *** 60,67 **** self.class_ = decl self.public_members = \ [x for x in self.class_.members if x.visibility == Scope.public] ! ! def Order(self): '''Return the TOTAL number of bases that this class has, including the bases' bases. Do this because base classes must be instantialized --- 60,66 ---- self.class_ = decl self.public_members = \ [x for x in self.class_.members if x.visibility == Scope.public] ! def Order(self): '''Return the TOTAL number of bases that this class has, including the bases' bases. Do this because base classes must be instantialized *************** *** 286,292 **** if wrapper: return '&' + wrapper.FullName() # return normal pointers to the methods of the class ! is_unique = self.class_.IsUnique(m.name) if is_unique: return '&' + method.FullName() else: --- 285,291 ---- if wrapper: return '&' + wrapper.FullName() # return normal pointers to the methods of the class ! is_unique = self.class_.IsUnique(m.name) and m.class_ == self.class_ if is_unique: return '&' + method.FullName() else: *************** *** 295,303 **** def IsExportable(m): 'Returns true if the given method is exportable by this routine' ignore = (Constructor, ClassOperator, Destructor) ! return isinstance(m, Method) and not isinstance(m, ignore) and not m.virtual ! methods = [x for x in self.public_members if IsExportable(x)] for method in methods: if self.info[method.name].exclude: --- 294,312 ---- def IsExportable(m): 'Returns true if the given method is exportable by this routine' ignore = (Constructor, ClassOperator, Destructor) ! return isinstance(m, Method) and not isinstance(m, ignore) and not (m.virtual and not self.info[m.name].unvirtual) ! # Extend this to include member functions defined in base classes. ! # This is quite primitive for now, just treats the member functions as ! # members of this class, for wrap/exclude/policy purposes, but let's ! # just see how it goes ! # ! # The logic here is also not to re-export methods which have already ! # been exported by the top level class (or another base class), hence ! # checking if method is already in list. Unfortunately, signature ! # is not checked ! #methods = [x for x in self.public_members if IsExportable(x)] ! methods = [x for x in self.class_.GetAllMethods() if x.IsVisible() and IsExportable(x)] for method in methods: if self.info[method.name].exclude: *************** *** 341,347 **** # check if this class has any virtual methods has_virtual_methods = False for member in self.class_.members: ! if type(member) == Method and member.virtual: has_virtual_methods = True break --- 350,356 ---- # check if this class has any virtual methods has_virtual_methods = False for member in self.class_.members: ! if type(member) == Method and member.virtual and not self.info[member.name].unvirtual: has_virtual_methods = True break *************** *** 670,681 **** else: pointer = method.PointerDeclaration() # generate the defs definitions = [] # basic def ! definitions.append('.def("%s", %s, %s)' % (rename, pointer, default_pointers[-1])) for default_pointer in default_pointers[:-1]: ! definitions.append('.def("%s", %s)' % (rename, default_pointer)) return definitions --- 679,695 ---- else: pointer = method.PointerDeclaration() + # Add policy to overloaded methods also + policy = self.info[method.name].policy or '' + if policy: + policy = ', %s%s()' % (namespaces.python, policy.Code()) + # generate the defs definitions = [] # basic def ! definitions.append('.def("%s", %s, %s%s)' % (rename, pointer, default_pointers[-1], policy)) for default_pointer in default_pointers[:-1]: ! definitions.append('.def("%s", %s%s)' % (rename, default_pointer,policy)) return definitions *************** *** 685,691 **** def VirtualMethods(self): def IsVirtual(m): ! return type(m) == Method and m.virtual return [m for m in self.class_.members if IsVirtual(m)] --- 699,705 ---- def VirtualMethods(self): def IsVirtual(m): ! return type(m) == Method and m.virtual and not self.info[m.name].unvirtual return [m for m in self.class_.members if IsVirtual(m)] diff -x '*.pyc' -C3 src.orig/declarations.py src/declarations.py *** src.orig/declarations.py 2003-06-12 12:11:36.000000000 -0400 --- src/declarations.py 2003-06-13 16:46:06.000000000 -0400 *************** *** 48,53 **** --- 48,54 ---- # instances of Base self.bases = bases self._members_count = {} + self._all_methods = [] def __iter__(self): *************** *** 106,111 **** --- 107,130 ---- print self._members_count print 'Key', member_name + def GetAllMethods(self): + """ + This function returns _ALL_ of the methods of this class, publicly + visible at the top level - i.e. including the ones inherited from + the base classes. It also avoids exporting member functions more + than once, i.e. only the topmost overloaded virtual method will be + exposed + """ + if not self._all_methods: + self._all_methods.extend([m for m in self + if isinstance(m, Method)] ) + + for base in [ b for b in self.bases if b.IsVisible() ]: + self._all_methods.extend ( [ m for m in base.GetClass() + if isinstance(m,Method) and m not in self._all_methods ]) + + return self._all_methods + class NestedClass(Class): *************** *** 125,138 **** class Base: 'Represents a base class of another class.' ! def __init__(self, name, visibility=None): # class_ is the full name of the base class ! self.name = name # visibility of the derivation if visibility is None: visibility = Scope.public self.visibility = visibility class Scope: --- 144,164 ---- class Base: 'Represents a base class of another class.' ! def __init__(self, class_, visibility=None): # class_ is the full name of the base class ! self.class_ = class_ ! self.name = class_.FullName() # visibility of the derivation if visibility is None: visibility = Scope.public self.visibility = visibility + def GetClass(self): + return self.class_ + + def IsVisible(self): + return self.visibility == Scope.public + class Scope: *************** *** 214,219 **** --- 240,255 ---- return '(%s (%s::*)(%s) %s)&%s' %\ (result, self.class_, params, const, self.FullName()) + def IsVisible(self): + return self.visibility == Scope.public + + def __cmp__(self, other): + """Basic comparison to detect virtual members that have been overloaded, + to avoid exporting twice""" + return cmp(self.name, other.name) or \ + cmp(self.result, other.result) or \ + cmp(self.parameters, other.parameters) + class Constructor(Method): 'A constructor of a class.' *************** *** 233,239 **** class_as_param = self.parameters[0].name == self.class_ param_reference = isinstance(param, ReferenceType) return param_reference and class_as_param and param.const ! class Destructor(Method): 'The destructor of a class.' --- 269,275 ---- class_as_param = self.parameters[0].name == self.class_ param_reference = isinstance(param, ReferenceType) return param_reference and class_as_param and param.const ! class Destructor(Method): 'The destructor of a class.' *************** *** 288,293 **** --- 324,333 ---- const = '' return const + self.name + def __cmp__(self, other): + """ Rudimentary comparisson """ + return cmp(self.FullName(), other.FullName()) + class ArrayType(Type): Only in src/: .declarations.py.swp diff -x '*.pyc' -C3 src.orig/GCCXMLParser.py src/GCCXMLParser.py *** src.orig/GCCXMLParser.py 2003-06-12 12:11:36.000000000 -0400 --- src/GCCXMLParser.py 2003-06-13 14:11:41.000000000 -0400 *************** *** 200,206 **** else: visib = Scope.public decl = self.GetDecl(base) ! baseobj = Base(decl.FullName(), visib) baseobjs.append(baseobj) return baseobjs --- 200,206 ---- else: visib = Scope.public decl = self.GetDecl(base) ! baseobj = Base(decl, visib) baseobjs.append(baseobj) return baseobjs *************** *** 307,312 **** --- 307,313 ---- const = bool(int(element.get('const', '0'))) location = self.GetLocation(element.get('location')) params = self.GetArguments(element) + method = methodType( name, classname, result, params, visib, virtual, abstract, static, const) method.location = location diff -x '*.pyc' -C3 src.orig/infos.py src/infos.py *** src.orig/infos.py 2003-06-12 12:11:36.000000000 -0400 --- src/infos.py 2003-06-12 16:10:24.000000000 -0400 *************** *** 172,177 **** --- 172,180 ---- def set_policy(option, policy): option._Attribute('policy', policy) + def unvirtual(option): + option._Attribute('unvirtual', True) + def rename(option, name): option._Attribute('rename', name) diff -x '*.pyc' -C3 src.orig/pyste.py src/pyste.py *** src.orig/pyste.py 2003-06-12 12:11:36.000000000 -0400 --- src/pyste.py 2003-06-13 10:23:14.000000000 -0400 *************** *** 91,96 **** --- 91,97 ---- context['set_policy'] = infos.set_policy context['exclude'] = infos.exclude context['set_wrapper'] = infos.set_wrapper + context['unvirtual'] = infos.unvirtual # make a method non-virtual # policies context['return_internal_reference'] = return_internal_reference context['with_custodian_and_ward'] = with_custodian_and_ward