Commit bff2f9a2 authored by François Grisez's avatar François Grisez

Reworking of wrappers generators

* Support of enums declared inside classes.
* Moving of Java translation code into abstractapi.py
  in order to have Java's API in the generated multi-language
  documentation.
parent 1c2f68ad
This diff is collapsed.
......@@ -103,7 +103,7 @@ class Name(object):
res += elem.title()
return res
else:
return Name.to_camel_case(self.prev, fullName=True, lower=lower) + Name.to_camel_case(self)
return self.prev.to_camel_case(fullName=True, lower=lower) + self.to_camel_case()
def concatenate(self, upper=False, fullName=False):
if self.prev is None or not fullName:
......@@ -146,7 +146,10 @@ class Name(object):
class ClassName(Name):
def to_c(self, addBrackets=False):
return self.to_camel_case(fullName=True)
def from_c(self, name, **kargs):
self.from_camel_case(name, **kargs)
def translate(self, translator, **params):
return translator.translate_class_name(self, **params)
......@@ -154,7 +157,11 @@ class ClassName(Name):
class InterfaceName(ClassName):
def to_c(self, addBrackets=False):
return ClassName.to_c(self)[:-8] + 'Cbs'
def from_c(self, **kargs):
ClassName.from_c(self, **kargs)
self.words[-1] = 'listener'
def translate(self, translator, **params):
return translator.translate_interface_name(self, **params)
......@@ -189,6 +196,9 @@ class MethodName(Name):
if addBrackets:
cName += '()'
return cName
def from_c(self, **kargs):
self.from_snake_case(**kargs)
def translate(self, translator, **params):
return translator.translate_method_name(self, **params)
......@@ -198,6 +208,9 @@ class ArgName(Name):
def to_c(self, addBrackets=False):
return self.to_snake_case()
def from_c(self, **kargs):
self.from_snake_case(**kargs)
def translate(self, translator, **params):
return translator.translate_argument_name(self, **params)
......@@ -321,9 +334,6 @@ class CppTranslator(JavaTranslator):
JavaTranslator.__init__(self)
self.nsSep = '::'
self.keyWordEscapes = {'new' : '_new'}
def translate_enumerator_name(self, name, **params):
return self.translate_enum_name(name.prev, **params) + name.to_camel_case()
class CSharpTranslator(JavaTranslator):
......
......@@ -46,7 +46,7 @@ struct {{{privCClassName}}};
namespace linphone {
{{#priorDeclarations}}
class {{{name}}};
{{{declaration}}};
{{/priorDeclarations}}
{{#_class}}
......@@ -69,6 +69,30 @@ namespace linphone {
{{/friendClasses}}
public:
{{#enums}}
{{#doc}}
/**
{{#lines}}
* {{{line}}}
{{/lines}}
*
*/
{{/doc}}
enum class {{name}} {
{{#enumerators}}
{{#doc}}
/**
{{#lines}}
* {{{line}}}
{{/lines}}
*/
{{/doc}}
{{name}}{{#value}} = {{{value}}}{{/value}}{{#notLast}},{{/notLast}}
{{/enumerators}}
};
{{/enums}}
{{#isNotListener}}
{{#isrefcountable}}
{{{className}}}(void *ptr, bool takeRef=true);
......
......@@ -30,7 +30,7 @@ namespace linphone {
*
*/
{{/doc}}
enum {{name}} {
enum class {{name}} {
{{#enumerators}}
{{#doc}}
/**
......
......@@ -36,19 +36,16 @@ import metaname
class CppTranslator(object):
sharedPtrTypeExtractor = re.compile('^(const )?std::shared_ptr<(.+)>( &)?$')
def __init__(self):
self.ambigousTypes = ['LinphonePayloadType']
def __init__(self, rootNs=None):
self.nameTranslator = metaname.Translator.get('Cpp')
self.langTranslator = AbsApi.Translator.get('Cpp')
self.langTranslator.ambigousTypes.append('LinphonePayloadType')
self.docTranslator = metadoc.DoxygenTranslator('Cpp')
def is_ambigous_type(self, _type):
return _type.name in self.ambigousTypes or (_type.name == 'list' and self.is_ambigous_type(_type.containedTypeDesc))
self.rootNs = rootNs
def translate_enum(self, enum):
enumDict = {}
enumDict['name'] = enum.name.to_camel_case()
enumDict['name'] = enum.name.translate(self.nameTranslator)
enumDict['doc'] = enum.briefDescription.translate(self.docTranslator)
enumDict['enumerators'] = []
for enumerator in enum.enumerators:
......@@ -87,6 +84,7 @@ class CppTranslator(object):
'cClassName' : '::' + _class.name.to_c(),
'privCClassName' : '_' + _class.name.to_c(),
'parentClassName' : 'Object' if _class.refcountable else None,
'enums' : [],
'methods' : [],
'staticMethods' : [],
'wrapperCbs' : [],
......@@ -120,6 +118,9 @@ class CppTranslator(object):
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 enum in _class.enums:
classDict['enums'].append(self.translate_enum(enum))
for _property in _class.properties:
classDict['methods'] += self.translate_property(_property)
......@@ -187,11 +188,11 @@ class CppTranslator(object):
return res
def translate_method(self, method, genImpl=True):
namespace = method.find_first_ancestor_by_type(AbsApi.Namespace)
namespace = method.find_first_ancestor_by_type(AbsApi.Class, AbsApi.Interface)
methodDict = {
'declPrototype': method.translate_as_prototype(self.langTranslator),
'implPrototype': method.translate_as_prototype(self.langTranslator, namespace=namespace),
'declPrototype': method.translate_as_prototype(self.langTranslator, namespace=namespace),
'implPrototype': method.translate_as_prototype(self.langTranslator, namespace=AbsApi.GlobalNs),
'deprecated': method.deprecated,
'suffix': '',
}
......@@ -355,6 +356,7 @@ class ClassHeader(object):
else:
self._class = translator.translate_interface(_class)
self.rootNs = translator.rootNs
self.define = '_{0}_HH'.format(_class.name.to_snake_case(upper=True, fullName=True))
self.filename = '{0}.hh'.format(_class.name.to_snake_case())
self.priorDeclarations = []
......@@ -362,16 +364,12 @@ class ClassHeader(object):
self.includes = {'internal': [], 'external': []}
includes = self.needed_includes(_class)
for include in includes['internal']:
if include == 'enums':
self.includes['internal'].append({'name': include})
else:
className = metaname.ClassName()
className.from_snake_case(include)
self.priorDeclarations.append({'name': className.to_camel_case()})
for include in includes['external']:
self.includes['external'].append({'name': include})
for include in includes['internal']:
self.includes['internal'].append({'name': include})
def needed_includes(self, _class):
includes = {'internal': [], 'external': []}
......@@ -394,7 +392,8 @@ class ClassHeader(object):
self._needed_includes_from_type(arg.type, includes)
if isinstance(_class, AbsApi.Class) and _class.listenerInterface is not None:
self._add_include(includes, 'internal', _class.listenerInterface.name.to_snake_case())
decl = 'class ' + _class.listenerInterface.name.translate(metaname.Translator.get('Cpp'))
self._add_prior_declaration(decl)
currentClassInclude = _class.name.to_snake_case()
if currentClassInclude in includes['internal']:
......@@ -407,26 +406,41 @@ class ClassHeader(object):
for arg in method.args:
self._needed_includes_from_type(arg.type, includes)
def _needed_includes_from_type(self, _type, includes):
if isinstance(_type, AbsApi.ClassType):
self._add_include(includes, 'external', 'memory')
if _type.desc is not None:
self._add_include(includes, 'internal', _type.desc.name.to_snake_case())
elif isinstance(_type, AbsApi.EnumType):
self._add_include(includes, 'internal', 'enums')
elif isinstance(_type, AbsApi.BaseType):
if _type.name == 'integer' and isinstance(_type.size, int):
def _needed_includes_from_type(self, type_, includes):
translator = metaname.Translator.get('Cpp')
if isinstance(type_, AbsApi.ClassType):
class_ = type_.desc
if class_.parent == self.rootNs:
decl = 'class ' + class_.name.translate(translator)
self._add_prior_declaration(decl)
else:
rootClass = class_.find_first_ancestor_by_type(AbsApi.Namespace, priorAncestor=True)
self._add_include(includes, 'internal', rootClass.name.to_snake_case())
elif isinstance(type_, AbsApi.EnumType):
enum = type_.desc
if enum.parent == self.rootNs:
headerFile = 'enums'
else:
rootClass = enum.find_first_ancestor_by_type(AbsApi.Namespace, priorAncestor=True)
headerFile = rootClass.name.to_snake_case()
self._add_include(includes, 'internal', headerFile)
elif isinstance(type_, AbsApi.BaseType):
if type_.name == 'integer' and isinstance(type_.size, int):
self._add_include(includes, 'external', 'cstdint')
elif _type.name == 'string':
elif type_.name == 'string':
self._add_include(includes, 'external', 'string')
elif isinstance(_type, AbsApi.ListType):
elif isinstance(type_, AbsApi.ListType):
self._add_include(includes, 'external', 'list')
self._needed_includes_from_type(_type.containedTypeDesc, includes)
self._needed_includes_from_type(type_.containedTypeDesc, includes)
def _add_include(self, includes, location, name):
if not name in includes[location]:
includes[location].append(name)
def _add_prior_declaration(self, decl):
if next((x for x in self.priorDeclarations if x['declaration']==decl), None) is None:
self.priorDeclarations.append({'declaration': decl})
class MainHeader(object):
def __init__(self):
......@@ -453,18 +467,16 @@ class GenWrapper(object):
self.parser = AbsApi.CParser(project)
self.parser.parse_all()
self.translator = CppTranslator()
self.translator = CppTranslator(self.parser.namespace)
self.renderer = pystache.Renderer()
self.mainHeader = MainHeader()
self.impl = ClassImpl()
def render_all(self):
header = EnumsHeader(self.translator)
for item in self.parser.enumsIndex.items():
if item[1] is not None:
header.add_enum(item[1])
else:
logging.info('{0} enum won\'t be translated because of parsing errors'.format(item[0]))
for enum in self.parser.namespace.enums:
header.add_enum(enum)
self.render(header, self.includedir + '/enums.hh')
self.mainHeader.add_include('enums.hh')
......
......@@ -21,6 +21,7 @@
############################################################################
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/src/linphone_jni.cc"
COMMAND ${CMAKE_COMMAND} -E remove -f java/org/linphone/core/* src/*
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/genwrapper.py" "${PROJECT_BINARY_DIR}/coreapi/help/doc/doxygen/xml" "-o" "${CMAKE_CURRENT_BINARY_DIR}"
DEPENDS ${PROJECT_SOURCE_DIR}/tools/genapixml.py ${LINPHONE_HEADER_FILES}
${PROJECT_SOURCE_DIR}/tools/metadoc.py
......
This diff is collapsed.
......@@ -45,7 +45,7 @@ import org.linphone.core.tools.OpenH264DownloadHelper;
{{/doc}}
public {{#isLinphoneFactory}}abstract class{{/isLinphoneFactory}}{{#isNotLinphoneFactory}}interface{{/isNotLinphoneFactory}} {{className}} {
{{#enums}}
enum {{className}} {
enum {{{className}}} {
{{#values}}
{{#doc}}
/**
......@@ -59,17 +59,17 @@ public {{#isLinphoneFactory}}abstract class{{/isLinphoneFactory}}{{#isNotLinphon
{{/values}}
protected final int mValue;
private {{className}} (int value) {
private {{{className}}} (int value) {
mValue = value;
}
static public {{className}} fromInt(int value) throws RuntimeException {
static public {{{className}}} fromInt(int value) throws RuntimeException {
switch(value) {
{{#values}}
case {{value}}: return {{name}};
{{/values}}
default:
throw new RuntimeException("Unhandled enum value " + value + " for {{className}}");
throw new RuntimeException("Unhandled enum value " + value + " for {{{className}}}");
}
}
......
......@@ -30,7 +30,7 @@ import {{import}}
{{/lines}}
*/
{{/doc}}
public enum {{className}} {
public enum {{{className}}} {
{{#values}}
{{#doc}}
/**
......@@ -61,4 +61,4 @@ public enum {{className}} {
public int toInt() {
return mValue;
}
}
\ No newline at end of file
}
......@@ -291,10 +291,10 @@ static {{return}} {{callbackName}}({{params}}) {
}
{{#isSingleListener}}
{{classCName}}Cbs *cbs = {{cPrefix}}_get_callbacks({{firstParam}});
{{classCName}} *cbs = {{cPrefix}}_get_callbacks({{firstParam}});
{{/isSingleListener}}
{{#isMultiListener}}
{{classCName}}Cbs *cbs = {{cPrefix}}_get_current_callbacks({{firstParam}});
{{classCName}} *cbs = {{cPrefix}}_get_current_callbacks({{firstParam}});
{{/isMultiListener}}
jobject jlistener = (jobject) {{cPrefix}}_cbs_get_user_data(cbs);
......
#!/bin/sh
# 1st pass
find ./src/android/org/linphone/ -type f -exec sed -i -e "s/import org.linphone.tools/import org.linphone.core.tools/g; \
s/import org.linphone.core.OpenH264DownloadHelperListener/import org.linphone.core.tools.OpenH264DownloadHelperListener/g; \
s/import org.linphone.core.LinphoneCore.Transports/import org.linphone.core.Transports/g; \
......@@ -270,7 +271,26 @@ s/linkPhoneNumberWithAccount()/linkAccount()/g; \
s/zoomVideo(/zoom(/g; \
s/mLc.setCpuCount(/\/\/mLc.setCpuCount(/g; \
s/new XmlRpcRequestImpl(/xmlRpcSession.createRequest(/g; \
s/new XmlRpcSessionImpl(LinphoneManager.getLcIfManagerNotDestroyedOrNull(), /LinphoneManager.getLcIfManagerNotDestroyedOrNull().createXmlRpcSession(/g" {} \;
s/new XmlRpcSessionImpl(LinphoneManager.getLcIfManagerNotDestroyedOrNull(), /LinphoneManager.getLcIfManagerNotDestroyedOrNull().createXmlRpcSession(/g;" {} \;
# 2nd pass
find ./src/android/org/linphone/ -type f -exec sed -i -e "s/Address\.TransportType/TransportType/g; \
s/\(CallLog\.\)\?CallStatus\([^[:alnum:]_]\)/Call.Status\2/g; \
s/CallStats\.AddressFamily/AddressFamily/g; \
s/CallStats\.StreamType/StreamType/g; \
s/Core\.AuthMethod/AuthMethod/g; \
s/Core\.ConfiguringState/ConfiguringState/g; \
s/Core\.EcCalibratorStatus/EcCalibratorStatus/g; \
s/Core\.GlobalState/GlobalState/g; \
s/Core\.LimeState/LimeState/g; \
s/Core\.LogCollectionState/LogCollectionState/g; \
s/Core\.MediaEncryption/MediaEncryption/g; \
s/Core\.RegistrationState/RegistrationState/g; \
s/Core\.VersionUpdateCheckResult/VersionUpdateCheckResult/g; \
s/Event\.PublishState/PublishState/g; \
s/Friend\.SubscribePolicy/SubscribePolicy/g; \
s/XmlRpcRequest\.ArgType/XmlRpcArgType/g; \
s/XmlRpcRequest\.Status/XmlRpcStatus/g;" {} \;
# TODO
#Tunnel, TunnelConfig
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment