gobject-introspection r972 - in trunk: . docs girepository giscanner tests/scanner



Author: johan
Date: Tue Nov 25 22:29:20 2008
New Revision: 972
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=972&view=rev

Log:
2008-11-25  Colin Walters  <walters verbum org>

        Bug 559705 â Missing association between static methods and classes

        * docs/typelib-format.txt:
        * girepository/ginfo.c (g_function_info_get_flags):
        * girepository/girmodule.c (g_ir_module_build_typelib):
        * girepository/girnode.c (g_ir_node_get_size),
        (g_ir_node_build_typelib):
        * girepository/girparser.c (start_function):
        * girepository/gtypelib.c (g_typelib_check_sanity),
        (validate_header), (validate_function_blob):
        * girepository/gtypelib.h:
        * giscanner/ast.py:
        * giscanner/girwriter.py:
        * giscanner/glibtransformer.py:
        * tests/scanner/foo-1.0-expected.gir:
        * tests/scanner/foo-1.0-expected.tgir:
        * tests/scanner/foo.h:



Modified:
   trunk/ChangeLog
   trunk/docs/typelib-format.txt
   trunk/girepository/ginfo.c
   trunk/girepository/girmodule.c
   trunk/girepository/girnode.c
   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/foo-1.0-expected.gir
   trunk/tests/scanner/foo-1.0-expected.tgir
   trunk/tests/scanner/foo.h

Modified: trunk/docs/typelib-format.txt
==============================================================================
--- trunk/docs/typelib-format.txt	(original)
+++ trunk/docs/typelib-format.txt	Tue Nov 25 22:29:20 2008
@@ -302,7 +302,7 @@
           An array of ArgBlob for the arguments of the function.
 
 
-FunctionBlob (16 bytes)
+FunctionBlob (20 bytes)
 
 struct FunctionBlob 
 {
@@ -313,12 +313,14 @@
   guint   is_getter      : 1;
   guint   is_constructor : 1;
   guint   wraps_vfunc    : 1;
-  guint   reserved       : 1;
+  guint   throws         : 1;
   guint   index          :10;
 
   guint32 name;
   guint32 c_name;
   guint32 signature;
+  guint   is_static      : 1;
+  guint   reserved       : 31;
 }
 
 c_name:   The symbol which can be used to obtain the function pointer with 
@@ -352,6 +354,10 @@
           Offset of the SignatureBlob describing the parameter types and the 
           return value type.
 
+is_static
+          The function is a "static method"; in other words it's a pure
+	  function whose name is conceptually scoped to the object.
+
 
 CallbackBlob (12 bytes)
 

Modified: trunk/girepository/ginfo.c
==============================================================================
--- trunk/girepository/ginfo.c	(original)
+++ trunk/girepository/ginfo.c	Tue Nov 25 22:29:20 2008
@@ -494,7 +494,7 @@
   flags = 0;
 
   /* Make sure we don't flag Constructors as methods */
-  if (base->container != NULL && !blob->constructor)
+  if (!blob->constructor && !blob->is_static)
     flags = flags | GI_FUNCTION_IS_METHOD;
     
   if (blob->constructor)

Modified: trunk/girepository/girmodule.c
==============================================================================
--- trunk/girepository/girmodule.c	(original)
+++ trunk/girepository/girmodule.c	Tue Nov 25 22:29:20 2008
@@ -209,7 +209,7 @@
                              : 0);
   header->directory = ALIGN_VALUE (header_size, 4);
   header->entry_blob_size = 12;
-  header->function_blob_size = 16;
+  header->function_blob_size = sizeof (FunctionBlob);
   header->callback_blob_size = 12;
   header->signal_blob_size = 12;
   header->vfunc_blob_size = 16;

Modified: trunk/girepository/girnode.c
==============================================================================
--- trunk/girepository/girnode.c	(original)
+++ trunk/girepository/girnode.c	Tue Nov 25 22:29:20 2008
@@ -415,7 +415,7 @@
       break;
 
     case G_IR_NODE_FUNCTION:
-      size = 16; 
+      size = sizeof (FunctionBlob);
       break;
 
     case G_IR_NODE_PARAM:
@@ -1581,6 +1581,7 @@
 
 	blob->blob_type = BLOB_TYPE_FUNCTION;
 	blob->deprecated = function->deprecated;
+        blob->is_static = !function->is_method;
 	blob->setter = function->is_setter;
 	blob->getter = function->is_getter;
 	blob->constructor = function->is_constructor;

Modified: trunk/girepository/girparser.c
==============================================================================
--- trunk/girepository/girparser.c	(original)
+++ trunk/girepository/girparser.c	Tue Nov 25 22:29:20 2008
@@ -674,10 +674,12 @@
 	       strcmp (element_name, "callback") == 0);
       break;
     case STATE_CLASS:
+      found = strcmp (element_name, "function") == 0;
+	/* fallthrough */
     case STATE_BOXED:
     case STATE_STRUCT:
     case STATE_UNION:
-      found = strcmp (element_name, "constructor") == 0;
+      found = (found || strcmp (element_name, "constructor") == 0);
       /* fallthrough */
     case STATE_INTERFACE:
       found = (found ||

Modified: trunk/girepository/gtypelib.c
==============================================================================
--- trunk/girepository/gtypelib.c	(original)
+++ trunk/girepository/gtypelib.c	Tue Nov 25 22:29:20 2008
@@ -167,7 +167,7 @@
   CHECK_SIZE (ArgBlob, 12);
   CHECK_SIZE (SignatureBlob, 8);
   CHECK_SIZE (CommonBlob, 8);
-  CHECK_SIZE (FunctionBlob, 16);
+  CHECK_SIZE (FunctionBlob, 20);
   CHECK_SIZE (InterfaceTypeBlob, 4);
   CHECK_SIZE (ArrayTypeBlob, 8);
   CHECK_SIZE (ParamTypeBlob, 4);
@@ -315,7 +315,7 @@
     }
 
   if (header->entry_blob_size != 12 ||
-      header->function_blob_size != 16 ||
+      header->function_blob_size != 20 ||
       header->callback_blob_size != 12 ||
       header->signal_blob_size != 12 ||
       header->vfunc_blob_size != 16 ||
@@ -731,7 +731,7 @@
       g_set_error (error,
 		   G_TYPELIB_ERROR,
 		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Wrong blob type");
+		   "Wrong blob type %d, expected function", blob->blob_type);
       return FALSE;
     }
 

Modified: trunk/girepository/gtypelib.h
==============================================================================
--- trunk/girepository/gtypelib.h	(original)
+++ trunk/girepository/gtypelib.h	Tue Nov 25 22:29:20 2008
@@ -172,10 +172,17 @@
   guint16 wraps_vfunc : 1;
   guint16 throws      : 1;
   guint16 index       :10;
+  /* Note the bits above need to match CommonBlob
+   * and are thus exhausted, extend things using
+   * the reserved block below. */
 
   guint32 name;
   guint32 symbol;
   guint32 signature;
+
+  guint16 is_static   : 1;
+  guint16 reserved    : 15;
+  guint16 reserved2   : 16;
 } FunctionBlob;
 
 typedef struct 

Modified: trunk/giscanner/ast.py
==============================================================================
--- trunk/giscanner/ast.py	(original)
+++ trunk/giscanner/ast.py	Tue Nov 25 22:29:20 2008
@@ -368,6 +368,7 @@
         self.parent = parent
         self.is_abstract = is_abstract
         self.methods = []
+        self.static_methods = []
         self.interfaces = []
         self.constructors = []
         self.properties = []

Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py	(original)
+++ trunk/giscanner/girwriter.py	Tue Nov 25 22:29:20 2008
@@ -121,6 +121,9 @@
     def _write_method(self, method):
         self._write_function(method, tag_name='method')
 
+    def _write_static_method(self, method):
+        self._write_function(method, tag_name='function')
+
     def _write_constructor(self, method):
         self._write_function(method, tag_name='constructor')
 
@@ -260,6 +263,8 @@
             if isinstance(node, Class):
                 for method in node.constructors:
                     self._write_constructor(method)
+                for method in node.static_methods:
+                    self._write_static_method(method)
             for method in node.methods:
                 self._write_method(method)
             for prop in node.properties:

Modified: trunk/giscanner/glibtransformer.py
==============================================================================
--- trunk/giscanner/glibtransformer.py	(original)
+++ trunk/giscanner/glibtransformer.py	Tue Nov 25 22:29:20 2008
@@ -329,6 +329,27 @@
         except KeyError, e:
             return False
 
+    def _parse_static_method(self, func):
+        components = func.symbol.split('_')
+        if len(components) < 2:
+            return None
+        target_klass = None
+        prefix_components = None
+        methname = None
+        for i in xrange(1, len(components)-1):
+            prefix_components = '_'.join(components[0:-i])
+            methname = '_'.join(components[-i:])
+            target_klass = self._uscore_type_names.get(prefix_components)
+            if target_klass and isinstance(target_klass, GLibObject):
+                break
+            target_klass = None
+        if not target_klass:
+            return None
+        self._remove_attribute(func.name)
+        func.name = methname
+        target_klass.static_methods.append(func)
+        return func
+
     def _parse_method(self, func):
         if not func.parameters:
             return False
@@ -378,19 +399,6 @@
                 return None
             prefix = func.symbol[:new_idx]
 
-        klass = None
-
-        def valid_matching_klass(tclass):
-            if tclass is None:
-                return False
-            elif isinstance(klass, (GLibEnum, GLibFlags)):
-                return False
-            elif not isinstance(tclass, (GLibObject, GLibBoxed,
-                                          GLibInterface)):
-                return False
-            else:
-                return True
-
         klass = self._uscore_type_names.get(prefix)
         if klass is None:
             #print "NOTE: No valid matching class for likely "+\
@@ -676,13 +684,14 @@
             self._resolve_alias(node)
 
     def _resolve_function_toplevel(self, func):
-        newfunc = self._parse_constructor(func)
-        if not newfunc:
-            newfunc = self._parse_method(func)
-            if not newfunc:
-                self._resolve_function(func)
+        for parser in [self._parse_constructor,
+                       self._parse_method,
+                       self._parse_static_method]:
+            newfunc = parser(func)
+            if newfunc:
+                self._resolve_function(newfunc)
                 return
-        self._resolve_function(newfunc)
+        self._resolve_function(func)
 
     def _pair_boxed_type(self, boxed):
         name = self._transformer.remove_prefix(boxed.type_name)
@@ -744,6 +753,7 @@
                                     for x in node.interfaces])
         self._resolve_constructors(node.constructors)
         self._resolve_methods(node.methods)
+        self._resolve_methods(node.static_methods)
         self._resolve_properties(node.properties, node)
         self._resolve_signals(node.signals)
         for field in node.fields:

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	Tue Nov 25 22:29:20 2008
@@ -87,6 +87,11 @@
           <type name="Object" c:type="FooObject*"/>
         </return-value>
       </constructor>
+      <function name="static_meth" c:identifier="foo_object_static_meth">
+        <return-value transfer-ownership="none">
+          <type name="int" c:type="int"/>
+        </return-value>
+      </function>
       <method name="external_type" c:identifier="foo_object_external_type">
         <return-value transfer-ownership="full">
           <type name="utility.Object" c:type="UtilityObject*"/>

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	Tue Nov 25 22:29:20 2008
@@ -36,6 +36,11 @@
           <type name="Object"/>
         </return-value>
       </constructor>
+      <function name="static_meth" c:identifier="foo_object_static_meth">
+        <return-value transfer-ownership="none">
+          <type name="int"/>
+        </return-value>
+      </function>
       <method name="external_type" c:identifier="foo_object_external_type">
         <return-value transfer-ownership="full">
           <type name="utility.Object"/>

Modified: trunk/tests/scanner/foo.h
==============================================================================
--- trunk/tests/scanner/foo.h	(original)
+++ trunk/tests/scanner/foo.h	Tue Nov 25 22:29:20 2008
@@ -91,6 +91,8 @@
 
 void                  foo_object_handle_glyph      (FooObject *object, UtilityGlyph glyph);
 
+int                   foo_object_static_meth       ();
+
 struct _FooSubobject
 {
   FooObject parent_instance;



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