Add "final" class attribute

A "final" class is a leaf node in a derivable type hierarchy, and cannot
be derived any further.

This matches the changes in libgobject that introduced G_TYPE_FLAG_FINAL
to the type flags.
This commit is contained in:
Emmanuele Bassi 2021-02-09 11:38:27 +00:00 committed by Emmanuele Bassi
parent ce4448f9e7
commit d127fc1136
8 changed files with 54 additions and 3 deletions

11
gdump.c
View File

@ -241,6 +241,12 @@ dump_object_type (GType type, const char *symbol, GOutputStream *out)
if (G_TYPE_IS_ABSTRACT (type)) if (G_TYPE_IS_ABSTRACT (type))
escaped_printf (out, " abstract=\"1\""); escaped_printf (out, " abstract=\"1\"");
#if GLIB_CHECK_VERSION (2, 70, 0)
if (G_TYPE_IS_FINAL (type))
escaped_printf (out, " final=\"1\"");
#endif
goutput_write (out, ">\n"); goutput_write (out, ">\n");
interfaces = g_type_interfaces (type, &n_interfaces); interfaces = g_type_interfaces (type, &n_interfaces);
@ -354,6 +360,11 @@ dump_fundamental_type (GType type, const char *symbol, GOutputStream *out)
if (G_TYPE_IS_ABSTRACT (type)) if (G_TYPE_IS_ABSTRACT (type))
escaped_printf (out, " abstract=\"1\""); escaped_printf (out, " abstract=\"1\"");
#if GLIB_CHECK_VERSION (2, 70, 0)
if (G_TYPE_IS_FINAL (type))
escaped_printf (out, " final=\"1\"");
#endif
if (G_TYPE_IS_INSTANTIATABLE (type)) if (G_TYPE_IS_INSTANTIATABLE (type))
escaped_printf (out, " instantiatable=\"1\""); escaped_printf (out, " instantiatable=\"1\"");

View File

@ -133,6 +133,31 @@ g_object_info_get_abstract (GIObjectInfo *info)
return blob->abstract != 0; return blob->abstract != 0;
} }
/**
* g_object_info_get_final:
* @info: a #GIObjectInfo
*
* Checks whether the object type is a final type, i.e. if it cannot
* be derived
*
* Returns: %TRUE if the object type is final
*
* Since: 1.70
*/
gboolean
g_object_info_get_final (GIObjectInfo *info)
{
GIRealInfo *rinfo = (GIRealInfo *) info;
ObjectBlob *blob;
g_return_val_if_fail (info != NULL, FALSE);
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE);
blob = (ObjectBlob *) &rinfo->typelib->data[rinfo->offset];
return blob->final_ != 0;
}
/** /**
* g_object_info_get_fundamental: * g_object_info_get_fundamental:
* @info: a #GIObjectInfo * @info: a #GIObjectInfo

View File

@ -87,6 +87,9 @@ const gchar * g_object_info_get_type_init (GIObjectInfo *info);
GI_AVAILABLE_IN_ALL GI_AVAILABLE_IN_ALL
gboolean g_object_info_get_abstract (GIObjectInfo *info); gboolean g_object_info_get_abstract (GIObjectInfo *info);
GI_AVAILABLE_IN_1_70
gboolean g_object_info_get_final (GIObjectInfo *info);
GI_AVAILABLE_IN_ALL GI_AVAILABLE_IN_ALL
gboolean g_object_info_get_fundamental (GIObjectInfo *info); gboolean g_object_info_get_fundamental (GIObjectInfo *info);

View File

@ -2096,6 +2096,7 @@ _g_ir_node_build_typelib (GIrNode *node,
blob->blob_type = BLOB_TYPE_OBJECT; blob->blob_type = BLOB_TYPE_OBJECT;
blob->abstract = object->abstract; blob->abstract = object->abstract;
blob->fundamental = object->fundamental; blob->fundamental = object->fundamental;
blob->final_ = object->final_;
blob->deprecated = object->deprecated; blob->deprecated = object->deprecated;
blob->reserved = 0; blob->reserved = 0;
blob->name = _g_ir_write_string (node->name, strings, data, offset2); blob->name = _g_ir_write_string (node->name, strings, data, offset2);

View File

@ -240,6 +240,7 @@ struct _GIrNodeInterface
gboolean abstract; gboolean abstract;
gboolean deprecated; gboolean deprecated;
gboolean fundamental; gboolean fundamental;
gboolean final_;
gchar *gtype_name; gchar *gtype_name;
gchar *gtype_init; gchar *gtype_init;

View File

@ -1806,6 +1806,7 @@ start_class (GMarkupParseContext *context,
const gchar *deprecated; const gchar *deprecated;
const gchar *abstract; const gchar *abstract;
const gchar *fundamental; const gchar *fundamental;
const gchar *final;
const gchar *ref_func; const gchar *ref_func;
const gchar *unref_func; const gchar *unref_func;
const gchar *set_value_func; const gchar *set_value_func;
@ -1826,6 +1827,7 @@ start_class (GMarkupParseContext *context,
typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
deprecated = find_attribute ("deprecated", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
abstract = find_attribute ("abstract", attribute_names, attribute_values); abstract = find_attribute ("abstract", attribute_names, attribute_values);
final = find_attribute ("final", attribute_names, attribute_values);
fundamental = find_attribute ("glib:fundamental", attribute_names, attribute_values); fundamental = find_attribute ("glib:fundamental", attribute_names, attribute_values);
ref_func = find_attribute ("glib:ref-func", attribute_names, attribute_values); ref_func = find_attribute ("glib:ref-func", attribute_names, attribute_values);
unref_func = find_attribute ("glib:unref-func", attribute_names, attribute_values); unref_func = find_attribute ("glib:unref-func", attribute_names, attribute_values);
@ -1861,6 +1863,7 @@ start_class (GMarkupParseContext *context,
iface->deprecated = FALSE; iface->deprecated = FALSE;
iface->abstract = abstract && strcmp (abstract, "1") == 0; iface->abstract = abstract && strcmp (abstract, "1") == 0;
iface->final_ = final && strcmp (final, "1") == 0;
if (fundamental) if (fundamental)
iface->fundamental = TRUE; iface->fundamental = TRUE;

View File

@ -988,6 +988,7 @@ write_object_info (const gchar *namespace,
gboolean deprecated; gboolean deprecated;
gboolean is_abstract; gboolean is_abstract;
gboolean is_fundamental; gboolean is_fundamental;
gboolean is_final;
GIObjectInfo *pnode; GIObjectInfo *pnode;
GIStructInfo *class_struct; GIStructInfo *class_struct;
gint i; gint i;
@ -996,6 +997,7 @@ write_object_info (const gchar *namespace,
deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
is_abstract = g_object_info_get_abstract (info); is_abstract = g_object_info_get_abstract (info);
is_fundamental = g_object_info_get_fundamental (info); is_fundamental = g_object_info_get_fundamental (info);
is_final = g_object_info_get_final (info);
type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
@ -1019,6 +1021,9 @@ write_object_info (const gchar *namespace,
if (is_abstract) if (is_abstract)
xml_printf (file, " abstract=\"1\""); xml_printf (file, " abstract=\"1\"");
if (is_final)
xml_printf (file, " final=\"1\"");
xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
if (is_fundamental) if (is_fundamental)

View File

@ -1034,10 +1034,11 @@ typedef struct {
/** /**
* ObjectBlob: * ObjectBlob:
* @blob_type: #BLOB_TYPE_OBJECT * @blob_type: #BLOB_TYPE_OBJECT
* @deprecated: TODO * @deprecated: whether the type is deprecated
* @abstract: TODO * @abstract: whether the type can be instantiated
* @fundamental: this object is not a GObject derived type, instead it's * @fundamental: this object is not a GObject derived type, instead it's
* an additional fundamental type. * an additional fundamental type.
* @final: whether the type can be derived
* @reserved: Reserved for future use. * @reserved: Reserved for future use.
* @name: TODO * @name: TODO
* @gtype_name: String name of the associated #GType * @gtype_name: String name of the associated #GType
@ -1076,7 +1077,8 @@ typedef struct {
guint16 deprecated : 1; guint16 deprecated : 1;
guint16 abstract : 1; guint16 abstract : 1;
guint16 fundamental : 1; guint16 fundamental : 1;
guint16 reserved :13; guint16 final_ : 1;
guint16 reserved :12;
guint32 name; guint32 name;
guint32 gtype_name; guint32 gtype_name;