forked from enlightenment/efl
Pyolian: implement an utility class: Namspace
Update tests and generator to use this new feature
This commit is contained in:
parent
b8f4dc296f
commit
b9ed84f4ed
|
@ -300,6 +300,20 @@ class Eolian_Unit(EolianBaseObject):
|
|||
def all_classes(self):
|
||||
return Iterator(Class, lib.eolian_all_classes_get(self._obj))
|
||||
|
||||
@property
|
||||
def all_namespaces(self):
|
||||
# TODO find a better way to find namespaces (maybe inside eolian?)
|
||||
nspaces = []
|
||||
for cls in self.all_classes:
|
||||
ns = Namespace(self, cls.namespace)
|
||||
if not ns in nspaces:
|
||||
nspaces.append(ns)
|
||||
nspaces.sort()
|
||||
return nspaces
|
||||
|
||||
def namespace_get_by_name(self, name):
|
||||
return Namespace(self, name)
|
||||
|
||||
@property
|
||||
def typedecl_all_enums(self):
|
||||
return Iterator(Typedecl, lib.eolian_typedecl_all_enums_get(self._obj))
|
||||
|
@ -416,6 +430,72 @@ class Eolian(Eolian_Unit):
|
|||
return bool(lib.eolian_all_eot_files_parse(self._obj))
|
||||
|
||||
|
||||
### Namespace Utility Class #################################################
|
||||
|
||||
class Namespace(object):
|
||||
def __init__(self, unit, namespace_name):
|
||||
self._name = namespace_name
|
||||
self._unit = unit
|
||||
|
||||
def __repr__(self):
|
||||
return "<eolian.Namespace '{0._name}'>".format(self)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.name == other.name
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.name < other.name
|
||||
|
||||
def __gt__(self, other):
|
||||
return self.name > other.name
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def namespaces(self):
|
||||
return self._name.split('.')
|
||||
|
||||
@property
|
||||
def classes(self):
|
||||
return [ c for c in self._unit.all_classes
|
||||
if c.namespace == self._name ]
|
||||
|
||||
@property
|
||||
def regulars(self):
|
||||
return [ c for c in self._unit.all_classes
|
||||
if c.type == Eolian_Class_Type.REGULAR and
|
||||
c.namespace == self._name]
|
||||
|
||||
@property
|
||||
def mixins(self):
|
||||
return [ c for c in self._unit.all_classes
|
||||
if c.type == Eolian_Class_Type.MIXIN and
|
||||
c.namespace == self._name]
|
||||
|
||||
@property
|
||||
def interfaces(self):
|
||||
return [ c for c in self._unit.all_classes
|
||||
if c.type == Eolian_Class_Type.INTERFACE and
|
||||
c.namespace == self._name]
|
||||
|
||||
@property
|
||||
def aliases(self):
|
||||
return [ td for td in self._unit.typedecl_all_aliases
|
||||
if td.namespace == self._name]
|
||||
|
||||
@property
|
||||
def structs(self):
|
||||
return [ td for td in self._unit.typedecl_all_structs
|
||||
if td.namespace == self._name]
|
||||
|
||||
@property
|
||||
def enums(self):
|
||||
return [ td for td in self._unit.typedecl_all_enums
|
||||
if td.namespace == self._name]
|
||||
|
||||
|
||||
### Eolian Classes ##########################################################
|
||||
|
||||
class Class(EolianBaseObject):
|
||||
|
@ -1240,6 +1320,7 @@ class _Eolian_Doc_Token_Struct(ctypes.Structure):
|
|||
("text", c_char_p),
|
||||
("text_end", c_char_p)]
|
||||
|
||||
|
||||
class Documentation(EolianBaseObject):
|
||||
# def __repr__(self):
|
||||
# return "<eolian.Documentation '{0.name}'>".format(self)
|
||||
|
@ -1345,7 +1426,6 @@ lib.eolian_init()
|
|||
atexit.register(lambda: lib.eolian_shutdown())
|
||||
|
||||
|
||||
|
||||
### API coverage statistics #################################################
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -90,9 +90,9 @@ class Template(pyratemp.Template):
|
|||
|
||||
Args:
|
||||
filename: Template file to load. (REQUIRED)
|
||||
data: User provided context for the template.
|
||||
context: User provided context for the template (dict).
|
||||
"""
|
||||
def __init__(self, filename, encoding='utf-8', data=None, escape=None,
|
||||
def __init__(self, filename, encoding='utf-8', context=None, escape=None,
|
||||
loader_class=pyratemp.LoaderFile,
|
||||
parser_class=pyratemp.Parser,
|
||||
renderer_class=pyratemp.Renderer,
|
||||
|
@ -101,8 +101,8 @@ class Template(pyratemp.Template):
|
|||
# Build the global context for the template
|
||||
global_ctx = {}
|
||||
# user provided context (low pri)
|
||||
if data:
|
||||
global_ctx.update(data)
|
||||
if context:
|
||||
global_ctx.update(context)
|
||||
# standard names (not overwritables)
|
||||
global_ctx.update({
|
||||
# Template info
|
||||
|
@ -164,23 +164,14 @@ class Template(pyratemp.Template):
|
|||
ctx.update(kargs)
|
||||
if cls:
|
||||
ctx['cls'] = eolian_db.class_get_by_name(cls)
|
||||
if ns:
|
||||
ctx['namespace'] = eolian_db.namespace_get_by_name(ns)
|
||||
if struct:
|
||||
ctx['struct'] = eolian_db.typedecl_struct_get_by_name(struct)
|
||||
if enum:
|
||||
ctx['enum'] = eolian_db.typedecl_enum_get_by_name(enum)
|
||||
if alias:
|
||||
ctx['alias'] = eolian_db.typedecl_alias_get_by_name(alias)
|
||||
if ns:
|
||||
ctx['namespace'] = ns
|
||||
ctx['namespaces'] = ns.split('.')
|
||||
ctx['classes'] = [ c for c in eolian_db.all_classes
|
||||
if c.full_name.startswith(ns + '.') ]
|
||||
ctx['aliases'] = [ a for a in eolian_db.typedecl_all_aliases
|
||||
if a.full_name.startswith(ns + '.') ]
|
||||
ctx['structs'] = [ s for s in eolian_db.typedecl_all_structs
|
||||
if s.full_name.startswith(ns + '.') ]
|
||||
ctx['enums'] = [ e for e in eolian_db.typedecl_all_enums
|
||||
if e.full_name.startswith(ns + '.') ]
|
||||
|
||||
if verbose and filename:
|
||||
print('generating "{}" from template "{}"'.format(
|
||||
|
@ -205,7 +196,7 @@ class Template(pyratemp.Template):
|
|||
if __name__ == '__main__':
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Pyolian generator.')
|
||||
parser = argparse.ArgumentParser(description='Pyolian template based generator.')
|
||||
parser.add_argument('template',
|
||||
help='The template file to use. (REQUIRED)')
|
||||
parser.add_argument('--output', '-o', metavar='FILE', default=None,
|
||||
|
|
|
@ -50,7 +50,6 @@ class TestBaseObject(unittest.TestCase):
|
|||
self.assertNotEqual(enum1, 0)
|
||||
|
||||
self.assertNotEqual(cls1, enum1)
|
||||
|
||||
|
||||
|
||||
class TestEolianUnit(unittest.TestCase):
|
||||
|
@ -149,6 +148,71 @@ class TestEolianUnit(unittest.TestCase):
|
|||
self.assertGreater(all_count, 400)
|
||||
|
||||
|
||||
class TestEolianNamespace(unittest.TestCase):
|
||||
def test_all_namespace(self):
|
||||
count = 0
|
||||
for ns in state.all_namespaces:
|
||||
self.assertIsInstance(ns, eolian.Namespace)
|
||||
count += 1
|
||||
self.assertGreater(count, 100)
|
||||
|
||||
def test_namespace_equality(self):
|
||||
ns1 = eolian.Namespace(state, 'Efl.Io')
|
||||
ns2 = eolian.Namespace(state, 'Efl.Net')
|
||||
self.assertIsInstance(ns1, eolian.Namespace)
|
||||
self.assertIsInstance(ns2, eolian.Namespace)
|
||||
self.assertNotEqual(ns1, ns2)
|
||||
self.assertEqual(ns1, eolian.Namespace(state, 'Efl.Io'))
|
||||
self.assertEqual(ns2, eolian.Namespace(state, 'Efl.Net'))
|
||||
|
||||
def test_namespace_sorting(self):
|
||||
nspaces = state.all_namespaces
|
||||
nspaces.sort(reverse=True)
|
||||
self.assertGreater(nspaces[0], nspaces[-1])
|
||||
self.assertLess(nspaces[1], nspaces[0])
|
||||
|
||||
def test_namespace_by_name(self):
|
||||
ns = eolian.Namespace(state, 'Efl.Net')
|
||||
self.assertIsInstance(ns, eolian.Namespace)
|
||||
self.assertEqual(ns.name, 'Efl.Net')
|
||||
self.assertEqual(ns.namespaces, ['Efl', 'Net'])
|
||||
|
||||
ns = state.namespace_get_by_name('Efl')
|
||||
self.assertIsInstance(ns, eolian.Namespace)
|
||||
self.assertEqual(ns.name, 'Efl')
|
||||
|
||||
self.assertGreater(len(ns.classes), 30)
|
||||
for cls in ns.classes:
|
||||
self.assertIsInstance(cls, eolian.Class)
|
||||
self.assertGreater(len(ns.regulars), 4)
|
||||
for cls in ns.regulars:
|
||||
self.assertIsInstance(cls, eolian.Class)
|
||||
self.assertEqual(cls.type, eolian.Eolian_Class_Type.REGULAR)
|
||||
self.assertGreater(len(ns.mixins), 0)
|
||||
for cls in ns.mixins:
|
||||
self.assertIsInstance(cls, eolian.Class)
|
||||
self.assertEqual(cls.type, eolian.Eolian_Class_Type.MIXIN)
|
||||
self.assertGreater(len(ns.interfaces), 15)
|
||||
for cls in ns.interfaces:
|
||||
self.assertIsInstance(cls, eolian.Class)
|
||||
self.assertEqual(cls.type, eolian.Eolian_Class_Type.INTERFACE)
|
||||
|
||||
self.assertGreater(len(ns.enums), 1)
|
||||
for td in ns.enums:
|
||||
self.assertIsInstance(td, eolian.Typedecl)
|
||||
self.assertEqual(td.type, eolian.Eolian_Typedecl_Type.ENUM)
|
||||
self.assertGreater(len(ns.aliases), 0)
|
||||
for td in ns.aliases:
|
||||
self.assertIsInstance(td, eolian.Typedecl)
|
||||
# TODO eolian_typedecl_all_aliases_get also return FUNCTION_POINTER
|
||||
# is this correct? or an eolian bug ?
|
||||
# self.assertEqual(td.type, eolian.Eolian_Typedecl_Type.ALIAS)
|
||||
self.assertGreater(len(ns.structs), 2)
|
||||
for td in ns.structs:
|
||||
self.assertIsInstance(td, eolian.Typedecl)
|
||||
self.assertEqual(td.type, eolian.Eolian_Typedecl_Type.STRUCT)
|
||||
|
||||
|
||||
class TestEolianClass(unittest.TestCase):
|
||||
def test_class(self):
|
||||
cls = state.class_get_by_file('efl_loop_timer.eo')
|
||||
|
|
|
@ -1,19 +1,35 @@
|
|||
|
||||
================================================================================
|
||||
Namespace: ${namespace}$ ${namespaces}$
|
||||
Namespace: ${namespace.name}$ ${namespace.namespaces}$
|
||||
================================================================================
|
||||
|
||||
Classes:
|
||||
========
|
||||
<!--(for cls in classes)-->
|
||||
* ${cls.full_name}$ (${cls.type}$)
|
||||
Regular Classes:
|
||||
================
|
||||
<!--(for cls in namespace.regulars)-->
|
||||
* ${cls.full_name}$ (${cls.type.name.lower()}$)
|
||||
<!--(else)-->
|
||||
no classes available
|
||||
<!--(end)-->
|
||||
|
||||
Interfaces:
|
||||
===========
|
||||
<!--(for cls in namespace.interfaces)-->
|
||||
* ${cls.full_name}$ (${cls.type.name.lower()}$)
|
||||
<!--(else)-->
|
||||
no classes available
|
||||
<!--(end)-->
|
||||
|
||||
Mixins:
|
||||
=======
|
||||
<!--(for cls in namespace.mixins)-->
|
||||
* ${cls.full_name}$ (${cls.type.name.lower()}$)
|
||||
<!--(else)-->
|
||||
no classes available
|
||||
<!--(end)-->
|
||||
|
||||
Aliases:
|
||||
========
|
||||
<!--(for typedecl in aliases)-->
|
||||
<!--(for typedecl in namespace.aliases)-->
|
||||
* ${typedecl.full_name}$
|
||||
<!--(else)-->
|
||||
no alias available
|
||||
|
@ -21,10 +37,10 @@ Aliases:
|
|||
|
||||
Structs:
|
||||
========
|
||||
<!--(for typedecl in structs)-->
|
||||
<!--(for typedecl in namespace.structs)-->
|
||||
* ${typedecl.full_name}$
|
||||
<!--(for field in typedecl.struct_fields)-->
|
||||
${field}$
|
||||
${field.type.name}$ ${field.name}$
|
||||
<!--(end)-->
|
||||
<!--(else)-->
|
||||
no structs available
|
||||
|
@ -32,10 +48,10 @@ Structs:
|
|||
|
||||
Enums:
|
||||
======
|
||||
<!--(for typedecl in enums)-->
|
||||
<!--(for typedecl in namespace.enums)-->
|
||||
* ${typedecl.full_name}$
|
||||
<!--(for field in typedecl.enum_fields)-->
|
||||
${field}$
|
||||
${field.c_name}$ = ${field.value.serialize}$
|
||||
<!--(end)-->
|
||||
<!--(else)-->
|
||||
no enums available
|
||||
|
|
Loading…
Reference in New Issue