diff --git a/etgtools/extractors.py b/etgtools/extractors.py index 6f14fb75..c6c307d2 100644 --- a/etgtools/extractors.py +++ b/etgtools/extractors.py @@ -601,32 +601,38 @@ class ClassDef(BaseDef): props = dict() for item in self.items: - if item.ignored: - continue if isinstance(item, MethodDef) and item.name not in ['Get', 'Set'] \ and (item.name.startswith('Get') or item.name.startswith('Set')): prefix = item.name[:3] name = item.name[3:] prop = props.get(name, PropertyDef(name)) - if prefix == 'Get': - prop.getter = item.name - # Getters must be able to be called with no args, ensure - # that item has exactly zero args without a default value - if countNonDefaultArgs(item) != 0: - # TODO: check overloads too + # look at all overloads + ok = False + for m in item.all(): + if m.ignored: continue - # Getters must not be static methods - if item.isStatic: - continue - elif prefix == 'Set': - prop.setter = item.name - # Setters must be able to be called with 1 arg, ensure - # that item has at least 1 arg and not more than 1 without - # a default value. - if len(item.items) == 0 or countNonDefaultArgs(item) > 1: - # TODO: check overloads too - continue - props[name] = prop + if prefix == 'Get': + prop.getter = m.name + # Getters must be able to be called with no args, ensure + # that item has exactly zero args without a default value + if countNonDefaultArgs(m) != 0: + continue + # Getters must not be static methods + if item.isStatic: + continue + ok = True + break + elif prefix == 'Set': + prop.setter = m.name + # Setters must be able to be called with 1 arg, ensure + # that item has at least 1 arg and not more than 1 without + # a default value. + if len(m.items) == 0 or countNonDefaultArgs(m) > 1: + continue + ok = True + break + if ok: + props[name] = prop if props: self.addPublic() @@ -698,6 +704,12 @@ class ClassDef(BaseDef): #------------------------------------------------------------------ + def _addMethod(self, md): + if self.findItem(md.name): + self.findItem(md.name).overloads.append(md) + else: + self.items.append(md) + def addCppMethod(self, type, name, argsString, body, doc=None, isConst=False, **kw): """ Add a new C++ method to a class. This method doesn't have to actually @@ -706,7 +718,7 @@ class ClassDef(BaseDef): target language. """ md = CppMethodDef(type, name, argsString, body, doc, isConst, klass=self, **kw) - self.items.append(md) + self._addMethod(md) return md @@ -717,7 +729,7 @@ class ClassDef(BaseDef): md = CppMethodDef('', self.name, argsString, body, doc=doc, isCtor=True, klass=self, noDerivedCtor=noDerivedCtor, useDerivedName=useDerivedName, **kw) - self.items.append(md) + self._addMethod(md) return md @@ -727,7 +739,7 @@ class ClassDef(BaseDef): the code body, instead of using the general purpose implementation. """ md = CppMethodDef_sip(type, name, argsString, body, doc, klass=self, **kw) - self.items.append(md) + self._addMethod(md) return md def addCppCtor_sip(self, argsString, body, doc=None, noDerivedCtor=True, **kw): @@ -736,7 +748,7 @@ class ClassDef(BaseDef): """ md = CppMethodDef_sip('', self.name, argsString, body, doc=doc, isCtor=True, klass=self, noDerivedCtor=noDerivedCtor, **kw) - self.items.append(md) + self._addMethod(md) return md #------------------------------------------------------------------ @@ -915,6 +927,7 @@ class CppMethodDef(MethodDef): self.klass = None self.noDerivedCtor = False self.isConst = isConst + self.isPureVirtual = False self.__dict__.update(kw) @staticmethod diff --git a/etgtools/sip_generator.py b/etgtools/sip_generator.py index b5592a00..65dbcc7b 100644 --- a/etgtools/sip_generator.py +++ b/etgtools/sip_generator.py @@ -349,35 +349,17 @@ from %s import * public = [i for i in klass if i.protection == 'public' and i not in ctors] protected = [i for i in klass if i.protection == 'protected'] - dispatch = { - extractors.MemberVarDef : self.generateMemberVar, - extractors.PropertyDef : self.generateProperty, - extractors.PyPropertyDef : self.generatePyProperty, - extractors.MethodDef : self.generateMethod, - extractors.EnumDef : self.generateEnum, - extractors.CppMethodDef : self.generateCppMethod, - extractors.CppMethodDef_sip : self.generateCppMethod_sip, - extractors.PyMethodDef : self.generatePyMethod, - extractors.PyCodeDef : self.generatePyCode, - extractors.WigCode : self.generateWigCode, - } for item in ctors: - item.klass = klass - f = dispatch[item.__class__] - f(item, stream, indent2) + self.dispatchClassItem(klass, item, stream, indent2) for item in public: - item.klass = klass - f = dispatch[item.__class__] - f(item, stream, indent2) + self.dispatchClassItem(klass, item, stream, indent2) if protected and [i for i in protected if not i.ignored]: stream.write('\nprotected:\n') for item in protected: - item.klass = klass - f = dispatch[item.__class__] - f(item, stream, indent2) + self.dispatchClassItem(klass, item, stream, indent2) if klass.convertFromPyObject: self.generateConvertCode('%ConvertToTypeCode', @@ -394,10 +376,27 @@ from %s import * # Now generate anything that was deferred until after the class is finished klass.generatingInClass = False for item in klass.generateAfterClass: - f = dispatch[item.__class__] - f(item, stream, indent) + self.dispatchClassItem(klass, item, stream, indent) + + def dispatchClassItem(self, klass, item, stream, indent): + dispatch = { + extractors.MemberVarDef : self.generateMemberVar, + extractors.PropertyDef : self.generateProperty, + extractors.PyPropertyDef : self.generatePyProperty, + extractors.MethodDef : self.generateMethod, + extractors.EnumDef : self.generateEnum, + extractors.CppMethodDef : self.generateCppMethod, + extractors.CppMethodDef_sip : self.generateCppMethod_sip, + extractors.PyMethodDef : self.generatePyMethod, + extractors.PyCodeDef : self.generatePyCode, + extractors.WigCode : self.generateWigCode, + } + item.klass = klass + f = dispatch[item.__class__] + f(item, stream, indent) + def generateConvertCode(self, kind, code, stream, indent): stream.write('%s%s\n' % (indent, kind)) @@ -457,8 +456,9 @@ from %s import * item.pyDocstring = nci(text) - def generateMethod(self, method, stream, indent, _needDocstring=True): + def generateMethod(self, method, stream, indent): assert isinstance(method, extractors.MethodDef) + _needDocstring = getattr(method, '_needDocstring', True) if not method.ignored: if method.isVirtual: stream.write("%svirtual\n" % indent) @@ -497,9 +497,11 @@ from %s import * self.generateCppMethod(cm, stream, indent, skipDeclaration=True) stream.write('\n') + if method.overloads: for m in method.overloads: - self.generateMethod(m, stream, indent, _needDocstring) + m._needDocstring = _needDocstring + self.dispatchClassItem(method.klass, m, stream, indent) def generateCppMethod(self, method, stream, indent='', skipDeclaration=False):