def translate_class_type(self, _type, **params): if _type.name in self.ignore: raise AbsApi.Error('{0} has been escaped'.format(_type.name)) if _type.desc is None: raise AbsApi.Error('{0} has not been fixed'.format(_type.name)) if 'namespace' in params: nsName = params['namespace'].name if params[ 'namespace'] is not None else None else: method = _type.find_first_ancestor_by_type(AbsApi.Method) nsName = AbsApi.Name.find_common_parent(_type.desc.name, method.name) res = CppTranslator.translate_class_name(_type.desc.name, recursive=True, topAncestor=nsName) if _type.desc.refcountable: if _type.isconst: res = 'const ' + res if type(_type.parent) is AbsApi.Argument: return 'const std::shared_ptr<{0}> &'.format(res) else: return 'std::shared_ptr<{0}>'.format(res) else: if type(_type.parent) is AbsApi.Argument: return 'const {0} &'.format(res) else: return '{0}'.format(res)
def translate_type(self, _type, isArg, dllImport=True): if type(_type) is AbsApi.EnumType: if dllImport and isArg: return 'int' return _type.desc.name.to_camel_case() elif type(_type) is AbsApi.ClassType: return "IntPtr" if dllImport else _type.desc.name.to_camel_case() elif type(_type) is AbsApi.BaseType: return self.translate_base_type(_type, isArg, dllImport) elif type(_type) is AbsApi.ListType: if dllImport: return 'IntPtr' else: if type(_type.containedTypeDesc) is AbsApi.BaseType: if _type.containedTypeDesc.name == 'string': return 'IEnumerable<string>' else: raise AbsApi.Error( 'translation of bctbx_list_t of basic C types is not supported' ) elif type(_type.containedTypeDesc) is AbsApi.ClassType: ptrType = _type.containedTypeDesc.desc.name.to_camel_case() return 'IEnumerable<' + ptrType + '>' else: if _type.containedTypeDesc: raise AbsApi.Error( 'translation of bctbx_list_t of enums') else: raise AbsApi.Error( 'translation of bctbx_list_t of unknow type !')
def translate_enum_type(self, _type, **params): if _type.name in self.ignore: raise AbsApi.Error('{0} has been escaped'.format(_type.name)) if _type.desc is None: raise AbsApi.Error('{0} has not been fixed'.format(_type.name)) if 'namespace' in params: nsName = params['namespace'].name if params['namespace'] is not None else None else: method = _type.find_first_ancestor_by_type(AbsApi.Method) nsName = AbsApi.Name.find_common_parent(_type.desc.name, method.name) return CppTranslator.translate_enum_name(_type.desc.name, recursive=True, topAncestor=nsName)
def translate_interface(self, interface): if interface.name.to_c() in self.ignore: raise AbsApi.Error('{0} has been escaped'.format( interface.name.to_c())) interfaceDict = {} interfaceDict['interfaceName'] = interface.name.translate( self.nameTranslator) interfaceDict[ 'set_user_data_name'] = interface.listenedClass.name.to_snake_case( fullName=True) + '_cbs_set_user_data' interfaceDict[ 'get_user_data_name'] = interface.listenedClass.name.to_snake_case( fullName=True) + '_cbs_get_user_data' interfaceDict['briefDoc'] = interface.briefDescription.translate( self.docTranslator, tagAsBrief=True) interfaceDict['detailedDoc'] = interface.detailedDescription.translate( self.docTranslator) interfaceDict[ 'interfaceCName'] = interface.listenedClass.name.to_snake_case( fullName=False) interfaceDict['methods'] = [] for method in interface.instanceMethods: interfaceDict['methods'].append( self.translate_listener(interface, method)) return interfaceDict
def translate_class(self, _class): if _class.name.to_c() in self.ignore: raise AbsApi.Error('{0} has been escaped'.format(_class.name.to_c())) classDict = {} classDict['className'] = _class.name.translate(self.nameTranslator) classDict['classDelegateName'] = classDict['className'] + "Delegate" classDict['isLinphoneFactory'] = classDict['className'] == "Factory" classDict['isLinphoneCall'] = _class.name.to_camel_case() == "Call" classDict['isLinphoneCore'] = _class.name.to_camel_case() == "Core" try: classDict['doc'] = _class.briefDescription.translate(self.docTranslator, tagAsBrief=True) classDict['detailedDoc'] = _class.detailedDescription.translate(self.docTranslator) except metadoc.TranslationError as e: logging.error(e.msg()) classDict['properties'] = [] classDict['classEnums'] = [] islistenable = _class.listenerInterface is not None if islistenable: classDict['hasListener'] = True listenerName = _class.listenerInterface.name.translate(self.nameTranslator) if _class.singlelistener: classDict['properties'].append(self.generate_getter_for_listener_callbacks(_class, listenerName)) if _class.multilistener: classDict['properties'].append(self.generate_add_for_listener_callbacks(_class, listenerName)) classDict['properties'].append(self.generate_remove_for_listener_callbacks(_class, listenerName)) for method in _class.classMethods: try: if 'get' in method.name.to_word_list(): methodDict = self.translate_property_getter(method, method.name.translate(self.nameTranslator), True) #The following doesn't work because there a at least one method that has both getter and setter, #and because it doesn't do both of them at once, property is declared twice #elif 'set' in method.name.to_word_list(): # methodDict = self.translate_property_setter(method, method.name.to_camel_case(), True) else: methodDict = self.translate_method(method, static=True, genImpl=True) classDict['properties'].append(methodDict) except AbsApi.Error as e: logging.error('Could not translate {0}: {1}'.format(method.name.to_c(), e.args[0])) for prop in _class.properties: try: classDict['properties'] += self.translate_property(prop) except AbsApi.Error as e: logging.error('error while translating {0} property: {1}'.format(prop.name.to_c(), e.args[0])) for method in _class.instanceMethods: try: methodDict = self.translate_method(method, static=False, genImpl=True) classDict['properties'].append(methodDict) except AbsApi.Error as e: logging.error('Could not translate {0}: {1}'.format(method.name.to_c(), e.args[0])) for enum in _class.enums: classDict['classEnums'].append(self.translate_enum(enum)) return classDict
def _wrap_cpp_expression_to_c(self, cppExpr, exprtype, usedNamespace=None): if type(exprtype) is AbsApi.BaseType: if exprtype.name == 'string': cExpr = 'StringUtilities::cppStringToC({0})'.format(cppExpr) else: cExpr = cppExpr elif type(exprtype) is AbsApi.EnumType: cExpr = '(::{0}){1}'.format(exprtype.desc.name.to_c(), cppExpr) elif type(exprtype) is AbsApi.ClassType: cPtrType = exprtype.desc.name.to_c() if exprtype.desc.refcountable: ptrType = self.translate_class_type(exprtype, namespace=usedNamespace) ptrType = CppTranslator.sharedPtrTypeExtractor.match( ptrType).group(2) param = { 'ptrType': ptrType, 'cPtrType': cPtrType, 'cppExpr': cppExpr, 'object': 'const Object' if exprtype.isconst else 'Object' } cExpr = '(::{cPtrType} *)Object::sharedPtrToCPtr(std::static_pointer_cast<{object},{ptrType}>({cppExpr}))'.format( **param) else: if exprtype.isref: cExpr = '(const ::{_type} *)({expr}).c_struct()'.format( _type=cPtrType, expr=cppExpr) else: cExpr = '*(const ::{_type} *)({expr}).c_struct()'.format( _type=cPtrType, expr=cppExpr) elif type(exprtype) is AbsApi.ListType: if type( exprtype.containedTypeDesc ) is AbsApi.BaseType and exprtype.containedTypeDesc.name == 'string': cExpr = 'StringBctbxListWrapper({0}).c_list()'.format(cppExpr) elif type(exprtype.containedTypeDesc) is AbsApi.ClassType: ptrType = self.translate_class_type(exprtype.containedTypeDesc, namespace=usedNamespace) if exprtype.containedTypeDesc.desc.refcountable: ptrType = CppTranslator.sharedPtrTypeExtractor.match( ptrType).group(2) cExpr = 'ObjectBctbxListWrapper<{0}>({1}).c_list()'.format( ptrType, cppExpr) else: cType = exprtype.containedTypeDesc.desc.name.to_c() if exprtype.isconst: cExpr = 'StructBctbxListWrapper<{0},{1}>({2}).c_list()'.format( ptrType, cType, cppExpr) else: cExpr = 'StructBctbxListWrapper<{0},{1}>::cppListToBctbxList({2})'.format( ptrType, cType, cppExpr) else: raise AbsApi.Error( 'translation of bctbx_list_t of enums or basic C types is not supported' ) return cExpr
def translate_base_type(self, _type): if _type.name == 'void': if _type.isref: return 'void *' else: return 'void' elif _type.name == 'boolean': res = 'bool' elif _type.name == 'character': res = 'char' elif _type.name == 'size': res = 'size_t' elif _type.name == 'time': res = 'time_t' elif _type.name == 'integer': if _type.size is None: res = 'int' elif isinstance(_type.size, str): res = _type.size else: res = 'int{0}_t'.format(_type.size) elif _type.name == 'floatant': if _type.size is not None and _type.size == 'double': res = 'double' else: res = 'float' elif _type.name == 'status': res = 'linphone::Status' elif _type.name == 'string': res = 'std::string' if type(_type.parent) is AbsApi.Argument: res += ' &' elif _type.name == 'string_array': res = 'std::list<std::string>' if type(_type.parent) is AbsApi.Argument: res += ' &' else: raise AbsApi.Error('\'{0}\' is not a base abstract type'.format( _type.name)) if _type.isUnsigned: if _type.name == 'integer' and isinstance(_type.size, int): res = 'u' + res else: res = 'unsigned ' + res if _type.isconst: if _type.name not in ['string', 'string_array' ] or type(_type.parent) is AbsApi.Argument: res = 'const ' + res if _type.isref: res += ' *' return res
def translate_interface(self, interface): if interface.name.to_c() in self.ignore: raise AbsApi.Error('{0} has been escaped'.format(interface.name.to_c())) interfaceDict = {} interfaceDict['interfaceName'] = interface.name.translate(self.nameTranslator) interfaceDict['methods'] = [] for method in interface.methods: interfaceDict['methods'].append(self.translate_listener(interface, method)) return interfaceDict
def translate_list_type(self, _type, **params): if _type.containedTypeDesc is None: raise AbsApi.Error('{0} has not been fixed'.format(_type.containedTypeName)) elif isinstance(_type.containedTypeDesc, AbsApi.BaseType): res = self.translate_type(_type.containedTypeDesc) else: res = self.translate_type(_type.containedTypeDesc, **params) if type(_type.parent) is AbsApi.Argument: return 'const std::list<{0} > &'.format(res) else: return 'std::list<{0} >'.format(res)
def translate_method(self, method, genImpl=True): if method.name.to_snake_case(fullName=True) in self.ignore: raise AbsApi.Error('{0} has been escaped'.format(method.name.to_snake_case(fullName=True))) namespace = method.find_first_ancestor_by_type(AbsApi.Namespace) methodElems = {} methodElems['return'] = self.translate_type(method.returnType) methodElems['name'] = CppTranslator.translate_method_name(method.name) methodElems['params'] = '' for arg in method.args: if arg is not method.args[0]: methodElems['params'] += ', ' methodElems['params'] += self.translate_argument(arg) methodElems['const'] = ' const' if method.constMethod else '' methodElems['semicolon'] = ';' if type(method.parent) is AbsApi.Class and method.type == AbsApi.Method.Type.Class: methodElems['methodType'] = 'static ' elif type(method.parent) is AbsApi.Interface: methodElems['methodType'] = 'virtual ' if isinstance(method.returnType, AbsApi.BaseType) and method.returnType.name == 'void': methodElems['semicolon'] = ' {}' else: methodElems['semicolon'] = ' = 0;' else: methodElems['methodType'] = '' methodElems['deprecated'] = 'LINPHONECXX_DEPRECATED ' if method.deprecated else '' methodDict = {} methodDict['prototype'] = 'LINPHONECXX_PUBLIC {deprecated}{methodType}{return} {name}({params}){const}{semicolon}'.format(**methodElems) if genImpl: if not self.is_ambigous_type(method.returnType): methodElems['implReturn'] = self.translate_type(method.returnType, namespace=namespace) else: methodElems['implReturn'] = self.translate_type(method.returnType, namespace=None) methodElems['longname'] = CppTranslator.translate_method_name(method.name, recursive=True) methodElems['implParams'] = '' for arg in method.args: if arg is not method.args[0]: methodElems['implParams'] += ', ' methodElems['implParams'] += self.translate_argument(arg, namespace=namespace) methodDict['implPrototype'] = '{implReturn} {longname}({implParams}){const}'.format(**methodElems) methodDict['sourceCode' ] = self._generate_source_code(method, usedNamespace=namespace) methodDict['doc'] = self.docTranslator.translate(method.briefDescription) if method.briefDescription is not None else None return methodDict
def translate_interface(self, interface): if interface.name.to_c() in self.ignore: raise AbsApi.Error('{0} has been escaped'.format(interface.name.to_c())) interfaceDict = {} interfaceDict['interfaceName'] = interface.name.translate(self.nameTranslator) interfaceDict['create_user_data_name'] = 'linphone_factory_create' + interface.listenedClass.name.to_snake_case(fullName=True).lstrip('linphone') + '_cbs' interfaceDict['methods'] = [] for method in interface.instanceMethods: interfaceDict['methods'].append(self.translate_listener(interface, method)) return interfaceDict
def _wrap_c_expression_to_cpp(self, cExpr, exprtype, usedNamespace=None): if type(exprtype) is AbsApi.BaseType: if exprtype.name == 'void' and not exprtype.isref: return cExpr elif exprtype.name == 'string': return 'cStringToCpp({0})'.format(cExpr) elif exprtype.name == 'string_array': return 'cStringArrayToCppList({0})'.format(cExpr) elif exprtype.name == 'boolean': return '({0} != FALSE)'.format(cExpr) else: return cExpr elif type(exprtype) is AbsApi.EnumType: cppEnumName = CppTranslator.translate_enum_type( self, exprtype, namespace=usedNamespace) return '({0}){1}'.format(cppEnumName, cExpr) elif type(exprtype) is AbsApi.ClassType: cppReturnType = CppTranslator.translate_class_type( self, exprtype, namespace=usedNamespace) cppReturnType = CppTranslator.sharedPtrTypeExtractor.match( cppReturnType).group(2) if type(exprtype.parent) is AbsApi.Method and len( exprtype.parent.name.words) >= 1 and ( exprtype.parent.name.words == ['new'] or exprtype.parent.name.words[0] == 'create'): return 'cPtrToSharedPtr<{0}>((::belle_sip_object_t *){1}, false)'.format( cppReturnType, cExpr) else: return 'cPtrToSharedPtr<{0}>((::belle_sip_object_t *){1})'.format( cppReturnType, cExpr) elif type(exprtype) is AbsApi.ListType: if type( exprtype.containedTypeDesc ) is AbsApi.BaseType and exprtype.containedTypeDesc.name == 'string': return 'bctbxStringListToCppList({0})'.format(cExpr) elif type(exprtype.containedTypeDesc) is AbsApi.ClassType: cppReturnType = CppTranslator.translate_class_type( self, exprtype.containedTypeDesc, namespace=usedNamespace) cppReturnType = CppTranslator.sharedPtrTypeExtractor.match( cppReturnType).group(2) return 'bctbxObjectListToCppList<{0}>({1})'.format( cppReturnType, cExpr) else: raise AbsApi.Error( 'translation of bctbx_list_t of enums or basic C types is not supported' ) else: return cExpr
def translate_base_type(self, _type, isArg, dllImport=True): if _type.name == 'void': if _type.isref: return 'IntPtr' return 'void' elif _type.name == 'status': if dllImport: return 'int' else: return 'void' elif _type.name == 'boolean': if dllImport: res = 'char' else: res = 'bool' elif _type.name == 'integer': if _type.isUnsigned: res = 'uint' else: res = 'int' elif _type.name == 'string': if dllImport: if isArg: return 'string' else: res = 'IntPtr' # Return as IntPtr and get string with Marshal.PtrToStringAnsi() else: return 'string' elif _type.name == 'character': if _type.isUnsigned: res = 'byte' else: res = 'sbyte' elif _type.name == 'time': res = 'long' #TODO check elif _type.name == 'size': res = 'long' #TODO check elif _type.name == 'floatant': return 'float' elif _type.name == 'string_array': if dllImport or isArg: return 'IntPtr' else: return 'IEnumerable<string>' else: raise AbsApi.Error('\'{0}\' is not a base abstract type'.format( _type.name)) return res
def translate_class(self, _class): if _class.name.to_c() in self.ignore: raise AbsApi.Error('{0} has been escaped'.format(_class.name.to_c())) classDict = {} classDict['className'] = _class.name.translate(self.nameTranslator) classDict['isLinphoneFactory'] = classDict['className'] == "Factory" classDict['isLinphoneCall'] = _class.name.to_camel_case() == "Call" classDict['isLinphoneCore'] = _class.name.to_camel_case() == "Core" classDict['doc'] = _class.briefDescription.translate(self.docTranslator, tagAsBrief=True) classDict['dllImports'] = [] islistenable = _class.listenerInterface is not None if islistenable: listenerName = _class.listenerInterface.name.translate(self.nameTranslator) classDict['listener'] = {} classDict['listener']['listener_constructor'] = _class.name.to_snake_case() classDict['listener']['interfaceName'] = listenerName for method in _class.classMethods: try: if 'get' in method.name.to_word_list(): methodDict = self.translate_property_getter(method, method.name.translate(self.nameTranslator), True) #The following doesn't work because there a at least one method that has both getter and setter, #and because it doesn't do both of them at once, property is declared twice #elif 'set' in method.name.to_word_list(): # methodDict = self.translate_property_setter(method, method.name.to_camel_case(), True) else: methodDict = self.translate_method(method, static=True, genImpl=True) classDict['dllImports'].append(methodDict) except AbsApi.Error as e: logging.error('Could not translate {0}: {1}'.format(method.name.to_c(), e.args[0])) for prop in _class.properties: try: classDict['dllImports'] += self.translate_property(prop) except AbsApi.Error as e: logging.error('error while translating {0} property: {1}'.format(prop.name.to_c(), e.args[0])) for method in _class.instanceMethods: try: methodDict = self.translate_method(method, static=False, genImpl=True) classDict['dllImports'].append(methodDict) except AbsApi.Error as e: logging.error('Could not translate {0}: {1}'.format(method.name.to_c(), e.args[0])) return classDict
def _wrap_c_expression_to_cpp(self, cExpr, exprtype, usedNamespace=None): if isinstance(exprtype, AbsApi.BaseType): if exprtype.name == 'string': return 'StringUtilities::cStringToCpp({0})'.format(cExpr) elif exprtype.name == 'string_array': return 'StringUtilities::cStringArrayToCppList({0})'.format(cExpr) elif exprtype.name == 'boolean': return '({0} != FALSE)'.format(cExpr) else: return cExpr elif isinstance(exprtype, AbsApi.EnumType): cppEnumName = exprtype.translate(self.langTranslator, namespace=usedNamespace) return '({0}){1}'.format(cppEnumName, cExpr) elif isinstance(exprtype, AbsApi.ClassType): cppReturnType = exprtype.translate(self.langTranslator, namespace=usedNamespace) if exprtype.desc.refcountable: cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2) if isinstance(exprtype.parent, AbsApi.Method) and len(exprtype.parent.name.words) >=1 and exprtype.parent.returnAllocatedObject: return 'Object::cPtrToSharedPtr<{0}>({1}, false)'.format(cppReturnType, cExpr) else: return 'Object::cPtrToSharedPtr<{0}>({1})'.format(cppReturnType, cExpr) else: if exprtype.isref: return '{0}({1})'.format(exprtype.desc.name.to_camel_case(), cExpr) else: return '{0}(StructWrapper<::{1}>({2}).ptr())'.format( exprtype.desc.name.to_camel_case(), exprtype.desc.name.to_c(), cExpr) elif isinstance(exprtype, AbsApi.ListType): if isinstance(exprtype.containedTypeDesc, AbsApi.BaseType) and exprtype.containedTypeDesc.name == 'string': return 'StringBctbxListWrapper::bctbxListToCppList({0})'.format(cExpr) elif isinstance(exprtype.containedTypeDesc, AbsApi.ClassType): cppReturnType = exprtype.containedTypeDesc.translate(self.langTranslator, namespace=usedNamespace) takeRef = 'false' if isinstance(exprtype, AbsApi.OnTheFlyListType) else 'true' if exprtype.containedTypeDesc.desc.refcountable: cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2) return 'ObjectBctbxListWrapper<{0}>::bctbxListToCppList({1}, {2})'.format(cppReturnType, cExpr, takeRef) else: cType = exprtype.containedTypeDesc.desc.name.to_c() return 'StructBctbxListWrapper<{0},{1}>::bctbxListToCppList({2}, {3})'.format(cppReturnType, cType, cExpr, takeRef) else: raise AbsApi.Error('translation of bctbx_list_t of enums or basic C types is not supported') else: return cExpr
def _wrap_c_expression_to_cpp(self, cExpr, exprtype, usedNamespace=None): if type(exprtype) is AbsApi.BaseType: if exprtype.name == 'string': return 'StringUtilities::cStringToCpp({0})'.format(cExpr) elif exprtype.name == 'string_array': return 'StringUtilities::cStringArrayToCppList({0})'.format(cExpr) elif exprtype.name == 'boolean': return '({0} != FALSE)'.format(cExpr) else: return cExpr elif type(exprtype) is AbsApi.EnumType: cppEnumName = self.translate_enum_type(exprtype, namespace=usedNamespace) return '({0}){1}'.format(cppEnumName, cExpr) elif type(exprtype) is AbsApi.ClassType: cppReturnType = self.translate_class_type(exprtype, namespace=usedNamespace) if exprtype.desc.refcountable: cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2) if type(exprtype.parent) is AbsApi.Method and len(exprtype.parent.name.words) >=1 and (exprtype.parent.name.words == ['new'] or exprtype.parent.name.words[0] == 'create'): return 'Object::cPtrToSharedPtr<{0}>({1}, false)'.format(cppReturnType, cExpr) else: return 'Object::cPtrToSharedPtr<{0}>({1})'.format(cppReturnType, cExpr) else: if exprtype.isref: return '{0}({1})'.format(exprtype.desc.name.to_camel_case(), cExpr) else: return '{0}(StructWrapper<::{1}>({2}).ptr())'.format( exprtype.desc.name.to_camel_case(), exprtype.desc.name.to_c(), cExpr) elif type(exprtype) is AbsApi.ListType: if type(exprtype.containedTypeDesc) is AbsApi.BaseType and exprtype.containedTypeDesc.name == 'string': return 'StringBctbxListWrapper::bctbxListToCppList({0})'.format(cExpr) elif type(exprtype.containedTypeDesc) is AbsApi.ClassType: cppReturnType = self.translate_class_type(exprtype.containedTypeDesc, namespace=usedNamespace) if exprtype.containedTypeDesc.desc.refcountable: cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2) return 'ObjectBctbxListWrapper<{0}>::bctbxListToCppList({1})'.format(cppReturnType, cExpr) else: cType = exprtype.containedTypeDesc.desc.name.to_c() return 'StructBctbxListWrapper<{0},{1}>::bctbxListToCppList({2})'.format(cppReturnType, cType, cExpr) else: raise AbsApi.Error('translation of bctbx_list_t of enums or basic C types is not supported') else: return cExpr
def translate_interface(self, interface): if interface.name.to_camel_case(fullName=True) in self.ignore: raise AbsApi.Error('{0} has been escaped'.format(interface.name.to_camel_case(fullName=True))) intDict = {} intDict['inheritFrom'] = {'name': 'Listener'} intDict['className'] = CppTranslator.translate_class_name(interface.name) intDict['constructor'] = None intDict['parentClassName'] = 'Listener' intDict['isNotListener'] = False intDict['methods'] = [] for method in interface.methods: try: methodDict = self.translate_method(method, genImpl=False) intDict['methods'].append(methodDict) except AbsApi.Error as e: print('Could not translate {0}: {1}'.format(method.name.to_snake_case(fullName=True), e.args[0])) return intDict
def _wrap_cpp_expression_to_c(self, cppExpr, exprtype, usedNamespace=None): if type(exprtype) is AbsApi.BaseType: if exprtype.name == 'string': cExpr = 'cppStringToC({0})'.format(cppExpr) elif exprtype not in ['void', 'string', 'string_array' ] and exprtype.isref: cExpr = '&' + cppExpr else: cExpr = cppExpr elif type(exprtype) is AbsApi.EnumType: cExpr = '(::{0}){1}'.format(exprtype.desc.name.to_c(), cppExpr) elif type(exprtype) is AbsApi.ClassType: param = {} param['ptrType'] = CppTranslator.translate_class_type( self, exprtype, namespace=usedNamespace) param['ptrType'] = CppTranslator.sharedPtrTypeExtractor.match( param['ptrType']).group(2) param['cPtrType'] = exprtype.desc.name.to_c() param['cppExpr'] = cppExpr param['object'] = 'const Object' if exprtype.isconst else 'Object' cExpr = '(::{cPtrType} *)sharedPtrToCPtr(std::static_pointer_cast<{object},{ptrType}>({cppExpr}))'.format( **param) elif type(exprtype) is AbsApi.ListType: if type( exprtype.containedTypeDesc ) is AbsApi.BaseType and exprtype.containedTypeDesc.name == 'string': cExpr = 'StringBctbxListWrapper({0}).c_list()'.format(cppExpr) elif type(exprtype.containedTypeDesc) is AbsApi.Class: ptrType = CppTranslator.translate_class_type( exprtype, namespace=usedNamespace) ptrType = CppTranslator.sharedPtrTypeExtractor.match( ptrType).group(2) cExpr = 'ObjectBctbxListWrapper<{0}>({1}).c_list()'.format( ptrType, cppExpr) else: raise AbsApi.Error( 'translation of bctbx_list_t of enums or basic C types is not supported' ) return cExpr
def translate_method(self, method, static=False, genImpl=True): if method.name.to_c() in self.ignore: raise AbsApi.Error('{0} has been escaped'.format( method.name.to_c())) methodDict = {} namespace = method.find_first_ancestor_by_type(AbsApi.Namespace) try: methodDict['doc'] = method.briefDescription.translate( self.docTranslator, tagAsBrief=True ) if method.briefDescription is not None else None methodDict['detailedDoc'] = method.detailedDescription.translate( self.docTranslator ) if method.detailedDescription is not None else None except metadoc.TranslationError as e: logging.error(e.msg()) if genImpl: methodDict['impl'] = {} methodDict['impl']['static'] = 'static ' if static else '' methodDict['impl']['exception'] = self.throws_exception( method.returnType) methodDict['impl']['type'] = method.returnType.translate( self.langTranslator, namespace=namespace) methodDict['impl']['return'] = '' if methodDict['impl'][ 'type'] == "void" else 'return ' methodDict['impl']['name'] = method.name.translate( self.nameTranslator) methodDict['impl']['c_name'] = method.name.to_c() methodDict['impl']['cPtr'] = '' if static else ( 'cPtr, ' if len(method.args) > 0 else 'cPtr') methodDict['list_type'] = self.get_class_array_type( methodDict['impl']['type']) methodDict['is_string_list'] = methodDict['list_type'] == 'String' methodDict['is_class_list'] = not methodDict[ 'list_type'] == None and not methodDict['list_type'] == 'String' methodDict['is_string'] = methodDict['impl']['type'] == "String" methodDict['is_bool'] = methodDict['impl']['type'] == "Bool" methodDict['is_int'] = methodDict['impl'][ 'type'] == "Int" or methodDict['impl']['type'] == "UInt" methodDict['is_class'] = type( method.returnType) is AbsApi.ClassType methodDict['is_enum'] = type(method.returnType) is AbsApi.EnumType methodDict['is_generic'] = self.is_generic(methodDict) methodDict['isNotConst'] = not method.returnType.isconst methodDict['impl'][ 'create_method'] = 'create' in method.name.to_word_list() if (methodDict['is_class'] and not methodDict['impl']['create_method']): methodDict['return_default'] = "?" methodDict['throw_default'] = " throws" if methodDict['impl'][ 'exception'] or methodDict['impl']['create_method'] else "" methodDict['impl']['args'] = '' methodDict['impl']['c_args'] = '' for arg in method.args: argType = arg.type.translate(self.langTranslator) argName = arg.name.translate(self.nameTranslator) if argType.endswith('Delegate'): argName = "delegate" if arg is not method.args[0]: methodDict['impl']['args'] += ', ' methodDict['impl']['c_args'] += ', ' if isinstance(arg.type, AbsApi.ClassType): methodDict['impl'][ 'c_args'] += argName + "?.cPtr" if arg.optional else argName + ".cPtr" elif isinstance(arg.type, AbsApi.EnumType): argType = arg.type.translate(self.langTranslator, namespace=namespace) if methodDict['impl']['type'] == "Int": methodDict['impl'][ 'c_args'] += arg.type.name + "(rawValue: CInt(" + argName + ".rawValue))" else: methodDict['impl'][ 'c_args'] += arg.type.name + "(rawValue: CUnsignedInt(" + argName + ".rawValue))" elif arg.type.name == "size" or arg.type.name == "time": methodDict['impl']['c_args'] += argName elif argType == "Int": methodDict['impl']['c_args'] += "CInt(" + argName + ")" elif argType == "UInt": methodDict['impl'][ 'c_args'] += "CUnsignedInt(" + argName + ")" elif argType == "Bool": methodDict['impl']['c_args'] += argName + "==true ? 1:0" elif self.get_class_array_type( arg.type.translate(self.langTranslator)) is not None: listtype = self.get_class_array_type( arg.type.translate(self.langTranslator)) if listtype == 'String': methodDict['impl'][ 'c_args'] += "StringArrayToBctbxList(list:" + argName + ")" else: methodDict['impl'][ 'c_args'] += "ObjectArrayToBctbxList(list: " + argName + ")" else: methodDict['impl']['c_args'] += argName if argType == "UnsafePointer<Int>" and not arg.type.isconst: argType = "UnsafeMutablePointer<Int32>" elif argType == "UnsafeMutableRawPointer": argType = "UnsafeMutableRawPointer?" methodDict['impl'][ 'args'] += argName + ":" + argType + "?" if arg.optional else argName + ":" + argType return methodDict
def fail(obj): raise AbsApi.Error('Cannot translate {0} type'.format(type(obj)))
def translate_class(self, _class): if _class.name.to_camel_case(fullName=True) in self.ignore: raise AbsApi.Error('{0} has been escaped'.format( _class.name.to_camel_case(fullName=True))) islistenable = _class.listenerInterface is not None ismonolistenable = (islistenable and not _class.multilistener) ismultilistenable = (islistenable and _class.multilistener) classDict = { 'islistenable': islistenable, 'isnotlistenable': not islistenable, 'ismonolistenable': ismonolistenable, 'ismultilistenable': ismultilistenable, 'isrefcountable': _class.refcountable, 'isnotrefcountable': not _class.refcountable, 'isNotListener': True, 'isfactory': (_class.name.to_c() == 'LinphoneFactory'), 'isVcard': (_class.name.to_c() == 'LinphoneVcard'), 'className': CppTranslator.translate_class_name(_class.name), 'cClassName': '::' + _class.name.to_c(), 'parentClassName': 'Object' if _class.refcountable else None, 'methods': [], 'staticMethods': [], 'wrapperCbs': [], 'friendClasses': [] } if _class.name.to_c() == 'LinphoneCore': classDict['friendClasses'].append({'name': 'Factory'}) classDict['doc'] = self.docTranslator.translate( _class.briefDescription) if islistenable: classDict[ 'listenerClassName'] = CppTranslator.translate_class_name( _class.listenerInterface.name) classDict['cListenerName'] = _class.listenerInterface.name.to_c() classDict['cppListenerName'] = CppTranslator.translate_class_name( _class.listenerInterface.name) for method in _class.listenerInterface.methods: classDict['wrapperCbs'].append( self._generate_wrapper_callback(_class, method)) if ismonolistenable: classDict['cCbsGetter'] = _class.name.to_snake_case( fullName=True) + '_get_callbacks' classDict['parentClassName'] = 'ListenableObject' elif ismultilistenable: classDict['parentClassName'] = 'MultiListenableObject' classDict[ 'listenerCreator'] = 'linphone_factory_create_' + _class.listenerInterface.name.to_snake_case( )[:-len('_listener')] + '_cbs' classDict['callbacksAdder'] = _class.name.to_snake_case( fullName=True) + '_add_callbacks' classDict['callbacksRemover'] = _class.name.to_snake_case( fullName=True) + '_remove_callbacks' classDict[ 'userDataSetter'] = _class.listenerInterface.name.to_snake_case( fullName=True)[:-len('_listener')] + '_cbs_set_user_data' classDict[ 'userDataGetter'] = _class.listenerInterface.name.to_snake_case( fullName=True)[:-len('_listener')] + '_cbs_get_user_data' classDict['currentCallbacksGetter'] = _class.name.to_snake_case( fullName=True) + '_get_current_callbacks' for _property in _class.properties: try: classDict['methods'] += self.translate_property(_property) except AbsApi.Error as e: print('error while translating {0} property: {1}'.format( _property.name.to_snake_case(), e.args[0])) for method in _class.instanceMethods: try: methodDict = self.translate_method(method) classDict['methods'].append(methodDict) except AbsApi.Error as e: print('Could not translate {0}: {1}'.format( method.name.to_snake_case(fullName=True), e.args[0])) for method in _class.classMethods: try: methodDict = self.translate_method(method) classDict['staticMethods'].append(methodDict) except AbsApi.Error as e: print('Could not translate {0}: {1}'.format( method.name.to_snake_case(fullName=True), e.args[0])) return classDict
def translate_method(self, method, static=False, genImpl=True): if method.name.to_c() in self.ignore: raise AbsApi.Error('{0} has been escaped'.format( method.name.to_c())) methodElems = {} methodElems['return'] = method.returnType.translate( self.langTranslator) methodElems['name'] = method.name.to_c() methodElems['params'] = '' if static else 'IntPtr thiz' for arg in method.args: if arg is not method.args[0] or not static: methodElems['params'] += ', ' methodElems['params'] += arg.translate(self.langTranslator) methodDict = {} methodDict[ 'prototype'] = "static extern {return} {name}({params});".format( **methodElems) methodDict['doc'] = method.briefDescription.translate( self.docTranslator, tagAsBrief=True) methodDict['has_impl'] = genImpl if genImpl: methodDict['impl'] = {} methodDict['impl']['static'] = 'static ' if static else '' methodDict['impl']['exception'] = self.throws_exception( method.returnType) methodDict['impl']['type'] = method.returnType.translate( self.langTranslator, dllImport=False) methodDict['impl']['name'] = method.name.translate( self.nameTranslator) methodDict['impl'][ 'override'] = 'override ' if method.name.translate( self.nameTranslator) == 'ToString' else '' methodDict['impl']['hasReturn'] = False if methodDict['impl'][ 'type'] == "void" else True methodDict['impl']['c_name'] = method.name.to_c() methodDict['impl']['nativePtr'] = '' if static else ( 'nativePtr, ' if len(method.args) > 0 else 'nativePtr') methodDict['list_type'] = self.get_class_array_type( methodDict['impl']['type']) methodDict['is_string_list'] = methodDict['list_type'] == 'string' methodDict['is_class_list'] = not methodDict[ 'list_type'] == None and not methodDict['list_type'] == 'string' methodDict['is_string'] = methodDict['impl']['type'] == "string" methodDict['is_bool'] = methodDict['impl']['type'] == "bool" methodDict['is_class'] = self.is_linphone_type( method.returnType, False, False) and type(method.returnType) is AbsApi.ClassType methodDict['is_enum'] = self.is_linphone_type( method.returnType, False, False) and type(method.returnType) is AbsApi.EnumType methodDict['is_generic'] = self.is_generic(methodDict) methodDict['takeRef'] = 'true' if isinstance(method.returnType.parent, AbsApi.Method) and len( method.returnType.parent.name.words) >= 1: if method.returnType.parent.name.words == [ 'new' ] or method.returnType.parent.name.words[0] == 'create': methodDict['takeRef'] = 'false' methodDict['impl']['args'] = '' methodDict['impl']['c_args'] = '' methodDict['impl']['clean_string_list_ptrs'] = False for arg in method.args: if arg is not method.args[0]: methodDict['impl']['args'] += ', ' methodDict['impl']['c_args'] += ', ' if self.is_linphone_type(arg.type, False, False): if isinstance(arg.type, AbsApi.ClassType): argname = arg.name.translate(self.nameTranslator) methodDict['impl'][ 'c_args'] += argname + " != null ? " + argname + ".nativePtr : IntPtr.Zero" else: methodDict['impl'][ 'c_args'] += '(int)' + arg.name.translate( self.nameTranslator) elif arg.type.translate(self.langTranslator, dllImport=False) == "bool": methodDict['impl']['c_args'] += arg.name.translate( self.nameTranslator) + " ? (char)1 : (char)0" elif self.get_class_array_type( arg.type.translate(self.langTranslator, dllImport=False)) is not None: listtype = self.get_class_array_type( arg.type.translate(self.langTranslator, dllImport=False)) if listtype == 'string': methodDict['impl'][ 'c_args'] += "StringArrayToBctbxList(" + arg.name.translate( self.nameTranslator) + ")" methodDict['impl']['clean_string_list_ptrs'] = True else: methodDict['impl'][ 'c_args'] += "ObjectArrayToBctbxList<" + listtype + ">(" + arg.name.translate( self.nameTranslator) + ")" else: methodDict['impl']['c_args'] += arg.name.translate( self.nameTranslator) methodDict['impl']['args'] += arg.translate( self.langTranslator, dllImport=False) return methodDict
def translate_class(self, _class): if _class.name.to_camel_case(fullName=True) in self.ignore: raise AbsApi.Error('{0} has been escaped'.format( _class.name.to_camel_case(fullName=True))) classDict = {} classDict['className'] = _class.name.to_camel_case() classDict['isLinphoneFactory'] = _class.name.to_camel_case( ) == "Factory" classDict['doc'] = self.docTranslator.translate( _class.briefDescription) classDict['dllImports'] = [] islistenable = _class.listenerInterface is not None ismonolistenable = (islistenable and not _class.multilistener) if islistenable: listenerName = _class.listenerInterface.name.to_camel_case() if ismonolistenable: classDict['dllImports'].append( self.generate_getter_for_listener_callbacks( _class, listenerName)) else: classDict['dllImports'].append( self.generate_add_for_listener_callbacks( _class, listenerName)) classDict['dllImports'].append( self.generate_remove_for_listener_callbacks( _class, listenerName)) for method in _class.classMethods: try: if 'get' in method.name.to_word_list(): methodDict = self.translate_property_getter( method, method.name.to_camel_case(), True) #The following doesn't work because there a at least one method that has both getter and setter, #and because it doesn't do both of them at once, property is declared twice #elif 'set' in method.name.to_word_list(): # methodDict = self.translate_property_setter(method, method.name.to_camel_case(), True) else: methodDict = self.translate_method(method, static=True, genImpl=True) classDict['dllImports'].append(methodDict) except AbsApi.Error as e: print('Could not translate {0}: {1}'.format( method.name.to_snake_case(fullName=True), e.args[0])) for prop in _class.properties: try: classDict['dllImports'] += self.translate_property(prop) except AbsApi.Error as e: print('error while translating {0} property: {1}'.format( prop.name.to_snake_case(), e.args[0])) for method in _class.instanceMethods: try: methodDict = self.translate_method(method, static=False, genImpl=True) classDict['dllImports'].append(methodDict) except AbsApi.Error as e: print('Could not translate {0}: {1}'.format( method.name.to_snake_case(fullName=True), e.args[0])) return classDict