Validate transfer annnotations
authorJohan Dahlin <johan@gnome.org>
Thu, 23 Sep 2010 21:36:37 +0000 (18:36 -0300)
committerJohan Dahlin <johan@gnome.org>
Thu, 23 Sep 2010 21:53:55 +0000 (18:53 -0300)
giscanner/annotationparser.py
giscanner/maintransformer.py
tests/warn/Makefile.am
tests/warn/invalid-transfer.h [new file with mode: 0644]

index 376919d..4febc59 100644 (file)
@@ -84,6 +84,12 @@ OPT_SCOPE_ASYNC = 'async'
 OPT_SCOPE_CALL = 'call'
 OPT_SCOPE_NOTIFIED = 'notified'
 
+# Transfer options
+OPT_TRANSFER_NONE = 'none'
+OPT_TRANSFER_CONTAINER = 'container'
+OPT_TRANSFER_FULL = 'full'
+
+
 class DocBlock(object):
 
     def __init__(self, name):
@@ -124,7 +130,22 @@ class DocTag(object):
             if not option in ALL_OPTIONS:
                 message.warn('invalid option: %s' % (option, ),
                              positions=self.position)
-
+            if option == OPT_TRANSFER:
+                value = self.options[option]
+                if value is None:
+                    message.warn('transfer needs a value',
+                                 self.position)
+                    continue
+                if value.length() != 1:
+                    message.warn('transfer needs one value, not %d' % (
+                        value.length()), self.position)
+                    continue
+                valuestr = value.one()
+                if valuestr not in [OPT_TRANSFER_NONE,
+                                    OPT_TRANSFER_CONTAINER,
+                                    OPT_TRANSFER_FULL]:
+                    message.warn('invalid transfer value: %r' % (
+                        valuestr, ), self.position)
 
 class DocOptions(object):
     def __init__(self):
@@ -178,6 +199,9 @@ class DocOption(object):
     def __repr__(self):
         return '<DocOption %r>' % (self._array, )
 
+    def length(self):
+        return len(self._array)
+
     def one(self):
         assert len(self._array) == 1
         return self._array[0]
index f36e5b7..d41b55f 100644 (file)
@@ -496,7 +496,7 @@ usage is void (*_gtk_reserved1)(void);"""
             node.transfer = self._get_transfer_default(parent, node)
 
         transfer_tag = options.get(OPT_TRANSFER)
-        if transfer_tag:
+        if transfer_tag and transfer_tag.length() == 1:
             node.transfer = transfer_tag.one()
 
         self._adjust_container_type(parent, node, options)
index 44515d7..bdcc970 100644 (file)
@@ -5,6 +5,7 @@ TESTS = \
        callback-missing-scope.h \
        return-gobject.h \
        invalid-option.h \
+       invalid-transfer.h \
        unknown-parameter.h \
        unresolved-element-type.h \
        unresolved-type.h
diff --git a/tests/warn/invalid-transfer.h b/tests/warn/invalid-transfer.h
new file mode 100644 (file)
index 0000000..3579ad1
--- /dev/null
@@ -0,0 +1,12 @@
+
+/**
+ * test_transfer_invalid:
+ * @param: (transfer):
+ * @param2: (transfer invalid):
+ * @param3: (transfer full foo):
+ */
+void test_transfer_invalid(int param, int param2, int param3);
+
+// EXPECT:4: Warning: Test: transfer annotation needs a value
+// EXPECT:5: Warning: Test: invalid transfer annotation value: 'invalid'
+// EXPECT:6: Warning: Test: transfer annotation needs one value, not 2