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:
parent
8b59680eec
commit
137e6b7e21
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue