Exemple #1
0
    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)
Exemple #2
0
 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 !')
Exemple #3
0
	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)
Exemple #4
0
    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
Exemple #5
0
    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
Exemple #6
0
    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
Exemple #7
0
    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
Exemple #8
0
	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
Exemple #9
0
	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)
Exemple #10
0
	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
Exemple #11
0
    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
Exemple #12
0
    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
Exemple #13
0
    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
Exemple #14
0
	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
Exemple #15
0
	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
Exemple #16
0
	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
Exemple #17
0
	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
Exemple #18
0
    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
Exemple #19
0
    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
Exemple #20
0
 def fail(obj):
     raise AbsApi.Error('Cannot translate {0} type'.format(type(obj)))
Exemple #21
0
    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
Exemple #23
0
    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