[gobject-introspection] scanner: Don't parse constructors on non-registered, warn for return values
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gobject-introspection] scanner: Don't parse constructors on non-registered, warn for return values
- Date: Wed, 1 Sep 2010 18:26:50 +0000 (UTC)
commit f7f93038881b1fe4be7356dc0ce2b1af0776fac4
Author: Colin Walters <walters verbum org>
Date: Wed Sep 1 14:25:46 2010 -0400
scanner: Don't parse constructors on non-registered, warn for return values
First, we can't support constructors on unregistered types.
Second, warn if we see a return value of an unregistered.
giscanner/introspectablepass.py | 57 +++++++++++++++++++++++++++--------
giscanner/maintransformer.py | 2 +-
tests/scanner/Foo-1.0-expected.gir | 30 ++++++++++---------
tests/scanner/foo.c | 17 +++++++++++
4 files changed, 78 insertions(+), 28 deletions(-)
---
diff --git a/giscanner/introspectablepass.py b/giscanner/introspectablepass.py
index 61604b1..4d19ab3 100644
--- a/giscanner/introspectablepass.py
+++ b/giscanner/introspectablepass.py
@@ -54,30 +54,61 @@ class IntrospectablePass(object):
self._transformer.log_node_warning(parent, prefix + context + text, *args)
def _introspectable_param_analysis(self, parent, node):
+ is_return = isinstance(node, ast.Return)
+ is_parameter = isinstance(node, ast.Parameter)
+ assert is_return or is_parameter
+
+ if node.type.target_giname is not None:
+ target = self._transformer.lookup_typenode(node.type)
+ else:
+ target = None
+
if not node.type.resolved:
self._parameter_warning(parent, node, "Unresolved ctype: %r" % (node.type.ctype, ))
parent.introspectable = False
- elif isinstance(node.type, ast.Varargs):
+ return
+
+ if isinstance(node.type, ast.Varargs):
parent.introspectable = False
- elif not isinstance(node.type, ast.List) and \
+ return
+
+ if not isinstance(node.type, ast.List) and \
(node.type.target_giname == 'GLib.List'):
self._parameter_warning(parent, node, "Missing (element-type) annotation")
parent.introspectable = False
- elif node.transfer is None:
- self._parameter_warning(parent, node, "Missing (transfer) annotation")
- parent.introspectable = False
+ return
- if isinstance(node, ast.Parameter) and node.type.target_giname:
- target = self._transformer.lookup_typenode(node.type)
- if (isinstance(target, ast.Callback)
- and not target.create_type().target_giname in ('GLib.DestroyNotify',
- 'Gio.AsyncReadyCallback')
- and node.scope is None):
+ if (is_parameter
+ and isinstance(target, ast.Callback)
+ and not node.type.target_giname in ('GLib.DestroyNotify',
+ 'Gio.AsyncReadyCallback')
+ and node.scope is None):
self._parameter_warning(parent, node,
("Missing (scope) annotation for callback" +
" without GDestroyNotify (valid: %s, %s)")
% (ast.PARAM_SCOPE_CALL, ast.PARAM_SCOPE_ASYNC))
parent.introspectable = False
+ return
+
+ if is_return and isinstance(target, ast.Callback):
+ self._parameter_warning(parent, node, "Callbacks cannot be return values; use (skip)")
+ parent.introspectable = False
+ return
+
+ if (is_return
+ and isinstance(target, (ast.Record, ast.Union))
+ and not target.foreign
+ and not isinstance(target, glibast.GLibBoxed)):
+ if node.transfer != ast.PARAM_TRANSFER_NONE:
+ self._parameter_warning(parent, node,
+"Invalid non-constant return of bare structure or union; register as boxed type or (skip)")
+ parent.introspectable = False
+ return
+
+ if node.transfer is None:
+ self._parameter_warning(parent, node, "Missing (transfer) annotation")
+ parent.introspectable = False
+ return
def _type_is_introspectable(self, typeval, warn=False):
if not typeval.resolved:
@@ -127,7 +158,7 @@ class IntrospectablePass(object):
def _introspectable_callable_analysis(self, obj, stack):
if obj.skip:
- return True
+ return False
# Propagate introspectability of parameters to entire functions
if isinstance(obj, ast.Callable):
for param in obj.parameters:
@@ -141,7 +172,7 @@ class IntrospectablePass(object):
def _introspectable_pass3(self, obj, stack):
if obj.skip:
- return True
+ return False
# Propagate introspectability for fields
if isinstance(obj, (ast.Class, ast.Interface, ast.Record, ast.Union)):
for field in obj.fields:
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index 460f8b3..5463744 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -794,7 +794,7 @@ method or constructor of some type."""
if not (func.symbol.find('_new_') >= 0 or func.symbol.endswith('_new')):
return False
target = self._transformer.lookup_typenode(func.retval.type)
- if not isinstance(target, (ast.Class, ast.Record, ast.Union, glibast.GLibBoxedOther)):
+ if not isinstance(target, (ast.Class, glibast.GLibBoxed)):
return False
new_idx = func.symbol.rfind('_new')
assert (new_idx >= 0)
diff --git a/tests/scanner/Foo-1.0-expected.gir b/tests/scanner/Foo-1.0-expected.gir
index c52a923..73c0310 100644
--- a/tests/scanner/Foo-1.0-expected.gir
+++ b/tests/scanner/Foo-1.0-expected.gir
@@ -565,8 +565,21 @@ uses a C sugar return type.</doc>
<field name="height" writable="1">
<type name="gint" c:type="gint"/>
</field>
- <constructor name="new" c:identifier="foo_rectangle_new">
- <return-value transfer-ownership="full">
+ <method name="add" c:identifier="foo_rectangle_add">
+ <return-value transfer-ownership="none">
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <parameter name="r2" transfer-ownership="none">
+ <doc xml:whitespace="preserve">source rectangle</doc>
+ <type name="Rectangle" c:type="FooRectangle*"/>
+ </parameter>
+ </parameters>
+ </method>
+ <function name="new" c:identifier="foo_rectangle_new" introspectable="0">
+ <doc xml:whitespace="preserve">This is a C convenience constructor; we have to (skip)
+it because it's not a boxed type.</doc>
+ <return-value>
<type name="Rectangle" c:type="FooRectangle*"/>
</return-value>
<parameters>
@@ -583,18 +596,7 @@ uses a C sugar return type.</doc>
<type name="gint" c:type="int"/>
</parameter>
</parameters>
- </constructor>
- <method name="add" c:identifier="foo_rectangle_add">
- <return-value transfer-ownership="none">
- <type name="none" c:type="void"/>
- </return-value>
- <parameters>
- <parameter name="r2" transfer-ownership="none">
- <doc xml:whitespace="preserve">source rectangle</doc>
- <type name="Rectangle" c:type="FooRectangle*"/>
- </parameter>
- </parameters>
- </method>
+ </function>
</record>
<constant name="SUCCESS_INT" value="4408">
<type name="gint" c:type="gint"/>
diff --git a/tests/scanner/foo.c b/tests/scanner/foo.c
index d66817f..db578ec 100644
--- a/tests/scanner/foo.c
+++ b/tests/scanner/foo.c
@@ -497,6 +497,23 @@ foo_test_array (void)
}
/**
+ * foo_rectangle_new: (skip)
+ *
+ * This is a C convenience constructor; we have to (skip)
+ * it because it's not a boxed type.
+ */
+FooRectangle *
+foo_rectangle_new (int x, int y, int width, int height)
+{
+ FooRectangle *r = g_slice_new (FooRectangle);
+ r->x = x;
+ r->y = y;
+ r->width = width;
+ r->height = height;
+ return r;
+}
+
+/**
* foo_rectangle_add:
* @r1: (inout): add to this rect
* @r2: source rectangle
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]