diff options
author | Tomeu Vizoso <tomeu.vizoso@collabora.co.uk> | 2011-01-21 17:32:51 +0100 |
---|---|---|
committer | Tomeu Vizoso <tomeu.vizoso@collabora.co.uk> | 2011-01-28 16:57:04 +0100 |
commit | 2c36790c0b5f8d74b77f0e7bbcbe2a81600018c5 (patch) | |
tree | c1dfe8d6fee47249cd94844a4ddfc99d9433080b | |
parent | 313fc70cee983220b7580010062d19aed71a6ab0 (diff) | |
download | gobject-introspection-2c36790c0b5f8d74b77f0e7bbcbe2a81600018c5.tar.gz |
Add (constructor) annotation
https://bugzilla.gnome.org/show_bug.cgi?id=561264
-rw-r--r-- | giscanner/annotationparser.py | 6 | ||||
-rw-r--r-- | giscanner/maintransformer.py | 33 | ||||
-rw-r--r-- | tests/scanner/Regress-1.0-expected.gir | 11 | ||||
-rw-r--r-- | tests/scanner/regress.c | 10 | ||||
-rw-r--r-- | tests/scanner/regress.h | 1 |
5 files changed, 49 insertions, 12 deletions
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py index 03a88832..3b376be2 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 8520dd8e..893b3b71 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 abf46f14..45f62c0a 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 f9c4b371..ad5cd255 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 2a3b3516..91b00843 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); |