Eolian: Handle multiple inheritance, accept several paths as args

The generator now needs inherited classes for parsing, so in args give
eo for evas etc., or full efl for elm, and so on.
This commit is contained in:
Kai Huuhko 2014-06-18 10:11:10 +03:00
parent 8b59680eec
commit 137e6b7e21
1 changed files with 86 additions and 31 deletions

View File

@ -6,11 +6,11 @@ import keyword
from argparse import ArgumentParser
parser = ArgumentParser(description="Python generator for eolian")
parser.add_argument(
'--header-file', required=True,
help="Filename of the library header")
# parser.add_argument(
# '--header-file', required=True,
# help="Filename of the library header")
parser.add_argument('-o', '--output', default="/tmp")
parser.add_argument('path')
parser.add_argument('paths', nargs="+")
args = parser.parse_args()
import logging
@ -444,6 +444,7 @@ class Class(object):
self.methods = []
self.props = []
self.default_ctor = None
self.header_path = None
@classmethod
def parse(klass, cls):
@ -451,17 +452,13 @@ class Class(object):
self.__init__()
self.cls = cls
for i in cls.inherits_list:
i_cls = eolian.class_find_by_name(i)
if i_cls and (
i_cls.type == eolian.ClassType.INTERFACE or
i_cls.type == eolian.ClassType.MIXIN):
continue
self.inherits.append("_" + i)
header_path = cls.filename
if not header_path:
return
header_path = os.path.basename(header_path + ".h")
self.header_path = header_path
if not self.inherits:
self.inherits = ("object", )
self.inherits = ", ".join(self.inherits)
self.inherits = cls.inherits_list
desc = self.cls.description
if desc:
@ -522,14 +519,32 @@ class Class(object):
def pyx_generate(self, gen):
if self.ctors or self.methods or self.props:
gen.write('cdef extern from "%s":' % (args.header_file))
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()
gen.write("cdef class _%s(%s):" % (self.cls.name, self.inherits))
inherits = []
for i in self.inherits:
i_cls = eolian.class_find_by_name(i)
if i_cls:
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, inherits: %r" % (cls, inherits))
if not inherits:
inherits = ("object", )
inherits = ", ".join(inherits)
gen.write("cdef class _%s(%s):" % (self.cls.name, inherits))
gen.indent()
gen.docstring_write(self.docs)
@ -550,23 +565,63 @@ class Class(object):
gen.dedent()
gen.write()
def py_generate(self, gen):
if len(self.inherits) < 2:
return
for dirpath, dirnames, filenames in os.walk(args.path):
for filename in filenames:
if filename.endswith(".eo"):
f = os.path.join(dirpath, filename)
eolian.eo_file_parse(f)
cls = eolian.class_find_by_file(f)
inherits = ["_" + self.cls.name]
for i in self.inherits:
i_cls = eolian.class_find_by_name(i)
if i_cls:
if i_cls.type == eolian.ClassType.REGULAR or \
i_cls.type == eolian.ClassType.ABSTRACT:
continue
else:
log.warn("Class %s is unknown" % (i))
inherits.append("_" + i)
pyxgen = PyxGenerator()
gencls = Class.parse(cls)
gencls.pyx_generate(pyxgen)
gen.write("class %s(%s):" % (self.cls.name, ", ".join(inherits)))
gen.indent()
gen.write("pass")
gen.dedent()
gen.write()
f_base = os.path.splitext(filename)[0]
pxi_path = os.path.join(args.output, f_base + ".pxi")
with open(pxi_path, "w") as f:
f.write(pyxgen.printout().encode("utf-8"))
f.write("\n")
log.info(pxi_path + " written")
py_path = os.path.join(args.output, "__init__" + ".py")
if os.path.exists(py_path):
os.remove(py_path)
for path in args.paths:
for dirpath, dirnames, filenames in os.walk(path):
eolian.directory_scan(dirpath)
eolian.all_eo_files_parse()
for filename in filenames:
if filename.endswith(".eo"):
f = os.path.join(dirpath, filename)
if not eolian.eo_file_parse(f):
log.error("Could not parse %s" % (f))
cls = eolian.class_find_by_file(f)
gencls = Class.parse(cls)
pyxgen = PyxGenerator()
gencls.pyx_generate(pyxgen)
f_base = os.path.splitext(filename)[0]
pxi_path = os.path.join(args.output, f_base + ".pxi")
o = pyxgen.printout()
if o:
with open(pxi_path, "w") as f:
f.write(o.encode("utf-8"))
log.info(pxi_path + " written")
pygen = Generator()
gencls.py_generate(pygen)
o = pygen.printout()
if o:
with open(py_path, "a") as f:
f.write(o.encode("utf-8"))
f.write("\n")
log.info(py_path + " written")
eolian.shutdown()