diff options
author | Garrett Regier <garrett.regier@riftio.com> | 2015-09-26 11:55:09 -0400 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2015-09-26 11:55:09 -0400 |
commit | 5ae7bd58b6266997b61d897ad6562118eeb59210 (patch) | |
tree | c68c962a7c690969471531369b07ea4dbef9a77a /giscanner/maintransformer.py | |
parent | b503f31c7cfa3329456de9bff5a2c816a607285e (diff) | |
download | gobject-introspection-5ae7bd58b6266997b61d897ad6562118eeb59210.tar.gz |
scanner: Warn and ignore on incorrect transfer annotations
This is an issue in various code bases and tends
to confuse newcomers.
https://bugzilla.gnome.org/show_bug.cgi?id=752047
Signed-off-by: Garrett Regier <garrett.regier@riftio.com>
Diffstat (limited to 'giscanner/maintransformer.py')
-rw-r--r-- | giscanner/maintransformer.py | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py index b138a121..6c0429da 100644 --- a/giscanner/maintransformer.py +++ b/giscanner/maintransformer.py @@ -30,7 +30,7 @@ from .annotationparser import (ANN_ALLOW_NONE, ANN_ARRAY, ANN_ATTRIBUTES, ANN_CL ANN_VFUNC, ANN_NULLABLE, ANN_OPTIONAL) from .annotationparser import (OPT_ARRAY_FIXED_SIZE, OPT_ARRAY_LENGTH, OPT_ARRAY_ZERO_TERMINATED, OPT_OUT_CALLEE_ALLOCATES, OPT_OUT_CALLER_ALLOCATES, - OPT_TRANSFER_FLOATING, OPT_TRANSFER_NONE) + OPT_TRANSFER_CONTAINER, OPT_TRANSFER_FLOATING, OPT_TRANSFER_NONE) from .utils import to_underscores_noprefix @@ -467,7 +467,7 @@ class MainTransformer(object): def _get_transfer_default_returntype_basic(self, typeval): if (typeval.is_equiv(ast.BASIC_GIR_TYPES) or typeval.is_const - or typeval.is_equiv(ast.TYPE_NONE)): + or typeval.is_equiv((ast.TYPE_ANY, ast.TYPE_NONE))): return ast.PARAM_TRANSFER_NONE elif typeval.is_equiv(ast.TYPE_STRING): # Non-const strings default to FULL @@ -537,6 +537,62 @@ class MainTransformer(object): else: raise AssertionError(node) + def _is_pointer_type(self, node, annotations): + if (not isinstance(node, ast.Return) and + node.direction in (ast.PARAM_DIRECTION_OUT, + ast.PARAM_DIRECTION_INOUT)): + return True + + target = self._transformer.lookup_typenode(node.type) + target = self._transformer.resolve_aliases(target) + target = node.type if target is None else target + + return (not isinstance(target, ast.Type) or + target not in ast.BASIC_TYPES or + target.ctype.endswith('*')) + + def _apply_transfer_annotation(self, parent, node, annotations): + transfer_annotation = annotations.get(ANN_TRANSFER) + if not transfer_annotation or len(transfer_annotation) != 1: + return + + transfer = transfer_annotation[0] + + target = self._transformer.lookup_typenode(node.type) + target = self._transformer.resolve_aliases(target) + target = node.type if target is None else target + node_type = target if isinstance(target, ast.Type) else node.type + + if transfer == OPT_TRANSFER_FLOATING: + transfer = OPT_TRANSFER_NONE + + if not isinstance(target, (ast.Class, ast.Interface)): + message.warn('invalid "transfer" annotation: ' + 'only valid for object and interface types', + annotations.position) + return + + elif transfer == OPT_TRANSFER_CONTAINER: + if (ANN_ARRAY not in annotations and + not isinstance(target, (ast.Array, ast.List, ast.Map))): + message.warn('invalid "transfer" annotation: ' + 'only valid for container types', + annotations.position) + return + + elif (not self._is_pointer_type(node, annotations) and + node_type not in (ast.TYPE_STRING, ast.TYPE_FILENAME) and + not isinstance(target, (ast.Array, ast.List, ast.Map, + ast.Record, ast.Compound, ast.Boxed, + ast.Class, ast.Interface))): + message.warn('invalid "transfer" annotation: ' + 'only valid for array, struct, union, boxed, ' + 'object and interface types', + annotations.position) + return + + node.transfer = transfer + def _apply_annotations_param_ret_common(self, parent, node, tag): annotations = tag.annotations if tag else {} @@ -577,13 +633,7 @@ class MainTransformer(object): # Also reset the transfer default if we're toggling direction node.transfer = self._get_transfer_default(parent, node) - transfer_annotation = annotations.get(ANN_TRANSFER) - if transfer_annotation and len(transfer_annotation) == 1: - transfer = transfer_annotation[0] - if transfer == OPT_TRANSFER_FLOATING: - transfer = OPT_TRANSFER_NONE - node.transfer = transfer - + self._apply_transfer_annotation(parent, node, annotations) self._adjust_container_type(parent, node, annotations) if ANN_NULLABLE in annotations: |