diff options
author | Matthias Clasen <mclasen@redhat.com> | 2022-10-20 20:04:01 -0400 |
---|---|---|
committer | Philip Withnall <pwithnall@endlessos.org> | 2022-11-09 12:07:31 +0000 |
commit | fd0dd9e93c46511d091add0f2097b3b12d674719 (patch) | |
tree | 56df03297b68f9f10128f231fa3b11141b3b8512 /gobject/gtype.c | |
parent | abdb81efa2eda9cc0bcbde40cb50287d67c4d407 (diff) | |
download | glib-fd0dd9e93c46511d091add0f2097b3b12d674719.tar.gz |
gobject: Add G_TYPE_FLAG_DEPRECATED
This can be used to mark entire types as deprecated,
and trigger a warning when they are instantiated
and `G_ENABLE_DIAGNOSTIC=1` is set in the environment.
There's currently no convenient macros for defining
types with the new flag, but you can do:
```c
_G_DEFINE_TYPE_EXTENDED_BEGIN (GtkAppChooserWidget,
gtk_app_chooser_widget,
GTK_TYPE_WIDGET,
G_TYPE_FLAG_DEPRECATED)
...
_G_DEFINE_TYPE_EXTENDED_END ()
```
Includes a unit test by Philip Withnall.
Diffstat (limited to 'gobject/gtype.c')
-rw-r--r-- | gobject/gtype.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/gobject/gtype.c b/gobject/gtype.c index 7a10f444e..65a23f81e 100644 --- a/gobject/gtype.c +++ b/gobject/gtype.c @@ -145,7 +145,7 @@ G_TYPE_FLAG_INSTANTIATABLE | \ G_TYPE_FLAG_DERIVABLE | \ G_TYPE_FLAG_DEEP_DERIVABLE) -#define TYPE_FLAG_MASK (G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT | G_TYPE_FLAG_FINAL) +#define TYPE_FLAG_MASK (G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT | G_TYPE_FLAG_FINAL | G_TYPE_FLAG_DEPRECATED) #define SIZEOF_FUNDAMENTAL_INFO ((gssize) MAX (MAX (sizeof (GTypeFundamentalInfo), \ sizeof (gpointer)), \ sizeof (glong))) @@ -1824,6 +1824,47 @@ type_iface_blow_holder_info_Wm (TypeNode *iface, } } +static void +maybe_issue_deprecation_warning (GType type) +{ + static GHashTable *already_warned_table; + static const gchar *enable_diagnostic; + static GMutex already_warned_lock; + gboolean already; + const char *name; + + if (g_once_init_enter (&enable_diagnostic)) + { + const gchar *value = g_getenv ("G_ENABLE_DIAGNOSTIC"); + + if (!value) + value = "0"; + + g_once_init_leave (&enable_diagnostic, value); + } + + if (enable_diagnostic[0] == '0') + return; + + g_mutex_lock (&already_warned_lock); + + if (already_warned_table == NULL) + already_warned_table = g_hash_table_new (NULL, NULL); + + name = g_type_name (type); + + already = g_hash_table_contains (already_warned_table, (gpointer) name); + if (!already) + g_hash_table_add (already_warned_table, (gpointer) name); + + g_mutex_unlock (&already_warned_lock); + + if (!already) + g_warning ("The type %s is deprecated and shouldn’t be used " + "any more. It may be removed in a future version.", + name); +} + /* We use the system allocator on UNIX-y systems, where we know we have * access to a decent allocator. On other systems, we fall back to the * slice allocator, as we know its performance profile @@ -1883,7 +1924,11 @@ g_type_create_instance (GType type) g_error ("cannot create instance of abstract (non-instantiatable) type '%s'", type_descriptive_name_I (type)); } - + if (G_UNLIKELY (G_TYPE_IS_DEPRECATED (type))) + { + maybe_issue_deprecation_warning (type); + } + class = g_type_class_ref (type); /* We allocate the 'private' areas before the normal instance data, in |