diff options
author | Jonathan Matthew <jonathan@d14n.org> | 2010-10-27 19:11:13 +1000 |
---|---|---|
committer | Jonathan Matthew <jonathan@d14n.org> | 2010-12-16 07:45:36 +1000 |
commit | 24a5ba0dc0be57146f6504679adf2527ed4a2802 (patch) | |
tree | f270f24231da3557c9a9e5e56bbb19dbe77419bf | |
parent | 112100a47956effefc07ed594fb921cf941fd828 (diff) | |
download | gobject-introspection-24a5ba0dc0be57146f6504679adf2527ed4a2802.tar.gz |
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
-rw-r--r-- | giscanner/girwriter.py | 24 | ||||
-rw-r--r-- | giscanner/introspectablepass.py | 7 | ||||
-rw-r--r-- | giscanner/maintransformer.py | 10 | ||||
-rw-r--r-- | tests/scanner/Regress-1.0-expected.gir | 31 | ||||
-rw-r--r-- | tests/scanner/regress.c | 18 | ||||
-rw-r--r-- | tests/scanner/regress.h | 18 |
6 files changed, 97 insertions, 11 deletions
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py index 43dbd26c..4f7bd64c 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 8aa7f8d3..4b35f7d9 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 9729d4d4..5a9530b3 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 17e130d6..965caa54 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 e6350b7b..faac481e 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 a7342a9b..5f82bbce 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 { |