summaryrefslogtreecommitdiff
path: root/giscanner/maintransformer.py
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2015-09-27 14:32:38 -0400
committerColin Walters <walters@verbum.org>2015-09-27 14:32:45 -0400
commit7c37a16ade424cf063414ce0dd4d170fd2f9c9b1 (patch)
tree0b09436c3e8c6dafd98c2e539fc9d2d8c8aecd6e /giscanner/maintransformer.py
parent4d9453f218074d03a5c44dbd44eeadb8e9e89f6c (diff)
downloadgobject-introspection-7c37a16ade424cf063414ce0dd4d170fd2f9c9b1.tar.gz
scanner: Warn and ignore on incorrect transfer annotations
This reverts commit 232f3c831260f596e36159112292897962a505b4.
Diffstat (limited to 'giscanner/maintransformer.py')
-rw-r--r--giscanner/maintransformer.py68
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: