[gobject-introspection] Use best known derived parent



commit 0d9cfb004d528fd0a7a0b05943db3b2097d8a085
Author: Colin Walters <walters verbum org>
Date:   Mon Oct 19 18:18:14 2009 -0400

    Use best known derived parent
    
    In the case where a known class derives from a hidden one, we want
    to use the most-derived parent class, rather than simply falling back
    to GObject.
    
    Example:
    ShellEmbedWidget in gnome-shell derives from ClutterGLXTexturePixmap from clutter,
    which is a hidden class.  ClutterGLXTexturePixmap's parent itself is
    ClutterX11TexturePixmap, which is also hidden.  But its parent is
    ClutterTexture, which we do know.  Use that.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=598993

 girepository/gdump.c         |   22 +++++++++++++++++++++-
 giscanner/glibtransformer.py |   18 ++++++++++++++++--
 2 files changed, 37 insertions(+), 3 deletions(-)
---
diff --git a/girepository/gdump.c b/girepository/gdump.c
index 519672a..b4a3e8e 100644
--- a/girepository/gdump.c
+++ b/girepository/gdump.c
@@ -154,7 +154,27 @@ dump_object_type (GType type, const char *symbol, GOutputStream *out)
   escaped_printf (out, "  <class name=\"%s\" get-type=\"%s\"",
 		  g_type_name (type), symbol);
   if (type != G_TYPE_OBJECT)
-    escaped_printf (out, " parent=\"%s\"", g_type_name (g_type_parent (type)));
+    {
+      GString *parent_str;
+      GType parent;
+      gboolean first = TRUE;
+      
+      parent = type;
+      parent_str = g_string_new ("");
+      do
+        {
+          parent = g_type_parent (parent);
+          if (first)
+            first = FALSE;
+          else
+            g_string_append_c (parent_str, ',');
+          g_string_append (parent_str, g_type_name (parent));
+        } while (parent != G_TYPE_OBJECT && parent != G_TYPE_INVALID);
+   
+      escaped_printf (out, " parents=\"%s\"", parent_str->str);
+      
+      g_string_free (parent_str, TRUE);
+    }
 
   if (G_TYPE_IS_ABSTRACT (type))
     escaped_printf (out, " abstract=\"1\"");
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index 5b94ef7..76085c1 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -255,6 +255,17 @@ class GLibTransformer(object):
                                                          self._names)
         except KeyError, e:
             return Unresolved(gtype_name)
+            
+    def _resolve_gtypename_chain(self, gtype_names):
+        """Like _resolve_gtypename, but grab the first one that resolves.
+        If none of them do, return an Unresolved for the first."""
+        for gtype_name in gtype_names:
+            try:
+                return self._transformer.gtypename_to_giname(gtype_name,
+                                                             self._names)
+            except KeyError, e:
+                continue
+        return Unresolved(gtype_names[0])
 
     def _execute_binary(self):
         in_path = os.path.join(self._binary.tmpdir, 'types.txt')
@@ -687,8 +698,11 @@ class GLibTransformer(object):
         # to skip it
         if type_name == 'GObject':
             return
-        parent_type_name = xmlnode.attrib['parent']
-        parent_gitype = self._resolve_gtypename(parent_type_name)
+        # Get a list of parents here; some of them may be hidden, and what
+        # we really want to do is use the most-derived one that we know of.
+        # 
+        parent_type_names = xmlnode.attrib['parents'].split(',')
+        parent_gitype = self._resolve_gtypename_chain(parent_type_names)
         is_abstract = not not xmlnode.attrib.get('abstract', False)
         node = GLibObject(
             self._transformer.remove_prefix(type_name),



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]