[gobject-introspection] Make caller-allocates detection work for struct aliases



commit 8896eb04d9cb9f8792da34ae9814c7d7b97a9729
Author: Pavel Holejsovsky <pholejs src gnome org>
Date:   Sun Jan 9 16:12:46 2011 +0100

    Make caller-allocates detection work for struct aliases
    
    Scanner tries to detect caller-allocates attribute automatically if
    not explicitly specified by checking that parameter is not double-referenced
    and is struct or union.  This patch adds resolving of aliases when
    checking whether parameter is struct or union.
    
    Also removes old incorrect method transformer.follow_aliases, which
    was never used in current code.
    
    Fixes https://bugzilla.gnome.org/show_bug.cgi?id=639081

 giscanner/maintransformer.py           |    1 +
 giscanner/transformer.py               |   17 ++++++++++-------
 tests/scanner/Regress-1.0-expected.gir |   18 ++++++++++++++++++
 tests/scanner/regress.c                |   10 ++++++++++
 tests/scanner/regress.h                |    9 +++++++++
 5 files changed, 48 insertions(+), 7 deletions(-)
---
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index 0868d78..345f0f0 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -501,6 +501,7 @@ usage is void (*_gtk_reserved1)(void);"""
             if subtype in (None, ''):
                 if node.type.target_giname and node.type.ctype:
                     target = self._transformer.lookup_giname(node.type.target_giname)
+                    target = self._transformer.resolve_aliases(target)
                     has_double_indirection = '**' in node.type.ctype
                     is_structure_or_union = isinstance(target, (ast.Record, ast.Union))
                     caller_allocates = (not has_double_indirection and is_structure_or_union)
diff --git a/giscanner/transformer.py b/giscanner/transformer.py
index 4cd2448..a651649 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -827,12 +827,15 @@ Note that type resolution may not succeed."""
         else:
             return None
 
-    def follow_aliases(self, type_name, names):
-        while True:
-            resolved = names.aliases.get(type_name)
-            if resolved:
-                (ns, alias) = resolved
-                type_name = alias.target
+    def resolve_aliases(self, typenode):
+        """Removes all aliases from typenode, returns first non-alias
+        in the typenode alias chain.  Returns typenode argument if it
+        is not an alias."""
+        while isinstance(typenode, ast.Alias):
+            if typenode.target.target_giname is not None:
+                typenode = self.lookup_giname(typenode.target.target_giname)
+            elif typenode.target.target_fundamental is not None:
+                typenode = ast.type_names[typenode.target.target_fundamental]
             else:
                 break
-        return type_name
+        return typenode
diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir
index c7fb783..3d4e56f 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -16,6 +16,10 @@ and/or use gtk-doc annotations.  -->
              shared-library="libregress.so"
              c:identifier-prefixes="Regress"
              c:symbol-prefixes="regress">
+    <alias name="AliasedTestBoxed" c:type="RegressAliasedTestBoxed">
+      <doc xml:whitespace="preserve">Typedef TestBoxed to test caller-allocates correctness</doc>
+      <type name="TestBoxed" c:type="RegressTestBoxed"/>
+    </alias>
     <alias name="IntSet" c:type="RegressIntSet" introspectable="0">
       <doc xml:whitespace="preserve">Compatibility typedef, like telepathy-glib's TpIntSet</doc>
       <type name="Intset" c:type="RegressIntset"/>
@@ -963,6 +967,20 @@ TpAccount::status-changed</doc>
         <type name="GObject.Object" c:type="GObject*"/>
       </field>
     </record>
+    <function name="aliased_caller_alloc"
+              c:identifier="regress_aliased_caller_alloc">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="boxed"
+                   direction="out"
+                   caller-allocates="1"
+                   transfer-ownership="none">
+          <type name="AliasedTestBoxed" c:type="RegressAliasedTestBoxed*"/>
+        </parameter>
+      </parameters>
+    </function>
     <function name="func_obj_null_in" c:identifier="regress_func_obj_null_in">
       <return-value transfer-ownership="none">
         <type name="none" c:type="void"/>
diff --git a/tests/scanner/regress.c b/tests/scanner/regress.c
index faac481..f9c4b37 100644
--- a/tests/scanner/regress.c
+++ b/tests/scanner/regress.c
@@ -2889,3 +2889,13 @@ void
 regress_not_introspectable_via_alias (RegressVaListAlias ok)
 {
 }
+
+/**
+ * regress_aliased_caller_alloc:
+ * @boxed: (out):
+ */
+void regress_aliased_caller_alloc (RegressAliasedTestBoxed *boxed)
+{
+  boxed->priv = g_slice_new0 (RegressTestBoxedPrivate);
+  boxed->priv->magic = 0xdeadbeef;
+}
diff --git a/tests/scanner/regress.h b/tests/scanner/regress.h
index 5f82bbc..2a3b351 100644
--- a/tests/scanner/regress.h
+++ b/tests/scanner/regress.h
@@ -579,6 +579,15 @@ typedef va_list RegressVaListAlias;
 
 void regress_not_introspectable_via_alias (RegressVaListAlias ok);
 
+/**
+ * RegressAliasedTestBoxed:
+ *
+ * Typedef TestBoxed to test caller-allocates correctness
+ */
+typedef RegressTestBoxed RegressAliasedTestBoxed;
+
+void regress_aliased_caller_alloc (RegressAliasedTestBoxed *boxed);
+
 /* private testing */
 
 typedef struct {



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