gobject-introspection r1017 - in trunk: . gir giscanner tests/everything tests/scanner tools



Author: johan
Date: Mon Jan 12 20:11:44 2009
New Revision: 1017
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=1017&view=rev

Log:
2009-01-12  Johan Dahlin  <jdahlin async com br>

    Bug 563794 - Redo annotation parsing & applying
    
    Thanks to Colin for helping out considerably in landing this.

    * giscanner/Makefile.am:
    * giscanner/ast.py:
    * giscanner/dumper.py:
    * giscanner/girparser.py:
    * giscanner/giscannermodule.c (pygi_source_scanner_get_comments),
    (calc_attrs_length), (pygi_collect_attributes), (init_giscanner):
    * giscanner/glibtransformer.py:
    * giscanner/scannerlexer.l:
    * giscanner/sourcescanner.c (gi_source_symbol_unref),
    (gi_source_scanner_new), (gi_source_scanner_free),
    (gi_source_scanner_get_comments):
    * giscanner/sourcescanner.h:
    * giscanner/sourcescanner.py:
    * giscanner/transformer.py:
    * giscanner/xmlwriter.py:
    * tests/scanner/annotation-1.0-expected.gir:
    * tests/scanner/annotation-1.0-expected.tgir:
    * tests/scanner/annotation.c:
    * tests/scanner/annotation.h:
    * tests/scanner/foo-1.0-expected.gir:
    * tests/scanner/foo-1.0-expected.tgir:
    * tests/scanner/foo.h:
    * tools/g-ir-scanner:

    This commit merges the annotation parser rewrite branch.
    It'll change the annotation parsing to be done completely in python
    code which will make it easier to do further annotation parsing 
    easier.



Added:
   trunk/giscanner/annotationparser.py
      - copied unchanged from r1016, /branches/annotation/giscanner/annotationparser.py
Modified:
   trunk/   (props changed)
   trunk/ChangeLog
   trunk/gir/GLib-2.0.xpath   (props changed)
   trunk/giscanner/Makefile.am
   trunk/giscanner/ast.py
   trunk/giscanner/dumper.py
   trunk/giscanner/girparser.py
   trunk/giscanner/giscannermodule.c
   trunk/giscanner/glibtransformer.py
   trunk/giscanner/scannerlexer.l
   trunk/giscanner/sourcescanner.c
   trunk/giscanner/sourcescanner.h
   trunk/giscanner/sourcescanner.py
   trunk/giscanner/transformer.py
   trunk/giscanner/xmlwriter.py
   trunk/tests/everything/everything.c   (props changed)
   trunk/tests/everything/everything.h   (props changed)
   trunk/tests/scanner/annotation-1.0-expected.gir
   trunk/tests/scanner/annotation-1.0-expected.tgir
   trunk/tests/scanner/annotation.c
   trunk/tests/scanner/annotation.h
   trunk/tests/scanner/foo-1.0-expected.gir
   trunk/tests/scanner/foo-1.0-expected.tgir
   trunk/tests/scanner/foo.h
   trunk/tools/g-ir-scanner

Modified: trunk/giscanner/Makefile.am
==============================================================================
--- trunk/giscanner/Makefile.am	(original)
+++ trunk/giscanner/Makefile.am	Mon Jan 12 20:11:44 2009
@@ -35,6 +35,7 @@
 pkgpyexec_LTLIBRARIES = _giscanner.la
 pkgpyexec_PYTHON = 		\
 	__init__.py		\
+	annotationparser.py	\
 	ast.py			\
 	cachestore.py		\
 	config.py		\

Modified: trunk/giscanner/ast.py
==============================================================================
--- trunk/giscanner/ast.py	(original)
+++ trunk/giscanner/ast.py	Mon Jan 12 20:11:44 2009
@@ -200,6 +200,17 @@
         self.parameters = parameters
         self.symbol = symbol
         self.throws = not not throws
+        self.is_method = False
+
+    def get_parameter_index(self, name):
+        for i, parameter in enumerate(self.parameters):
+            if parameter.name == name:
+                return i + int(self.is_method)
+
+    def get_parameter(self, name):
+        for parameter in self.parameters:
+            if parameter.name == name:
+                return parameter
 
     def __repr__(self):
         return '%s(%r, %r, %r)' % (self.__class__.__name__,
@@ -217,6 +228,9 @@
         Node.__init__(self, name)
         self.ctype = ctype
         self.resolved = False
+        self.is_const = False
+        self.canonical = None
+        self.derefed_canonical = None
 
 
 class Varargs(Type):
@@ -236,7 +250,7 @@
         self.size = None
 
     def __repr__(self):
-        return 'Array(%r of %r)' % (self.name, self.element_type, )
+        return 'Array(%r, %r)' % (self.name, self.element_type, )
 
 
 class List(Type):
@@ -282,22 +296,19 @@
         else:
             self.transfer = None
 
-        # transformer.py overrides this as needed
-        self.transfer_inferred = False
-
 
 class Parameter(TypeContainer):
 
-    def __init__(self, name, typenode, direction=PARAM_DIRECTION_IN,
+    def __init__(self, name, typenode, direction=None,
                  transfer=None, allow_none=False, scope=None):
         TypeContainer.__init__(self, name, typenode, transfer)
         if direction in [PARAM_DIRECTION_IN, PARAM_DIRECTION_OUT,
-                         PARAM_DIRECTION_INOUT]:
+                         PARAM_DIRECTION_INOUT, None]:
             self.direction = direction
         else:
             self.direction = PARAM_DIRECTION_IN
 
-        self.allow_none = not not allow_none
+        self.allow_none = allow_none
         self.scope = scope
         self.closure_index = -1
         self.destroy_index = -1
@@ -328,7 +339,7 @@
         return 'Member(%r, %r)' % (self.name, self.value)
 
 
-class Struct(Node):
+class Record(Node):
 
     def __init__(self, name, symbol, disguised=False):
         Node.__init__(self, name)
@@ -337,6 +348,9 @@
         self.symbol = symbol
         self.disguised = disguised
 
+# BW compat, remove
+Struct = Record
+
 
 class Field(Node):
 
@@ -359,6 +373,7 @@
 
     def __init__(self, rtype, transfer=None):
         TypeContainer.__init__(self, None, rtype, transfer)
+        self.direction = PARAM_DIRECTION_OUT
 
     def __repr__(self):
         return 'Return(%r)' % (self.type, )
@@ -431,6 +446,7 @@
 
 # FIXME: Inherit from Function
 
+
 class Callback(Node):
 
     def __init__(self, name, retval, parameters, ctype=None):

Modified: trunk/giscanner/dumper.py
==============================================================================
--- trunk/giscanner/dumper.py	(original)
+++ trunk/giscanner/dumper.py	Mon Jan 12 20:11:44 2009
@@ -88,6 +88,7 @@
             self._packages.append('gobject-introspection-1.0')
 
     # Public API
+
     def run(self):
         c_path = self._generate_tempfile('.c')
         f = open(c_path, 'w')
@@ -112,6 +113,7 @@
         return IntrospectionBinary([bin_path], self._tmpdir)
 
     # Private API
+
     def _generate_tempfile(self, suffix=''):
         tmpl = '%s-%s%s' % (self._options.namespace_name,
                             self._options.namespace_version, suffix)

Modified: trunk/giscanner/girparser.py
==============================================================================
--- trunk/giscanner/girparser.py	(original)
+++ trunk/giscanner/girparser.py	Mon Jan 12 20:11:44 2009
@@ -53,6 +53,7 @@
         self._namespace = None
 
     # Public API
+
     def parse(self, filename):
         tree = parse(filename)
         self.parse_tree(tree)
@@ -79,6 +80,7 @@
         self._include_parsing = include_parsing
 
     # Private
+
     def _add_node(self, node):
         self._namespace.nodes.append(node)
 
@@ -152,7 +154,9 @@
         for iface in node.findall(_corens('prerequisites')):
             obj.prerequisities.append(iface.attrib['name'])
         for method in node.findall(_corens('method')):
-            obj.methods.append(self._parse_function_common(method, Function))
+            func = self._parse_function_common(method, Function)
+            func.is_method = True
+            obj.methods.append(func)
         for ctor in node.findall(_corens('constructor')):
             obj.constructors.append(
                 self._parse_function_common(ctor, Function))
@@ -284,8 +288,9 @@
         if self._include_parsing:
             return
         for method in node.findall(_corens('method')):
-            obj.methods.append(
-                self._parse_function_common(method, Function))
+            func = self._parse_function_common(method, Function)
+            func.is_method = True
+            obj.methods.append(func)
         for ctor in node.findall(_corens('constructor')):
             obj.constructors.append(
                 self._parse_function_common(ctor, Function))

Modified: trunk/giscanner/giscannermodule.c
==============================================================================
--- trunk/giscanner/giscannermodule.c	(original)
+++ trunk/giscanner/giscannermodule.c	Mon Jan 12 20:11:44 2009
@@ -64,11 +64,6 @@
 
 typedef struct {
   PyObject_HEAD
-  GISourceDirective *directive;
-} PyGISourceDirective;
-
-typedef struct {
-  PyObject_HEAD
   GISourceType *type;
 } PyGISourceType;
 
@@ -77,7 +72,6 @@
 typedef struct {
   PyObject_HEAD
   GISourceSymbol *symbol;
-  PyObject *directives;
 } PyGISourceSymbol;
 
 typedef struct {
@@ -85,76 +79,11 @@
   GISourceScanner *scanner;
 } PyGISourceScanner;
 
-NEW_CLASS (PyGISourceDirective, "SourceDirective", GISourceDirective);
 NEW_CLASS (PyGISourceSymbol, "SourceSymbol", GISourceSymbol);
 NEW_CLASS (PyGISourceType, "SourceType", GISourceType);
 NEW_CLASS (PyGISourceScanner, "SourceScanner", GISourceScanner);
 
 
-/* Directive */
-
-static PyObject *
-pygi_source_directive_new (GISourceDirective *directive)
-{
-  PyGISourceDirective *self;
-
-  if (directive == NULL)
-    {
-      Py_INCREF (Py_None);
-      return Py_None;
-    }
-    
-  self = (PyGISourceDirective *)PyObject_New (PyGISourceDirective,
-					      &PyGISourceDirective_Type);
-  self->directive = directive;
-  return (PyObject*)self;
-}
-
-static PyObject *
-directive_get_name (PyGISourceDirective *self,
-		    void                *context)
-{
-  return PyString_FromString (self->directive->name);
-}
-
-static PyObject *
-directive_get_value (PyGISourceDirective *self,
-		     void                *context)
-{
-  return PyString_FromString (self->directive->value);
-}
-
-static PyObject *
-directive_get_options (PyGISourceDirective *self,
-		       void                *context)
-{
-  GSList *l;
-  PyObject *list;
-  int i = 0;
-
-  if (!self->directive)
-    return Py_BuildValue("[]");
-  
-  list = PyList_New (g_slist_length (self->directive->options));
-  
-  for (l = self->directive->options; l; l = l->next)
-    {
-      PyObject *item = PyString_FromString (l->data);
-      PyList_SetItem (list, i++, item);
-      Py_INCREF (item);
-    }
-
-  Py_INCREF (list);
-  return list;
-}
-
-static const PyGetSetDef _PyGISourceDirective_getsets[] = {
-  { "name", (getter)directive_get_name, NULL, NULL},
-  { "value", (getter)directive_get_value, NULL, NULL},
-  { "options", (getter)directive_get_options, NULL, NULL},
-  { 0 }
-};
-
 /* Symbol */
 
 static PyObject *
@@ -222,26 +151,6 @@
   return PyString_FromString (self->symbol->const_string);
 }
 
-static PyObject *
-symbol_get_directives (PyGISourceSymbol *self,
-		       void             *context)
-{
-  if (!self->directives)
-    self->directives = Py_BuildValue("[]");
-  Py_INCREF (self->directives);
-  return self->directives;
-}
-
-static int
-symbol_set_directives (PyGISourceSymbol *self,
-		       PyObject         *value,
-		       void             *context)
-{
-  self->directives = value;
-  Py_INCREF(value);
-  return 0;
-}
-
 static const PyGetSetDef _PyGISourceSymbol_getsets[] = {
   /* int ref_count; */
   { "type", (getter)symbol_get_type, NULL, NULL},
@@ -251,8 +160,6 @@
   /* gboolean const_int_set; */
   { "const_int", (getter)symbol_get_const_int, NULL, NULL},  
   { "const_string", (getter)symbol_get_const_string, NULL, NULL},  
-  { "directives", (getter)symbol_get_directives,
-    (setter)symbol_set_directives, NULL},  
   { 0 }
 };
 
@@ -555,23 +462,18 @@
 }
 
 static PyObject *
-pygi_source_scanner_get_directives (PyGISourceScanner *self,
-				    PyObject          *args)
+pygi_source_scanner_get_comments (PyGISourceScanner *self)
 {
-  GSList *l, *directives;
+  GSList *l, *comments;
   PyObject *list;
   int i = 0;
-  char *name;
-  
-  if (!PyArg_ParseTuple (args, "s:SourceScanner.get_directives", &name))
-    return NULL;
   
-  directives = gi_source_scanner_get_directives (self->scanner, name);
-  list = PyList_New (g_slist_length (directives));
+  comments = gi_source_scanner_get_comments (self->scanner);
+  list = PyList_New (g_slist_length (comments));
   
-  for (l = directives; l; l = l->next)
+  for (l = comments; l; l = l->next)
     {
-      PyObject *item = pygi_source_directive_new (l->data);
+      PyObject *item = PyString_FromString (l->data);
       PyList_SetItem (list, i++, item);
       Py_INCREF (item);
     }
@@ -581,7 +483,7 @@
 }
 
 static const PyMethodDef _PyGISourceScanner_methods[] = {
-  { "get_directives", (PyCFunction) pygi_source_scanner_get_directives, METH_VARARGS },
+  { "get_comments", (PyCFunction) pygi_source_scanner_get_comments, METH_NOARGS },
   { "get_symbols", (PyCFunction) pygi_source_scanner_get_symbols, METH_NOARGS },
   { "append_filename", (PyCFunction) pygi_source_scanner_append_filename, METH_VARARGS },
   { "parse_file", (PyCFunction) pygi_source_scanner_parse_file, METH_VARARGS },
@@ -611,7 +513,8 @@
       if (PyTuple_GetItem(tuple, 1) == Py_None)
 	continue;
 
-      g_assert(PyArg_ParseTuple(tuple, "ss", &attr, &value));
+      if (!PyArg_ParseTuple(tuple, "ss", &attr, &value))
+        return -1;
       
       escaped = g_markup_escape_text (value, -1);
       attr_length += 2 + strlen(attr) + strlen(escaped) + 2;
@@ -631,6 +534,7 @@
   char *indent_char;
   gboolean first;
   GString *attr_value;
+  int len;
   
   if (!PyArg_ParseTuple(args, "sOisi",
 			&tag_name, &attributes,
@@ -641,7 +545,10 @@
   if (attributes == Py_None || !PyList_Size(attributes))
     return PyString_FromString("");
 
-  if (calc_attrs_length(attributes, indent, self_indent) > 79)
+  len = calc_attrs_length(attributes, indent, self_indent);
+  if (len < 0)
+    return NULL;
+  if (len > 79)
     indent_len = self_indent + strlen(tag_name) + 1;
   else
     indent_len = 0;
@@ -660,7 +567,9 @@
       if (PyTuple_GetItem(tuple, 1) == Py_None)
 	continue;
 
-      g_assert(PyArg_ParseTuple(tuple, "ss", &attr, &value));
+      /* this leaks, but we exit after, so */
+      if (!PyArg_ParseTuple(tuple, "ss", &attr, &value))
+        return NULL;
 
       if (indent_len && !first)
 	{
@@ -699,9 +608,6 @@
 		       (PyMethodDef*)pyscanner_functions);
     d = PyModule_GetDict (m);
 
-    PyGISourceDirective_Type.tp_getset = (PyGetSetDef*)_PyGISourceDirective_getsets;
-    REGISTER_TYPE (d, "SourceDirective", PyGISourceDirective_Type);
-
     PyGISourceScanner_Type.tp_init = (initproc)pygi_source_scanner_init;
     PyGISourceScanner_Type.tp_methods = (PyMethodDef*)_PyGISourceScanner_methods;
     REGISTER_TYPE (d, "SourceScanner", PyGISourceScanner_Type);

Modified: trunk/giscanner/glibtransformer.py
==============================================================================
--- trunk/giscanner/glibtransformer.py	(original)
+++ trunk/giscanner/glibtransformer.py	Mon Jan 12 20:11:44 2009
@@ -28,7 +28,7 @@
 from .ast import (Callback, Constant, Enum, Function, Member, Namespace,
                   Parameter, Property, Return, Struct, Type, Alias,
                   Union, Field, type_name_from_ctype,
-                  default_array_types, TYPE_UINT8, PARAM_DIRECTION_IN)
+                  default_array_types, TYPE_UINT8, PARAM_TRANSFER_FULL)
 from .transformer import Names
 from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
                       GLibInterface, GLibObject, GLibSignal, GLibBoxedStruct,
@@ -85,8 +85,6 @@
     def __init__(self, transformer, noclosure=False):
         self._transformer = transformer
         self._noclosure = noclosure
-        self._transformer.set_container_types(['GList*', 'GSList*'],
-                                              ['GHashTable*'])
         self._namespace_name = None
         self._names = Names()
         self._uscore_type_names = {}
@@ -99,6 +97,7 @@
         self._validating = False
 
     # Public API
+
     def set_introspection_binary(self, binary):
         self._binary = binary
 
@@ -165,6 +164,7 @@
         return namespace
 
     # Private
+
     def _add_attribute(self, node, replace=False):
         node_name = node.name
         if (not replace) and node_name in self._names.names:
@@ -203,6 +203,7 @@
         self._uscore_type_names[no_uscore_prefixed] = node
 
     # Helper functions
+
     def _resolve_gtypename(self, gtype_name):
         try:
             return self._transformer.gtypename_to_giname(gtype_name,
@@ -254,6 +255,7 @@
         self._register_internal_type(type_name, gnode)
 
     # Parser
+
     def _parse_node(self, node):
         if isinstance(node, Enum):
             self._parse_enum(node)
@@ -345,6 +347,7 @@
         self._remove_attribute(func.name)
         func.name = methname
         target_klass.static_methods.append(func)
+        func.is_method = True
         return func
 
     def _parse_method(self, func):
@@ -431,6 +434,7 @@
             # We don't need the "this" parameter
             del func.parameters[0]
             klass.methods.append(func)
+            func.is_method = True
         else:
             klass.constructors.append(func)
         return func
@@ -512,6 +516,7 @@
             del self._names.names[maybe_class.name]
 
     # Introspection
+
     def _introspect_type(self, xmlnode):
         if xmlnode.tag in ('enum', 'flags'):
             self._introspect_enum(xmlnode)
@@ -627,7 +632,7 @@
             rctype = signal_info.attrib['return']
             rtype = Type(self._transformer.parse_ctype(rctype), rctype)
             return_ = Return(rtype, signal_info.attrib['return'])
-            return_.transfer = 'full'
+            return_.transfer = PARAM_TRANSFER_FULL
             signal = GLibSignal(signal_info.attrib['name'], return_)
             for i, parameter in enumerate(signal_info.findall('param')):
                 if i == 0:
@@ -642,6 +647,7 @@
             node.signals.append(signal)
 
     # Resolver
+
     def _resolve_type_name(self, type_name, ctype=None):
         # Workaround glib bug #548689, to be included in 2.18.0
         if type_name == "GParam":
@@ -784,25 +790,6 @@
     def _resolve_property(self, prop):
         prop.type = self._resolve_param_type(prop.type, allow_invalid=False)
 
-    def _adjust_transfer(self, param):
-        if not (param.transfer is None or param.transfer_inferred):
-            return
-
-        # Do GLib/GObject-specific type transformations here
-        node = self._lookup_node(param.type.name)
-        if node is None:
-            return
-
-        if isinstance(param, Parameter):
-            if param.direction != PARAM_DIRECTION_IN:
-                transfer = 'full'
-            else:
-                transfer = 'none'
-        else:
-            transfer = 'full'
-
-        param.transfer = transfer
-
     def _adjust_throws(self, func):
         if func.parameters == []:
             return
@@ -820,12 +807,10 @@
         self._resolve_parameters(func.parameters)
         func.retval.type = self._resolve_param_type(func.retval.type)
         self._adjust_throws(func)
-        self._adjust_transfer(func.retval)
 
     def _resolve_parameters(self, parameters):
         for parameter in parameters:
             parameter.type = self._resolve_param_type(parameter.type)
-            self._adjust_transfer(parameter)
 
     def _resolve_field(self, field):
         if isinstance(field, Callback):
@@ -837,6 +822,7 @@
         alias.target = self._resolve_type_name(alias.target, alias.target)
 
     # Validation
+
     def _validate(self, nodes):
         nodes = list(self._names.names.itervalues())
         i = 0

Modified: trunk/giscanner/scannerlexer.l
==============================================================================
--- trunk/giscanner/scannerlexer.l	(original)
+++ trunk/giscanner/scannerlexer.l	Mon Jan 12 20:11:44 2009
@@ -200,187 +200,27 @@
 
 
 static void
-parse_gtkdoc (GISourceScanner *scanner,
-	      gchar           *symbol,
-	      int             *c1,
-	      int             *c2)
-{
-  gboolean isline = FALSE;
-  GString *line_buf;
-  char *line;
-  gchar **parts;
-  GISourceDirective *directive;
-  char *name,*value;
-  GSList *directives;
-  GSList *options = NULL;
-  char *rname;
-  int n_parts;
-
-  line_buf = g_string_new ("");
-
-  do 
-    {
-      *c1 = *c2;
-      if (*c1 == '\n')
-        {
-          isline = TRUE;
-          break;
-        }
-      g_string_append_c (line_buf, *c1);
-      *c2 = input();
-    } while (*c2 != EOF && !(*c1 == '*' && *c2 == '/'));
-  
-  if (!isline)
-    {
-      g_string_free (line_buf, TRUE);
-      return;
-    }
-
-  line = g_string_free (line_buf, FALSE);
-
-  /* Ignore lines that don't have a : - this is a hack but avoids
-   * trying to parse too many things as annotations
-   */
-  if (!strchr (line, ':'))
-    {
-      g_free (line);
-      return;
-    }
-
-  parts = g_strsplit (line, ":", 3);
-  n_parts = g_strv_length (parts);
-
-  if (g_ascii_strcasecmp (parts[0], "eprecated") == 0)
-    {
-      if (n_parts == 3)
-	options = g_slist_prepend (options, g_strdup_printf ("%s: %s", parts[1], parts[2]));
-      else if (n_parts == 2)
-	options = g_slist_prepend (options, g_strdup (parts[1]));
-      else
-	options = g_slist_prepend (options, g_strdup (""));
-      name = parts[0];
-      value = NULL;
-    }
-  else if (g_ascii_strcasecmp (parts[0], "ince") == 0)
-    {
-      if (n_parts == 2)
-	options = g_slist_prepend (options, g_strdup (parts[1]));
-      else
-	options = g_slist_prepend (options, g_strdup (""));
-      name = parts[0];
-      value = NULL;
-    }
-  else if (n_parts >= 2)
-    {
-      name = parts[0];
-
-      if (n_parts == 3) 
-        {
-          char *ptr = g_strdup (parts[1]);
-	  char *start;
-	  char *end;
-
-	  options = NULL;
-	  start = strchr (ptr, '(');
-	  while (start != NULL) 
-	    {
-	      end = strchr (start, ')');
-	      if (end)
-		{
-		  options = g_slist_prepend (options, g_strndup (start+1, end-(start+1)));
-		  start = strchr (end+1, '(');
-		}
-	      else
-		{
-		  break;
-		}
-	    }
-	  g_free (ptr);
-          value = parts[2];
-        } 
-      else
-        value = parts[1];
-    }
-  else /* parts == 1 */
-    {
-      name = parts[0];
-      value = NULL;
-    }
-
-  /*
-   * Special cases for global annotations.
-   * Context-sensitive parsing would probably be the right way to go.
-   */
-  if (g_ascii_strncasecmp ("eturn", name, 5) == 0)
-    rname = "return";
-  else if (g_ascii_strncasecmp ("eprecated", name, 9) == 0)
-    rname = "deprecated";
-  else if (g_ascii_strncasecmp ("ince", name, 4) == 0)
-    rname = "since";
-  else
-    rname = name;
-
-  directive = gi_source_directive_new (rname, value, options);
-  directives = g_hash_table_lookup (scanner->directives_map, symbol);
-  directives = g_slist_prepend (directives, directive);
-  g_hash_table_replace (scanner->directives_map,
-			g_strdup (symbol), directives);
-
-  g_strfreev (parts);
-  g_free (line);
-}
-
-
-static void
 parse_comment (GISourceScanner *scanner)
 {
-  GString *symbol = NULL;
-  gboolean startofline = FALSE, have_symbol = FALSE, start1 = FALSE, start_symbol = FALSE;
+  GString *comment;
   int c1, c2;
 
   c1 = input();
   c2 = input();
 
+  comment = g_string_new ("");
+
   while (c2 != EOF && !(c1 == '*' && c2 == '/'))
     {
-      if (c1 == ':')
-        have_symbol = TRUE;
-      else if (c1 == '\n')
-         start1 = TRUE;
-      else if (c1 == '*' && start1)
-         start_symbol = TRUE;
-      else if (!have_symbol && start_symbol) 
-        {
-          if (!symbol)
-            symbol = g_string_new ("");
-          if (c1 != ' ')
-            g_string_append_c (symbol, c1);
-        }
-
-      if (c1 == '\n') 
-        {
-          ++lineno;
-          startofline = TRUE;
-        }
+      g_string_append_c (comment, c1);
 
       c1 = c2;
       c2 = input();
 
-      if ((c1 != '*' && c1 != ' '))
-          startofline = FALSE;
-
-      if (startofline && (c1 == ' ') && ((c2 == '@') || (c2 == 'r') || (c2 == 'R') || (c2 == 'D') || (c2 == 'S')))
-        {
-           c1 = c2;
-           c2 = input();
-           if (symbol)
-             parse_gtkdoc (scanner, symbol->str, &c1, &c2);
-        }
     }
 
-  if (symbol)
-    g_string_free (symbol, TRUE);
-  
+  scanner->comments = g_slist_prepend (scanner->comments,
+                                       g_string_free (comment, FALSE));
 }
 
 static int

Modified: trunk/giscanner/sourcescanner.c
==============================================================================
--- trunk/giscanner/sourcescanner.c	(original)
+++ trunk/giscanner/sourcescanner.c	Mon Jan 12 20:11:44 2009
@@ -60,8 +60,6 @@
       if (symbol->base_type)
         ctype_free (symbol->base_type);
       g_free (symbol->const_string);
-      g_slist_foreach (symbol->directives, (GFunc)gi_source_directive_free, NULL);
-      g_slist_free (symbol->directives);
       g_slice_free (GISourceSymbol, symbol);
     }
 }
@@ -178,28 +176,6 @@
   return func;
 }
 
-GISourceDirective *
-gi_source_directive_new (const gchar *name,
-			 const gchar *value,
-			 GSList *options)
-{
-  GISourceDirective *directive;
-    
-  directive = g_slice_new (GISourceDirective);
-  directive->name = g_strdup (name);
-  directive->value = g_strdup (value);
-  directive->options = options;
-  return directive;
-}
-
-void
-gi_source_directive_free (GISourceDirective *directive)
-{
-  g_free (directive->name);
-  g_free (directive->value);
-  g_slice_free (GISourceDirective, directive);
-}
-
 GISourceScanner *
 gi_source_scanner_new (void)
 {
@@ -208,7 +184,6 @@
   scanner = g_slice_new0 (GISourceScanner);
   scanner->typedef_table = g_hash_table_new_full (g_str_hash, g_str_equal,
 						  g_free, NULL);
-  scanner->directives_map = g_hash_table_new (g_str_hash, g_str_equal);
   scanner->struct_or_union_or_enum_table =
     g_hash_table_new_full (g_str_hash, g_str_equal,
 			   g_free, (GDestroyNotify)gi_source_symbol_unref);
@@ -221,10 +196,11 @@
 {
   g_free (scanner->current_filename);
 
-  g_hash_table_destroy (scanner->directives_map);
   g_hash_table_destroy (scanner->typedef_table);
   g_hash_table_destroy (scanner->struct_or_union_or_enum_table);
 
+  g_slist_foreach (scanner->comments, (GFunc)g_free, NULL);
+  g_slist_free (scanner->comments);
   g_slist_foreach (scanner->symbols, (GFunc)gi_source_symbol_unref, NULL);
   g_slist_free (scanner->symbols);
 
@@ -295,8 +271,7 @@
 }
 
 GSList *
-gi_source_scanner_get_directives(GISourceScanner  *scanner,
-				 const gchar      *name)
+gi_source_scanner_get_comments(GISourceScanner  *scanner)
 {
-  return g_hash_table_lookup (scanner->directives_map, name);
+  return g_slist_reverse (scanner->comments);
 }

Modified: trunk/giscanner/sourcescanner.h
==============================================================================
--- trunk/giscanner/sourcescanner.h	(original)
+++ trunk/giscanner/sourcescanner.h	Mon Jan 12 20:11:44 2009
@@ -31,7 +31,6 @@
 typedef struct _GISourceScanner GISourceScanner;
 typedef struct _GISourceSymbol GISourceSymbol;
 typedef struct _GISourceType GISourceType;
-typedef struct _GISourceDirective GISourceDirective;
 
 typedef enum
 {
@@ -102,7 +101,7 @@
   gboolean macro_scan;
   GSList *symbols;
   GList *filenames;
-  GHashTable *directives_map;
+  GSList *comments;
   GHashTable *typedef_table;
   GHashTable *struct_or_union_or_enum_table;
 };
@@ -117,7 +116,6 @@
   gboolean const_int_set;
   int const_int;
   char *const_string;
-  GSList *directives; /* list of GISourceDirective */
 };
 
 struct _GISourceType
@@ -131,13 +129,6 @@
   GList *child_list; /* list of GISourceSymbol */
 };
 
-struct _GISourceDirective
-{
-  char *name;
-  char *value;
-  GSList *options; /* list of options (key=value) */
-};
-
 GISourceScanner *   gi_source_scanner_new              (void);
 gboolean            gi_source_scanner_lex_filename     (GISourceScanner  *igenerator,
 						        const gchar      *filename);
@@ -148,8 +139,7 @@
 void                gi_source_scanner_set_macro_scan   (GISourceScanner  *scanner,
 							gboolean          macro_scan);
 GSList *            gi_source_scanner_get_symbols      (GISourceScanner  *scanner);
-GSList *            gi_source_scanner_get_directives   (GISourceScanner  *scanner,
-							const gchar      *name);
+GSList *            gi_source_scanner_get_comments     (GISourceScanner  *scanner);
 void                gi_source_scanner_free             (GISourceScanner  *scanner);
 
 GISourceSymbol *    gi_source_symbol_new               (GISourceSymbolType  type);
@@ -157,11 +147,6 @@
 GISourceSymbol *    gi_source_symbol_ref               (GISourceSymbol     *symbol);
 void                gi_source_symbol_unref             (GISourceSymbol     *symbol);
 
-GISourceDirective * gi_source_directive_new            (const gchar 	   *name,
-							const gchar 	   *value,
-							GSList             *options);
-void                gi_source_directive_free           (GISourceDirective  *directive);
-
 /* Private */
 void                gi_source_scanner_add_symbol       (GISourceScanner  *scanner,
 							GISourceSymbol   *symbol);

Modified: trunk/giscanner/sourcescanner.py
==============================================================================
--- trunk/giscanner/sourcescanner.py	(original)
+++ trunk/giscanner/sourcescanner.py	Mon Jan 12 20:11:44 2009
@@ -154,12 +154,6 @@
             symbol_type_name(self.type),
             self.ident)
 
-    def directives(self):
-        mapping = {}
-        for directive in self._scanner.get_directives(self._symbol.ident):
-            mapping[directive.name] = directive.options
-        return mapping
-
     @property
     def const_int(self):
         return self._symbol.const_int
@@ -192,6 +186,7 @@
         self._cpp_options = []
 
     # Public API
+
     def set_cpp_options(self, includes, defines, undefines):
         for prefix, args in [('-I', includes),
                              ('-D', defines),
@@ -226,12 +221,16 @@
         for symbol in self._scanner.get_symbols():
             yield SourceSymbol(self._scanner, symbol)
 
+    def get_comments(self):
+        return self._scanner.get_comments()
+
     def dump(self):
         print '-'*30
         for symbol in self._scanner.get_symbols():
             print symbol.ident, symbol.base_type.name, symbol.type
 
     # Private
+
     def _parse(self, filenames):
         if not filenames:
             return

Modified: trunk/giscanner/transformer.py
==============================================================================
--- trunk/giscanner/transformer.py	(original)
+++ trunk/giscanner/transformer.py	Mon Jan 12 20:11:44 2009
@@ -19,14 +19,12 @@
 #
 
 import os
-import re
 
 from .ast import (Callback, Enum, Function, Namespace, Member,
-                  Parameter, Return, Array, Struct, Field,
-                  Type, Alias, Interface, Class, Node, Union,
-                  List, Map, Varargs, Constant, type_name_from_ctype,
-                  type_names, default_array_types, default_out_types,
-                  TYPE_STRING, BASIC_GIR_TYPES, TYPE_NONE)
+                  Parameter, Return, Struct, Field,
+                  Type, Array, Alias, Interface, Class, Node, Union,
+                  Varargs, Constant, type_name_from_ctype,
+                  type_names, TYPE_STRING, BASIC_GIR_TYPES)
 from .config import DATADIR
 from .glibast import GLibBoxed
 from .girparser import GIRParser
@@ -75,8 +73,6 @@
         self._strip_prefix = ''
         self._includes = set()
         self._includepaths = []
-        self._list_ctypes = []
-        self._map_ctypes = []
 
     def get_names(self):
         return self._names
@@ -84,10 +80,6 @@
     def get_includes(self):
         return self._includes
 
-    def set_container_types(self, list_ctypes, map_ctypes):
-        self._list_ctypes = list_ctypes
-        self._map_ctypes = map_ctypes
-
     def set_strip_prefix(self, strip_prefix):
         self._strip_prefix = strip_prefix
 
@@ -109,6 +101,7 @@
         self._includes.add(include)
 
     # Private
+
     def _find_include(self, include):
         searchdirs = self._includepaths[:]
         for path in _xdg_data_dirs:
@@ -210,7 +203,6 @@
 
     def _create_enum(self, symbol):
         members = []
-        directives = symbol.directives()
         for child in symbol.base_type.child_list:
             name = strip_common_prefix(symbol.ident, child.ident).lower()
             members.append(Member(name,
@@ -219,7 +211,6 @@
 
         enum_name = self.remove_prefix(symbol.ident)
         enum = Enum(enum_name, symbol.ident, members)
-        self._parse_version(enum, directives)
         self._names.type_names[symbol.ident] = (None, enum)
         return enum
 
@@ -227,48 +218,6 @@
         return Member(symbol.ident, symbol.base_type.name,
                       symbol.ident)
 
-    def _parse_deprecated(self, node, directives):
-        deprecated = directives.get('deprecated', False)
-        if deprecated:
-            deprecated_value = deprecated[0]
-            if ':' in deprecated_value:
-                # Split out gtk-doc version
-                (node.deprecated_version, node.deprecated) = \
-                    [x.strip() for x in deprecated_value.split(':', 1)]
-            else:
-                # No version, just include str
-                node.deprecated = deprecated_value.strip()
-
-    def _parse_version(self, node, directives):
-        version = directives.get('since', False)
-        if version:
-            version_value = version[0]
-            node.version = version_value.strip()
-
-    def _pair_array(self, params, array):
-        if not array.type.length_param_name:
-            return
-        target_name = array.type.length_param_name
-        for i, param in enumerate(params):
-            if param.name == array.type.length_param_name:
-                array.type.length_param_index = i
-                return
-        raise ValueError("Unmatched length parameter name %r"\
-                             % (target_name, ))
-
-    def _pair_annotations(self, params, return_):
-        names = {}
-        for param in params:
-            if param.name in names:
-                raise ValueError("Duplicate parameter name %r"\
-                                     % (param.name, ))
-            names[param.name] = 1
-            if isinstance(param.type, Array):
-                self._pair_array(params, param)
-
-        if isinstance(return_.type, Array):
-            self._pair_array(params, return_)
-
     def _type_is_callback(self, type):
         if (isinstance(type, Callback) or
             isinstance(self._typedefs_ns.get(type.name), Callback)):
@@ -294,50 +243,35 @@
 
     def _augment_callback_params(self, params):
         for i, param in enumerate(params):
-            if self._type_is_callback(param.type):
-                # j is the index where we look for closure/destroy to
-                # group with the callback param
-                j = i + 1
-                if j == len(params):
-                    continue # no more args -> nothing to group look
-                # at the param directly following for either a closure
-                # or a destroy; only one of these will fire
-                had_closure = self._handle_closure(param, j, params[j])
-                had_destroy = self._handle_destroy(param, j, params[j])
-                j += 1
-                # are we out of params, or did we find neither?
-                if j == len(params) or (not had_closure and not had_destroy):
-                    continue
-                # we found either a closure or a destroy; check the
-                # parameter following for the other
-                if not had_closure:
-                    self._handle_closure(param, j, params[j])
-                if not had_destroy:
-                    self._handle_destroy(param, j, params[j])
-
-    # 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
+            if not self._type_is_callback(param.type):
+                continue
+
+            # j is the index where we look for closure/destroy to
+            # group with the callback param
+            j = i + 1
+            if j == len(params):
+                continue # no more args -> nothing to group look
+            # at the param directly following for either a closure
+            # or a destroy; only one of these will fire
+            had_closure = self._handle_closure(param, j, params[j])
+            had_destroy = self._handle_destroy(param, j, params[j])
+            j += 1
+            # are we out of params, or did we find neither?
+            if j == len(params) or (not had_closure and not had_destroy):
+                continue
+            # we found either a closure or a destroy; check the
+            # parameter following for the other
+            if not had_closure:
+                self._handle_closure(param, j, params[j])
+            if not had_destroy:
+                self._handle_destroy(param, j, params[j])
 
     def _create_function(self, symbol):
-        directives = symbol.directives()
-        parameters = list(self._create_parameters(
-            symbol.base_type, directives))
-        return_ = self._create_return(symbol.base_type.base_type,
-                                      directives.get('return', {}))
+        parameters = list(self._create_parameters(symbol.base_type))
+        return_ = self._create_return(symbol.base_type.base_type)
         self._augment_callback_params(parameters)
-        self._pair_annotations(parameters, return_)
         name = self._strip_namespace_func(symbol.ident)
         func = Function(name, return_, parameters, symbol.ident)
-        self._parse_version(func, directives)
-        self._parse_deprecated(func, directives)
         return func
 
     def _create_source_type(self, source_type):
@@ -357,47 +291,42 @@
             value = 'any'
         return value
 
-    def _create_parameters(self, base_type, directives=None):
-        if directives is None:
-            dirs = {}
-        else:
-            dirs = directives
+    def _create_parameters(self, base_type):
 
         # warn if we see annotations for unknown parameters
         param_names = set(child.ident for child in base_type.child_list)
-        dirs_for = set(dirs)
-        dirs_for = dirs_for.difference(param_names)
-        dirs_for.discard('return')
-        dirs_for.discard('deprecated')
-        dirs_for.discard('since')
-        if dirs_for:
-            print 'Unexpected annotations for %s, parameters are %s' % (
-                list(dirs_for), list(param_names), )
-
         for child in base_type.child_list:
-            yield self._create_parameter(
-                child, dirs.get(child.ident, {}))
+            yield self._create_parameter(child)
 
     def _create_member(self, symbol):
-        ctype = symbol.base_type.type
-        if (ctype == CTYPE_POINTER and
+        source_type = symbol.base_type
+        if (source_type.type == CTYPE_POINTER and
             symbol.base_type.base_type.type == CTYPE_FUNCTION):
             node = self._create_callback(symbol)
         else:
-            opts = {}
-            if ctype == CTYPE_ARRAY:
-                opts['array'] = []
+            # Special handling for fields; we don't have annotations on them
+            # to apply later, yet.
+            if source_type.type == CTYPE_ARRAY:
+                ctype = self._create_source_type(source_type)
+                canonical_ctype = self._canonicalize_ctype(ctype)
+                if canonical_ctype[-1] == '*':
+                    derefed_name = canonical_ctype[:-1]
+                else:
+                    derefed_name = canonical_ctype
+                derefed_name = self.resolve_param_type(derefed_name)
+                ftype = Array(ctype, self.parse_ctype(derefed_name))
                 child_list = list(symbol.base_type.child_list)
+                ftype.zeroterminated = False
                 if child_list:
-                    size_opt = 'fixed-size=%d' % (child_list[0].const_int, )
-                    opts['array'].append(size_opt)
-            ftype = self._create_type(symbol.base_type, opts,
-                                      is_param=False, is_retval=False)
+                    ftype.size = '%d' % (child_list[0].const_int, )
+            else:
+                ftype = self._create_type(symbol.base_type,
+                                          is_param=False, is_retval=False)
             ftype = self.resolve_param_type(ftype)
             # Fields are assumed to be read-write
             # (except for Objects, see also glibtransformer.py)
-            node = Field(symbol.ident, ftype, symbol.ident,
-                       readable=True, writable=True, bits=symbol.const_int)
+            node = Field(symbol.ident, ftype, ftype.name,
+                         readable=True, writable=True, bits=symbol.const_int)
         return node
 
     def _create_typedef(self, symbol):
@@ -473,7 +402,7 @@
         else:
             return derefed_typename
 
-    def _create_type(self, source_type, options, is_param, is_retval):
+    def _create_type(self, source_type, is_param, is_retval):
         ctype = self._create_source_type(source_type)
         if ctype == 'va_list':
             raise SkipError()
@@ -482,188 +411,37 @@
         elif ctype == 'FILE*':
             raise SkipError
 
-        canonical_ctype = self._canonicalize_ctype(ctype)
-
-        # Now check for a list/map/array type
-        if canonical_ctype in self._list_ctypes:
-            param = options.get('element-type')
-            if param:
-                contained_type = self.parse_ctype(param[0])
-            else:
-                contained_type = None
-            derefed_name = self.parse_ctype(ctype)
-            rettype = List(derefed_name,
-                           ctype,
-                           contained_type)
-        elif canonical_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
-            derefed_name = self.parse_ctype(ctype)
-            rettype = Map(derefed_name,
-                          ctype,
-                          key_type, value_type)
-        elif ((is_param and canonical_ctype in default_array_types
-               and not 'out' in options)
-              or ('array' in options)):
-            if canonical_ctype[-1] == '*':
-                derefed_name = canonical_ctype[:-1]
-            else:
-                derefed_name = canonical_ctype
-            rettype = Array(ctype,
-                            self.parse_ctype(derefed_name))
-            array_opts = dict([opt.split('=')
-                               for opt in options.get('array', [])])
-            if 'length' in array_opts:
-                rettype.length_param_name = array_opts['length']
-                rettype.zeroterminated = False
-            if 'fixed-size' in array_opts:
-                rettype.size = array_opts['fixed-size']
-                rettype.zeroterminated = False
-            if 'zero-terminated' in array_opts:
-                rettype.zeroterminated = array_opts['zero-terminated'] != '0'
-        else:
-            derefed_name = self.parse_ctype(ctype,
-                                            not (is_param or is_retval))
-            rettype = Type(derefed_name, ctype)
-
-        # Deduce direction for some types passed by reference that
-        # aren't arrays; modifies the options array.
-        if ('array' not in options and
-            not ('out' in options or
-                 'in' in options or
-                 'inout' in options or
-                 'in-out' in options) and
-            source_type.type == CTYPE_POINTER and
-            derefed_name in default_out_types):
-            options['out'] = []
-
-        if 'transfer' in options:
-            # Transfer is specified, we don't question it.
-            return rettype
+        is_member = not (is_param or is_retval)
+        # Here we handle basic type parsing; most of the heavy lifting
+        # and inference comes in annotationparser.py when we merge
+        # in annotation data.
+        derefed_name = self.parse_ctype(ctype, is_member)
+        rettype = Type(derefed_name, ctype)
+        rettype.canonical = self._canonicalize_ctype(ctype)
+        derefed_ctype = ctype.replace('*', '')
+        rettype.derefed_canonical = self._canonicalize_ctype(derefed_ctype)
 
         canontype = type_name_from_ctype(ctype)
-
-        # Since no transfer is specified, we drop into a bunch of
-        # heuristics to guess it.  This mutates the options array to
-        # set the 'transfer' option.
-        # Note that we inferred the transfer
-        options['transfer-inferred'] = []
-        stype = source_type
-        if canontype == TYPE_STRING:
-            # It's a string - we just look at 'const'
-            if source_type.base_type.type_qualifier & TYPE_QUALIFIER_CONST:
-                options['transfer'] = ['none']
-            else:
-                options['transfer'] = ['full']
-        elif 'array' in options or stype.type == CTYPE_ARRAY:
-            # It's rare to mutate arrays in public GObject APIs
-            options['transfer'] = ['none']
-        elif (canontype in BASIC_GIR_TYPES or
-              canontype == TYPE_NONE or
-              stype.type == CTYPE_ENUM):
-            # Basic types default to 'none'
-            options['transfer'] = ['none']
-        elif (stype.type == CTYPE_POINTER and
-              stype.base_type.type_qualifier & TYPE_QUALIFIER_CONST):
-            # Anything with 'const' gets none
-            options['transfer'] = ['none']
-        elif is_param and stype.type == CTYPE_POINTER:
-            # For generic pointer types, let's look at the argument
-            # direction.  An out/inout argument gets full, everything
-            # else none.
-            if ('out' in options or
-                'inout' in options or
-                'in-out' in options):
-                options['transfer'] = ['full']
-            else:
-                options['transfer'] = ['none']
-        else:
-            # For anything else we default to none for parameters;
-            # this covers enums and possibly some other corner cases.
-            # Return values of structures and the like will end up
-            # full.
-            if is_param:
-                options['transfer'] = ['none']
-            else:
-                options['transfer'] = ['full']
-
+        if ((canontype == TYPE_STRING or
+             source_type.type == CTYPE_POINTER) and
+            source_type.base_type.type_qualifier & TYPE_QUALIFIER_CONST):
+            rettype.is_const = True
         return rettype
 
-    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
-            elif option == 'transfer-inferred':
-                # This is a purely internal flag; we don't expect
-                # people to write it
-                param.transfer_inferred = True
-
-    def _create_parameter(self, symbol, options):
-        options = self._parse_options(options)
+    def _create_parameter(self, symbol):
         if symbol.type == CSYMBOL_TYPE_ELLIPSIS:
             ptype = Varargs()
-            if 'transfer' not in options:
-                options['transfer'] = ['none']
         else:
-            ptype = self._create_type(symbol.base_type, options,
+            ptype = self._create_type(symbol.base_type,
                                       is_param=True, is_retval=False)
             ptype = self.resolve_param_type(ptype)
-        param = Parameter(symbol.ident, ptype)
-        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 == 'allow-none':
-                param.allow_none = True
-            elif option.startswith(('element-type', 'array')):
-                pass
-            elif option in ('transfer', 'transfer-inferred'):
-                pass
-            elif option == 'scope':
-                param.scope = data[0]
-            else:
-                print 'Unhandled parameter annotation option: %r' % (
-                    option, )
-        self._handle_generic_param_options(param, options)
-
-        assert param.transfer is not None, param
-        return param
-
-    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,
+        return Parameter(symbol.ident, ptype)
+
+    def _create_return(self, source_type):
+        rtype = self._create_type(source_type,
                                   is_param=False, is_retval=True)
         rtype = self.resolve_param_type(rtype)
         return_ = Return(rtype)
-        self._handle_generic_param_options(return_, options_map)
-        for option, data in options_map.iteritems():
-            if option in ('transfer', 'transfer-inferred',
-                          'element-type', 'out'):
-                pass
-            elif option.startswith(('element-type', 'array')):
-                pass
-            else:
-                print 'Unhandled return type annotation option: %r' % (
-                    option, )
-
-        assert return_.transfer is not None, return_
         return return_
 
     def _create_const(self, symbol):
@@ -697,7 +475,6 @@
         return callback
 
     def _create_struct(self, symbol):
-        directives = symbol.directives()
         struct = self._typedefs_ns.get(symbol.ident, None)
         if struct is None:
             # This is a bit of a hack; really we should try
@@ -715,12 +492,9 @@
             if field:
                 struct.fields.append(field)
 
-        self._parse_version(struct, directives)
-
         return struct
 
     def _create_union(self, symbol):
-        directives = symbol.directives()
         union = self._typedefs_ns.get(symbol.ident, None)
         if union is None:
             # This is a bit of a hack; really we should try
@@ -738,24 +512,17 @@
             if field:
                 union.fields.append(field)
 
-        self._parse_version(union, directives)
-
         return union
 
     def _create_callback(self, symbol):
-        directives = symbol.directives()
-        parameters = self._create_parameters(symbol.base_type.base_type,
-            directives)
-        retval = self._create_return(symbol.base_type.base_type.base_type,
-            directives.get('return', {}))
+        parameters = self._create_parameters(symbol.base_type.base_type)
+        retval = self._create_return(symbol.base_type.base_type.base_type)
         if symbol.ident.find('_') > 0:
             name = self.remove_prefix(symbol.ident, True)
         else:
             name = self.remove_prefix(symbol.ident)
         callback = Callback(name, retval, list(parameters), symbol.ident)
 
-        self._parse_version(callback, directives)
-
         return callback
 
     def _typepair_to_str(self, item):
@@ -833,19 +600,6 @@
             ptype.name = self.resolve_type_name_full(ptype.name,
                                                      self.ctype_of(ptype),
                                                      names, **kwargs)
-            if isinstance(ptype, (Array, List)):
-                if ptype.element_type is not None:
-                    ptype.element_type = \
-                        self.resolve_param_type_full(ptype.element_type,
-                                                     names, **kwargs)
-            if isinstance(ptype, Map):
-                if ptype.key_type is not None:
-                    ptype.key_type = \
-                        self.resolve_param_type_full(ptype.key_type,
-                                                     names, **kwargs)
-                    ptype.value_type = \
-                        self.resolve_param_type_full(ptype.value_type,
-                                                     names, **kwargs)
         elif isinstance(ptype, basestring):
             return self.resolve_type_name_full(ptype, None, names, **kwargs)
         else:

Modified: trunk/giscanner/xmlwriter.py
==============================================================================
--- trunk/giscanner/xmlwriter.py	(original)
+++ trunk/giscanner/xmlwriter.py	Mon Jan 12 20:11:44 2009
@@ -82,6 +82,7 @@
         self._indent_char = ' '
 
     # Private
+
     def _open_tag(self, tag_name, attributes=None):
         attrs = collect_attributes(
             tag_name, attributes, self._indent,
@@ -93,6 +94,7 @@
         self.write_line('</%s>' % (tag_name, ))
 
     # Public API
+
     def get_xml(self):
         return self._data.getvalue()
 

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	Mon Jan 12 20:11:44 2009
@@ -328,5 +328,12 @@
         <type name="none" c:type="void"/>
       </return-value>
     </function>
+    <record name="Struct" c:type="_AnnotationStruct">
+      <field name="objects" writable="1">
+        <array zero-terminated="0" c:type="AnnotationObject*" fixed-size="10">
+          <type name="Object"/>
+        </array>
+      </field>
+    </record>
   </namespace>
 </repository>

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	Mon Jan 12 20:11:44 2009
@@ -306,5 +306,12 @@
         <type name="none"/>
       </return-value>
     </function>
+    <record name="Struct">
+      <field name="objects" writable="1">
+        <array fixed-size="10">
+          <type name="Object"/>
+        </array>
+      </field>
+    </record>
   </namespace>
 </repository>

Modified: trunk/tests/scanner/annotation.c
==============================================================================
--- trunk/tests/scanner/annotation.c	(original)
+++ trunk/tests/scanner/annotation.c	Mon Jan 12 20:11:44 2009
@@ -50,7 +50,7 @@
  *
  * This is a test for in arguments
  *
- * @inarg: (in): This is an argument test
+ * @inarg: (in): (transfer none): This is an argument test
  * Return value: an int
  */
 gint
@@ -246,7 +246,7 @@
 /**
  * annotation_object_compute_sum_n:
  * @object: a #GObject
- * @nums: (array length=n_nums): Sequence of numbers
+ * @nums: (array length=n_nums zero-terminated=0): Sequence of numbers
  * @n_nums: Length of number array
  *
  * Test taking an array with length parameter

Modified: trunk/tests/scanner/annotation.h
==============================================================================
--- trunk/tests/scanner/annotation.h	(original)
+++ trunk/tests/scanner/annotation.h	Mon Jan 12 20:11:44 2009
@@ -90,4 +90,9 @@
 char **  annotation_return_array        (int             *length);
 void     annotation_versioned           (void);
 
+struct _AnnotationStruct
+{
+  AnnotationObject *objects[10];
+};
+
 #endif /* __ANNOTATION_OBJECT_H__ */

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	Mon Jan 12 20:11:44 2009
@@ -578,6 +578,40 @@
         </parameter>
       </parameters>
     </function>
+    <function name="test_const_char_retval"
+              c:identifier="foo_test_const_char_retval">
+      <return-value transfer-ownership="none">
+        <type name="utf8" c:type="char*"/>
+      </return-value>
+    </function>
+    <function name="test_const_struct_retval"
+              c:identifier="foo_test_const_struct_retval">
+      <return-value transfer-ownership="none">
+        <type name="Struct" c:type="FooStruct*"/>
+      </return-value>
+    </function>
+    <function name="test_const_char_param"
+              c:identifier="foo_test_const_char_param">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="param" transfer-ownership="none">
+          <type name="utf8" c:type="char*"/>
+        </parameter>
+      </parameters>
+    </function>
+    <function name="test_const_struct_param"
+              c:identifier="foo_test_const_struct_param">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="param" transfer-ownership="none">
+          <type name="Struct" c:type="FooStruct*"/>
+        </parameter>
+      </parameters>
+    </function>
     <constant name="SUCCESS_INT" value="4408">
       <type name="int"/>
     </constant>

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	Mon Jan 12 20:11:44 2009
@@ -453,6 +453,36 @@
         </parameter>
       </parameters>
     </function>
+    <function name="test_const_char_retval" c:identifier="foo_test_const_char_retval">
+      <return-value transfer-ownership="none">
+        <type name="utf8"/>
+      </return-value>
+    </function>
+    <function name="test_const_struct_retval" c:identifier="foo_test_const_struct_retval">
+      <return-value transfer-ownership="none">
+        <type name="Struct"/>
+      </return-value>
+    </function>
+    <function name="test_const_char_param" c:identifier="foo_test_const_char_param">
+      <return-value transfer-ownership="none">
+        <type name="none"/>
+      </return-value>
+      <parameters>
+        <parameter name="param" transfer-ownership="none">
+          <type name="utf8"/>
+        </parameter>
+      </parameters>
+    </function>
+    <function name="test_const_struct_param" c:identifier="foo_test_const_struct_param">
+      <return-value transfer-ownership="none">
+        <type name="none"/>
+      </return-value>
+      <parameters>
+        <parameter name="param" transfer-ownership="none">
+          <type name="Struct"/>
+        </parameter>
+      </parameters>
+    </function>
     <constant name="SUCCESS_INT" value="4408">
       <type name="int"/>
     </constant>

Modified: trunk/tests/scanner/foo.h
==============================================================================
--- trunk/tests/scanner/foo.h	(original)
+++ trunk/tests/scanner/foo.h	Mon Jan 12 20:11:44 2009
@@ -281,4 +281,9 @@
 
 void foo_test_string_array_with_g (gchar **array);
 
+const char * foo_test_const_char_retval (void);
+const FooStruct * foo_test_const_struct_retval (void);
+void foo_test_const_char_param (const char * param);
+void foo_test_const_struct_param (const FooStruct * param);
+
 #endif /* __FOO_OBJECT_H__ */

Modified: trunk/tools/g-ir-scanner
==============================================================================
--- trunk/tools/g-ir-scanner	(original)
+++ trunk/tools/g-ir-scanner	Mon Jan 12 20:11:44 2009
@@ -41,6 +41,7 @@
                         'site-packages')
 sys.path.insert(0, path)
 
+from giscanner.annotationparser import AnnotationParser, InvalidAnnotationError
 from giscanner.ast import Include
 from giscanner.cachestore import CacheStore
 from giscanner.dumper import compile_introspection_binary
@@ -313,6 +314,12 @@
 
     namespace = glibtransformer.parse()
 
+    ap = AnnotationParser(namespace, ss, transformer)
+    try:
+        ap.parse()
+    except InvalidAnnotationError, e:
+        raise SystemExit("ERROR in annotation: %s" % (str(e), ))
+
     # Write out AST
     writer = Writer(namespace, libraries, transformer.get_includes())
     data = writer.get_xml()



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