Assume allow-none for GCancellable
[gnome.gobject-introspection] / giscanner / annotationparser.py
index 67d732e..fe5e721 100644 (file)
@@ -209,8 +209,9 @@ class AnnotationParser(object):
             tag_name, value = self._split_tag_namevalue(line)
             canon_name = tag_name.lower()
             if canon_name in block.tags:
-                print >>sys.stderr, "Multiple definition of tag %r" \
-                    % (canon_name, )
+                print >> sys.stderr, (
+                    "Symbol %s has multiple definition of tag %r" % (
+                    block_name, canon_name, ))
             block.tags[canon_name] = self._create_tag(canon_name, value)
         block.comment = '\n'.join(comment_lines)
         self._blocks[block.name] = block
@@ -221,6 +222,8 @@ class AnnotationParser(object):
         if len(parts) == 1:
             tag_name = parts[0]
             value = ''
+            if tag_name.endswith(':'):
+                tag_name = tag_name[:-1]
         else:
             tag_name, value = parts
         return (tag_name, value)
@@ -414,7 +417,8 @@ class AnnotationApplier(object):
     def _parse_callable(self, callable, block):
         self._parse_node_common(callable, block)
         for i, param in enumerate(callable.parameters):
-            if param.type.name not in ['DestroyNotify', 'GLib.DestroyNotify']:
+            if (param.type.ctype != 'GDestroyNotify' and
+                param.type.name != 'GLib.DestroyNotify'):
                 continue
             if i < 2:
                 break
@@ -503,13 +507,13 @@ class AnnotationApplier(object):
 
     def _parse_param(self, parent, param, tag):
         options = getattr(tag, 'options', {})
-        if isinstance(parent, Function) and not param.scope:
+        if isinstance(parent, Function):
             scope = options.get(OPT_SCOPE)
             if scope:
                 param.scope = scope.one()
                 param.transfer = PARAM_TRANSFER_NONE
-            elif param.type.name in ['AsyncReadyCallback',
-                                     'Gio.AsyncReadyCallback']:
+            elif (param.type.ctype == 'GAsyncReadyCallback' or
+                  param.type.name == 'Gio.AsyncReadyCallback'):
                 param.scope = OPT_SCOPE_ASYNC
                 param.transfer = PARAM_TRANSFER_NONE
 
@@ -548,12 +552,14 @@ class AnnotationApplier(object):
         if node.direction is None:
             node.direction = self._guess_direction(node)
         node.transfer = self._extract_transfer(parent, node, options)
-        if OPT_ALLOW_NONE in options:
-            node.allow_none = True
         param_type = options.get(OPT_TYPE)
         if param_type:
             node.type = self._resolve(param_type.one(), node.type)
 
+        if (OPT_ALLOW_NONE in options or
+            node.type.ctype == 'GCancellable*'):
+            node.allow_none = True
+
         assert node.transfer is not None
         if tag is not None and tag.comment is not None:
             node.doc = tag.comment
@@ -658,9 +664,11 @@ class AnnotationApplier(object):
         def combiner(base, *rest):
             if not rest:
                 return base
-            if base.name in ['GLib.List', 'GLib.SList'] and len(rest)==1:
+            if (base.name in ['GLib.List', 'GLib.SList'] or
+                base.ctype in ['GList*', 'GSList*']) and len(rest)==1:
                 return List(base.name, base.ctype, *rest)
-            if base.name in ['GLib.HashTable'] and len(rest)==2:
+            if (base.name in ['GLib.HashTable'] or
+                base.ctype in ['GHashTable*']) and len(rest)==2:
                 return Map(base.name, base.ctype, *rest)
             print "WARNING: throwing away type parameters:", type_str
             return base
@@ -679,13 +687,15 @@ class AnnotationApplier(object):
     def _parse_element_type(self, parent, node, options):
         element_type_opt = options.get(OPT_ELEMENT_TYPE)
         element_type = element_type_opt.flat()
-        if node.type.name in ['GLib.List', 'GLib.SList']:
+        if (node.type.name in ['GLib.List', 'GLib.SList'] or
+            node.type.ctype in ['GList*', 'GSList*']):
             assert len(element_type) == 1
             container_type = List(
                 node.type.name,
                 node.type.ctype,
                 self._resolve(element_type[0]))
-        elif node.type.name in ['GLib.HashTable']:
+        elif (node.type.name in ['GLib.HashTable'] or
+              node.type.ctype in ['GHashTable*']):
             assert len(element_type) == 2
             container_type = Map(
                 node.type.name,