Commit cf7621f3 authored by Andreas Rottmann's avatar Andreas Rottmann

Bug 574284 - Add support for a 'closure' and 'destroy' annotations

This allows to annotate cases where the heuristics don't work.

TODO: According to Juerbi, there are cases where two callbacks refer
      to the same user_data, which is prohibited by the current
      implementation.
Signed-off-by: default avatarAndreas Rottmann <a.rottmann@gmx.at>
parent bec176d2
......@@ -60,6 +60,8 @@ OPT_OUT = 'out'
OPT_SCOPE = 'scope'
OPT_TRANSFER = 'transfer'
OPT_TYPE = 'type'
OPT_CLOSURE = 'closure'
OPT_DESTROY = 'destroy'
# Specific option values
OPT_VAL_BITFIELD = 'bitfield'
......@@ -476,14 +478,37 @@ class AnnotationApplier(object):
self._parse_param_ret_common(parent, return_, tag)
def _parse_param(self, parent, param, tag):
options = getattr(tag, 'options', {})
if isinstance(parent, Function):
options = getattr(tag, 'options', {})
scope = options.get(OPT_SCOPE)
if scope:
param.scope = scope.one()
param.transfer = PARAM_TRANSFER_NONE
destroy = options.get(OPT_DESTROY)
if destroy:
param.destroy_index = parent.get_parameter_index(destroy.one())
self._fixup_param_destroy(parent, param)
closure = options.get(OPT_CLOSURE)
if closure:
param.closure_index = parent.get_parameter_index(closure.one())
self._fixup_param_closure(parent, param)
if isinstance(parent, Callback):
if OPT_CLOSURE in options:
param.closure_index = parent.get_parameter_index(param.name)
self._fixup_param_closure(parent, param)
self._parse_param_ret_common(parent, param, tag)
def _fixup_param_destroy(self, parent, param):
for p in parent.parameters:
if p is not param and p.destroy_index == param.destroy_index:
p.destroy_index = None
def _fixup_param_closure(self, parent, param):
for p in parent.parameters:
if p is not param and p.closure_index == param.closure_index:
p.closure_index = None
def _parse_param_ret_common(self, parent, node, tag):
options = getattr(tag, 'options', {})
node.direction = self._extract_direction(node, options)
......
......@@ -521,6 +521,16 @@ class Callback(Node):
self.throws = False
self.doc = None
def get_parameter_index(self, name):
for i, parameter in enumerate(self.parameters):
if parameter.name == name:
return i
def get_parameter(self, name):
for parameter in self.parameters:
if parameter.name == name:
return parameter
def __repr__(self):
return 'Callback(%r, %r, %r)' % (
self.name, self.retval, self.parameters)
......
......@@ -58,6 +58,22 @@ and/or use gtk-doc annotations. -->
</parameter>
</parameters>
</callback>
<callback name="NotifyFunc"
c:type="AnnotationNotifyFunc"
doc="This is a callback with a &apos;closure&apos; argument that is not named
&apos;user_data&apos; and hence has to be annotated.">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
</return-value>
<parameters>
<parameter name="data"
transfer-ownership="none"
closure="0"
doc="The user data">
<type name="any" c:type="gpointer"/>
</parameter>
</parameters>
</callback>
<class name="Object"
c:type="AnnotationObject"
doc="This is an object used to test annotations."
......@@ -517,6 +533,29 @@ known by GObject as it&apos;s only marked as G_TYPE_POINTER">
</array>
</field>
</record>
<function name="custom_destroy"
c:identifier="annotation_custom_destroy"
doc="Test messing up the heuristic of closure/destroy-notification
detection, and fixing it via annotations.">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
</return-value>
<parameters>
<parameter name="callback"
transfer-ownership="none"
closure="2"
destroy="1"
doc="Destroy notification">
<type name="Callback" c:type="AnnotationCallback"/>
</parameter>
<parameter name="destroy" transfer-ownership="none">
<type name="NotifyFunc" c:type="AnnotationNotifyFunc"/>
</parameter>
<parameter name="data" transfer-ownership="none">
<type name="any" c:type="gpointer"/>
</parameter>
</parameters>
</function>
<function name="get_source_file" c:identifier="annotation_get_source_file">
<return-value transfer-ownership="full" doc="Source file">
<type name="filename" c:type="char*"/>
......
......@@ -47,6 +47,16 @@
</parameter>
</parameters>
</callback>
<callback name="NotifyFunc">
<return-value transfer-ownership="none">
<type name="none"/>
</return-value>
<parameters>
<parameter name="data" transfer-ownership="none" closure="0">
<type name="any"/>
</parameter>
</parameters>
</callback>
<class name="Object" parent="GObject.Object" glib:type-struct="ObjectClass" glib:type-name="AnnotationObject" glib:get-type="annotation_object_get_type">
<attribute name="org.example.Test" value="cows"/>
<field name="parent_instance">
......@@ -384,6 +394,22 @@
</array>
</field>
</record>
<function name="custom_destroy" c:identifier="annotation_custom_destroy">
<return-value transfer-ownership="none">
<type name="none"/>
</return-value>
<parameters>
<parameter name="callback" transfer-ownership="none" closure="2" destroy="1">
<type name="Callback"/>
</parameter>
<parameter name="destroy" transfer-ownership="none">
<type name="NotifyFunc"/>
</parameter>
<parameter name="data" transfer-ownership="none">
<type name="any"/>
</parameter>
</parameters>
</function>
<function name="get_source_file" c:identifier="annotation_get_source_file">
<return-value transfer-ownership="full">
<type name="filename"/>
......
......@@ -610,6 +610,21 @@ annotation_object_extra_annos (AnnotationObject *object)
{
}
/**
* annotation_custom_destroy:
*
* @callback: (destroy destroy) (closure data): Destroy notification
*
* Test messing up the heuristic of closure/destroy-notification
* detection, and fixing it via annotations.
*/
void
annotation_custom_destroy (AnnotationCallback callback,
AnnotationNotifyFunc destroy,
gpointer data)
{
}
/**
* annotation_get_source_file:
*
......
......@@ -21,6 +21,15 @@ typedef const gint* (*AnnotationCallback) (const gint *in);
*/
typedef GList* (*AnnotationListCallback) (GList *in);
/**
* AnnotationNotifyFunc:
* @data: (closure): The user data
*
* This is a callback with a 'closure' argument that is not named
* 'user_data' and hence has to be annotated.
*/
typedef void (*AnnotationNotifyFunc) (gpointer data);
/**
* AnnotationObject:
*
......@@ -122,6 +131,9 @@ void annotation_string_zero_terminated_out (char ***out);
void annotation_object_extra_annos (AnnotationObject *object);
void annotation_custom_destroy (AnnotationCallback callback,
AnnotationNotifyFunc destroy,
gpointer data);
char * annotation_get_source_file (void);
void annotation_set_source_file (const char *fname);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment