diff options
author | Colin Walters <walters@src.gnome.org> | 2009-02-06 18:37:13 +0000 |
---|---|---|
committer | Colin Walters <walters@src.gnome.org> | 2009-02-06 18:37:13 +0000 |
commit | d1bf6a23c6fa14e918aa93e346237b1c832fb2ea (patch) | |
tree | 715bf149bfa948eed8a1da945e2c0984ea81df73 | |
parent | 3ae9127e53032065df14be8539aba0cf50835386 (diff) | |
download | gobject-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.txt | 15 | ||||
-rw-r--r-- | girepository/ginfo.c | 37 | ||||
-rw-r--r-- | girepository/girepository.h | 2 | ||||
-rw-r--r-- | girepository/girmodule.c | 2 | ||||
-rw-r--r-- | girepository/girnode.c | 16 | ||||
-rw-r--r-- | girepository/girnode.h | 2 | ||||
-rw-r--r-- | girepository/girparser.c | 7 | ||||
-rw-r--r-- | girepository/gtypelib.c | 38 | ||||
-rw-r--r-- | girepository/gtypelib.h | 7 | ||||
-rw-r--r-- | giscanner/ast.py | 4 | ||||
-rw-r--r-- | giscanner/girwriter.py | 10 | ||||
-rw-r--r-- | giscanner/glibtransformer.py | 27 | ||||
-rw-r--r-- | tests/scanner/BarApp-1.0-expected.gir | 7 | ||||
-rw-r--r-- | tests/scanner/BarApp-1.0-expected.tgir | 4 | ||||
-rw-r--r-- | tests/scanner/annotation-1.0-expected.gir | 7 | ||||
-rw-r--r-- | tests/scanner/annotation-1.0-expected.tgir | 14 | ||||
-rw-r--r-- | tests/scanner/drawable-1.0-expected.gir | 9 | ||||
-rw-r--r-- | tests/scanner/drawable-1.0-expected.tgir | 6 | ||||
-rw-r--r-- | tests/scanner/foo-1.0-expected.gir | 21 | ||||
-rw-r--r-- | tests/scanner/foo-1.0-expected.tgir | 12 | ||||
-rw-r--r-- | tests/scanner/utility-1.0-expected.gir | 7 | ||||
-rw-r--r-- | tests/scanner/utility-1.0-expected.tgir | 4 | ||||
-rw-r--r-- | tools/generate.c | 13 |
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'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\""); |