[gobject-introspection] scanner: support virtual functions with a typedef-ed callback
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gobject-introspection] scanner: support virtual functions with a typedef-ed callback
- Date: Thu, 20 Feb 2014 02:09:32 +0000 (UTC)
commit b6568a4c8007f574f8b9c6a048d04f80dd291f37
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Sun Feb 2 00:57:24 2014 +0100
scanner: support virtual functions with a typedef-ed callback
The field of a callback need not be anonymous, it could be a
typedef, with a proper Type node.
Fixes TelepathyGlib.BaseClient having no virtual functions
(and probably others)
https://bugzilla.gnome.org/show_bug.cgi?id=723439
giscanner/ast.py | 4 +-
giscanner/maintransformer.py | 14 ++++-
.../Regress.TestExternallyDefinedCallback.page | 33 ++++++++++++
.../Regress.TestFundamentalObject-copy.page | 28 ++++++++++
.../Regress.TestFundamentalObject-finalize.page | 28 ++++++++++
.../Regress.TestObj-complex_vfunc.page | 33 ++++++++++++
.../Regress.TestObjClass-complex_vfunc.page | 14 +++++
.../Regress.TestExternallyDefinedCallback.page | 29 +++++++++++
.../Regress.TestObj-complex_vfunc.page | 25 +++++++++
.../Regress.TestExternallyDefinedCallback.page | 30 +++++++++++
.../Regress.TestFundamentalObject-copy.page | 30 +++++++++++
.../Regress.TestFundamentalObject-finalize.page | 26 +++++++++
.../Regress.TestObj-complex_vfunc.page | 30 +++++++++++
tests/scanner/Regress-1.0-expected.gir | 54 ++++++++++++++++++++
tests/scanner/regress.h | 4 ++
15 files changed, 377 insertions(+), 5 deletions(-)
---
diff --git a/giscanner/ast.py b/giscanner/ast.py
index b992c11..130f50c 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -681,8 +681,8 @@ class VFunction(Callable):
self.invoker = None
@classmethod
- def from_callback(cls, cb):
- obj = cls(cb.name, cb.retval, cb.parameters[1:],
+ def from_callback(cls, name, cb):
+ obj = cls(name, cb.retval, cb.parameters[1:],
cb.throws)
return obj
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index c107bee..e6f0468 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -1225,16 +1225,24 @@ method or constructor of some type."""
field.writable = False
for field in class_struct.fields:
- if not isinstance(field.anonymous_node, ast.Callback):
+ callback = None
+
+ if isinstance(field.anonymous_node, ast.Callback):
+ callback = field.anonymous_node
+ elif field.type is not None:
+ callback = self._transformer.lookup_typenode(field.type)
+ if not isinstance(callback, ast.Callback):
+ continue
+ else:
continue
- callback = field.anonymous_node
+
# Check the first parameter is the object
if len(callback.parameters) == 0:
continue
firstparam_type = callback.parameters[0].type
if firstparam_type != node_type:
continue
- vfunc = ast.VFunction.from_callback(callback)
+ vfunc = ast.VFunction.from_callback(field.name, callback)
vfunc.instance_parameter = callback.parameters[0]
vfunc.inherit_file_positions(callback)
diff --git a/tests/scanner/Regress-1.0-C-expected/Regress.TestExternallyDefinedCallback.page
b/tests/scanner/Regress-1.0-C-expected/Regress.TestExternallyDefinedCallback.page
new file mode 100644
index 0000000..6514a35
--- /dev/null
+++ b/tests/scanner/Regress-1.0-C-expected/Regress.TestExternallyDefinedCallback.page
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<page id="Regress.TestExternallyDefinedCallback"
+ type="topic"
+ style="callback"
+ xmlns="http://projectmallard.org/1.0/"
+ xmlns:api="http://projectmallard.org/experimental/api/"
+ xmlns:ui="http://projectmallard.org/1.0/ui/">
+ <info>
+ <link xref="index" group="callback" type="guide"/>
+ </info>
+ <title>Regress.TestExternallyDefinedCallback</title>
+ <synopsis><code mime="text/x-csrc">
+void TestExternallyDefinedCallback (RegressTestObj* obj,
+ int someint);
+ </code></synopsis>
+
+
+<terms>
+<item>
+<title><code>obj</code></title>
+
+</item>
+<item>
+<title><code>someint</code></title>
+
+</item>
+<item>
+<title><code>Returns</code></title>
+
+</item>
+</terms>
+
+</page>
diff --git a/tests/scanner/Regress-1.0-C-expected/Regress.TestFundamentalObject-copy.page
b/tests/scanner/Regress-1.0-C-expected/Regress.TestFundamentalObject-copy.page
new file mode 100644
index 0000000..d4435c6
--- /dev/null
+++ b/tests/scanner/Regress-1.0-C-expected/Regress.TestFundamentalObject-copy.page
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<page id="Regress.TestFundamentalObject-copy"
+ type="topic"
+ style="vfunc"
+ xmlns="http://projectmallard.org/1.0/"
+ xmlns:api="http://projectmallard.org/experimental/api/"
+ xmlns:ui="http://projectmallard.org/1.0/ui/">
+ <info>
+ <link xref="Regress.TestFundamentalObject" group="vfunc" type="guide"/>
+ </info>
+ <title>Regress.TestFundamentalObject::copy</title>
+ <synopsis><code mime="text/x-csrc">
+RegressTestFundamentalObject* copy (const RegressTestFundamentalObject* obj);
+ </code></synopsis>
+
+
+<terms>
+<item>
+<title><code>obj</code></title>
+
+</item>
+<item>
+<title><code>Returns</code></title>
+
+</item>
+</terms>
+
+</page>
diff --git a/tests/scanner/Regress-1.0-C-expected/Regress.TestFundamentalObject-finalize.page
b/tests/scanner/Regress-1.0-C-expected/Regress.TestFundamentalObject-finalize.page
new file mode 100644
index 0000000..060684a
--- /dev/null
+++ b/tests/scanner/Regress-1.0-C-expected/Regress.TestFundamentalObject-finalize.page
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<page id="Regress.TestFundamentalObject-finalize"
+ type="topic"
+ style="vfunc"
+ xmlns="http://projectmallard.org/1.0/"
+ xmlns:api="http://projectmallard.org/experimental/api/"
+ xmlns:ui="http://projectmallard.org/1.0/ui/">
+ <info>
+ <link xref="Regress.TestFundamentalObject" group="vfunc" type="guide"/>
+ </info>
+ <title>Regress.TestFundamentalObject::finalize</title>
+ <synopsis><code mime="text/x-csrc">
+void finalize (RegressTestFundamentalObject* obj);
+ </code></synopsis>
+
+
+<terms>
+<item>
+<title><code>obj</code></title>
+
+</item>
+<item>
+<title><code>Returns</code></title>
+
+</item>
+</terms>
+
+</page>
diff --git a/tests/scanner/Regress-1.0-C-expected/Regress.TestObj-complex_vfunc.page
b/tests/scanner/Regress-1.0-C-expected/Regress.TestObj-complex_vfunc.page
new file mode 100644
index 0000000..50b9b0f
--- /dev/null
+++ b/tests/scanner/Regress-1.0-C-expected/Regress.TestObj-complex_vfunc.page
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<page id="Regress.TestObj-complex_vfunc"
+ type="topic"
+ style="vfunc"
+ xmlns="http://projectmallard.org/1.0/"
+ xmlns:api="http://projectmallard.org/experimental/api/"
+ xmlns:ui="http://projectmallard.org/1.0/ui/">
+ <info>
+ <link xref="Regress.TestObj" group="vfunc" type="guide"/>
+ </info>
+ <title>Regress.TestObj::complex_vfunc</title>
+ <synopsis><code mime="text/x-csrc">
+void complex_vfunc (RegressTestObj* obj,
+ int someint);
+ </code></synopsis>
+
+
+<terms>
+<item>
+<title><code>obj</code></title>
+
+</item>
+<item>
+<title><code>someint</code></title>
+
+</item>
+<item>
+<title><code>Returns</code></title>
+
+</item>
+</terms>
+
+</page>
diff --git a/tests/scanner/Regress-1.0-C-expected/Regress.TestObjClass-complex_vfunc.page
b/tests/scanner/Regress-1.0-C-expected/Regress.TestObjClass-complex_vfunc.page
new file mode 100644
index 0000000..d658928
--- /dev/null
+++ b/tests/scanner/Regress-1.0-C-expected/Regress.TestObjClass-complex_vfunc.page
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<page id="Regress.TestObjClass-complex_vfunc"
+ type="topic"
+ style="field"
+ xmlns="http://projectmallard.org/1.0/"
+ xmlns:api="http://projectmallard.org/experimental/api/"
+ xmlns:ui="http://projectmallard.org/1.0/ui/">
+ <info>
+ <link xref="Regress.TestObjClass" group="field" type="guide"/>
+ </info>
+ <title>Regress.TestObjClass->complex_vfunc</title>
+
+
+</page>
diff --git a/tests/scanner/Regress-1.0-Gjs-expected/Regress.TestExternallyDefinedCallback.page
b/tests/scanner/Regress-1.0-Gjs-expected/Regress.TestExternallyDefinedCallback.page
new file mode 100644
index 0000000..f9d241c
--- /dev/null
+++ b/tests/scanner/Regress-1.0-Gjs-expected/Regress.TestExternallyDefinedCallback.page
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<page id="Regress.TestExternallyDefinedCallback"
+ type="topic"
+ style="callback"
+ xmlns="http://projectmallard.org/1.0/"
+ xmlns:api="http://projectmallard.org/experimental/api/"
+ xmlns:ui="http://projectmallard.org/1.0/ui/">
+ <info>
+ <link xref="index" group="callback" type="guide"/>
+ </info>
+ <title>Regress.TestExternallyDefinedCallback</title>
+ <synopsis><code mime="text/x-gjs">
+function onTestExternallyDefinedCallback(obj: <link xref="Regress.TestObj">Regress.TestObj</link>, someint:
Number(gint)): void {
+}
+ </code></synopsis>
+
+
+<terms>
+<item>
+<title><code>obj</code></title>
+
+</item>
+<item>
+<title><code>someint</code></title>
+
+</item>
+</terms>
+
+</page>
diff --git a/tests/scanner/Regress-1.0-Gjs-expected/Regress.TestObj-complex_vfunc.page
b/tests/scanner/Regress-1.0-Gjs-expected/Regress.TestObj-complex_vfunc.page
new file mode 100644
index 0000000..682d7f3
--- /dev/null
+++ b/tests/scanner/Regress-1.0-Gjs-expected/Regress.TestObj-complex_vfunc.page
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<page id="Regress.TestObj-complex_vfunc"
+ type="topic"
+ style="vfunc"
+ xmlns="http://projectmallard.org/1.0/"
+ xmlns:api="http://projectmallard.org/experimental/api/"
+ xmlns:ui="http://projectmallard.org/1.0/ui/">
+ <info>
+ <link xref="Regress.TestObj" group="vfunc" type="guide"/>
+ </info>
+ <title>Regress.TestObj::complex_vfunc</title>
+ <synopsis><code mime="text/x-gjs">
+function vfunc_complex_vfunc(someint: Number(gint)): void {
+}
+ </code></synopsis>
+
+
+<terms>
+<item>
+<title><code>someint</code></title>
+
+</item>
+</terms>
+
+</page>
diff --git a/tests/scanner/Regress-1.0-Python-expected/Regress.TestExternallyDefinedCallback.page
b/tests/scanner/Regress-1.0-Python-expected/Regress.TestExternallyDefinedCallback.page
new file mode 100644
index 0000000..f53f37e
--- /dev/null
+++ b/tests/scanner/Regress-1.0-Python-expected/Regress.TestExternallyDefinedCallback.page
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<page id="Regress.TestExternallyDefinedCallback"
+ type="topic"
+ style="callback"
+ xmlns="http://projectmallard.org/1.0/"
+ xmlns:api="http://projectmallard.org/experimental/api/"
+ xmlns:ui="http://projectmallard.org/1.0/ui/">
+ <info>
+ <link xref="index" group="callback" type="guide"/>
+ </info>
+ <title>Regress.TestExternallyDefinedCallback</title>
+ <synopsis><code mime="text/x-python">
+ accepts(Regress.TestObj, int)
+ returns(none)
+def on_TestExternallyDefinedCallback(obj, someint):
+ </code></synopsis>
+
+
+<terms>
+<item>
+<title><code>obj</code></title>
+
+</item>
+<item>
+<title><code>someint</code></title>
+
+</item>
+</terms>
+
+</page>
diff --git a/tests/scanner/Regress-1.0-Python-expected/Regress.TestFundamentalObject-copy.page
b/tests/scanner/Regress-1.0-Python-expected/Regress.TestFundamentalObject-copy.page
new file mode 100644
index 0000000..d80c40b
--- /dev/null
+++ b/tests/scanner/Regress-1.0-Python-expected/Regress.TestFundamentalObject-copy.page
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<page id="Regress.TestFundamentalObject-copy"
+ type="topic"
+ style="vfunc"
+ xmlns="http://projectmallard.org/1.0/"
+ xmlns:api="http://projectmallard.org/experimental/api/"
+ xmlns:ui="http://projectmallard.org/1.0/ui/">
+ <info>
+ <link xref="Regress.TestFundamentalObject" group="vfunc" type="guide"/>
+ </info>
+ <title>Regress.TestFundamentalObject::copy</title>
+ <synopsis><code mime="text/x-python">
+ accepts(Regress.TestFundamentalObject)
+ returns(Regress.TestFundamentalObject)
+def do_copy(obj):
+ </code></synopsis>
+
+
+<terms>
+<item>
+<title><code>obj</code></title>
+
+</item>
+<item>
+<title><code>Returns</code></title>
+
+</item>
+</terms>
+
+</page>
diff --git a/tests/scanner/Regress-1.0-Python-expected/Regress.TestFundamentalObject-finalize.page
b/tests/scanner/Regress-1.0-Python-expected/Regress.TestFundamentalObject-finalize.page
new file mode 100644
index 0000000..5ff38ee
--- /dev/null
+++ b/tests/scanner/Regress-1.0-Python-expected/Regress.TestFundamentalObject-finalize.page
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<page id="Regress.TestFundamentalObject-finalize"
+ type="topic"
+ style="vfunc"
+ xmlns="http://projectmallard.org/1.0/"
+ xmlns:api="http://projectmallard.org/experimental/api/"
+ xmlns:ui="http://projectmallard.org/1.0/ui/">
+ <info>
+ <link xref="Regress.TestFundamentalObject" group="vfunc" type="guide"/>
+ </info>
+ <title>Regress.TestFundamentalObject::finalize</title>
+ <synopsis><code mime="text/x-python">
+ accepts(Regress.TestFundamentalObject)
+ returns(none)
+def do_finalize(obj):
+ </code></synopsis>
+
+
+<terms>
+<item>
+<title><code>obj</code></title>
+
+</item>
+</terms>
+
+</page>
diff --git a/tests/scanner/Regress-1.0-Python-expected/Regress.TestObj-complex_vfunc.page
b/tests/scanner/Regress-1.0-Python-expected/Regress.TestObj-complex_vfunc.page
new file mode 100644
index 0000000..c4d02b1
--- /dev/null
+++ b/tests/scanner/Regress-1.0-Python-expected/Regress.TestObj-complex_vfunc.page
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<page id="Regress.TestObj-complex_vfunc"
+ type="topic"
+ style="vfunc"
+ xmlns="http://projectmallard.org/1.0/"
+ xmlns:api="http://projectmallard.org/experimental/api/"
+ xmlns:ui="http://projectmallard.org/1.0/ui/">
+ <info>
+ <link xref="Regress.TestObj" group="vfunc" type="guide"/>
+ </info>
+ <title>Regress.TestObj::complex_vfunc</title>
+ <synopsis><code mime="text/x-python">
+ accepts(Regress.TestObj, int)
+ returns(none)
+def do_complex_vfunc(obj, someint):
+ </code></synopsis>
+
+
+<terms>
+<item>
+<title><code>obj</code></title>
+
+</item>
+<item>
+<title><code>someint</code></title>
+
+</item>
+</terms>
+
+</page>
diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir
index a565113..5ba2be8 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -2466,6 +2466,20 @@ use it should be.</doc>
</return-value>
</function>
</enumeration>
+ <callback name="TestExternallyDefinedCallback"
+ c:type="RegressTestExternallyDefinedCallback">
+ <return-value transfer-ownership="none">
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <parameter name="obj" transfer-ownership="none">
+ <type name="TestObj" c:type="RegressTestObj*"/>
+ </parameter>
+ <parameter name="someint" transfer-ownership="none">
+ <type name="gint" c:type="int"/>
+ </parameter>
+ </parameters>
+ </callback>
<bitfield name="TestFlags"
glib:type-name="RegressTestFlags"
glib:get-type="regress_test_flags_get_type"
@@ -2523,6 +2537,29 @@ use it should be.</doc>
glib:unref-func="regress_test_fundamental_object_unref"
glib:set-value-func="regress_test_value_set_fundamental_object"
glib:get-value-func="regress_test_value_get_fundamental_object">
+ <virtual-method name="copy">
+ <return-value transfer-ownership="full">
+ <type name="TestFundamentalObject"
+ c:type="RegressTestFundamentalObject*"/>
+ </return-value>
+ <parameters>
+ <instance-parameter name="obj" transfer-ownership="none">
+ <type name="TestFundamentalObject"
+ c:type="const RegressTestFundamentalObject*"/>
+ </instance-parameter>
+ </parameters>
+ </virtual-method>
+ <virtual-method name="finalize">
+ <return-value transfer-ownership="none">
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <instance-parameter name="obj" transfer-ownership="none">
+ <type name="TestFundamentalObject"
+ c:type="RegressTestFundamentalObject*"/>
+ </instance-parameter>
+ </parameters>
+ </virtual-method>
<method name="ref" c:identifier="regress_test_fundamental_object_ref">
<return-value transfer-ownership="full">
<doc xml:space="preserve">A new #RegressTestFundamentalObject</doc>
@@ -2866,6 +2903,19 @@ use it should be.</doc>
</parameter>
</parameters>
</virtual-method>
+ <virtual-method name="complex_vfunc">
+ <return-value transfer-ownership="none">
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <instance-parameter name="obj" transfer-ownership="none">
+ <type name="TestObj" c:type="RegressTestObj*"/>
+ </instance-parameter>
+ <parameter name="someint" transfer-ownership="none">
+ <type name="gint" c:type="int"/>
+ </parameter>
+ </parameters>
+ </virtual-method>
<virtual-method name="matrix" invoker="do_matrix">
<doc xml:space="preserve">This method is virtual. Notably its name differs from the virtual
slot name, which makes it useful for testing bindings handle this
@@ -3597,6 +3647,10 @@ the introspection client langage.</doc>
<field name="test_signal_with_static_scope_arg">
<type name="guint" c:type="guint"/>
</field>
+ <field name="complex_vfunc">
+ <type name="TestExternallyDefinedCallback"
+ c:type="RegressTestExternallyDefinedCallback"/>
+ </field>
<field name="_regress_reserved1" introspectable="0">
<callback name="_regress_reserved1">
<return-value transfer-ownership="none">
diff --git a/tests/scanner/regress.h b/tests/scanner/regress.h
index 3f917e6..e6ae1c2 100644
--- a/tests/scanner/regress.h
+++ b/tests/scanner/regress.h
@@ -487,6 +487,8 @@ struct _RegressTestObj
GType gtype;
};
+typedef void (*RegressTestExternallyDefinedCallback) (RegressTestObj *obj, int someint);
+
struct _RegressTestObjClass
{
GObjectClass parent_class;
@@ -502,6 +504,8 @@ struct _RegressTestObjClass
guint test_signal;
guint test_signal_with_static_scope_arg;
+ RegressTestExternallyDefinedCallback complex_vfunc;
+
/* Should be replaced with simple "gpointer" and not be callback */
void (*_regress_reserved1) (void);
void (*_regress_reserved2) (void);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]