gobject-introspection r1088 - in trunk: docs girepository giscanner tests/scanner tools



Author: walters
Date: Fri Feb  6 18:37:13 2009
New Revision: 1088
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=1088&view=rev

Log:
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.

Modified:
   trunk/docs/typelib-format.txt
   trunk/girepository/ginfo.c
   trunk/girepository/girepository.h
   trunk/girepository/girmodule.c
   trunk/girepository/girnode.c
   trunk/girepository/girnode.h
   trunk/girepository/girparser.c
   trunk/girepository/gtypelib.c
   trunk/girepository/gtypelib.h
   trunk/giscanner/ast.py
   trunk/giscanner/girwriter.py
   trunk/giscanner/glibtransformer.py
   trunk/tests/scanner/BarApp-1.0-expected.gir
   trunk/tests/scanner/BarApp-1.0-expected.tgir
   trunk/tests/scanner/annotation-1.0-expected.gir
   trunk/tests/scanner/annotation-1.0-expected.tgir
   trunk/tests/scanner/drawable-1.0-expected.gir
   trunk/tests/scanner/drawable-1.0-expected.tgir
   trunk/tests/scanner/foo-1.0-expected.gir
   trunk/tests/scanner/foo-1.0-expected.tgir
   trunk/tests/scanner/utility-1.0-expected.gir
   trunk/tests/scanner/utility-1.0-expected.tgir
   trunk/tools/generate.c

Modified: trunk/docs/typelib-format.txt
==============================================================================
--- trunk/docs/typelib-format.txt	(original)
+++ trunk/docs/typelib-format.txt	Fri Feb  6 18:37:13 2009
@@ -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 @@
   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 @@
 
 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 @@
 values:   Describes the enum values. 
 
 
-ObjectBlob (32 + x bytes)
+ObjectBlob (36 + x bytes)
 
 struct ObjectBlob
 {
@@ -931,6 +939,7 @@
   GTypeBlob gtype;
 
   guint16 parent;
+  guint16 class_struct;
 
   guint16 n_interfaces;
   guint16 n_fields;

Modified: trunk/girepository/ginfo.c
==============================================================================
--- trunk/girepository/ginfo.c	(original)
+++ trunk/girepository/ginfo.c	Fri Feb  6 18:37:13 2009
@@ -1178,6 +1178,24 @@
   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 @@
 					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

Modified: trunk/girepository/girepository.h
==============================================================================
--- trunk/girepository/girepository.h	(original)
+++ trunk/girepository/girepository.h	Fri Feb  6 18:37:13 2009
@@ -412,6 +412,7 @@
 						    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 @@
 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 */

Modified: trunk/girepository/girmodule.c
==============================================================================
--- trunk/girepository/girmodule.c	(original)
+++ trunk/girepository/girmodule.c	Fri Feb  6 18:37:13 2009
@@ -223,7 +223,7 @@
   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;
 

Modified: trunk/girepository/girnode.c
==============================================================================
--- trunk/girepository/girnode.c	(original)
+++ trunk/girepository/girnode.c	Fri Feb  6 18:37:13 2009
@@ -285,7 +285,8 @@
 	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 @@
 	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 @@
 	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 @@
 	
 	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 @@
 	  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 @@
 	blob->n_vfuncs = 0;
 	blob->n_constants = 0;
 	
-	*offset += 32;
+	*offset += sizeof(ObjectBlob);
 	for (l = object->interfaces; l; l = l->next)
 	  {
 	    blob->n_interfaces++;

Modified: trunk/girepository/girnode.h
==============================================================================
--- trunk/girepository/girnode.h	(original)
+++ trunk/girepository/girnode.h	Fri Feb  6 18:37:13 2009
@@ -228,6 +228,7 @@
   gchar *gtype_init;
 
   gchar *parent;
+  gchar *class_struct; /* Only applies to classes */
   
   GList *interfaces;
   GList *prerequisites;
@@ -292,6 +293,7 @@
 
   gboolean deprecated;
   gboolean disguised;
+  gboolean is_gclass_struct;
 
   gchar *gtype_name;
   gchar *gtype_init;

Modified: trunk/girepository/girparser.c
==============================================================================
--- trunk/girepository/girparser.c	(original)
+++ trunk/girepository/girparser.c	Fri Feb  6 18:37:13 2009
@@ -1530,6 +1530,7 @@
     {
       const gchar *name;
       const gchar *parent;
+      const gchar *class_struct;      
       const gchar *typename;
       const gchar *typeinit;
       const gchar *deprecated;
@@ -1537,6 +1538,7 @@
       
       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 @@
 	  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 @@
       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 @@
       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 @@
 
       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);

Modified: trunk/girepository/gtypelib.c
==============================================================================
--- trunk/girepository/gtypelib.c	(original)
+++ trunk/girepository/gtypelib.c	Fri Feb  6 18:37:13 2009
@@ -181,7 +181,7 @@
   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 @@
 		   "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 @@
       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 @@
     {
       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 @@
 	}
     }
   
+  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 @@
 	  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))

Modified: trunk/girepository/gtypelib.h
==============================================================================
--- trunk/girepository/gtypelib.h	(original)
+++ trunk/girepository/gtypelib.h	Fri Feb  6 18:37:13 2009
@@ -306,8 +306,9 @@
 
   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 @@
   guint32   gtype_init;
 
   guint16   parent;
+  guint16   class_struct;
+  guint16   reserved2;
 
   guint16   n_interfaces;
   guint16   n_fields;

Modified: trunk/giscanner/ast.py
==============================================================================
--- trunk/giscanner/ast.py	(original)
+++ trunk/giscanner/ast.py	Fri Feb  6 18:37:13 2009
@@ -365,6 +365,9 @@
         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 @@
         Node.__init__(self, name)
         self.ctype = name
         self.parent = parent
+        self.class_struct = None
         self.is_abstract = is_abstract
         self.methods = []
         self.static_methods = []

Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py	(original)
+++ trunk/giscanner/girwriter.py	Fri Feb  6 18:37:13 2009
@@ -298,6 +298,9 @@
             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 @@
         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)

Modified: trunk/giscanner/glibtransformer.py
==============================================================================
--- trunk/giscanner/glibtransformer.py	(original)
+++ trunk/giscanner/glibtransformer.py	Fri Feb  6 18:37:13 2009
@@ -545,9 +545,15 @@
         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 @@
         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
 

Modified: trunk/tests/scanner/BarApp-1.0-expected.gir
==============================================================================
--- trunk/tests/scanner/BarApp-1.0-expected.gir	(original)
+++ trunk/tests/scanner/BarApp-1.0-expected.gir	Fri Feb  6 18:37:13 2009
@@ -13,12 +13,15 @@
            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>

Modified: trunk/tests/scanner/BarApp-1.0-expected.tgir
==============================================================================
--- trunk/tests/scanner/BarApp-1.0-expected.tgir	(original)
+++ trunk/tests/scanner/BarApp-1.0-expected.tgir	Fri Feb  6 18:37:13 2009
@@ -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>

Modified: trunk/tests/scanner/annotation-1.0-expected.gir
==============================================================================
--- trunk/tests/scanner/annotation-1.0-expected.gir	(original)
+++ trunk/tests/scanner/annotation-1.0-expected.gir	Fri Feb  6 18:37:13 2009
@@ -43,7 +43,8 @@
            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 @@
         </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>

Modified: trunk/tests/scanner/annotation-1.0-expected.tgir
==============================================================================
--- trunk/tests/scanner/annotation-1.0-expected.tgir	(original)
+++ trunk/tests/scanner/annotation-1.0-expected.tgir	Fri Feb  6 18:37:13 2009
@@ -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>

Modified: trunk/tests/scanner/drawable-1.0-expected.gir
==============================================================================
--- trunk/tests/scanner/drawable-1.0-expected.gir	(original)
+++ trunk/tests/scanner/drawable-1.0-expected.gir	Fri Feb  6 18:37:13 2009
@@ -15,7 +15,8 @@
            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 @@
         <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>

Modified: trunk/tests/scanner/drawable-1.0-expected.tgir
==============================================================================
--- trunk/tests/scanner/drawable-1.0-expected.tgir	(original)
+++ trunk/tests/scanner/drawable-1.0-expected.tgir	Fri Feb  6 18:37:13 2009
@@ -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>

Modified: trunk/tests/scanner/foo-1.0-expected.gir
==============================================================================
--- trunk/tests/scanner/foo-1.0-expected.gir	(original)
+++ trunk/tests/scanner/foo-1.0-expected.gir	Fri Feb  6 18:37:13 2009
@@ -83,7 +83,8 @@
            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 @@
         </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 @@
            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 @@
         <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 @@
            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 @@
         </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">

Modified: trunk/tests/scanner/foo-1.0-expected.tgir
==============================================================================
--- trunk/tests/scanner/foo-1.0-expected.tgir	(original)
+++ trunk/tests/scanner/foo-1.0-expected.tgir	Fri Feb  6 18:37:13 2009
@@ -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"/>

Modified: trunk/tests/scanner/utility-1.0-expected.gir
==============================================================================
--- trunk/tests/scanner/utility-1.0-expected.gir	(original)
+++ trunk/tests/scanner/utility-1.0-expected.gir	Fri Feb  6 18:37:13 2009
@@ -14,7 +14,8 @@
            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 @@
         <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>

Modified: trunk/tests/scanner/utility-1.0-expected.tgir
==============================================================================
--- trunk/tests/scanner/utility-1.0-expected.tgir	(original)
+++ trunk/tests/scanner/utility-1.0-expected.tgir	Fri Feb  6 18:37:13 2009
@@ -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>

Modified: trunk/tools/generate.c
==============================================================================
--- trunk/tools/generate.c	(original)
+++ trunk/tools/generate.c	Fri Feb  6 18:37:13 2009
@@ -566,6 +566,7 @@
   const gchar *type_name;
   const gchar *type_init;
   gboolean deprecated;
+  gboolean is_class_struct;
   gint i;
   int n_elts;
 
@@ -591,6 +592,10 @@
 	  
   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 @@
   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_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\"");



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]