gobject-introspection r674 - in trunk: . giscanner tests/scanner



Author: walters
Date: Sat Oct 11 23:36:24 2008
New Revision: 674
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=674&view=rev

Log:
Bug 555947 - update annotations syntax


Modified:
   trunk/ChangeLog
   trunk/giscanner/ast.py
   trunk/giscanner/girwriter.py
   trunk/giscanner/scannerlexer.l
   trunk/giscanner/transformer.py
   trunk/tests/scanner/annotation-expected.gir
   trunk/tests/scanner/annotation.c
   trunk/tests/scanner/foo-expected.gir

Modified: trunk/giscanner/ast.py
==============================================================================
--- trunk/giscanner/ast.py	(original)
+++ trunk/giscanner/ast.py	Sat Oct 11 23:36:24 2008
@@ -227,7 +227,7 @@
         Node.__init__(self, name)
         self.type = typenode
         self.direction = PARAM_DIRECTION_IN
-        self.transfer = False
+        self.transfer = None
         self.allow_none = False
 
     def __repr__(self):
@@ -282,11 +282,13 @@
 
 class Return(Node):
 
-    def __init__(self, rtype, transfer=False):
+    def __init__(self, rtype, transfer=None):
         Node.__init__(self)
         self.type = rtype
-        self.transfer = isinstance(rtype, (List, Map, Array)) or \
-            rtype.name in ('utf8', 'filename') or transfer
+        if transfer is None and rtype.name in ['utf8', 'filename']:
+            self.transfer = 'full'
+        else:
+            self.transfer = transfer
 
     def __repr__(self):
         return 'Return(%r)' % (self.type, )

Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py	(original)
+++ trunk/giscanner/girwriter.py	Sat Oct 11 23:36:24 2008
@@ -121,7 +121,7 @@
         attrs = []
         if return_.transfer:
             attrs.append(('transfer-ownership',
-                          str(int(return_.transfer))))
+                          return_.transfer))
         with self.tagcontext('return-value', attrs):
             self._write_type(return_.type)
 
@@ -140,7 +140,7 @@
             attrs.append(('direction', parameter.direction))
         if parameter.transfer:
             attrs.append(('transfer-ownership',
-                          str(int(parameter.transfer))))
+                          parameter.transfer))
         if parameter.allow_none:
             attrs.append(('allow-none', '1'))
         with self.tagcontext('parameter', attrs):

Modified: trunk/giscanner/scannerlexer.l
==============================================================================
--- trunk/giscanner/scannerlexer.l	(original)
+++ trunk/giscanner/scannerlexer.l	Sat Oct 11 23:36:24 2008
@@ -250,20 +250,20 @@
       if (n_parts == 3) 
         {
           char *ptr = g_strdup (parts[1]);
+	  char *start;
+	  char *end;
 	  char **option_parts, **option_part;
 
-	  if (*ptr == '<')
+	  options = NULL;
+	  start = strchr (ptr, '(');
+	  while (start != NULL) 
 	    {
-	      char *end = strchr (ptr, '>');
-	      if (end) 
+	      end = strchr (start, ')');
+	      if (end)
 		{
-		  *end = '\0';
-		  option_parts = g_strsplit (ptr+1, ",", 0);
-		  for (option_part = option_parts; *option_part; option_part++)
-		    options = g_slist_prepend (options, g_strdup (*option_part));
-		  options = g_slist_reverse (options);
-		  g_strfreev (option_parts);
+		  options = g_slist_prepend (options, g_strndup (start+1, end-(start+1)));
 		}
+	      start = strchr (end+1, '(');
 	    }
 	  g_free (ptr);
           value = parts[2];

Modified: trunk/giscanner/transformer.py
==============================================================================
--- trunk/giscanner/transformer.py	(original)
+++ trunk/giscanner/transformer.py	Sat Oct 11 23:36:24 2008
@@ -19,6 +19,7 @@
 #
 
 import os
+import re
 
 from giscanner.ast import (Callback, Enum, Function, Namespace, Member,
                            Parameter, Return, Array, Struct, Field,
@@ -259,13 +260,25 @@
             if isinstance(param.type, Array):
                 self._pair_array(params, param)
 
+    # We take the annotations from the parser as strings; here we
+    # want to split them into components, so:
+    # (transfer full) -> {'transfer' : [ 'full' ]}
+
+    def _parse_options(self, options):
+        ret = {}
+        ws_re = re.compile(r'\s+')
+        for opt in options:
+            items = ws_re.split(opt)
+            ret[items[0]] = items[1:]
+        return ret
+
     def _create_function(self, symbol):
         directives = symbol.directives()
         parameters = list(self._create_parameters(
             symbol.base_type, directives))
         self._pair_annotations(parameters)
         return_ = self._create_return(symbol.base_type.base_type,
-                                      directives.get('return', []))
+                                      directives.get('return', {}))
         name = self._strip_namespace_func(symbol.ident)
         func = Function(name, return_, parameters, symbol.ident)
         self._parse_deprecated(func, directives)
@@ -290,12 +303,14 @@
             value = 'any'
         return value
 
-    def _create_parameters(self, base_type, options=None):
-        if not options:
-            options = {}
+    def _create_parameters(self, base_type, directives=None):
+        if directives is None:
+            dirs = {}
+        else:
+            dirs = directives
         for child in base_type.child_list:
             yield self._create_parameter(
-                child, options.get(child.ident, []))
+                child, dirs.get(child.ident, {}))
 
     def _create_member(self, symbol):
         ctype = symbol.base_type.type
@@ -303,7 +318,7 @@
             symbol.base_type.base_type.type == CTYPE_FUNCTION):
             node = self._create_callback(symbol)
         else:
-            ftype = self._create_type(symbol.base_type)
+            ftype = self._create_type(symbol.base_type, {})
             node = Field(symbol.ident, ftype, symbol.ident, symbol.const_int)
         return node
 
@@ -340,7 +355,7 @@
         derefed = canonical.replace('*', '')
         return derefed
 
-    def _create_type(self, source_type, options=[]):
+    def _create_type(self, source_type, options):
         ctype = self._create_source_type(source_type)
         if ctype == 'va_list':
             raise SkipError()
@@ -349,19 +364,19 @@
         elif ctype == 'FILE*':
             raise SkipError
         if ctype in self._list_ctypes:
-            if len(options) > 0:
-                contained_type = self._parse_ctype(options[0])
-                del options[0]
+            param = options.get('element-type')
+            if param:
+                contained_type = self._parse_ctype(param[0])
             else:
                 contained_type = None
             return List(ctype.replace('*', ''),
                         ctype,
                         contained_type)
-        if ctype in self._list_ctypes:
-            if len(options) > 0:
-                key_type = self._parse_ctype(options[0])
-                value_type = self._parse_ctype(options[1])
-                del options[0:2]
+        if ctype in self._map_ctypes:
+            param = options.get('element-type')
+            if param:
+                key_type = self._parse_ctype(param[0])
+                value_type = self._parse_ctype(param[1])
             else:
                 key_type = None
                 value_type = None
@@ -369,58 +384,74 @@
                        ctype,
                        key_type, value_type)
         if (ctype in default_array_types) or ('array' in options):
-            if 'array' in options:
-                options.remove('array')
             derefed = ctype[:-1] # strip the *
-            return Array(ctype,
+            result = Array(ctype,
                          self._parse_ctype(derefed))
+            array_opts = options.get('array')
+            if array_opts:
+                (_, len_name) = array_opts[0].split('=')
+                result.length_param_name = len_name
+            return result
         resolved_type_name = self._parse_ctype(ctype)
 
         # string memory management
         if ctype == 'char*':
             if source_type.base_type.type_qualifier & TYPE_QUALIFIER_CONST:
-                options.append('notransfer')
+                options['transfer'] = ['none']
             else:
-                options.append('transfer')
+                options['transfer'] = ['full']
 
         return Type(resolved_type_name, ctype)
 
+    def _handle_generic_param_options(self, param, options):
+        for option, data in options.iteritems():
+            if option == 'transfer':
+                if data:
+                    depth = data[0]
+                    if depth not in ('none', 'container', 'full'):
+                        raise ValueError("Invalid transfer %r" % (depth, ))
+                else:
+                    depth = 'full'
+                param.transfer = depth
+
     def _create_parameter(self, symbol, options):
+        options = self._parse_options(options)
         if symbol.type == CSYMBOL_TYPE_ELLIPSIS:
             ptype = Varargs()
         else:
             ptype = self._create_type(symbol.base_type, options)
         param = Parameter(symbol.ident, ptype)
-        for option in options:
+        for option, data in options.iteritems():
             if option in ['in-out', 'inout']:
                 param.direction = 'inout'
             elif option == 'in':
                 param.direction = 'in'
             elif option == 'out':
                 param.direction = 'out'
-            elif option == 'transfer':
-                param.transfer = True
-            elif option == 'notransfer':
-                param.transfer = False
-            elif isinstance(ptype, Array) and option.startswith('length'):
-                (_, index_param) = option.split('=')
-                ptype.length_param_name = index_param
             elif option == 'allow-none':
                 param.allow_none = True
+            elif option.startswith(('element-type', 'array')):
+                pass
+            elif option == 'transfer':
+                pass
             else:
                 print 'Unhandled parameter annotation option: %r' % (
                     option, )
+        self._handle_generic_param_options(param, options)
         return param
 
-    def _create_return(self, source_type, options=[]):
-        rtype = self._create_type(source_type, options)
+    def _create_return(self, source_type, options=None):
+        if options is None:
+            options_map = {}
+        else:
+            options_map = self._parse_options(options)
+        rtype = self._create_type(source_type, options_map)
         rtype = self.resolve_param_type(rtype)
         return_ = Return(rtype)
-        for option in options:
+        self._handle_generic_param_options(return_, options_map)
+        for option, data in options_map.iteritems():
             if option == 'transfer':
-                return_.transfer = True
-            elif option == 'notransfer':
-                return_.transfer = False
+                pass
             else:
                 print 'Unhandled return type annotation option: %r' % (
                     option, )

Modified: trunk/tests/scanner/annotation-expected.gir
==============================================================================
--- trunk/tests/scanner/annotation-expected.gir	(original)
+++ trunk/tests/scanner/annotation-expected.gir	Sat Oct 11 23:36:24 2008
@@ -29,7 +29,7 @@
       </method>
       <method name="create_object"
               c:identifier="annotation_object_create_object">
-        <return-value transfer-ownership="1">
+        <return-value transfer-ownership="full">
           <type name="GObject.Object" c:type="GObject*"/>
         </return-value>
       </method>
@@ -88,7 +88,7 @@
           <type name="int" c:type="gint"/>
         </return-value>
         <parameters>
-          <parameter name="toown" direction="out" transfer-ownership="1">
+          <parameter name="toown" direction="out" transfer-ownership="full">
             <type name="GObject.Object" c:type="GObject**"/>
           </parameter>
         </parameters>
@@ -98,23 +98,23 @@
           <type name="int" c:type="gint"/>
         </return-value>
         <parameters>
-          <parameter name="toown1" direction="out" transfer-ownership="1">
+          <parameter name="toown1" direction="out" transfer-ownership="full">
             <type name="GObject.Object" c:type="GObject**"/>
           </parameter>
-          <parameter name="toown2" direction="out" transfer-ownership="1">
+          <parameter name="toown2" direction="out" transfer-ownership="full">
             <type name="GObject.Object" c:type="GObject**"/>
           </parameter>
         </parameters>
       </method>
       <method name="get_strings" c:identifier="annotation_object_get_strings">
-        <return-value transfer-ownership="1">
+        <return-value transfer-ownership="full">
           <type name="GLib.List" c:type="GList*">
             <type name="utf8"/>
           </type>
         </return-value>
       </method>
       <method name="get_objects" c:identifier="annotation_object_get_objects">
-        <return-value transfer-ownership="1">
+        <return-value transfer-ownership="container">
           <type name="GLib.SList" c:type="GSList*">
             <type name="Object"/>
           </type>

Modified: trunk/tests/scanner/annotation.c
==============================================================================
--- trunk/tests/scanner/annotation.c	(original)
+++ trunk/tests/scanner/annotation.c	Sat Oct 11 23:36:24 2008
@@ -34,7 +34,7 @@
  *
  * This is a test for out arguments
  *
- * @outarg: <out>: This is an argument test
+ * @outarg: (out): This is an argument test
  * Return value: an int
  */
 gint
@@ -50,7 +50,7 @@
  *
  * This is a test for out arguments
  *
- * @outarg: <in>: This is an argument test
+ * @outarg: (in): This is an argument test
  * Return value: an int
  */
 gint
@@ -67,7 +67,7 @@
  *
  * This is a test for out arguments
  *
- * @inoutarg: <inout>: This is an argument test
+ * @inoutarg: (inout): This is an argument test
  * Return value: an int
  */
 gint
@@ -82,7 +82,7 @@
  *
  * This is a second test for out arguments
  *
- * @inoutarg: <inout>: This is an argument test
+ * @inoutarg: (inout): This is an argument test
  * Return value: an int
  */
 gint
@@ -98,7 +98,7 @@
  *
  * This is a 3th test for out arguments
  *
- * @inoutarg: <inout,allow-none>: This is an argument test
+ * @inoutarg: (inout) (allow-none): This is an argument test
  * Return value: an int
  */
 gint
@@ -115,7 +115,7 @@
  *
  * This is a test for out arguments
  *
- * @toown: <out,transfer>: a #GObject
+ * @toown: (out) (transfer): a #GObject
  * Return value: an int
  */
 gint
@@ -131,8 +131,8 @@
  *
  * This is a test for out arguments
  *
- * @toown1: <out,transfer>: a #GObject
- * @toown2: <out,transfer>: a #GObject
+ * @toown1: (out) (transfer): a #GObject
+ * @toown2: (out) (transfer): a #GObject
  * Return value: an int
  */
 gint
@@ -151,7 +151,7 @@
  * This is a test for returning a list of strings, where
  * each string needs to be freed.
  *
- * Return value: <char*,transfer>: list of strings
+ * Return value: (element-type utf8) (transfer): list of strings
  */
 GList*
 annotation_object_get_strings (AnnotationObject *object)
@@ -181,7 +181,7 @@
  * The list itself should be freed, but not the internal objects,
  * intentionally similar example to gtk_container_get_children
  *
- * Return value: <AnnotationObject*>: list of objects
+ * Return value: (element-type AnnotationObject) (transfer container): list of objects
  */
 GSList*
 annotation_object_get_objects (AnnotationObject *object)
@@ -197,7 +197,7 @@
  *
  * Test returning a caller-owned object
  *
- * Return value: <transfer>: The object
+ * Return value: (transfer): The object
  **/
 GObject* 
 annotation_object_create_object (AnnotationObject *object)
@@ -215,7 +215,7 @@
 /**
  * annotation_object_compute_sum:
  * @object: a #GObject
- * @nums: <array>: Sequence of numbers
+ * @nums: (array): Sequence of numbers
  *
  * Test taking a zero-terminated array
  **/
@@ -229,7 +229,7 @@
 /**
  * annotation_object_compute_sum_n:
  * @object: a #GObject
- * @nums: <array,length=n_nums>: Sequence of numbers
+ * @nums: (array length=n_nums): Sequence of numbers
  * @n_nums: Length of number array
  *
  * Test taking an array with length parameter
@@ -245,7 +245,7 @@
 /**
  * annotation_object_allow_none: 
  * @object: a #GObject
- * @somearg: <allow-none>: 
+ * @somearg: (allow-none): 
  **/
 GObject*
 annotation_object_allow_none (AnnotationObject *object, gchar *somearg)

Modified: trunk/tests/scanner/foo-expected.gir
==============================================================================
--- trunk/tests/scanner/foo-expected.gir	(original)
+++ trunk/tests/scanner/foo-expected.gir	Sat Oct 11 23:36:24 2008
@@ -98,7 +98,7 @@
           <type name="ObjectCookie" c:type="FooObjectCookie"/>
         </return-value>
         <parameters>
-          <parameter name="target">
+          <parameter name="target" transfer-ownership="none">
             <type name="utf8" c:type="char*"/>
           </parameter>
         </parameters>
@@ -114,12 +114,12 @@
         </parameters>
       </method>
       <method name="get_name" c:identifier="foo_object_get_name">
-        <return-value>
+        <return-value transfer-ownership="none">
           <type name="utf8" c:type="char*"/>
         </return-value>
       </method>
       <method name="dup_name" c:identifier="foo_object_dup_name">
-        <return-value transfer-ownership="1">
+        <return-value transfer-ownership="full">
           <type name="utf8" c:type="char*"/>
         </return-value>
       </method>
@@ -140,7 +140,7 @@
         </parameters>
       </callback>
       <glib:signal name="signal">
-        <return-value transfer-ownership="1">
+        <return-value transfer-ownership="full">
           <type name="utf8" c:type="gchararray"/>
         </return-value>
         <parameters>



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