[gobject-introspection] Add (constructor) annotation



commit 2c36790c0b5f8d74b77f0e7bbcbe2a81600018c5
Author: Tomeu Vizoso <tomeu vizoso collabora co uk>
Date:   Fri Jan 21 17:32:51 2011 +0100

    Add (constructor) annotation
    
    https://bugzilla.gnome.org/show_bug.cgi?id=561264

 giscanner/annotationparser.py          |    6 ++++-
 giscanner/maintransformer.py           |   33 +++++++++++++++++++++----------
 tests/scanner/Regress-1.0-expected.gir |   11 ++++++++++
 tests/scanner/regress.c                |   10 +++++++++
 tests/scanner/regress.h                |    1 +
 5 files changed, 49 insertions(+), 12 deletions(-)
---
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index 03a8883..3b376be 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -54,6 +54,7 @@ OPT_SCOPE = 'scope'
 OPT_TRANSFER = 'transfer'
 OPT_TYPE = 'type'
 OPT_SKIP = 'skip'
+OPT_CONSTRUCTOR = 'constructor'
 
 ALL_OPTIONS = [
     OPT_ALLOW_NONE,
@@ -70,7 +71,8 @@ ALL_OPTIONS = [
     OPT_SCOPE,
     OPT_TRANSFER,
     OPT_TYPE,
-    OPT_SKIP]
+    OPT_SKIP,
+    OPT_CONSTRUCTOR]
 
 # Array options - array specific annotations
 OPT_ARRAY_FIXED_SIZE = 'fixed-size'
@@ -326,6 +328,8 @@ class DocTag(object):
             elif option == OPT_TYPE:
                 self._validate_option('type', value, required=True,
                                       n_params=1)
+            elif option == OPT_CONSTRUCTOR:
+                self._validate_option('constructor', value, n_params=0)
             else:
                 message.warn('invalid annotation option: %s' % (option, ),
                              self.position)
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index 8520dd8..893b3b7 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -31,7 +31,8 @@ from .annotationparser import (OPT_ALLOW_NONE, OPT_ARRAY, OPT_ATTRIBUTE,
                                OPT_OUT_CALLER_ALLOCATES, OPT_OUT_CALLEE_ALLOCATES,
                                OPT_TYPE, OPT_CLOSURE, OPT_DESTROY, OPT_TRANSFER, OPT_SKIP,
                                OPT_FOREIGN, OPT_ARRAY_FIXED_SIZE,
-                               OPT_ARRAY_LENGTH, OPT_ARRAY_ZERO_TERMINATED)
+                               OPT_ARRAY_LENGTH, OPT_ARRAY_ZERO_TERMINATED,
+                               OPT_CONSTRUCTOR)
 from .annotationparser import AnnotationParser
 from .transformer import TransformerException
 from .utils import to_underscores, to_underscores_noprefix
@@ -574,6 +575,9 @@ usage is void (*_gtk_reserved1)(void);"""
         if OPT_FOREIGN in block.options:
             node.foreign = True
 
+        if OPT_CONSTRUCTOR in block.options and isinstance(node, ast.Function):
+            node.is_constructor = True
+
     def _apply_annotations_alias(self, node, chain):
         block = self._get_block(node)
         self._apply_annotations_annotated(node, block)
@@ -885,7 +889,8 @@ method or constructor of some type."""
             return
         (ns, subsymbol) = self._transformer.split_csymbol(func.symbol)
         assert ns == self._namespace
-        if self._pair_constructor(func, subsymbol):
+        if func.is_constructor or self._is_constructor(func, subsymbol):
+            self._set_up_constructor(func, subsymbol)
             return
         elif self._pair_method(func, subsymbol):
             return
@@ -957,7 +962,20 @@ method or constructor of some type."""
         func.name = funcname
         node.static_methods.append(func)
 
-    def _pair_constructor(self, func, subsymbol):
+    def _set_up_constructor(self, func, subsymbol):
+        self._namespace.float(func)
+
+        origin_node, funcname = self._split_uscored_by_type(subsymbol)
+        func.name = funcname
+        origin_node.constructors.append(func)
+
+        func.is_constructor = True
+
+        # Constructors have default return semantics
+        if not func.retval.transfer:
+            func.retval.transfer = self._get_transfer_default_return(func, func.retval)
+
+    def _is_constructor(self, func, subsymbol):
         if not (func.symbol.find('_new_') >= 0 or func.symbol.endswith('_new')):
             return False
         target = self._transformer.lookup_typenode(func.retval.type)
@@ -968,7 +986,6 @@ method or constructor of some type."""
 
         split = self._split_uscored_by_type(subsymbol)
         if split is None:
-            # TODO - need a e.g. (method) annotation
             message.warn_node(func,
                 "Can't find matching type for constructor; symbol=%r" % (func.symbol, ))
             return False
@@ -1013,13 +1030,7 @@ method or constructor of some type."""
                     str(origin_node.create_type()),
                     str(func.retval.type)))
                 return False
-        self._namespace.float(func)
-        func.name = funcname
-        func.is_constructor = True
-        origin_node.constructors.append(func)
-        # Constructors have default return semantics
-        if not func.retval.transfer:
-            func.retval.transfer = self._get_transfer_default_return(func, func.retval)
+
         return True
 
     def _pair_class_virtuals(self, node):
diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir
index abf46f1..45f62c0 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -372,6 +372,17 @@ use it should be.</doc>
            glib:type-name="RegressTestObj"
            glib:get-type="regress_test_obj_get_type"
            glib:type-struct="TestObjClass">
+      <constructor name="new" c:identifier="regress_test_obj_new">
+        <return-value transfer-ownership="full">
+          <type name="TestObj" c:type="RegressTestObj*"/>
+        </return-value>
+        <parameters>
+          <parameter name="obj" transfer-ownership="none">
+            <doc xml:whitespace="preserve">A #RegressTestObj</doc>
+            <type name="TestObj" c:type="RegressTestObj*"/>
+          </parameter>
+        </parameters>
+      </constructor>
       <constructor name="new_callback"
                    c:identifier="regress_test_obj_new_callback">
         <return-value transfer-ownership="full">
diff --git a/tests/scanner/regress.c b/tests/scanner/regress.c
index f9c4b37..ad5cd25 100644
--- a/tests/scanner/regress.c
+++ b/tests/scanner/regress.c
@@ -1910,6 +1910,16 @@ regress_test_obj_init (RegressTestObj *obj)
 }
 
 /**
+ * regress_test_obj_new: (constructor)
+ * @obj: A #RegressTestObj
+ */
+RegressTestObj *
+regress_test_obj_new (RegressTestObj *obj)
+{
+  return g_object_new (REGRESS_TEST_TYPE_OBJ, NULL);
+}
+
+/**
  * regress_test_obj_new_from_file:
  */
 RegressTestObj *
diff --git a/tests/scanner/regress.h b/tests/scanner/regress.h
index 2a3b351..91b0084 100644
--- a/tests/scanner/regress.h
+++ b/tests/scanner/regress.h
@@ -297,6 +297,7 @@ struct _RegressTestObjClass
 };
 
 GType      regress_test_obj_get_type (void);
+RegressTestObj*   regress_test_obj_new (RegressTestObj *obj);
 RegressTestObj*   regress_test_obj_new_from_file (const char *x, GError **error);
 void       regress_test_obj_set_bare (RegressTestObj *obj, GObject *bare);
 int        regress_test_obj_instance_method (RegressTestObj *obj);



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