Add new annotations for property accessors

We introduce two new annotations:

  - (set-property PROPERTY_NAME)
  - (get-property PROPERTY_NAME)

These annotations are valid inside function blocks for methods on
objects and interfaces, and define whether a function is a property
accessor, e.g.:

    /**
     * gtk_widget_set_name: (set-property name)
     * @self: ...
     * @name: ...
     *
     * ...
     */

    /**
     * gtk_widget_get_name: (get-property name)
     * @self: ...
     *
     * ...
     *
     * Returns: ...
     */

The annotations are transformed into the GIR data as attributes:

 - glib:set-property="PROPERTY_NAME"
 - glib:get-property="PROPERTY_NAME"

The underlying typelib data has had flags for setter and getter
functions for a while, but they have never been plugged into the GIR
data or the introspection scanner. Now they are; you can retrieve the
GIPropertyInfo from a GIFunctionInfo that has the GI_FUNCTION_IS_SETTER
or GI_FUNCTION_IS_GETTER flags set.

Fixes: #13
This commit is contained in:
Emmanuele Bassi 2021-06-16 19:17:27 +01:00
parent efa58b3f8d
commit 39d518267b
4 changed files with 58 additions and 6 deletions

View File

@ -218,6 +218,7 @@ _g_ir_node_free (GIrNode *node)
g_free (node->name);
g_free (function->symbol);
g_free (function->property);
_g_ir_node_free ((GIrNode *)function->result);
for (l = function->parameters; l; l = l->next)
_g_ir_node_free ((GIrNode *)l->data);
@ -1648,8 +1649,8 @@ _g_ir_node_build_typelib (GIrNode *node,
blob->blob_type = BLOB_TYPE_FUNCTION;
blob->deprecated = function->deprecated;
blob->is_static = !function->is_method;
blob->setter = function->is_setter;
blob->getter = function->is_getter;
blob->setter = FALSE;
blob->getter = FALSE;
blob->constructor = function->is_constructor;
blob->wraps_vfunc = function->wraps_vfunc;
blob->throws = function->throws; /* Deprecated. Also stored in SignatureBlob. */
@ -1658,6 +1659,21 @@ _g_ir_node_build_typelib (GIrNode *node,
blob->symbol = _g_ir_write_string (function->symbol, strings, data, offset2);
blob->signature = signature;
if (function->is_setter || function->is_getter)
{
int index = get_index_of_member_type ((GIrNodeInterface*)parent,
G_IR_NODE_PROPERTY,
function->property);
if (index == -1)
{
g_error ("Unknown property %s for accessor %s", function->property, node->name);
}
blob->setter = function->is_setter;
blob->getter = function->is_getter;
blob->index = (guint) index;
}
/* function->result is special since it doesn't appear in the serialized format but
* we do want the attributes for it to appear
*/

View File

@ -103,6 +103,7 @@ struct _GIrNodeFunction
gboolean instance_transfer_full;
gchar *symbol;
char *property;
GIrNodeParam *result;
GList *parameters;

View File

@ -807,6 +807,8 @@ start_function (GMarkupParseContext *context,
const gchar *symbol;
const gchar *deprecated;
const gchar *throws;
const gchar *set_property;
const gchar *get_property;
GIrNodeFunction *function;
gboolean found = FALSE;
ParseState in_embedded_state = STATE_NONE;
@ -854,6 +856,8 @@ start_function (GMarkupParseContext *context,
symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
throws = find_attribute ("throws", attribute_names, attribute_values);
set_property = find_attribute ("glib:set-property", attribute_names, attribute_values);
get_property = find_attribute ("glib:get-property", attribute_names, attribute_values);
if (name == NULL)
{
@ -889,6 +893,25 @@ start_function (GMarkupParseContext *context,
function->is_constructor = TRUE;
else
function->is_constructor = FALSE;
if (set_property != NULL)
{
function->is_setter = TRUE;
function->is_getter = FALSE;
function->property = g_strdup (set_property);
}
else if (get_property != NULL)
{
function->is_setter = FALSE;
function->is_getter = TRUE;
function->property = g_strdup (get_property);
}
else
{
function->is_setter = FALSE;
function->is_getter = FALSE;
function->property = NULL;
}
}
else
{

View File

@ -586,10 +586,22 @@ write_function_info (const gchar *namespace,
xml_printf (file, " name=\"%s\" c:identifier=\"%s\"",
name, symbol);
if (flags & GI_FUNCTION_IS_SETTER)
xml_printf (file, " type=\"setter\"");
else if (flags & GI_FUNCTION_IS_GETTER)
xml_printf (file, " type=\"getter\"");
if ((flags & GI_FUNCTION_IS_SETTER) || (flags & GI_FUNCTION_IS_GETTER))
{
GIPropertyInfo *property = g_function_info_get_property (info);
if (property != NULL)
{
const char *property_name = g_base_info_get_name ((GIBaseInfo *)property);
if (flags & GI_FUNCTION_IS_SETTER)
xml_printf (file, " glib:set-property=\"%s\"", property_name);
else if (flags & GI_FUNCTION_IS_GETTER)
xml_printf (file, " glib:get-property=\"%s\"", property_name);
g_base_info_unref (property);
}
}
if (deprecated)
xml_printf (file, " deprecated=\"1\"");