[Telepathy-commits] [telepathy-qt4/master] codegen: support 'array-depth' attribute on types

Simon McVittie simon.mcvittie at collabora.co.uk
Tue Jan 6 09:38:29 PST 2009


In the Qt world, we need to generate a named type for every level of
nested list that makes sense. I've implemented this by adding an
array-depth attribute to <tp:mapping> etc. indicating the maximum
number of levels of nested lists that make sense for this type, so:

<tp:mapping name="MessagePart" array-name="MessagePartList"
  array-depth="2">

generates types MessagePart, MessagePartList = QList<MessagePart>,
and MessagePartListList = QList<MessagePartList>. If array-depth is
omitted, its value can be assumed to be 1 if array-name is present,
or 0 otherwise.

For the moment, the extra "List" suffix for arrays of nesting depth >= 2
is hard-coded.
---
 tools/libqt4codegen.py |   36 +++++++++++++++++++++++++++++++-----
 tools/qt4-types-gen.py |   37 +++++++++++++++++++++++++++++++++++--
 2 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/tools/libqt4codegen.py b/tools/libqt4codegen.py
index 62700a2..bd814f3 100644
--- a/tools/libqt4codegen.py
+++ b/tools/libqt4codegen.py
@@ -27,16 +27,25 @@ from libtpcodegen import get_by_path, get_descendant_text, NS_TP, xml_escape
 
 
 class _Qt4TypeBinding:
-    def __init__(self, val, inarg, outarg, array_val, custom_type, array_of):
+    def __init__(self, val, inarg, outarg, array_val, custom_type, array_of,
+            array_depth=None):
         self.val = val
         self.inarg = inarg
         self.outarg = outarg
         self.array_val = array_val
         self.custom_type = custom_type
         self.array_of = array_of
+        self.array_depth = array_depth
+
+        if array_depth is None:
+            self.array_depth = int(bool(array_val))
+        elif array_depth >= 1:
+            assert array_val
+        else:
+            assert not array_val
 
 def binding_from_usage(sig, tptype, custom_lists, external=False, explicit_own_ns=None):
-    # 'signature' : ('qt-type', 'pass-by-reference')
+    # 'signature' : ('qt-type', 'pass-by-reference', 'array-type')
     natives = {
             'y' : ('uchar', False, None),
             'b' : ('bool', False, 'BoolList'),
@@ -82,8 +91,14 @@ def binding_from_usage(sig, tptype, custom_lists, external=False, explicit_own_n
 
         if tptype.endswith('[]'):
             tptype = tptype[:-2]
+            extra_list_nesting = 0
+
+            while tptype.endswith('[]'):
+                extra_list_nesting += 1
+                tptype = tptype[:-2]
+
             assert custom_lists.has_key(tptype), ('No array version of custom type %s in the spec, but array version used' % tptype)
-            val = custom_lists[tptype]
+            val = custom_lists[tptype] + 'List' * extra_list_nesting
         else:
             val = tptype
 
@@ -94,11 +109,11 @@ def binding_from_usage(sig, tptype, custom_lists, external=False, explicit_own_n
     outarg = val + '&'
     return _Qt4TypeBinding(val, inarg, outarg, None, custom_type, array_of)
 
-def binding_from_decl(name, array_name):
+def binding_from_decl(name, array_name, array_depth=None):
     val = name.replace('_', '')
     inarg = 'const %s&' % val
     outarg = '%s&' % val
-    return _Qt4TypeBinding(val, inarg, outarg, array_name.replace('_', ''), True, None)
+    return _Qt4TypeBinding(val, inarg, outarg, array_name.replace('_', ''), True, None, array_depth)
 
 def extract_arg_or_member_info(els, custom_lists, externals, typesns, docstring_indent=' * ', docstring_brackets=None, docstring_maxwidth=80):
     names = []
@@ -196,10 +211,21 @@ def gather_custom_lists(spec, typesns):
     for (provider, ns) in structs + mappings + exts:
         tptype = provider.getAttribute('name').replace('_', '')
         array_val = provider.getAttribute('array-name').replace('_', '')
+        array_depth = provider.getAttribute('array-depth')
+        if array_depth:
+            array_depth = int(array_depth)
+        else:
+            array_depth = None
 
         if array_val:
             custom_lists[tptype] = array_val
             custom_lists[ns + '::' + tptype] = ns + '::' + array_val
+            if array_depth >= 2:
+                for i in xrange(array_depth):
+                    custom_lists[tptype + ('[]' * (i+1))] = (
+                            array_val + ('List' * i))
+                    custom_lists[ns + '::' + tptype + ('[]' * (i+1))] = (
+                            ns + '::' + array_val + ('List' * i))
 
     return custom_lists
 
diff --git a/tools/qt4-types-gen.py b/tools/qt4-types-gen.py
index 5525ae1..e59bfa7 100644
--- a/tools/qt4-types-gen.py
+++ b/tools/qt4-types-gen.py
@@ -29,7 +29,12 @@ class DepInfo:
         self.el = el
         name = get_by_path(el, '@name')
         array_name = get_by_path(el, '@array-name')
-        self.binding = binding_from_decl(name, array_name)
+        array_depth = get_by_path(el, '@array-depth')
+        if array_depth:
+            array_depth = int(array_depth)
+        else:
+            array_depth = None
+        self.binding = binding_from_decl(name, array_name, array_depth)
         self.deps = []
 
         for member in get_by_path(el, 'member'):
@@ -294,15 +299,27 @@ void registerTypes()
         for provider in structs + mappings + exts:
             name = get_by_path(provider, '@name')
             array_name = get_by_path(provider, '@array-name')
-            binding = binding_from_decl(name, array_name)
+            array_depth = get_by_path(provider, '@array-depth')
+            if array_depth:
+                array_depth = int(array_depth)
+            else:
+                array_depth = None
+            binding = binding_from_decl(name, array_name, array_depth)
             self.provide(binding.val)
 
             if binding.array_val:
                 self.provide(binding.array_val)
 
+            d = binding.array_depth
+            print "%s has max array depth %d" % (binding.val, d)
+            while d > 1:
+                d -= 1
+                self.provide(binding.array_val + ('List' * d))
+
         assert not self.required_custom, 'These required types were not provided by the spec: ' + ', '.join(self.required_custom)
 
     def provide(self, type):
+        print "Have type: %s" % type
         if type in self.required_custom:
             self.required_custom.remove(type)
 
@@ -392,6 +409,22 @@ typedef %s %s;
 
 """ % (get_headerfile_cmd(self.realinclude, self.prettyinclude), depinfo.binding.val, 'QList<%s>' % depinfo.binding.val, depinfo.binding.array_val))
 
+        i = depinfo.binding.array_depth
+        while i > 1:
+            i -= 1
+            self.to_declare.append('%s::%s%s' % (self.namespace, depinfo.binding.array_val, ('List' * i)))
+            list_of = depinfo.binding.array_val + ('List' * (i-1))
+            self.decl("""\
+/**
+ * \\ingroup list
+%s\
+ *
+ * Array of %s values.
+ */
+typedef QList<%s> %sList;
+
+""" % (get_headerfile_cmd(self.realinclude, self.prettyinclude), list_of, list_of, list_of))
+
     def faketype(self, fake, real):
         return """\
 struct %(fake)s : public %(real)s
-- 
1.5.6.5




More information about the Telepathy-commits mailing list