[gobject-introspection] scanner: support typedefs for container types
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gobject-introspection] scanner: support typedefs for container types
- Date: Wed, 15 Dec 2010 21:46:22 +0000 (UTC)
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]