[glib/type-deprecation] Add G_TYPE_FLAG_DEPRECATED




commit 4de16eb198c03e1f9b71955836910628ebfd3f7f
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Oct 20 20:04:01 2022 -0400

    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:
    
    _G_DEFINE_TYPE_EXTENDED_BEGIN (GtkAppChooserWidget,
                                   gtk_app_chooser_widget,
                                   GTK_TYPE_WIDGET,
                                   G_TYPE_FLAG_DEPRECATED)
    ...
    _G_DEFINE_TYPE_EXTENDED_END ()

 gobject/gtype.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
 gobject/gtype.h | 19 ++++++++++++++++++-
 2 files changed, 65 insertions(+), 3 deletions(-)
---
diff --git a/gobject/gtype.c b/gobject/gtype.c
index 66db7bc9d4..8c18b13c87 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 "
+               "anymore. It will 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
diff --git a/gobject/gtype.h b/gobject/gtype.h
index 8be826b40d..5f5c36d553 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -390,6 +390,19 @@ G_BEGIN_DECLS
  */
 #define G_TYPE_IS_FINAL(type)                   (g_type_test_flags ((type), G_TYPE_FLAG_FINAL)) 
GOBJECT_AVAILABLE_MACRO_IN_2_70
 
+/**
+ * G_TYPE_IS_DEPRECATED:
+ * @type: a #GType value
+ *
+ * Checks if @type is deprecated. Instantiating a deprecated type will
+ * trigger a warning if running with G_ENABLE_DIAGNOSTIC=1.
+ *
+ * Returns: %TRUE on success
+ *
+ * Since: 2.76
+ */
+#define G_TYPE_IS_DEPRECATED(type)                   (g_type_test_flags ((type), G_TYPE_FLAG_DEPRECATED)) 
GOBJECT_AVAILABLE_MACRO_IN_2_76
+
 
 /* Typedefs
  */
@@ -1050,6 +1063,9 @@ typedef enum    /*< skip >*/
  *  g_value_init()
  * @G_TYPE_FLAG_FINAL: Indicates a final type. A final type is a non-derivable
  *  leaf node in a deep derivable type hierarchy tree. Since: 2.70
+ * @G_TYPE_FLAG_DEPRECATED: The type is deprecated and will be removed in a
+ *  future wersion. A warning will be deprecated if it is instantiated while
+ *  running with G_ENABLE_DIAGNOSTIC=1. Since 2.76
  * 
  * Bit masks used to check or determine characteristics of a type.
  */
@@ -1058,7 +1074,8 @@ typedef enum    /*< skip >*/
   G_TYPE_FLAG_NONE GOBJECT_AVAILABLE_ENUMERATOR_IN_2_74 = 0,
   G_TYPE_FLAG_ABSTRACT = (1 << 4),
   G_TYPE_FLAG_VALUE_ABSTRACT = (1 << 5),
-  G_TYPE_FLAG_FINAL GOBJECT_AVAILABLE_ENUMERATOR_IN_2_70 = (1 << 6)
+  G_TYPE_FLAG_FINAL GOBJECT_AVAILABLE_ENUMERATOR_IN_2_70 = (1 << 6),
+  G_TYPE_FLAG_DEPRECATED GOBJECT_AVAILABLE_ENUMERATOR_IN_2_76 = (1 << 7)
 } GTypeFlags;
 /**
  * GTypeInfo:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]