summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@src.gnome.org>2009-02-06 18:37:13 +0000
committerColin Walters <walters@src.gnome.org>2009-02-06 18:37:13 +0000
commitd1bf6a23c6fa14e918aa93e346237b1c832fb2ea (patch)
tree715bf149bfa948eed8a1da945e2c0984ea81df73
parent3ae9127e53032065df14be8539aba0cf50835386 (diff)
downloadgobject-introspection-d1bf6a23c6fa14e918aa93e346237b1c832fb2ea.tar.gz
Bug 551738 - Associate classes with their structs
Inside glibtransformer, we now look at structures ending in "Class" and see if they have an associated GlibObject (i.e. a structure of the same name without the "Class" suffix). If found, pair them up. The .gir file for <class> gains an attribute denoting its associated class struct. Any <record> many now have a glib:is-class-struct-for annotation which tells which (if any) <class> for which it defines the layout. In the .typelib, we record the association between the class and its structure. Generic structures however just have a boolean saying whether they're a class struct. (Going from a generic class struct to its class should not be necessary). Finally, we expose GIRepository APIs to access both bits of information from the .typelib. svn path=/trunk/; revision=1088
-rw-r--r--docs/typelib-format.txt15
-rw-r--r--girepository/ginfo.c37
-rw-r--r--girepository/girepository.h2
-rw-r--r--girepository/girmodule.c2
-rw-r--r--girepository/girnode.c16
-rw-r--r--girepository/girnode.h2
-rw-r--r--girepository/girparser.c7
-rw-r--r--girepository/gtypelib.c38
-rw-r--r--girepository/gtypelib.h7
-rw-r--r--giscanner/ast.py4
-rw-r--r--giscanner/girwriter.py10
-rw-r--r--giscanner/glibtransformer.py27
-rw-r--r--tests/scanner/BarApp-1.0-expected.gir7
-rw-r--r--tests/scanner/BarApp-1.0-expected.tgir4
-rw-r--r--tests/scanner/annotation-1.0-expected.gir7
-rw-r--r--tests/scanner/annotation-1.0-expected.tgir14
-rw-r--r--tests/scanner/drawable-1.0-expected.gir9
-rw-r--r--tests/scanner/drawable-1.0-expected.tgir6
-rw-r--r--tests/scanner/foo-1.0-expected.gir21
-rw-r--r--tests/scanner/foo-1.0-expected.tgir12
-rw-r--r--tests/scanner/utility-1.0-expected.gir7
-rw-r--r--tests/scanner/utility-1.0-expected.tgir4
-rw-r--r--tools/generate.c13
23 files changed, 211 insertions, 60 deletions
diff --git a/docs/typelib-format.txt b/docs/typelib-format.txt
index a47a9f78..68125cdf 100644
--- a/docs/typelib-format.txt
+++ b/docs/typelib-format.txt
@@ -1,7 +1,11 @@
GObject binary typelib for introspection
-----------------------------------------
-Version 0.8
+Version 0.9
+
+Changes since 0.8:
+- Add class struct concept to ObjectBlob
+- Add is_class_struct bit to StructBlob
Changes since 0.7:
- Add dependencies
@@ -847,7 +851,8 @@ struct StructBlob
guint deprecated : 1;
guint unregistered : 1;
guint alignment : 6;
- guint reserved : 8;
+ guint is_class_struct : 1
+ guint reserved : 7;
guint32 name;
GTypeBlob gtype;
@@ -866,6 +871,9 @@ unregistered:
alignment:
The byte boundary that the struct is aligned to in memory
+
+is_class_struct:
+ Whether this structure is the "class structure" for a GObject
size: The size of the struct in bytes.
@@ -918,7 +926,7 @@ n_values:
values: Describes the enum values.
-ObjectBlob (32 + x bytes)
+ObjectBlob (36 + x bytes)
struct ObjectBlob
{
@@ -931,6 +939,7 @@ struct ObjectBlob
GTypeBlob gtype;
guint16 parent;
+ guint16 class_struct;
guint16 n_interfaces;
guint16 n_fields;
diff --git a/girepository/ginfo.c b/girepository/ginfo.c
index 289717d5..a51c6cb3 100644
--- a/girepository/ginfo.c
+++ b/girepository/ginfo.c
@@ -1178,6 +1178,24 @@ g_struct_info_get_alignment (GIStructInfo *info)
return blob->alignment;
}
+/**
+ * g_struct_info_is_class_struct:
+ * @info: GIStructInfo
+ *
+ * Return true if this structure represents the "class structure" for some
+ * GObject. This function is mainly useful to hide this kind of structure
+ * from public APIs.
+ *
+ */
+gboolean
+g_struct_info_is_class_struct (GIStructInfo *info)
+{
+ GIBaseInfo *base = (GIBaseInfo *)info;
+ StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset];
+
+ return blob->is_class_struct;
+}
+
gint
g_enum_info_get_n_values (GIEnumInfo *info)
{
@@ -1469,6 +1487,25 @@ g_object_info_get_constant (GIObjectInfo *info,
base->typelib, offset);
}
+/**
+ * g_object_info_get_class_struct:
+ * @info: A #GIObjectInfo to query
+ *
+ * Every GObject has two structures; an instance structure and a class
+ * structure. This function returns the metadata for the class structure.
+ */
+GIStructInfo *
+g_object_info_get_class_struct (GIObjectInfo *info)
+{
+ GIBaseInfo *base = (GIBaseInfo *)info;
+ ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
+
+ if (blob->class_struct)
+ return (GIStructInfo *) g_info_from_entry (base->repository,
+ base->typelib, blob->class_struct);
+ else
+ return NULL;
+}
/* GIInterfaceInfo functions */
gint
diff --git a/girepository/girepository.h b/girepository/girepository.h
index 340c7fa4..ac1b279b 100644
--- a/girepository/girepository.h
+++ b/girepository/girepository.h
@@ -412,6 +412,7 @@ GIFunctionInfo * g_struct_info_find_method (GIStructInfo *info,
const gchar *name);
gsize g_struct_info_get_size (GIStructInfo *info);
gsize g_struct_info_get_alignment (GIStructInfo *info);
+gboolean g_struct_info_is_class_struct (GIStructInfo *info);
/* GIRegisteredTypeInfo */
@@ -455,6 +456,7 @@ GIVFuncInfo * g_object_info_get_vfunc (GIObjectInfo *in
gint g_object_info_get_n_constants (GIObjectInfo *info);
GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info,
gint n);
+GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info);
/* GIInterfaceInfo */
diff --git a/girepository/girmodule.c b/girepository/girmodule.c
index 85103bff..63d42cce 100644
--- a/girepository/girmodule.c
+++ b/girepository/girmodule.c
@@ -223,7 +223,7 @@ g_ir_module_build_typelib (GIrModule *module,
header->signature_blob_size = 8;
header->enum_blob_size = 20;
header->struct_blob_size = 24;
- header->object_blob_size = 32;
+ header->object_blob_size = sizeof(ObjectBlob);
header->interface_blob_size = 28;
header->union_blob_size = 32;
diff --git a/girepository/girnode.c b/girepository/girnode.c
index abec606a..cc8aa508 100644
--- a/girepository/girnode.c
+++ b/girepository/girnode.c
@@ -285,7 +285,8 @@ g_ir_node_free (GIrNode *node)
g_free (node->name);
g_free (iface->gtype_name);
g_free (iface->gtype_init);
-
+
+ g_free (iface->class_struct);
g_free (iface->parent);
for (l = iface->interfaces; l; l = l->next)
@@ -431,7 +432,7 @@ g_ir_node_get_size (GIrNode *node)
GIrNodeInterface *iface = (GIrNodeInterface *)node;
n = g_list_length (iface->interfaces);
- size = 32 + 2 * (n + (n % 2));
+ size = sizeof(ObjectBlob) + 2 * (n + (n % 2));
for (l = iface->members; l; l = l->next)
size += g_ir_node_get_size ((GIrNode *)l->data);
@@ -647,9 +648,11 @@ g_ir_node_get_full_size_internal (GIrNode *parent,
GIrNodeInterface *iface = (GIrNodeInterface *)node;
n = g_list_length (iface->interfaces);
- size = 32;
+ size = sizeof(ObjectBlob);
if (iface->parent)
size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
+ if (iface->class_struct)
+ size += ALIGN_VALUE (strlen (iface->class_struct) + 1, 4);
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
if (iface->gtype_init)
@@ -1792,6 +1795,7 @@ g_ir_node_build_typelib (GIrNode *node,
blob->blob_type = BLOB_TYPE_STRUCT;
blob->deprecated = struct_->deprecated;
+ blob->is_class_struct = struct_->is_gclass_struct;
blob->reserved = 0;
blob->name = write_string (node->name, strings, data, offset2);
blob->alignment = struct_->alignment;
@@ -2001,6 +2005,10 @@ g_ir_node_build_typelib (GIrNode *node,
blob->parent = find_entry (module, modules, object->parent);
else
blob->parent = 0;
+ if (object->class_struct)
+ blob->class_struct = find_entry (module, modules, object->class_struct);
+ else
+ blob->class_struct = 0;
blob->n_interfaces = 0;
blob->n_fields = 0;
@@ -2010,7 +2018,7 @@ g_ir_node_build_typelib (GIrNode *node,
blob->n_vfuncs = 0;
blob->n_constants = 0;
- *offset += 32;
+ *offset += sizeof(ObjectBlob);
for (l = object->interfaces; l; l = l->next)
{
blob->n_interfaces++;
diff --git a/girepository/girnode.h b/girepository/girnode.h
index a1b8f0dc..fad67991 100644
--- a/girepository/girnode.h
+++ b/girepository/girnode.h
@@ -228,6 +228,7 @@ struct _GIrNodeInterface
gchar *gtype_init;
gchar *parent;
+ gchar *class_struct; /* Only applies to classes */
GList *interfaces;
GList *prerequisites;
@@ -292,6 +293,7 @@ struct _GIrNodeStruct
gboolean deprecated;
gboolean disguised;
+ gboolean is_gclass_struct;
gchar *gtype_name;
gchar *gtype_init;
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 3e1f9dfe..eb3c11d3 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -1530,6 +1530,7 @@ start_class (GMarkupParseContext *context,
{
const gchar *name;
const gchar *parent;
+ const gchar *class_struct;
const gchar *typename;
const gchar *typeinit;
const gchar *deprecated;
@@ -1537,6 +1538,7 @@ start_class (GMarkupParseContext *context,
name = find_attribute ("name", attribute_names, attribute_values);
parent = find_attribute ("parent", attribute_names, attribute_values);
+ class_struct = find_attribute ("glib:class-struct", attribute_names, attribute_values);
typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
@@ -1557,6 +1559,7 @@ start_class (GMarkupParseContext *context,
iface->gtype_name = g_strdup (typename);
iface->gtype_init = g_strdup (typeinit);
iface->parent = g_strdup (parent);
+ iface->class_struct = g_strdup (class_struct);
if (deprecated)
iface->deprecated = TRUE;
else
@@ -2122,6 +2125,7 @@ start_struct (GMarkupParseContext *context,
const gchar *disguised;
const gchar *gtype_name;
const gchar *gtype_init;
+ const gchar *gclass_struct;
GIrNodeStruct *struct_;
name = find_attribute ("name", attribute_names, attribute_values);
@@ -2129,6 +2133,7 @@ start_struct (GMarkupParseContext *context,
disguised = find_attribute ("disguised", attribute_names, attribute_values);
gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
+ gclass_struct = find_attribute ("glib:is-class-struct-for", attribute_names, attribute_values);
if (name == NULL && ctx->node_stack == NULL)
{
@@ -2156,6 +2161,8 @@ start_struct (GMarkupParseContext *context,
if (disguised && strcmp (disguised, "1") == 0)
struct_->disguised = TRUE;
+
+ struct_->is_gclass_struct = gclass_struct != NULL;
struct_->gtype_name = g_strdup (gtype_name);
struct_->gtype_init = g_strdup (gtype_init);
diff --git a/girepository/gtypelib.c b/girepository/gtypelib.c
index d7b09f21..e3b1214e 100644
--- a/girepository/gtypelib.c
+++ b/girepository/gtypelib.c
@@ -181,7 +181,7 @@ g_typelib_check_sanity (void)
CHECK_SIZE (PropertyBlob, 12);
CHECK_SIZE (SignalBlob, 12);
CHECK_SIZE (VFuncBlob, 16);
- CHECK_SIZE (ObjectBlob, 32);
+ CHECK_SIZE (ObjectBlob, 36);
CHECK_SIZE (InterfaceBlob, 28);
CHECK_SIZE (ConstantBlob, 20);
CHECK_SIZE (AnnotationBlob, 12);
@@ -313,6 +313,15 @@ validate_header (ValidateContext *ctx,
"Typelib size mismatch");
return FALSE;
}
+
+ /* This is a sanity check for a specific typelib; it
+ * prevents us from loading an incompatible typelib. It's OK to change
+ * these hardcoded constants to sizeof() as you see fit.
+ *
+ * We want to keep the hardcoded checks in g_typelib_check_sanity to
+ * protect against inadvertent or buggy changes to the typelib format
+ * itself.
+ */
if (header->entry_blob_size != 12 ||
header->function_blob_size != 20 ||
@@ -329,7 +338,7 @@ validate_header (ValidateContext *ctx,
header->signature_blob_size != 8 ||
header->enum_blob_size != 20 ||
header->struct_blob_size != 24 ||
- header->object_blob_size != 32 ||
+ header->object_blob_size != sizeof(ObjectBlob) ||
header->interface_blob_size != 28 ||
header->union_blob_size != 32)
{
@@ -1435,7 +1444,9 @@ validate_object_blob (ValidateContext *ctx,
{
DirEntry *entry;
- entry = g_typelib_get_dir_entry (typelib, blob->parent);
+ entry = get_dir_entry_checked (typelib, blob->parent, error);
+ if (!entry)
+ return FALSE;
if (entry->blob_type != BLOB_TYPE_OBJECT &&
(entry->local || entry->blob_type != 0))
{
@@ -1447,6 +1458,23 @@ validate_object_blob (ValidateContext *ctx,
}
}
+ if (blob->class_struct != 0)
+ {
+ DirEntry *entry;
+
+ entry = get_dir_entry_checked (typelib, blob->class_struct, error);
+ if (!entry)
+ return FALSE;
+ if (entry->blob_type != BLOB_TYPE_STRUCT && entry->local)
+ {
+ g_set_error (error,
+ G_TYPELIB_ERROR,
+ G_TYPELIB_ERROR_INVALID_BLOB,
+ "Class struct invalid type or not local");
+ return FALSE;
+ }
+ }
+
if (typelib->len < offset + sizeof (ObjectBlob) +
(blob->n_interfaces + blob->n_interfaces % 2) * 2 +
blob->n_fields * sizeof (FieldBlob) +
@@ -1481,7 +1509,9 @@ validate_object_blob (ValidateContext *ctx,
return FALSE;
}
- entry = g_typelib_get_dir_entry (typelib, iface);
+ entry = get_dir_entry_checked (typelib, iface, error);
+ if (!entry)
+ return FALSE;
if (entry->blob_type != BLOB_TYPE_INTERFACE &&
(entry->local || entry->blob_type != 0))
diff --git a/girepository/gtypelib.h b/girepository/gtypelib.h
index a68d0080..ee7442f3 100644
--- a/girepository/gtypelib.h
+++ b/girepository/gtypelib.h
@@ -306,8 +306,9 @@ typedef struct
guint16 deprecated : 1;
guint16 unregistered : 1;
- guint16 alignment : 6;
- guint16 reserved : 8;
+ guint16 is_class_struct : 1;
+ guint16 alignment : 6;
+ guint16 reserved : 7;
guint32 name;
@@ -438,6 +439,8 @@ typedef struct
guint32 gtype_init;
guint16 parent;
+ guint16 class_struct;
+ guint16 reserved2;
guint16 n_interfaces;
guint16 n_fields;
diff --git a/giscanner/ast.py b/giscanner/ast.py
index 8343009b..14cd1a60 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -365,6 +365,9 @@ class Record(Node):
self.doc = None
self.constructors = []
self.methods = []
+ # If true, this record defines the FooClass C structure
+ # for some Foo GObject
+ self.is_gobject_struct_for = False
# BW compat, remove
Struct = Record
@@ -404,6 +407,7 @@ class Class(Node):
Node.__init__(self, name)
self.ctype = name
self.parent = parent
+ self.class_struct = None
self.is_abstract = is_abstract
self.methods = []
self.static_methods = []
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index cd19e989..657063e6 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -298,6 +298,9 @@ and/or use gtk-doc annotations. ''')
attrs.append(('glib:type-name', node.type_name))
if node.get_type:
attrs.append(('glib:get-type', node.get_type))
+ if isinstance(node, GLibObject):
+ if node.class_struct:
+ attrs.append(('glib:class-struct', node.class_struct.name))
with self.tagcontext(tag_name, attrs):
if isinstance(node, GLibObject):
for iface in node.interfaces:
@@ -365,14 +368,17 @@ and/or use gtk-doc annotations. ''')
return [('glib:type-name', boxed.type_name),
('glib:get-type', boxed.get_type)]
- def _write_record(self, record):
- attrs = []
+ def _write_record(self, record, extra_attrs=[]):
+ attrs = list(extra_attrs)
if record.name is not None:
attrs.append(('name', record.name))
if record.symbol is not None: # the record might be anonymous
attrs.append(('c:type', record.symbol))
if record.disguised:
attrs.append(('disguised', '1'))
+ if record.is_gobject_struct_for:
+ attrs.append(('glib:is-class-struct-for',
+ record.is_gobject_struct_for))
if record.doc:
attrs.append(('doc', record.doc))
self._append_version(record, attrs)
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index 6b6a2d38..f05ce65e 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -545,9 +545,15 @@ class GLibTransformer(object):
if name == maybe_class.name:
return
- if self._arg_is_failed(maybe_class):
- print "WARNING: deleting no-type %r" % (maybe_class.name, )
- del self._names.names[maybe_class.name]
+ class_struct = maybe_class
+ if self._arg_is_failed(class_struct):
+ print "WARNING: deleting no-type %r" % (class_struct.name, )
+ del self._names.names[class_struct.name]
+ return
+
+ pair_class = self._get_attribute(name)
+ if (not pair_class or
+ not isinstance(pair_class, (GLibObject, GLibInterface))):
return
# Object class fields are assumed to be read-only
@@ -555,20 +561,13 @@ class GLibTransformer(object):
for field in maybe_class.fields:
if isinstance(field, Field):
field.writable = False
-
- name = self._resolve_type_name(name)
- resolved = self._transformer.remove_prefix(name)
- pair_class = self._get_attribute(resolved)
- if pair_class and isinstance(pair_class, GLibInterface):
+ if isinstance(pair_class, GLibInterface):
for field in maybe_class.fields[1:]:
pair_class.fields.append(field)
return
- name = self._transformer.remove_prefix(maybe_class.name)
- pair_class = self._get_attribute(name)
- if pair_class and isinstance(pair_class,
- (GLibObject, GLibInterface)):
-
- del self._names.names[maybe_class.name]
+ elif isinstance(pair_class, GLibObject):
+ pair_class.class_struct = class_struct
+ class_struct.is_gobject_struct_for = name
# Introspection
diff --git a/tests/scanner/BarApp-1.0-expected.gir b/tests/scanner/BarApp-1.0-expected.gir
index 2ba6b91d..209f0622 100644
--- a/tests/scanner/BarApp-1.0-expected.gir
+++ b/tests/scanner/BarApp-1.0-expected.gir
@@ -13,12 +13,15 @@ and/or use gtk-doc annotations. -->
c:type="BarBaz"
parent="GObject.Object"
glib:type-name="BarBaz"
- glib:get-type="bar_baz_get_type">
+ glib:get-type="bar_baz_get_type"
+ glib:class-struct="BazClass">
<field name="parent_instance">
<type name="GObject.Object" c:type="GObject"/>
</field>
</class>
- <record name="BazClass" c:type="BarBazClass">
+ <record name="BazClass"
+ c:type="BarBazClass"
+ glib:is-class-struct-for="Baz">
<field name="parent_class">
<type name="GObject.ObjectClass" c:type="GObjectClass"/>
</field>
diff --git a/tests/scanner/BarApp-1.0-expected.tgir b/tests/scanner/BarApp-1.0-expected.tgir
index 3de9dad1..4a99be5d 100644
--- a/tests/scanner/BarApp-1.0-expected.tgir
+++ b/tests/scanner/BarApp-1.0-expected.tgir
@@ -6,12 +6,12 @@
<include name="GObject" version="2.0"/>
<include name="GLib" version="2.0"/>
<namespace name="BarApp" version="1.0" shared-library="">
- <class name="Baz" parent="GObject.Object" glib:type-name="BarBaz" glib:get-type="bar_baz_get_type">
+ <class name="Baz" parent="GObject.Object" glib:class-struct="BazClass" glib:type-name="BarBaz" glib:get-type="bar_baz_get_type">
<field name="parent_instance">
<type name="GObject.Object"/>
</field>
</class>
- <record name="BazClass">
+ <record name="BazClass" glib:is-class-struct="1">
<field name="parent_class">
<type name="GObject.ObjectClass"/>
</field>
diff --git a/tests/scanner/annotation-1.0-expected.gir b/tests/scanner/annotation-1.0-expected.gir
index ba4d991a..11ee31e1 100644
--- a/tests/scanner/annotation-1.0-expected.gir
+++ b/tests/scanner/annotation-1.0-expected.gir
@@ -43,7 +43,8 @@ and/or use gtk-doc annotations. -->
doc="This is an object used to test annotations."
parent="GObject.Object"
glib:type-name="AnnotationObject"
- glib:get-type="annotation_object_get_type">
+ glib:get-type="annotation_object_get_type"
+ glib:class-struct="ObjectClass">
<method name="method" c:identifier="annotation_object_method">
<return-value transfer-ownership="none">
<type name="int" c:type="gint"/>
@@ -452,7 +453,9 @@ known by GObject as it&apos;s only marked as G_TYPE_POINTER">
</parameters>
</glib:signal>
</class>
- <record name="ObjectClass" c:type="AnnotationObjectClass">
+ <record name="ObjectClass"
+ c:type="AnnotationObjectClass"
+ glib:is-class-struct-for="Object">
<field name="parent_class">
<type name="GObject.ObjectClass" c:type="GObjectClass"/>
</field>
diff --git a/tests/scanner/annotation-1.0-expected.tgir b/tests/scanner/annotation-1.0-expected.tgir
index 756c81c5..bb85894e 100644
--- a/tests/scanner/annotation-1.0-expected.tgir
+++ b/tests/scanner/annotation-1.0-expected.tgir
@@ -31,7 +31,7 @@
</parameter>
</parameters>
</callback>
- <class name="Object" parent="GObject.Object" glib:type-name="AnnotationObject" glib:get-type="annotation_object_get_type">
+ <class name="Object" parent="GObject.Object" glib:class-struct="ObjectClass" glib:type-name="AnnotationObject" glib:get-type="annotation_object_get_type">
<field name="parent_instance">
<type name="GObject.Object"/>
</field>
@@ -148,6 +148,16 @@
</type>
</return-value>
</method>
+ <method name="with_voidp" c:identifier="annotation_object_with_voidp">
+ <return-value transfer-ownership="none">
+ <type name="none"/>
+ </return-value>
+ <parameters>
+ <parameter name="data" transfer-ownership="none">
+ <type name="any"/>
+ </parameter>
+ </parameters>
+ </method>
<method name="get_objects" c:identifier="annotation_object_get_objects">
<return-value transfer-ownership="container">
<type name="GLib.SList">
@@ -323,7 +333,7 @@
</parameters>
</glib:signal>
</class>
- <record name="ObjectClass">
+ <record name="ObjectClass" glib:is-class-struct="1">
<field name="parent_class">
<type name="GObject.ObjectClass"/>
</field>
diff --git a/tests/scanner/drawable-1.0-expected.gir b/tests/scanner/drawable-1.0-expected.gir
index 79eba8b1..738296ff 100644
--- a/tests/scanner/drawable-1.0-expected.gir
+++ b/tests/scanner/drawable-1.0-expected.gir
@@ -15,7 +15,8 @@ and/or use gtk-doc annotations. -->
parent="GObject.Object"
abstract="1"
glib:type-name="TestDrawable"
- glib:get-type="test_drawable_get_type">
+ glib:get-type="test_drawable_get_type"
+ glib:class-struct="TestDrawableClass">
<method name="do_foo" c:identifier="test_drawable_do_foo">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
@@ -68,13 +69,15 @@ and/or use gtk-doc annotations. -->
<type name="GObject.Object" c:type="GObject"/>
</field>
</class>
- <record name="TestDrawableClass" c:type="TestDrawableClass">
+ <record name="TestDrawableClass"
+ c:type="TestDrawableClass"
+ glib:is-class-struct-for="TestDrawable">
<field name="parent_class">
<type name="GObject.ObjectClass" c:type="GObjectClass"/>
</field>
</record>
<record name="TestPixmapObjectClass" c:type="_TestPixmapObjectClass">
- <field name="parent_class">
+ <field name="parent_class" writable="1">
<type name="TestDrawableClass" c:type="TestDrawableClass"/>
</field>
</record>
diff --git a/tests/scanner/drawable-1.0-expected.tgir b/tests/scanner/drawable-1.0-expected.tgir
index 0a317140..612022b7 100644
--- a/tests/scanner/drawable-1.0-expected.tgir
+++ b/tests/scanner/drawable-1.0-expected.tgir
@@ -7,7 +7,7 @@
<include name="GObject" version="2.0"/>
<include name="GLib" version="2.0"/>
<namespace name="drawable" version="1.0" shared-library="drawable">
- <class name="TestDrawable" parent="GObject.Object" abstract="1" glib:type-name="TestDrawable" glib:get-type="test_drawable_get_type">
+ <class name="TestDrawable" parent="GObject.Object" glib:class-struct="TestDrawableClass" abstract="1" glib:type-name="TestDrawable" glib:get-type="test_drawable_get_type">
<field name="parent_instance">
<type name="GObject.Object"/>
</field>
@@ -58,13 +58,13 @@
</parameters>
</method>
</class>
- <record name="TestDrawableClass">
+ <record name="TestDrawableClass" glib:is-class-struct="1">
<field name="parent_class">
<type name="GObject.ObjectClass"/>
</field>
</record>
<record name="TestPixmapObjectClass">
- <field name="parent_class">
+ <field name="parent_class" writable="1">
<type name="TestDrawableClass"/>
</field>
</record>
diff --git a/tests/scanner/foo-1.0-expected.gir b/tests/scanner/foo-1.0-expected.gir
index 2d69099b..7bc20095 100644
--- a/tests/scanner/foo-1.0-expected.gir
+++ b/tests/scanner/foo-1.0-expected.gir
@@ -83,7 +83,8 @@ and/or use gtk-doc annotations. -->
c:type="FooObject"
parent="GObject.Object"
glib:type-name="FooObject"
- glib:get-type="foo_object_get_type">
+ glib:get-type="foo_object_get_type"
+ glib:class-struct="ObjectClass">
<implements name="Interface"/>
<constructor name="new" c:identifier="foo_object_new">
<return-value transfer-ownership="full">
@@ -200,7 +201,9 @@ and/or use gtk-doc annotations. -->
</parameters>
</glib:signal>
</class>
- <record name="ObjectClass" c:type="FooObjectClass">
+ <record name="ObjectClass"
+ c:type="FooObjectClass"
+ glib:is-class-struct-for="Object">
<field name="parent_class">
<type name="GObject.ObjectClass" c:type="GObjectClass"/>
</field>
@@ -223,7 +226,8 @@ and/or use gtk-doc annotations. -->
parent="Object"
abstract="1"
glib:type-name="FooSubobject"
- glib:get-type="foo_subobject_get_type">
+ glib:get-type="foo_subobject_get_type"
+ glib:class-struct="SubobjectClass">
<implements name="Interface"/>
<constructor name="new" c:identifier="foo_subobject_new">
<return-value transfer-ownership="full">
@@ -234,7 +238,9 @@ and/or use gtk-doc annotations. -->
<type name="Object" c:type="FooObject"/>
</field>
</class>
- <record name="SubobjectClass" c:type="FooSubobjectClass">
+ <record name="SubobjectClass"
+ c:type="FooSubobjectClass"
+ glib:is-class-struct-for="Subobject">
<field name="parent_class">
<type name="ObjectClass" c:type="FooObjectClass"/>
</field>
@@ -243,7 +249,8 @@ and/or use gtk-doc annotations. -->
c:type="FooBuffer"
parent="GObject.Object"
glib:type-name="FooBuffer"
- glib:get-type="foo_buffer_get_type">
+ glib:get-type="foo_buffer_get_type"
+ glib:class-struct="BufferClass">
<implements name="Interface"/>
<method name="some_method" c:identifier="foo_buffer_some_method">
<return-value transfer-ownership="none">
@@ -251,7 +258,9 @@ and/or use gtk-doc annotations. -->
</return-value>
</method>
</class>
- <record name="BufferClass" c:type="FooBufferClass">
+ <record name="BufferClass"
+ c:type="FooBufferClass"
+ glib:is-class-struct-for="Buffer">
</record>
<function name="init" c:identifier="foo_init">
<return-value transfer-ownership="none">
diff --git a/tests/scanner/foo-1.0-expected.tgir b/tests/scanner/foo-1.0-expected.tgir
index 80e6fc50..3f57f3c0 100644
--- a/tests/scanner/foo-1.0-expected.tgir
+++ b/tests/scanner/foo-1.0-expected.tgir
@@ -26,7 +26,7 @@
<type name="GObject.TypeInterface"/>
</field>
</record>
- <class name="Object" parent="GObject.Object" glib:type-name="FooObject" glib:get-type="foo_object_get_type">
+ <class name="Object" parent="GObject.Object" glib:class-struct="ObjectClass" glib:type-name="FooObject" glib:get-type="foo_object_get_type">
<implements name="Interface"/>
<field name="parent_instance">
<type name="GObject.Object"/>
@@ -131,12 +131,12 @@
</parameters>
</glib:signal>
</class>
- <record name="ObjectClass">
+ <record name="ObjectClass" glib:is-class-struct="1">
<field name="parent_class">
<type name="GObject.ObjectClass"/>
</field>
</record>
- <class name="Subobject" parent="Object" abstract="1" glib:type-name="FooSubobject" glib:get-type="foo_subobject_get_type">
+ <class name="Subobject" parent="Object" glib:class-struct="SubobjectClass" abstract="1" glib:type-name="FooSubobject" glib:get-type="foo_subobject_get_type">
<implements name="Interface"/>
<field name="parent_instance">
<type name="Object"/>
@@ -147,12 +147,12 @@
</return-value>
</constructor>
</class>
- <record name="SubobjectClass">
+ <record name="SubobjectClass" glib:is-class-struct="1">
<field name="parent_class">
<type name="ObjectClass"/>
</field>
</record>
- <class name="Buffer" parent="GObject.Object" glib:type-name="FooBuffer" glib:get-type="foo_buffer_get_type">
+ <class name="Buffer" parent="GObject.Object" glib:class-struct="BufferClass" glib:type-name="FooBuffer" glib:get-type="foo_buffer_get_type">
<implements name="Interface"/>
<method name="some_method" c:identifier="foo_buffer_some_method">
<return-value transfer-ownership="none">
@@ -160,7 +160,7 @@
</return-value>
</method>
</class>
- <record name="BufferClass"/>
+ <record name="BufferClass" glib:is-class-struct="1"/>
<function name="init" c:identifier="foo_init">
<return-value transfer-ownership="none">
<type name="int"/>
diff --git a/tests/scanner/utility-1.0-expected.gir b/tests/scanner/utility-1.0-expected.gir
index bb5a5e46..c04d984d 100644
--- a/tests/scanner/utility-1.0-expected.gir
+++ b/tests/scanner/utility-1.0-expected.gir
@@ -14,7 +14,8 @@ and/or use gtk-doc annotations. -->
c:type="UtilityObject"
parent="GObject.Object"
glib:type-name="UtilityObject"
- glib:get-type="utility_object_get_type">
+ glib:get-type="utility_object_get_type"
+ glib:class-struct="ObjectClass">
<method name="watch_dir" c:identifier="utility_object_watch_dir">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
@@ -41,7 +42,9 @@ and/or use gtk-doc annotations. -->
<type name="GObject.Object" c:type="GObject"/>
</field>
</class>
- <record name="ObjectClass" c:type="UtilityObjectClass">
+ <record name="ObjectClass"
+ c:type="UtilityObjectClass"
+ glib:is-class-struct-for="Object">
<field name="parent_class">
<type name="GObject.ObjectClass" c:type="GObjectClass"/>
</field>
diff --git a/tests/scanner/utility-1.0-expected.tgir b/tests/scanner/utility-1.0-expected.tgir
index 08ba692c..e55fc80e 100644
--- a/tests/scanner/utility-1.0-expected.tgir
+++ b/tests/scanner/utility-1.0-expected.tgir
@@ -6,7 +6,7 @@
<include name="GObject" version="2.0"/>
<include name="GLib" version="2.0"/>
<namespace name="utility" version="1.0" shared-library="utility">
- <class name="Object" parent="GObject.Object" glib:type-name="UtilityObject" glib:get-type="utility_object_get_type">
+ <class name="Object" parent="GObject.Object" glib:class-struct="ObjectClass" glib:type-name="UtilityObject" glib:get-type="utility_object_get_type">
<field name="parent_instance">
<type name="GObject.Object"/>
</field>
@@ -30,7 +30,7 @@
</parameters>
</method>
</class>
- <record name="ObjectClass">
+ <record name="ObjectClass" glib:is-class-struct="1">
<field name="parent_class">
<type name="GObject.ObjectClass"/>
</field>
diff --git a/tools/generate.c b/tools/generate.c
index dcc36faf..8b4185fc 100644
--- a/tools/generate.c
+++ b/tools/generate.c
@@ -566,6 +566,7 @@ write_struct_info (const gchar *namespace,
const gchar *type_name;
const gchar *type_init;
gboolean deprecated;
+ gboolean is_class_struct;
gint i;
int n_elts;
@@ -591,6 +592,10 @@ write_struct_info (const gchar *namespace,
if (deprecated)
xml_printf (file, " deprecated=\"1\"");
+
+ is_class_struct = g_struct_info_is_class_struct (info);
+ if (is_class_struct)
+ xml_printf (file, " glib:is-class-struct=\"1\"");
n_elts = g_struct_info_get_n_fields (info) + g_struct_info_get_n_methods (info);
if (n_elts > 0)
@@ -904,6 +909,7 @@ write_object_info (const gchar *namespace,
gboolean deprecated;
gboolean is_abstract;
GIObjectInfo *pnode;
+ GIStructInfo *class_struct;
gint i;
name = g_base_info_get_name ((GIBaseInfo *)info);
@@ -921,6 +927,13 @@ write_object_info (const gchar *namespace,
write_type_name_attribute (namespace, (GIBaseInfo *)pnode, "parent", file);
g_base_info_unref ((GIBaseInfo *)pnode);
}
+
+ class_struct = g_object_info_get_class_struct (info);
+ if (class_struct)
+ {
+ write_type_name_attribute (namespace, (GIBaseInfo*) class_struct, "glib:class-struct", file);
+ g_base_info_unref ((GIBaseInfo*)class_struct);
+ }
if (is_abstract)
xml_printf (file, " abstract=\"1\"");