summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--giscanner/ast.py1
-rw-r--r--giscanner/girwriter.py3
-rw-r--r--giscanner/glibtransformer.py30
-rw-r--r--tests/scanner/foo-expected.gir22
-rw-r--r--tests/scanner/foo.c25
-rw-r--r--tests/scanner/foo.h3
7 files changed, 85 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 19f7fa6a..30f249f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2008-08-25 Colin Walters <walters@verbum.org>
+ * giscanner/ast.py: Add interfaces property
+ to class.
+ * giscanner/girwriter.py: Write out implemented
+ interfaces.
+ * giscanner/glibtransformer.py: Introspect
+ implemented interfaces.
+ * tests/scanner/*: Make FooObject implement
+ FooInterface.
+
+2008-08-25 Colin Walters <walters@verbum.org>
+
* giscanner/glibtransformer.py: More correctly pair
methods; if we have a symbol that starts with
e.g. hippo_canvas look for a matching HippoCanvas
diff --git a/giscanner/ast.py b/giscanner/ast.py
index eaafa65c..7c51bb85 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -238,6 +238,7 @@ class Class(Node):
self.ctype = name
self.parent = parent
self.methods = []
+ self.interfaces = []
self.constructors = []
self.properties = []
self.fields = []
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index 18ba1b8d..54f5104c 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -192,6 +192,9 @@ class GIRWriter(XMLWriter):
if node.get_type:
attrs.append(('glib:get-type', node.get_type))
with self.tagcontext(tag_name, attrs):
+ if isinstance(node, GLibObject):
+ for iface in node.interfaces:
+ self.write_tag('implements', [('name', iface)])
if isinstance(node, Class):
for method in node.constructors:
self._write_constructor(method)
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index ca9fc574..ad0dbb4a 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -449,6 +449,7 @@ class GLibTransformer(object):
type_name, symbol)
self._introspect_properties(node, type_id)
self._introspect_signals(node, type_id)
+ self._introspect_implemented_interfaces(node, type_id)
self._add_attribute(node, replace=True)
self._register_internal_type(type_name, node)
@@ -475,6 +476,18 @@ class GLibTransformer(object):
self._add_attribute(node, replace=True)
self._register_internal_type(type_name, node)
+ def _introspect_implemented_interfaces(self, node, type_id):
+ fundamental_type_id = cgobject.type_fundamental(type_id)
+ if fundamental_type_id != cgobject.TYPE_OBJECT:
+ raise AssertionError
+ interfaces = cgobject.type_interfaces(type_id)
+ gt_interfaces = []
+ for interface_typeid in interfaces:
+ iname = cgobject.type_name(interface_typeid)
+ gitype = self._resolve_gtypename(iname)
+ gt_interfaces.append(gitype)
+ node.interfaces = gt_interfaces
+
def _introspect_properties(self, node, type_id):
fundamental_type_id = cgobject.type_fundamental(type_id)
if fundamental_type_id == cgobject.TYPE_OBJECT:
@@ -591,22 +604,21 @@ class GLibTransformer(object):
for field in node.fields:
self._resolve_field(field)
- def _resolve_parent(self, node):
- if not isinstance(node, (GLibInterface, GLibObject)):
- raise AssertionError
- if isinstance(node.parent, Unresolved):
- node.parent = \
- self._transformer.gtypename_to_giname(node.parent.target,
- self._names)
+ def _force_resolve(self, item):
+ if isinstance(item, Unresolved):
+ return self._transformer.gtypename_to_giname(item.target,
+ self._names)
+ return item
def _resolve_glib_interface(self, node):
- self._resolve_parent(node)
+ node.parent = self._force_resolve(node.parent)
self._resolve_methods(node.methods)
self._resolve_properties(node.properties)
self._resolve_signals(node.signals)
def _resolve_glib_object(self, node):
- self._resolve_parent(node)
+ node.parent = self._force_resolve(node.parent)
+ node.interfaces = [self._force_resolve(x) for x in node.interfaces]
self._resolve_constructors(node.constructors)
self._resolve_methods(node.methods)
self._resolve_properties(node.properties)
diff --git a/tests/scanner/foo-expected.gir b/tests/scanner/foo-expected.gir
index 2bcfd4b9..acd2492f 100644
--- a/tests/scanner/foo-expected.gir
+++ b/tests/scanner/foo-expected.gir
@@ -13,17 +13,38 @@
c:type="FooInterface"
glib:type-name="FooInterface"
glib:get-type="foo_interface_get_type">
+ <callback name="do_foo" c:type="do_foo">
+ <return-value>
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <parameter name="self">
+ <type name="Interface" c:type="FooInterface*"/>
+ </parameter>
+ </parameters>
+ </callback>
</interface>
<record name="InterfaceIface" c:type="FooInterfaceIface">
<field name="parent_iface">
<type name="GObject.TypeInterface" c:type="GTypeInterface"/>
</field>
+ <callback name="do_foo" c:type="do_foo">
+ <return-value>
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <parameter name="self">
+ <type name="Interface" c:type="FooInterface*"/>
+ </parameter>
+ </parameters>
+ </callback>
</record>
<class name="Object"
c:type="FooObject"
parent="GObject.Object"
glib:type-name="FooObject"
glib:get-type="foo_object_get_type">
+ <implements name="Interface"/>
<constructor name="new" c:identifier="foo_object_new">
<return-value>
<type name="Object" c:type="FooObject*"/>
@@ -121,6 +142,7 @@
parent="Object"
glib:type-name="FooSubobject"
glib:get-type="foo_subobject_get_type">
+ <implements name="Interface"/>
<constructor name="new" c:identifier="foo_subobject_new">
<return-value>
<type name="Subobject" c:type="FooSubobject*"/>
diff --git a/tests/scanner/foo.c b/tests/scanner/foo.c
index f6f7b9dc..8fa09212 100644
--- a/tests/scanner/foo.c
+++ b/tests/scanner/foo.c
@@ -2,6 +2,8 @@
#include "foo.h"
+static void foo_do_foo (FooInterface *self);
+
typedef struct
{
int i;
@@ -30,6 +32,10 @@ foo_interface_get_type (void)
return object_type;
}
+void foo_interface_do_foo (FooInterface *self)
+{
+ FOO_INTERFACE_GET_INTERFACE(self)->do_foo (self);
+}
enum {
PROP_0,
@@ -43,7 +49,17 @@ enum {
static guint foo_object_signals[LAST_SIGNAL] = { 0 };
-G_DEFINE_TYPE (FooObject, foo_object, G_TYPE_OBJECT);
+static void
+foo_foo_interface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ FooInterfaceIface *iface = (FooInterfaceIface *)g_iface;
+ iface->do_foo = foo_do_foo;
+}
+
+G_DEFINE_TYPE_EXTENDED (FooObject, foo_object, G_TYPE_OBJECT,
+ 0, G_IMPLEMENT_INTERFACE (FOO_TYPE_INTERFACE,
+ foo_foo_interface_init));
static void
foo_object_set_property (GObject *object,
@@ -121,6 +137,13 @@ foo_object_external_type (FooObject *object)
}
+void
+foo_do_foo (FooInterface *self)
+{
+
+
+}
+
G_DEFINE_TYPE (FooSubobject, foo_subobject, FOO_TYPE_OBJECT);
static void
diff --git a/tests/scanner/foo.h b/tests/scanner/foo.h
index 793946c0..caf6774e 100644
--- a/tests/scanner/foo.h
+++ b/tests/scanner/foo.h
@@ -7,6 +7,7 @@
#define FOO_TYPE_INTERFACE (foo_interface_get_type ())
#define FOO_INTERFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), FOO_TYPE_INTERFACE, FooInterface))
#define FOO_IS_INTERFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), FOO_TYPE_INTERFACE))
+#define FOO_INTERFACE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), FOO_TYPE_INTERFACE, FooInterfaceIface))
#define FOO_TYPE_OBJECT (foo_object_get_type ())
#define FOO_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), FOO_TYPE_OBJECT, FooObject))
@@ -26,6 +27,8 @@ typedef struct _FooSubobjectClass FooSubobjectClass;
struct _FooInterfaceIface
{
GTypeInterface parent_iface;
+
+ void (*do_foo) (FooInterface *self);
};
GType foo_interface_get_type (void) G_GNUC_CONST;