[gobject-introspection] scanner: support typedefs for container types



commit 24a5ba0dc0be57146f6504679adf2527ed4a2802
Author: Jonathan Matthew <jonathan d14n org>
Date:   Wed Oct 27 19:11:13 2010 +1000

    scanner: support typedefs for container types
    
    Inside an alias definition, we only need the name of the alias target
    type.  Add a method to GIRWriter to write out a type reference rather
    than full type definition and use it when writing out an alias.
    
    Determine introspectableness of aliases in IntrospectablePass so functions
    using aliases can be marked not-introspectable if the alias itself is not.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=629682

 giscanner/girwriter.py                 |   24 +++++++++++++++++++++++-
 giscanner/introspectablepass.py        |    7 +++++++
 giscanner/maintransformer.py           |   10 ----------
 tests/scanner/Regress-1.0-expected.gir |   31 +++++++++++++++++++++++++++++++
 tests/scanner/regress.c                |   18 ++++++++++++++++++
 tests/scanner/regress.h                |   18 ++++++++++++++++++
 6 files changed, 97 insertions(+), 11 deletions(-)
---
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index 43dbd26..4f7bd64 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -157,7 +157,7 @@ and/or use gtk-doc annotations. ''')
         self._append_node_generic(alias, attrs)
         with self.tagcontext('alias', attrs):
             self._write_generic(alias)
-            self._write_type(alias.target)
+            self._write_type_ref(alias.target)
 
     def _write_callable(self, callable, tag_name, extra_attrs):
         attrs = [('name', callable.name)]
@@ -241,6 +241,28 @@ and/or use gtk-doc annotations. ''')
             return typeval.target_giname[len(prefix):]
         return typeval.target_giname
 
+    def _write_type_ref(self, ntype):
+	""" Like _write_type, but only writes the type name rather than the full details """
+        assert isinstance(ntype, ast.Type), ntype
+        attrs = []
+        if ntype.ctype:
+            attrs.append(('c:type', ntype.ctype))
+        if isinstance(ntype, ast.Array):
+            if ntype.array_type != ast.Array.C:
+                attrs.insert(0, ('name', ntype.array_type))
+        elif isinstance(ntype, ast.List):
+            if ntype.name:
+                attrs.insert(0, ('name', ntype.name))
+        elif isinstance(ntype, ast.Map):
+            attrs.insert(0, ('name', 'GLib.HashTable'))
+        else:
+            if ntype.target_giname:
+                attrs.insert(0, ('name', self._type_to_name(ntype)))
+            elif ntype.target_fundamental:
+                attrs.insert(0, ('name', ntype.target_fundamental))
+
+        self.write_tag('type', attrs)
+
     def _write_type(self, ntype, relation=None, function=None):
         assert isinstance(ntype, ast.Type), ntype
         attrs = []
diff --git a/giscanner/introspectablepass.py b/giscanner/introspectablepass.py
index 8aa7f8d..4b35f7d 100644
--- a/giscanner/introspectablepass.py
+++ b/giscanner/introspectablepass.py
@@ -31,6 +31,7 @@ class IntrospectablePass(object):
     # Public API
 
     def validate(self):
+        self._namespace.walk(self._introspectable_alias_analysis)
         self._namespace.walk(self._propagate_callable_skips)
         self._namespace.walk(self._analyze_node)
         self._namespace.walk(self._introspectable_callable_analysis)
@@ -166,6 +167,12 @@ class IntrospectablePass(object):
         if target.skip:
             parent.skip = True
 
+    def _introspectable_alias_analysis(self, obj, stack):
+        if isinstance(obj, ast.Alias):
+            if not self._type_is_introspectable(obj.target):
+                obj.introspectable = False
+        return True
+
     def _propagate_callable_skips(self, obj, stack):
         if isinstance(obj, ast.Callable):
             for param in obj.parameters:
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index 9729d4d..5a9530b 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -53,16 +53,6 @@ class MainTransformer(object):
 * Not including .h files to be scanned
 * Broken --identifier-prefix
 """)
-        ## WORKAROUND ##
-        # Dirty hack for now...maybe eventually we'll support the "typedef GSList FooSet"
-        # pattern.
-        # https://bugzilla.gnome.org/show_bug.cgi?id=629682
-        if self._namespace.name == 'Atk':
-            attribute = self._namespace.get('Attribute')
-            attributeset = self._namespace.get('AttributeSet')
-            if attribute and attributeset:
-                alias = ast.Alias('AttributeSet', target=ast.TYPE_ANY)
-                self._namespace.append(alias, replace=True)
 
         # Some initial namespace surgery
         self._namespace.walk(self._pass_fixup_hidden_fields)
diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir
index 17e130d..965caa5 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -19,6 +19,14 @@ and/or use gtk-doc annotations.  -->
       <doc xml:whitespace="preserve">Compatibility typedef, like telepathy-glib's TpIntSet</doc>
       <type name="Intset" c:type="RegressIntset"/>
     </alias>
+    <alias name="PtrArrayAlias" c:type="RegressPtrArrayAlias">
+      <doc xml:whitespace="preserve">Typedef'd GPtrArray for some reason</doc>
+      <type name="GLib.PtrArray" c:type="GPtrArray"/>
+    </alias>
+    <alias name="VaListAlias" c:type="RegressVaListAlias" introspectable="0">
+      <doc xml:whitespace="preserve">Typedef'd va_list for additional reasons</doc>
+      <type name="va_list" c:type="va_list"/>
+    </alias>
     <constant name="DOUBLE_CONSTANT" value="44.220000">
       <type name="gdouble" c:type="gdouble"/>
     </constant>
@@ -980,6 +988,29 @@ TpAccount::status-changed</doc>
         </parameter>
       </parameters>
     </function>
+    <function name="introspectable_via_alias"
+              c:identifier="regress_introspectable_via_alias">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="data" transfer-ownership="none">
+          <type name="PtrArrayAlias" c:type="RegressPtrArrayAlias*"/>
+        </parameter>
+      </parameters>
+    </function>
+    <function name="not_introspectable_via_alias"
+              c:identifier="regress_not_introspectable_via_alias"
+              introspectable="0">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="ok" transfer-ownership="none">
+          <type name="VaListAlias" c:type="RegressVaListAlias"/>
+        </parameter>
+      </parameters>
+    </function>
     <function name="random_function_with_skipped_structure"
               c:identifier="regress_random_function_with_skipped_structure"
               introspectable="0">
diff --git a/tests/scanner/regress.c b/tests/scanner/regress.c
index e6350b7..faac481 100644
--- a/tests/scanner/regress.c
+++ b/tests/scanner/regress.c
@@ -2871,3 +2871,21 @@ regress_test_strv_in_gvalue (void)
 
   return value;
 }
+
+/**
+ * regress_introspectable_via_alias:
+ *
+ */
+void
+regress_introspectable_via_alias (RegressPtrArrayAlias *data)
+{
+}
+
+/**
+ * regress_not_introspectable_via_alias:
+ *
+ */
+void
+regress_not_introspectable_via_alias (RegressVaListAlias ok)
+{
+}
diff --git a/tests/scanner/regress.h b/tests/scanner/regress.h
index a7342a9..5f82bbc 100644
--- a/tests/scanner/regress.h
+++ b/tests/scanner/regress.h
@@ -561,6 +561,24 @@ typedef struct _RegressIntset RegressIntset;
  */
 typedef RegressIntset RegressIntSet;
 
+/**
+ * RegressPtrArrayAlias:
+ *
+ * Typedef'd GPtrArray for some reason
+ */
+typedef GPtrArray RegressPtrArrayAlias;
+
+void regress_introspectable_via_alias (RegressPtrArrayAlias *data);
+
+/**
+ * RegressVaListAlias:
+ *
+ * Typedef'd va_list for additional reasons
+ */
+typedef va_list RegressVaListAlias;
+
+void regress_not_introspectable_via_alias (RegressVaListAlias ok);
+
 /* private testing */
 
 typedef struct {



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