Eolian: Remove conversion code which has to be rewritten
This commit is contained in:
parent
60f0f6b814
commit
f2148fe743
|
@ -1426,6 +1426,13 @@ cdef class Type(object):
|
|||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s(%s, %s, %s, %s)>" % (
|
||||
self.name,
|
||||
self.c_type, self.type, list(self.arguments), self.description,
|
||||
#self.return_type,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def alias_get_by_name(cls, name):
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
import logging
|
||||
log = logging.getLogger("efl.eolian.conv")
|
||||
|
||||
import re
|
||||
|
||||
docstring_replacements = (
|
||||
("@brief ", ""),
|
||||
(re.compile(r"@ingroup .+", re.S), r""),
|
||||
(re.compile(r"@see (.+)(?!@)"), r":see: \1"),
|
||||
("@return ", ":return: "),
|
||||
(re.compile(r"@(note|warning) "), r".. \1:: "),
|
||||
(re.compile(r"@(p|c) (\w+)"), r"``\2``"),
|
||||
(re.compile(r"@(b) (\w+)"), r"**\2**"),
|
||||
(re.compile(r"@(i) (\w+)"), r"*\2*"),
|
||||
("EINA_TRUE", "True"),
|
||||
("EINA_FALSE", "False"),
|
||||
("NULL", "None"),
|
||||
)
|
||||
|
||||
complex_types = (
|
||||
"Eina_List"
|
||||
)
|
||||
|
||||
param_type_mapping = {
|
||||
# c_type: pyx_type
|
||||
"Eina_Bool": "bint",
|
||||
"char *": "",
|
||||
"Evas_Object *": "_Eo_Base",
|
||||
"Eo *": "_Eo_Base",
|
||||
}
|
||||
|
||||
param_conversions = {
|
||||
# c_type: (conversion, c_param_convert)
|
||||
"Eina_Bool": (None, None),
|
||||
"char *": (
|
||||
"if isinstance({0}, unicode): {0} = PyUnicode_AsUTF8String({0})",
|
||||
"<{1}>if {0} is not None else NULL"
|
||||
),
|
||||
"Evas_Object *": (None, "{0}.obj"),
|
||||
"Eo *": (None, "{0}.obj"),
|
||||
}
|
||||
|
||||
return_type_mapping = {
|
||||
# c_type: pyx_type
|
||||
"Eina_Bool": "bint",
|
||||
"char *": "unicode",
|
||||
"Elm_Object_Item *": "_ObjectItem",
|
||||
"Evas_Object *": "_Eo_Base",
|
||||
"Eo *": "_Eo_Base",
|
||||
}
|
||||
|
||||
return_conversions = {
|
||||
# c_type: conversion
|
||||
"Eina_Bool": None,
|
||||
"char *": '{0}.decode("utf-8")',
|
||||
"Elm_Object_Item *": 'object_item_to_python({0})',
|
||||
"Evas_Object *": 'object_from_instance({0})',
|
||||
"Eo *": 'object_from_instance({0})',
|
||||
}
|
||||
|
||||
|
||||
def conv_cls_name(name):
|
||||
s = name.split("_")
|
||||
if len(s) > 1:
|
||||
return s[0], "_".join(s[1:])
|
||||
else:
|
||||
return name, name
|
||||
|
||||
|
||||
def remove_type_prefixes(ctype):
|
||||
for t in "const ", "unsigned ", "short ":
|
||||
ctype = ctype.replace(t, "")
|
||||
return ctype
|
||||
|
||||
|
||||
def conv_type_in(tp):
|
||||
pass
|
||||
return py_type, c_type
|
||||
|
||||
|
||||
def conv_type_out(tp):
|
||||
pass
|
||||
return cdef, c_type, ret_type
|
||||
|
||||
|
||||
def conv_type_in_out(tp):
|
||||
pass
|
||||
return py_type, c_type
|
||||
|
||||
|
||||
def conv_type_ret(tp):
|
||||
tp = tp.return_type.c_type
|
||||
if not tp:
|
||||
log.error("ret type empty")
|
||||
return
|
||||
|
||||
if tp in return_type_mapping:
|
||||
c_t = remove_type_prefixes(tp)
|
||||
py_t = return_type_mapping[c_t][0]
|
||||
if py_t is not None:
|
||||
py_ret_type = py_t
|
||||
else:
|
||||
log.warn("Unknown ret type")
|
||||
|
||||
c_ret_type = remove_type_prefixes(tp)
|
||||
|
||||
return py_ret_type, c_ret_type
|
|
@ -13,6 +13,8 @@ parser.add_argument(
|
|||
'-v', '--verbose', action="count", help="max is -vvv")
|
||||
parser.add_argument(
|
||||
'--enable-docstrings', action="store_true")
|
||||
parser.add_argument(
|
||||
'--with-legacy-api', action="store_true")
|
||||
parser.add_argument(
|
||||
'-o', '--output', default="/tmp", help="defaults to /tmp")
|
||||
parser.add_argument('paths', nargs="+")
|
||||
|
@ -33,71 +35,9 @@ log.setLevel(level)
|
|||
from efl import eolian
|
||||
eolian.init()
|
||||
|
||||
import re
|
||||
|
||||
docstring_replacements = (
|
||||
("@brief ", ""),
|
||||
(re.compile(r"@ingroup .+", re.S), r""),
|
||||
(re.compile(r"@see (.+)(?!@)"), r":see: \1"),
|
||||
("@return ", ":return: "),
|
||||
(re.compile(r"@(note|warning) "), r".. \1:: "),
|
||||
(re.compile(r"@(p|c) (\w+)"), r"``\2``"),
|
||||
(re.compile(r"@(b) (\w+)"), r"**\2**"),
|
||||
(re.compile(r"@(i) (\w+)"), r"*\2*"),
|
||||
("EINA_TRUE", "True"),
|
||||
("EINA_FALSE", "False"),
|
||||
("NULL", "None"),
|
||||
)
|
||||
|
||||
complex_types = (
|
||||
"Eina_List"
|
||||
)
|
||||
|
||||
param_type_mapping = {
|
||||
# c_type: (py_type, conversion, c_param_convert)
|
||||
"int": (None, None, None),
|
||||
"short": (None, None, None),
|
||||
"double": (None, None, None),
|
||||
"Evas_Coord": ("int", None, None),
|
||||
"Eina_Bool": ("bint", None, None),
|
||||
"char *": (
|
||||
"",
|
||||
"if isinstance({0}, unicode): {0} = PyUnicode_AsUTF8String({0})",
|
||||
"<{1}>if {0} is not None else NULL"
|
||||
),
|
||||
"Evas_Object *": ("_Eo_Base", None, "{0}.obj"),
|
||||
"Eo *": ("_Eo_Base", None, "{0}.obj"),
|
||||
}
|
||||
|
||||
return_type_mapping = {
|
||||
# c_type: (py_type, conversion)
|
||||
"int": (None, None),
|
||||
"short": (None, None, None),
|
||||
"double": (None, None),
|
||||
"Evas_Coord": ("int", None),
|
||||
"Eina_Bool": ("bint", None),
|
||||
"char *": ("unicode", '{0}.decode("utf-8")'),
|
||||
"Elm_Object_Item *": (
|
||||
"_ObjectItem", 'object_item_to_python({0})'
|
||||
),
|
||||
"Evas_Object *": ("_Eo_Base", 'object_from_instance({0})'),
|
||||
"Eo *": ("_Eo_Base", 'object_from_instance({0})'),
|
||||
}
|
||||
|
||||
|
||||
def conv_cls_name(name):
|
||||
s = name.split("_")
|
||||
if len(s) > 1:
|
||||
return s[0], "_".join(s[1:])
|
||||
else:
|
||||
return name, name
|
||||
|
||||
|
||||
def remove_type_prefixes(ctype):
|
||||
print(ctype.name, list(ctype.namespaces), list(ctype.subtypes))
|
||||
#for t in "const ", "unsigned ", "short ":
|
||||
#ctype = ctype.replace(t, "")
|
||||
return ctype
|
||||
from converters import conv_type_in, conv_type_out, conv_type_ret, \
|
||||
conv_type_in_out, conv_cls_name
|
||||
|
||||
|
||||
class Generator(object):
|
||||
|
@ -132,29 +72,29 @@ class Generator(object):
|
|||
else:
|
||||
self.result.append("")
|
||||
|
||||
def docstring_write(self, docstrings):
|
||||
if not args.enable_docstrings or not docstrings:
|
||||
return
|
||||
elif len(docstrings) == 1:
|
||||
self.write('"""' + docstrings[0] + '"""')
|
||||
else:
|
||||
self.write('"""')
|
||||
for docs in docstrings:
|
||||
if docs.startswith("- ") or \
|
||||
docs.startswith(".. ") or \
|
||||
docs.startswith(":"):
|
||||
self.write(
|
||||
docs, wrapped=True,
|
||||
s_ind=self.level * self.tab + " "
|
||||
)
|
||||
elif docs.startswith(" - "):
|
||||
self.write(
|
||||
docs, wrapped=True,
|
||||
s_ind=self.level * self.tab + " "
|
||||
)
|
||||
else:
|
||||
self.write(docs, wrapped=True)
|
||||
self.write('"""')
|
||||
#def docstring_write(self, docstrings):
|
||||
#if not args.enable_docstrings or not docstrings:
|
||||
#return
|
||||
#elif len(docstrings) == 1:
|
||||
#self.write('"""' + docstrings[0] + '"""')
|
||||
#else:
|
||||
#self.write('"""')
|
||||
#for docs in docstrings:
|
||||
#if docs.startswith("- ") or \
|
||||
#docs.startswith(".. ") or \
|
||||
#docs.startswith(":"):
|
||||
#self.write(
|
||||
#docs, wrapped=True,
|
||||
#s_ind=self.level * self.tab + " "
|
||||
#)
|
||||
#elif docs.startswith(" - "):
|
||||
#self.write(
|
||||
#docs, wrapped=True,
|
||||
#s_ind=self.level * self.tab + " "
|
||||
#)
|
||||
#else:
|
||||
#self.write(docs, wrapped=True)
|
||||
#self.write('"""')
|
||||
|
||||
def printout(self):
|
||||
return "\n".join(self.result)
|
||||
|
@ -170,11 +110,6 @@ class PyxGenerator(Generator):
|
|||
params2.append("self")
|
||||
|
||||
for t, n in params:
|
||||
if t in param_type_mapping:
|
||||
c_t = t.replace("const ", "").replace("unsigned ", "")
|
||||
py_t = param_type_mapping[c_t][0]
|
||||
if py_t is not None:
|
||||
t = py_t
|
||||
params2.append(" ".join((t, n)).strip())
|
||||
|
||||
params2 = ", ".join(params2)
|
||||
|
@ -188,6 +123,7 @@ class PyxGenerator(Generator):
|
|||
for t, n in cdefs:
|
||||
types.setdefault(t, []).append(n)
|
||||
for t, names in types.items():
|
||||
#t = t.c_type
|
||||
if "*" in t:
|
||||
# complex, write one per line
|
||||
for n in names:
|
||||
|
@ -197,52 +133,33 @@ class PyxGenerator(Generator):
|
|||
self.write("%s %s" % (t, ", ".join(names)))
|
||||
self.dedent()
|
||||
|
||||
def c_call_write(self, name, params, ret_type, ret_param, legacy=False):
|
||||
if legacy:
|
||||
def c_call_write(self, name, params, ret_type, ret_param):
|
||||
if args.with_legacy_api:
|
||||
c_call = "%s(%s)" % (name, ", ".join(("self.obj", params)))
|
||||
else:
|
||||
c_call = "eo_do(self.obj, %s(%s))" % (name, params)
|
||||
if ret_type:
|
||||
r_type = ret_type
|
||||
if r_type in return_type_mapping:
|
||||
conv = return_type_mapping[r_type][1]
|
||||
if conv:
|
||||
c_call = conv.format(c_call)
|
||||
c_call = ret_param + " = " + c_call
|
||||
self.write(c_call)
|
||||
|
||||
|
||||
class Method(object):
|
||||
class Function(object):
|
||||
|
||||
def __init__(self, eo_prefix, legacy_prefix):
|
||||
self.params = []
|
||||
self.py_params = []
|
||||
self.c_params = []
|
||||
self.cdefs = []
|
||||
self.returns = []
|
||||
self.docs = []
|
||||
self.enum_types = []
|
||||
self.ret_type = None
|
||||
def __init__(self, prefix):
|
||||
self.py_name = None
|
||||
self.eo_prefix = eo_prefix
|
||||
self.legacy_prefix = legacy_prefix
|
||||
self.py_params = []
|
||||
|
||||
@classmethod
|
||||
def parse(cls, func, eo_prefix, legacy_prefix):
|
||||
self = cls.__new__(cls)
|
||||
self.__init__(eo_prefix, legacy_prefix)
|
||||
self.c_name = None
|
||||
self.c_params = []
|
||||
|
||||
self.py_name = func.name
|
||||
if keyword.iskeyword(self.py_name):
|
||||
self.py_name += "_"
|
||||
self.cdefs = []
|
||||
|
||||
if self.eo_prefix:
|
||||
self.c_name = func.full_c_name_get(self.eo_prefix)
|
||||
elif self.legacy_prefix:
|
||||
self.c_name = func.full_c_name_get(self.legacy_prefix)
|
||||
else:
|
||||
raise ValueError("No prefix found for function %r" % (func))
|
||||
self.returns = []
|
||||
self.ret_type = None
|
||||
|
||||
self.prefix = prefix
|
||||
|
||||
def doc_generate(self, gen):
|
||||
func_desc = func.description_get(eolian.FunctionType.METHOD)
|
||||
if func_desc:
|
||||
func_desc = func_desc.split("\n\n")
|
||||
|
@ -256,47 +173,8 @@ class Method(object):
|
|||
self.docs.append(desc)
|
||||
self.docs.append("")
|
||||
|
||||
for p in func.parameters:
|
||||
pdir, ptype, name, desc = p.direction, p.type, p.name, p.description
|
||||
for i in dir(ptype):
|
||||
if i.startswith("__"):
|
||||
continue
|
||||
a = getattr(ptype, i)
|
||||
if callable(a):
|
||||
a = "callable"
|
||||
elif isinstance(a, eolian.EinaIterator):
|
||||
a = list(a)
|
||||
print("%s: %r" % (i, a))
|
||||
return
|
||||
ptype2 = remove_type_prefixes(ptype)
|
||||
if not ptype2 in param_type_mapping:
|
||||
raise TypeError("Unknown param type: %s" % (ptype2))
|
||||
self.params.append((ptype, name))
|
||||
if pdir == eolian.ParameterDir.IN:
|
||||
self.py_params.append((ptype, name))
|
||||
self.c_params.append((ptype, name))
|
||||
self.docs.append(":param %s: %s" % (name, desc))
|
||||
self.docs.append(":type %s: %s" % (name, ptype))
|
||||
elif pdir == eolian.ParameterDir.OUT:
|
||||
self.cdefs.append((ptype, name))
|
||||
self.c_params.append((ptype, "&%s" % (name)))
|
||||
self.returns.append((ptype, name))
|
||||
else:
|
||||
self.py_params.append((ptype, name))
|
||||
self.c_params.append((ptype, name))
|
||||
self.returns.append((ptype, name))
|
||||
|
||||
ret_type = func.return_type_get(func.type)
|
||||
if ret_type:
|
||||
ret_type2 = remove_type_prefixes(ret_type)
|
||||
if not ret_type2 in return_type_mapping:
|
||||
if not ret_type2 in enums:
|
||||
raise TypeError("Unknown return type: %s" % (ret_type2))
|
||||
else:
|
||||
self.enum_types.append(ret_type2)
|
||||
enums_counter[ret_type2] += 1
|
||||
self.ret_type = ret_type
|
||||
ret_desc = func.return_comment_get(func.type)
|
||||
|
||||
if self.returns:
|
||||
self.docs.append(
|
||||
|
@ -308,24 +186,14 @@ class Method(object):
|
|||
self.docs.append(":return: " + ret_desc)
|
||||
self.docs.append(":rtype: " + self.ret_type)
|
||||
|
||||
return self
|
||||
|
||||
def pyx_generate(self, gen, param_conv=None):
|
||||
gen.method_header_write(self.py_name, self.py_params)
|
||||
gen.indent()
|
||||
|
||||
RET_PARAM = "py_efl_ret"
|
||||
|
||||
if self.docs:
|
||||
gen.docstring_write(self.docs)
|
||||
|
||||
if self.ret_type:
|
||||
t = self.ret_type
|
||||
if t in return_type_mapping:
|
||||
c_t = remove_type_prefixes(t)
|
||||
py_t = return_type_mapping[c_t][0]
|
||||
if py_t is not None:
|
||||
t = py_t
|
||||
self.cdefs.append((t, RET_PARAM))
|
||||
|
||||
if self.cdefs:
|
||||
|
@ -335,97 +203,88 @@ class Method(object):
|
|||
if conv:
|
||||
gen.write(conv)
|
||||
|
||||
for t, n in self.py_params:
|
||||
t = remove_type_prefixes(t)
|
||||
if t in param_type_mapping:
|
||||
conv = param_type_mapping[t][1]
|
||||
if conv:
|
||||
gen.write(conv.format(n, t))
|
||||
|
||||
for i, (t, n) in enumerate(self.c_params):
|
||||
t2 = remove_type_prefixes(t)
|
||||
if t2 in param_type_mapping:
|
||||
conv = param_type_mapping[t2][2]
|
||||
if conv:
|
||||
self.c_params[i] = (t, conv.format(n, t))
|
||||
|
||||
c_params = ", ".join([c[1] for c in self.c_params])
|
||||
if self.eo_prefix:
|
||||
gen.c_call_write(
|
||||
self.c_name, c_params, self.ret_type, RET_PARAM, legacy=False
|
||||
)
|
||||
elif self.legacy_prefix:
|
||||
gen.c_call_write(
|
||||
self.c_name, c_params, self.ret_type, RET_PARAM, legacy=True
|
||||
)
|
||||
else:
|
||||
raise ValueError("no prefix found for %r" % (self.name))
|
||||
gen.c_call_write(
|
||||
self.c_name, c_params, self.ret_type, RET_PARAM
|
||||
)
|
||||
|
||||
if self.returns:
|
||||
ret = self.returns[:]
|
||||
for i, (t, n) in enumerate(self.returns):
|
||||
t = remove_type_prefixes(t)
|
||||
if t in return_type_mapping:
|
||||
conv = return_type_mapping[t][1]
|
||||
if conv:
|
||||
gen.write("conv_%s = %s" % (n, conv.format(n)))
|
||||
ret[i] = t, "conv_%s" % (n)
|
||||
gen.write("return %s" % (", ".join([r[1] for r in ret])))
|
||||
elif self.ret_type:
|
||||
ret = RET_PARAM
|
||||
r_type = self.ret_type
|
||||
if r_type in return_type_mapping:
|
||||
conv = return_type_mapping[r_type][1]
|
||||
if conv:
|
||||
ret = conv.format(ret)
|
||||
gen.write("return %s" % (ret))
|
||||
|
||||
gen.dedent()
|
||||
gen.write()
|
||||
|
||||
def cdef_generate(self, gen):
|
||||
def cdefs_generate(self, gen):
|
||||
rtype = self.ret_type
|
||||
if not rtype:
|
||||
rtype = "void"
|
||||
line = " ".join((rtype, self.c_name))
|
||||
line += "("
|
||||
line += ", ".join([" ".join((t, n)) for t, n in self.params])
|
||||
line += ", ".join([" ".join((t, n)) for t, n in self.c_params])
|
||||
line += ")"
|
||||
|
||||
gen.write(line)
|
||||
|
||||
|
||||
class Method(Function):
|
||||
@classmethod
|
||||
def parse(cls, eol_func, prefix):
|
||||
self = cls.__new__(cls)
|
||||
self.__init__(prefix)
|
||||
|
||||
# Python name
|
||||
self.py_name = eol_func.name
|
||||
if keyword.iskeyword(self.py_name):
|
||||
self.py_name += "_"
|
||||
|
||||
# C name
|
||||
self.c_name = eol_func.full_c_name_get(self.prefix)
|
||||
|
||||
# params
|
||||
for p in eol_func.parameters:
|
||||
ptype = p.type.c_type
|
||||
if p.direction == eolian.ParameterDir.IN:
|
||||
self.py_params.append((ptype, p.name))
|
||||
self.c_params.append((ptype, p.name))
|
||||
elif p.direction == eolian.ParameterDir.OUT:
|
||||
self.cdefs.append((ptype, p.name))
|
||||
self.c_params.append((ptype, "&%s" % (p.name)))
|
||||
self.returns.append((ptype, p.name))
|
||||
elif p.direction == eolian.ParameterDir.INOUT:
|
||||
self.py_params.append((ptype, p.name))
|
||||
self.c_params.append((ptype, p.name))
|
||||
self.returns.append((ptype, p.name))
|
||||
else:
|
||||
raise RuntimeError("unknown param type")
|
||||
|
||||
# ret type
|
||||
ret_type = eol_func.return_type_get(eolian.FunctionType.METHOD)
|
||||
if ret_type:
|
||||
self.ret_type = ret_type.c_type
|
||||
|
||||
return self
|
||||
|
||||
|
||||
class Property(object):
|
||||
def __init__(self, eo_prefix, legacy_prefix):
|
||||
def __init__(self, prefix):
|
||||
super(type(self), self).__init__()
|
||||
self.docs = []
|
||||
self.eo_prefix = eo_prefix
|
||||
self.prefix = prefix
|
||||
self.enum_types = []
|
||||
|
||||
@classmethod
|
||||
def parse(cls, func, eo_prefix, legacy_prefix):
|
||||
def parse(cls, func, prefix):
|
||||
self = cls.__new__(cls)
|
||||
self.__init__(eo_prefix, legacy_prefix)
|
||||
self.__init__(prefix)
|
||||
|
||||
self.py_name = func.name
|
||||
if keyword.iskeyword(self.py_name):
|
||||
self.py_name += "_"
|
||||
|
||||
getter_desc = func.description_get(eolian.FunctionType.PROP_GET)
|
||||
setter_desc = func.description_get(eolian.FunctionType.PROP_SET)
|
||||
for func_desc in getter_desc, setter_desc:
|
||||
if func_desc:
|
||||
func_desc = func_desc.split("\n\n")
|
||||
for desc in func_desc:
|
||||
for pat, repl in docstring_replacements:
|
||||
if isinstance(pat, basestring):
|
||||
desc = desc.replace(pat, repl)
|
||||
else:
|
||||
desc = pat.sub(repl, desc)
|
||||
if desc:
|
||||
self.docs.append(desc)
|
||||
self.docs.append("")
|
||||
|
||||
self.getter = None
|
||||
self.setter = None
|
||||
|
||||
|
@ -435,80 +294,51 @@ class Property(object):
|
|||
if func.type == eolian.FunctionType.PROP_SET or \
|
||||
func.type == eolian.FunctionType.PROPERTY:
|
||||
# Create setter
|
||||
m = self.setter = Method(eo_prefix, legacy_prefix)
|
||||
m = self.setter = Function(prefix)
|
||||
m.py_name = "__set__"
|
||||
if eo_prefix:
|
||||
fname = func.full_c_name_get(eo_prefix)
|
||||
m.c_name = "_".join((fname, "set"))
|
||||
elif legacy_prefix:
|
||||
fname = func.full_c_name_get(legacy_prefix)
|
||||
m.c_name = "_".join((fname, "set"))
|
||||
else:
|
||||
raise ValueError("No prefix found for %r" % (func))
|
||||
|
||||
fname = func.full_c_name_get(prefix)
|
||||
m.c_name = "_".join((fname, "set"))
|
||||
|
||||
py_params = []
|
||||
for p in func.property_values:
|
||||
pdir, ptype, name, desc = p.direction, p.type, p.name, p.description
|
||||
assert pdir == eolian.ParameterDir.IN, "prop has other than IN"
|
||||
ptype2 = remove_type_prefixes(ptype)
|
||||
if not ptype2 in param_type_mapping:
|
||||
raise TypeError("Unknown param type: %s" % (ptype2))
|
||||
m.params.append((ptype, name))
|
||||
py_params.append(name)
|
||||
m.c_params.append((ptype, name))
|
||||
assert p.direction == eolian.ParameterDir.IN, \
|
||||
"prop %s has other than IN" % (fname)
|
||||
py_params.append((p.type, p.name))
|
||||
m.c_params.append((p.type.c_type, p.name))
|
||||
|
||||
assert py_params, (
|
||||
"params should not be empty for setter of: %s" % (func.name)
|
||||
)
|
||||
py_params = ", ".join(py_params)
|
||||
py_params = ", ".join(x[1] for x in py_params)
|
||||
m.params_conv = "%s = value" % (py_params)
|
||||
|
||||
m.py_params = (("", "value"),)
|
||||
|
||||
m.ret_type = func.return_type_get(eolian.FunctionType.PROP_SET)
|
||||
if m.ret_type:
|
||||
ret_type2 = remove_type_prefixes(m.ret_type)
|
||||
if not ret_type2 in return_type_mapping:
|
||||
if not ret_type2 in enums:
|
||||
raise TypeError(
|
||||
"Unknown return type: %s" % (ret_type2))
|
||||
else:
|
||||
self.enum_types.append(ret_type2)
|
||||
enums_counter[ret_type2] += 1
|
||||
ret_type = func.return_type_get(eolian.FunctionType.PROP_SET)
|
||||
if ret_type.return_type.c_type:
|
||||
ret_type2 = ret_type.return_type.c_type
|
||||
m.ret_type = ret_type2
|
||||
|
||||
if func.type == eolian.FunctionType.PROP_GET or \
|
||||
func.type == eolian.FunctionType.PROPERTY:
|
||||
# Create getter
|
||||
m = self.getter = Method(eo_prefix, legacy_prefix)
|
||||
m = self.getter = Function(prefix)
|
||||
m.py_name = "__get__"
|
||||
if eo_prefix:
|
||||
fname = func.full_c_name_get(eo_prefix)
|
||||
m.c_name = "_".join((fname, "get"))
|
||||
elif legacy_prefix:
|
||||
fname = func.full_c_name_get(legacy_prefix)
|
||||
m.c_name = "_".join((fname, "get"))
|
||||
else:
|
||||
raise ValueError("No prefix found for %r" % (func))
|
||||
for p in func.property_values:
|
||||
pdir, ptype, name, desc = p.direction, p.type, p.name, p.description
|
||||
assert pdir == eolian.ParameterDir.IN, "prop has other than IN"
|
||||
ptype2 = remove_type_prefixes(ptype)
|
||||
if not ptype2 in param_type_mapping:
|
||||
raise TypeError("Unknown param type: %s" % (ptype2))
|
||||
m.params.append((ptype, name))
|
||||
m.cdefs.append((ptype, name))
|
||||
m.c_params.append((ptype, "&%s" % (name)))
|
||||
m.returns.append((ptype, name))
|
||||
|
||||
m.ret_type = func.return_type_get(eolian.FunctionType.PROP_GET)
|
||||
if m.ret_type:
|
||||
ret_type2 = remove_type_prefixes(m.ret_type)
|
||||
if not ret_type2 in return_type_mapping:
|
||||
if not ret_type2 in enums:
|
||||
raise TypeError(
|
||||
"Unknown return type: %s" % (ret_type2))
|
||||
else:
|
||||
self.enum_types.append(ret_type2)
|
||||
enums_counter[ret_type2] += 1
|
||||
fname = func.full_c_name_get(prefix)
|
||||
m.c_name = "_".join((fname, "get"))
|
||||
|
||||
for p in func.property_values:
|
||||
assert p.direction == eolian.ParameterDir.IN, \
|
||||
"prop %s has other than IN" % (fname)
|
||||
m.cdefs.append((p.type.c_type, p.name))
|
||||
m.c_params.append((p.type.c_type, "&%s" % (p.name)))
|
||||
m.returns.append((p.type.c_type, p.name))
|
||||
|
||||
ret_type = func.return_type_get(eolian.FunctionType.PROP_GET)
|
||||
if ret_type.return_type.c_type:
|
||||
m.ret_type = ret_type2
|
||||
|
||||
return self
|
||||
|
||||
|
@ -516,7 +346,6 @@ class Property(object):
|
|||
gen.write("property %s:" % (self.py_name))
|
||||
|
||||
gen.indent()
|
||||
gen.docstring_write(self.docs)
|
||||
|
||||
if self.setter:
|
||||
self.setter.pyx_generate(gen)
|
||||
|
@ -525,14 +354,14 @@ class Property(object):
|
|||
|
||||
gen.dedent()
|
||||
|
||||
def cdef_generate(self, gen):
|
||||
def cdefs_generate(self, gen):
|
||||
if self.setter:
|
||||
self.setter.cdef_generate(gen)
|
||||
self.setter.cdefs_generate(gen)
|
||||
if self.getter:
|
||||
self.getter.cdef_generate(gen)
|
||||
self.getter.cdefs_generate(gen)
|
||||
|
||||
|
||||
class EoConstructor(Method):
|
||||
class EoConstructor(Function):
|
||||
|
||||
def pyx_generate(self, gen):
|
||||
cls_get = self.eo_prefix + "_class_get()"
|
||||
|
@ -542,7 +371,7 @@ class EoConstructor(Method):
|
|||
|
||||
gen.indent()
|
||||
|
||||
gen.docstring_write(self.docs)
|
||||
#gen.docstring_write(self.docs)
|
||||
|
||||
c_params = ", ".join([c[1] for c in self.c_params])
|
||||
gen.write("self = cls.__new__(cls)")
|
||||
|
@ -562,7 +391,7 @@ class EoConstructor(Method):
|
|||
class EoDefaultConstructor(EoConstructor):
|
||||
|
||||
def pyx_generate(self, gen):
|
||||
cls_get = self.eo_prefix + "_class_get()"
|
||||
cls_get = self.prefix + "_class_get()"
|
||||
gen.write("def __init__(self, parent=None):")
|
||||
gen.indent()
|
||||
gen.write(
|
||||
|
@ -575,11 +404,11 @@ class EoDefaultConstructor(EoConstructor):
|
|||
gen.dedent()
|
||||
gen.write()
|
||||
|
||||
def cdef_generate(self, gen):
|
||||
def cdefs_generate(self, gen):
|
||||
pass
|
||||
|
||||
|
||||
class LegacyDefaultConstructor(Method):
|
||||
class LegacyDefaultConstructor(Function):
|
||||
|
||||
def pyx_generate(self, gen):
|
||||
call = self.legacy_prefix + "_add"
|
||||
|
@ -626,56 +455,54 @@ class Class(object):
|
|||
|
||||
self.inherits = list(cls.inherits)
|
||||
|
||||
desc = cls.description
|
||||
if desc:
|
||||
descs = desc.split("\n\n")
|
||||
for desc in descs:
|
||||
for pat, repl in docstring_replacements:
|
||||
if isinstance(pat, basestring):
|
||||
desc = desc.replace(pat, repl)
|
||||
else:
|
||||
desc = pat.sub(repl, desc)
|
||||
if desc:
|
||||
self.docs.append(desc)
|
||||
self.docs.append("")
|
||||
# desc = cls.description
|
||||
# if desc:
|
||||
# descs = desc.split("\n\n")
|
||||
# for desc in descs:
|
||||
# for pat, repl in docstring_replacements:
|
||||
# if isinstance(pat, basestring):
|
||||
# desc = desc.replace(pat, repl)
|
||||
# else:
|
||||
# desc = pat.sub(repl, desc)
|
||||
# if desc:
|
||||
# self.docs.append(desc)
|
||||
# self.docs.append("")
|
||||
|
||||
for k, v in (
|
||||
type(cls).__dict__.items()
|
||||
):
|
||||
if k.startswith("__") or hasattr(v, "__call__") or \
|
||||
k == "description" or k == "implements":
|
||||
continue
|
||||
#for k, v in (
|
||||
#type(cls).__dict__.items()
|
||||
#):
|
||||
#if k.startswith("__") or hasattr(v, "__call__") or \
|
||||
#k == "description" or k == "implements":
|
||||
#continue
|
||||
|
||||
if k == "events" or k == "inherits":
|
||||
objs = v.__get__(cls)
|
||||
if not objs:
|
||||
continue
|
||||
self.docs.append(
|
||||
"- %s: " % (k)
|
||||
)
|
||||
for obj in objs:
|
||||
self.docs.append(
|
||||
" - %s" % (obj)
|
||||
)
|
||||
else:
|
||||
self.docs.append(
|
||||
"- %s: %s" % (k, v.__get__(cls))
|
||||
)
|
||||
#if k == "events" or k == "inherits":
|
||||
#objs = v.__get__(cls)
|
||||
#if not objs:
|
||||
#continue
|
||||
#self.docs.append(
|
||||
#"- %s: " % (k)
|
||||
#)
|
||||
#for obj in objs:
|
||||
#self.docs.append(
|
||||
#" - %s" % (obj)
|
||||
#)
|
||||
#else:
|
||||
#self.docs.append(
|
||||
#"- %s: %s" % (k, v.__get__(cls))
|
||||
#)
|
||||
|
||||
ctors = None
|
||||
eo_prefix = self.eo_prefix = cls.eo_prefix
|
||||
legacy_prefix = self.legacy_prefix = cls.legacy_prefix
|
||||
|
||||
if eo_prefix and eo_prefix != "null":
|
||||
prefix = eo_prefix
|
||||
elif legacy_prefix and legacy_prefix != "null":
|
||||
log.warn("Class %s has legacy prefix" % (cls.name))
|
||||
prefix = legacy_prefix
|
||||
if args.with_legacy_api:
|
||||
prefix = cls.legacy_prefix
|
||||
else:
|
||||
prefix = cls.eo_prefix
|
||||
|
||||
if not prefix:
|
||||
log.warn("Class %s has no prefix!" % (cls.name))
|
||||
nspaces = list(cls.namespaces)
|
||||
nspaces.append(cls.name.lower())
|
||||
prefix = eo_prefix = self.eo_prefix = "_".join(nspaces)
|
||||
prefix = cls.name.lower()
|
||||
|
||||
self.prefix = prefix
|
||||
|
||||
if cls.type == eolian.ClassType.REGULAR: # \
|
||||
#or cls.type == eolian.ClassType.MIXIN:
|
||||
|
@ -683,9 +510,9 @@ class Class(object):
|
|||
if ctors:
|
||||
for ctor in ctors:
|
||||
function_counter[ctor.full_name] += 1
|
||||
if eo_prefix:
|
||||
if not args.with_legacy_api:
|
||||
try:
|
||||
o = EoConstructor.parse(ctor, eo_prefix, None)
|
||||
o = EoConstructor.parse(ctor, prefix)
|
||||
except Exception as e:
|
||||
log.warn(
|
||||
"Skipping %s.%s because of an exception"
|
||||
|
@ -699,17 +526,17 @@ class Class(object):
|
|||
self.ctors.append(o)
|
||||
generated_function_counter[
|
||||
"_".join((prefix, ctor.name))] += 1
|
||||
if eo_prefix:
|
||||
self.default_ctor = EoDefaultConstructor(eo_prefix, None)
|
||||
if not args.with_legacy_api:
|
||||
self.default_ctor = EoDefaultConstructor(prefix)
|
||||
else:
|
||||
self.default_ctor = LegacyDefaultConstructor(
|
||||
None, legacy_prefix)
|
||||
None, prefix)
|
||||
|
||||
props = cls.functions_get(eolian.FunctionType.PROPERTY)
|
||||
for prop in props:
|
||||
function_counter["_".join((prefix, prop.name))] += 1
|
||||
try:
|
||||
o = Property.parse(prop, eo_prefix, legacy_prefix)
|
||||
o = Property.parse(prop, prefix)
|
||||
except Exception as e:
|
||||
log.exception(
|
||||
"Skipping %s.%s because of an exception"
|
||||
|
@ -724,7 +551,7 @@ class Class(object):
|
|||
for method in methods:
|
||||
function_counter["_".join((prefix, method.name))] += 1
|
||||
try:
|
||||
o = Method.parse(method, eo_prefix, legacy_prefix)
|
||||
o = Method.parse(method, prefix)
|
||||
except Exception as e:
|
||||
log.exception(
|
||||
"Skipping %s.%s because of an exception"
|
||||
|
@ -740,29 +567,31 @@ class Class(object):
|
|||
return self
|
||||
|
||||
def pyx_generate(self, gen):
|
||||
if self.ctors or self.methods or self.props:
|
||||
gen.write('cdef extern from "%s":' % (self.header_path))
|
||||
gen.indent()
|
||||
for o in self.ctors + self.methods + self.props:
|
||||
o.cdef_generate(gen)
|
||||
gen.dedent()
|
||||
gen.write()
|
||||
|
||||
inherits = []
|
||||
for i in self.inherits:
|
||||
i_cls = eolian.Class.get_by_name(i)
|
||||
if i_cls:
|
||||
print(i_cls.name)
|
||||
print(i_cls.type)
|
||||
if i_cls.type == eolian.ClassType.INTERFACE or \
|
||||
i_cls.type == eolian.ClassType.MIXIN:
|
||||
continue
|
||||
else:
|
||||
log.warn("Class %s is unknown" % (i))
|
||||
inherits.append("_" + i)
|
||||
assert len(inherits) < 2, (
|
||||
"Multiple inheritance is not supported in extension classes.\n"
|
||||
"Class: %r" % (cls, inherits))
|
||||
if len(inherits) > 1:
|
||||
log.error(
|
||||
"Multiple inheritance is not supported in extension classes.\n"
|
||||
"Class: %r" % (cls)
|
||||
)
|
||||
return
|
||||
|
||||
if self.ctors or self.methods or self.props:
|
||||
gen.write('cdef extern from "%s":' % (self.header_path))
|
||||
gen.indent()
|
||||
for o in self.ctors + self.methods + self.props:
|
||||
o.cdefs_generate(gen)
|
||||
gen.dedent()
|
||||
gen.write()
|
||||
|
||||
|
||||
if not inherits:
|
||||
inherits = ("object", )
|
||||
|
@ -771,7 +600,7 @@ class Class(object):
|
|||
gen.write("cdef class _%s(%s):" % (self.name, inherits))
|
||||
gen.indent()
|
||||
|
||||
gen.docstring_write(self.docs)
|
||||
#gen.docstring_write(self.docs)
|
||||
|
||||
if not self.ctors and not self.props and not self.methods and \
|
||||
not self.default_ctor:
|
||||
|
@ -839,13 +668,13 @@ generated_function_counter = Counter()
|
|||
for path in args.paths:
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
eolian.directory_scan(dirpath)
|
||||
eolian.all_eo_files_parse()
|
||||
eolian.all_eot_files_parse()
|
||||
# for filename in filenames:
|
||||
# if filename.endswith(".eo"):
|
||||
# f = os.path.join(dirpath, filename)
|
||||
# if not eolian.eo_file_parse(f):
|
||||
# log.warn("Errors in parsing %s" % (f))
|
||||
#eolian.all_eo_files_parse()
|
||||
#eolian.all_eot_files_parse()
|
||||
for filename in filenames:
|
||||
if filename.endswith(".eo"):
|
||||
f = os.path.join(dirpath, filename)
|
||||
if not eolian.eo_file_parse(f):
|
||||
log.warn("Errors in parsing %s" % (f))
|
||||
|
||||
|
||||
with open(py_path, "a") as py_f:
|
||||
|
@ -877,21 +706,24 @@ with open(py_path, "a") as py_f:
|
|||
py_f.write("\n")
|
||||
log.info(py_path + " appended")
|
||||
|
||||
print("===============================================")
|
||||
print("Number of classes: %d" % (len(class_counter)))
|
||||
print("Number of classes generated: %d" % (len(generated_class_counter)))
|
||||
if len(class_counter) > 0:
|
||||
print("Percentage of classes generated: %f" % (
|
||||
float(len(generated_class_counter)) / float(len(class_counter)) * 100.0
|
||||
))
|
||||
print("Number of functions: %d" % (len(function_counter)))
|
||||
print("Number of functions generated: %d" % (
|
||||
len(generated_function_counter)))
|
||||
if len(function_counter) > 0:
|
||||
print("Percentage of functions generated: %f" % (
|
||||
float(len(generated_function_counter)) / float(len(function_counter))
|
||||
* 100.0
|
||||
))
|
||||
|
||||
def report():
|
||||
print("===============================================")
|
||||
print("Number of classes: %d" % (len(class_counter)))
|
||||
print("Number of classes generated: %d" % (len(generated_class_counter)))
|
||||
if len(class_counter) > 0:
|
||||
print("Percentage of classes generated: %f" % (
|
||||
float(len(generated_class_counter)) / float(len(class_counter)) * 100.0
|
||||
))
|
||||
print("Number of functions: %d" % (len(function_counter)))
|
||||
print("Number of functions generated: %d" % (
|
||||
len(generated_function_counter)))
|
||||
if len(function_counter) > 0:
|
||||
print("Percentage of functions generated: %f" % (
|
||||
float(len(generated_function_counter)) / float(len(function_counter))
|
||||
* 100.0
|
||||
))
|
||||
|
||||
report()
|
||||
|
||||
eolian.shutdown()
|
||||
|
|
Loading…
Reference in New Issue