From 8c753a30e513742e14c250636a662e0c64f5d3b6 Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Mon, 22 Jun 2020 23:41:06 +0200 Subject: [PATCH] gst-hotdoc-plugins-scanner: don't instantiate base classes --- docs/gst-hotdoc-plugins-scanner.c | 76 +++++++++++++++++-------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/docs/gst-hotdoc-plugins-scanner.c b/docs/gst-hotdoc-plugins-scanner.c index ebe0e16320..aaac761575 100644 --- a/docs/gst-hotdoc-plugins-scanner.c +++ b/docs/gst-hotdoc-plugins-scanner.c @@ -12,7 +12,8 @@ static GRegex *cleanup_caps_field = NULL; static void _add_object_details (GString * json, GString * other_types, - GHashTable * seen_other_types, GObject * object); + GHashTable * seen_other_types, GObject * object, GType gtype, + GType inst_type); static gchar * json_strescape (const gchar * str) @@ -199,8 +200,14 @@ _serialize_enum (GString * json, GType gtype, GstPluginAPIFlags api_flags) } } +/* @inst_type is used when serializing base classes in the hierarchy: + * we don't instantiate the base class, which may very well be abstract, + * but instantiate the final type (@inst_type), and use @type to determine + * what properties / signals / etc.. we are actually interested in. + */ static void -_serialize_object (GString * json, GHashTable * seen_other_types, GType gtype) +_serialize_object (GString * json, GHashTable * seen_other_types, GType gtype, + GType inst_type) { GObject *tmpobj; GString *other_types = NULL; @@ -208,16 +215,12 @@ _serialize_object (GString * json, GHashTable * seen_other_types, GType gtype) g_string_append_printf (json, "%s\"%s\": { " "\"kind\": \"object\"", json->len ? "," : "", g_type_name (gtype)); - if (!G_TYPE_IS_ABSTRACT (gtype) && !G_TYPE_IS_INTERFACE (gtype) - && G_TYPE_IS_INSTANTIATABLE (gtype) - && !g_type_is_a (gtype, G_TYPE_INITABLE) - && !g_type_is_a (gtype, G_TYPE_ASYNC_INITABLE)) { - other_types = g_string_new (""); - g_string_append_c (json, ','); - tmpobj = g_object_new (gtype, NULL); - _add_object_details (json, other_types, seen_other_types, tmpobj); - gst_object_unref (tmpobj); - } + other_types = g_string_new (""); + g_string_append_c (json, ','); + tmpobj = g_object_new (inst_type, NULL); + _add_object_details (json, other_types, seen_other_types, tmpobj, gtype, + inst_type); + gst_object_unref (tmpobj); g_string_append_c (json, '}'); @@ -229,7 +232,7 @@ _serialize_object (GString * json, GHashTable * seen_other_types, GType gtype) static void _add_signals (GString * json, GString * other_types, - GHashTable * seen_other_types, GObject * object) + GHashTable * seen_other_types, GObject * object, GType type) { gboolean opened = FALSE; guint *signals = NULL; @@ -237,7 +240,7 @@ _add_signals (GString * json, GString * other_types, gint i = 0, j; GstPluginAPIFlags api_flags; - signals = g_signal_list_ids (G_OBJECT_TYPE (object), &nsignals); + signals = g_signal_list_ids (type, &nsignals); for (i = 0; i < nsignals; i++) { GSignalQuery query = { 0, }; @@ -269,7 +272,7 @@ _add_signals (GString * json, GString * other_types, _serialize_flags (other_types, query.param_types[j]); } else if (g_type_is_a (query.param_types[j], G_TYPE_OBJECT)) { _serialize_object (other_types, seen_other_types, - query.param_types[j]); + query.param_types[j], query.param_types[j]); } } } @@ -286,7 +289,8 @@ _add_signals (GString * json, GString * other_types, } else if (g_type_is_a (query.return_type, G_TYPE_FLAGS)) { _serialize_flags (other_types, query.return_type); } else if (g_type_is_a (query.return_type, G_TYPE_OBJECT)) { - _serialize_object (other_types, seen_other_types, query.return_type); + _serialize_object (other_types, seen_other_types, query.return_type, + query.return_type); } } @@ -324,7 +328,8 @@ _add_signals (GString * json, GString * other_types, static void _add_properties (GString * json, GString * other_types, - GHashTable * seen_other_types, GObject * object, GObjectClass * klass) + GHashTable * seen_other_types, GObject * object, GObjectClass * klass, + GType type) { gchar *tmpstr; guint i, n_props; @@ -339,7 +344,7 @@ _add_properties (GString * json, GString * other_types, const gchar *mutable_str = NULL; spec = specs[i]; - if (spec->owner_type != G_OBJECT_TYPE (object)) + if (spec->owner_type != type) continue; g_value_init (&value, spec->value_type); @@ -400,7 +405,8 @@ _add_properties (GString * json, GString * other_types, } else if (G_IS_PARAM_SPEC_FLAGS (spec)) { _serialize_flags (other_types, spec->value_type); } else if (G_IS_PARAM_SPEC_OBJECT (spec)) { - _serialize_object (other_types, seen_other_types, spec->value_type); + _serialize_object (other_types, seen_other_types, spec->value_type, + spec->value_type); } } @@ -695,7 +701,7 @@ _add_element_pad_templates (GString * json, GString * other_types, && gst_type_is_plugin_api (pad_type, &api_flags)) { g_hash_table_insert (seen_other_types, (gpointer) g_type_name (pad_type), NULL); - _serialize_object (other_types, seen_other_types, pad_type); + _serialize_object (other_types, seen_other_types, pad_type, pad_type); } } g_string_append_c (json, '}'); @@ -757,31 +763,32 @@ _add_factory_details (GString * json, GstElementFactory * factory) static void _add_object_details (GString * json, GString * other_types, - GHashTable * seen_other_types, GObject * object) + GHashTable * seen_other_types, GObject * object, GType type, + GType inst_type) { - GType type; GType *interfaces; guint n_interfaces; + GType ptype = type; g_string_append (json, "\"hierarchy\": ["); - for (type = G_OBJECT_TYPE (object);; type = g_type_parent (type)) { - g_string_append_printf (json, "\"%s\"%c", g_type_name (type), - type == G_TYPE_OBJECT ? ' ' : ','); + for (;; ptype = g_type_parent (ptype)) { + g_string_append_printf (json, "\"%s\"%c", g_type_name (ptype), + ptype == G_TYPE_OBJECT ? ' ' : ','); - if (!g_hash_table_contains (seen_other_types, g_type_name (type)) - && gst_type_is_plugin_api (type, NULL)) { - g_hash_table_insert (seen_other_types, (gpointer) g_type_name (type), + if (!g_hash_table_contains (seen_other_types, g_type_name (ptype)) + && gst_type_is_plugin_api (ptype, NULL)) { + g_hash_table_insert (seen_other_types, (gpointer) g_type_name (ptype), NULL); - _serialize_object (other_types, seen_other_types, type); + _serialize_object (other_types, seen_other_types, ptype, inst_type); } - if (type == G_TYPE_OBJECT) + if (ptype == G_TYPE_OBJECT) break; } g_string_append (json, "]"); - interfaces = g_type_interfaces (G_OBJECT_TYPE (object), &n_interfaces); + interfaces = g_type_interfaces (type, &n_interfaces); if (n_interfaces) { GType *iface; @@ -796,8 +803,8 @@ _add_object_details (GString * json, GString * other_types, } _add_properties (json, other_types, seen_other_types, object, - G_OBJECT_GET_CLASS (object)); - _add_signals (json, other_types, seen_other_types, object); + G_OBJECT_GET_CLASS (object), type); + _add_signals (json, other_types, seen_other_types, object, type); } static void @@ -817,7 +824,8 @@ _add_element_details (GString * json, GString * other_types, get_rank_name (s, gst_plugin_feature_get_rank (feature))); _add_factory_details (json, GST_ELEMENT_FACTORY (feature)); - _add_object_details (json, other_types, seen_other_types, G_OBJECT (element)); + _add_object_details (json, other_types, seen_other_types, G_OBJECT (element), + G_OBJECT_TYPE (element), G_OBJECT_TYPE (element)); _add_element_pad_templates (json, other_types, seen_other_types, element, GST_ELEMENT_FACTORY (feature));