summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Matthew <jonathan@d14n.org>2010-10-27 19:11:13 +1000
committerJonathan Matthew <jonathan@d14n.org>2010-12-16 07:45:36 +1000
commit24a5ba0dc0be57146f6504679adf2527ed4a2802 (patch)
treef270f24231da3557c9a9e5e56bbb19dbe77419bf
parent112100a47956effefc07ed594fb921cf941fd828 (diff)
downloadgobject-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.py24
-rw-r--r--giscanner/introspectablepass.py7
-rw-r--r--giscanner/maintransformer.py10
-rw-r--r--tests/scanner/Regress-1.0-expected.gir31
-rw-r--r--tests/scanner/regress.c18
-rw-r--r--tests/scanner/regress.h18
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 {