summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagna@src.gnome.org>2014-02-02 00:57:24 +0100
committerGiovanni Campagna <gcampagna@src.gnome.org>2014-02-20 03:09:38 +0100
commitb6568a4c8007f574f8b9c6a048d04f80dd291f37 (patch)
tree6519689ee028c39cfff837b2bef13ab433b22904
parent6cc9207cbdb1328c746e0899f459bb09d1e3e954 (diff)
downloadgobject-introspection-b6568a4c8007f574f8b9c6a048d04f80dd291f37.tar.gz
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
-rw-r--r--giscanner/ast.py4
-rw-r--r--giscanner/maintransformer.py14
-rw-r--r--tests/scanner/Regress-1.0-C-expected/Regress.TestExternallyDefinedCallback.page33
-rw-r--r--tests/scanner/Regress-1.0-C-expected/Regress.TestFundamentalObject-copy.page28
-rw-r--r--tests/scanner/Regress-1.0-C-expected/Regress.TestFundamentalObject-finalize.page28
-rw-r--r--tests/scanner/Regress-1.0-C-expected/Regress.TestObj-complex_vfunc.page33
-rw-r--r--tests/scanner/Regress-1.0-C-expected/Regress.TestObjClass-complex_vfunc.page14
-rw-r--r--tests/scanner/Regress-1.0-Gjs-expected/Regress.TestExternallyDefinedCallback.page29
-rw-r--r--tests/scanner/Regress-1.0-Gjs-expected/Regress.TestObj-complex_vfunc.page25
-rw-r--r--tests/scanner/Regress-1.0-Python-expected/Regress.TestExternallyDefinedCallback.page30
-rw-r--r--tests/scanner/Regress-1.0-Python-expected/Regress.TestFundamentalObject-copy.page30
-rw-r--r--tests/scanner/Regress-1.0-Python-expected/Regress.TestFundamentalObject-finalize.page26
-rw-r--r--tests/scanner/Regress-1.0-Python-expected/Regress.TestObj-complex_vfunc.page30
-rw-r--r--tests/scanner/Regress-1.0-expected.gir54
-rw-r--r--tests/scanner/regress.h4
15 files changed, 377 insertions, 5 deletions
diff --git a/giscanner/ast.py b/giscanner/ast.py
index b992c111..130f50c5 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 c107beed..e6f04684 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 00000000..6514a359
--- /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 00000000..d4435c60
--- /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 00000000..060684a6
--- /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 00000000..50b9b0f2
--- /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 00000000..d658928f
--- /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 00000000..f9d241cf
--- /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 00000000..682d7f31
--- /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 00000000..f53f37e9
--- /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 00000000..d80c40b3
--- /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 00000000..5ff38ee4
--- /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 00000000..c4d02b19
--- /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 a5651134..5ba2be8b 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 3f917e62..e6ae1c22 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);