[libpeas] Find extension construct properties also in interface prerequisites



commit 3c1ac8d343034dd33105ed0f675d5b4afd4ea813
Author: Garrett Regier <garrettregier gmail com>
Date:   Tue Jul 17 09:14:25 2012 -0700

    Find extension construct properties also in interface prerequisites
    
    Based on patch by Jesse van den Kieboom <jesse vandenkieboom epfl ch>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=679995

 libpeas/peas-helpers.c                             |   55 ++++++++++++++++++--
 tests/libpeas/introspection/Makefile.am            |    2 +
 .../introspection-properties-prerequisite.c        |   52 ++++++++++++++++++
 .../introspection-properties-prerequisite.h        |   52 ++++++++++++++++++
 .../introspection/introspection-properties.c       |    6 ++-
 tests/libpeas/plugins/extension-js/extension-js.js |    1 +
 .../plugins/extension-python/extension-python.py   |    2 +
 tests/libpeas/testing/testing-extension.c          |   20 +++++++
 8 files changed, 184 insertions(+), 6 deletions(-)
---
diff --git a/libpeas/peas-helpers.c b/libpeas/peas-helpers.c
index 36cf576..185694c 100644
--- a/libpeas/peas-helpers.c
+++ b/libpeas/peas-helpers.c
@@ -29,6 +29,48 @@
 
 #include "peas-helpers.h"
 
+static void
+add_all_interfaces (GType      iface_type,
+                    GPtrArray *type_structs)
+{
+  GType *prereq;
+  guint n_prereq;
+  guint i;
+
+  g_ptr_array_add (type_structs,
+                   g_type_default_interface_ref (iface_type));
+
+  prereq = g_type_interface_prerequisites (iface_type, &n_prereq);
+
+  for (i = 0; i < n_prereq; ++i)
+    {
+      if (G_TYPE_IS_INTERFACE (prereq[i]))
+        add_all_interfaces (prereq[i], type_structs);
+    }
+
+  g_free (prereq);
+}
+
+static GParamSpec *
+find_param_spec_in_interfaces (GPtrArray   *type_structs,
+                               const gchar *name)
+{
+  guint i;
+
+  for (i = 0; i < type_structs->len; ++i)
+    {
+      GParamSpec *pspec;
+
+      pspec = g_object_interface_find_property (g_ptr_array_index (type_structs, i),
+                                                name);
+
+      if (pspec != NULL)
+        return pspec;
+    }
+
+  return NULL;
+}
+
 gboolean
 _valist_to_parameter_list (GType         iface_type,
                            const gchar  *first_property_name,
@@ -36,13 +78,16 @@ _valist_to_parameter_list (GType         iface_type,
                            GParameter  **params,
                            guint        *n_params)
 {
-  gpointer type_struct;
+  GPtrArray *type_structs;
   const gchar *name;
   guint n_allocated_params;
 
   g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_type), FALSE);
 
-  type_struct = g_type_default_interface_ref (iface_type);
+  type_structs = g_ptr_array_new ();
+  g_ptr_array_set_free_func (type_structs,
+                             (GDestroyNotify) g_type_default_interface_unref);
+  add_all_interfaces (iface_type, type_structs);
 
   *n_params = 0;
   n_allocated_params = 16;
@@ -52,7 +97,7 @@ _valist_to_parameter_list (GType         iface_type,
   while (name)
     {
       gchar *error_msg = NULL;
-      GParamSpec *pspec = g_object_interface_find_property (type_struct, name);
+      GParamSpec *pspec = find_param_spec_in_interfaces (type_structs, name);
 
       if (!pspec)
         {
@@ -85,7 +130,7 @@ _valist_to_parameter_list (GType         iface_type,
       name = va_arg (args, gchar*);
     }
 
-  g_type_default_interface_unref (type_struct);
+  g_ptr_array_unref (type_structs);
 
   return TRUE;
 
@@ -95,7 +140,7 @@ error:
     g_value_unset (&(*params)[*n_params].value);
 
   g_free (*params);
-  g_type_default_interface_unref (type_struct);
+  g_ptr_array_unref (type_structs);
 
   return FALSE;
 }
diff --git a/tests/libpeas/introspection/Makefile.am b/tests/libpeas/introspection/Makefile.am
index 1d522d3..4a95e7d 100644
--- a/tests/libpeas/introspection/Makefile.am
+++ b/tests/libpeas/introspection/Makefile.am
@@ -23,6 +23,8 @@ libintrospection_1_0_la_SOURCES = \
 	introspection-has-prerequisite.h		\
 	introspection-properties.c			\
 	introspection-properties.h			\
+	introspection-properties-prerequisite.c		\
+	introspection-properties-prerequisite.h		\
 	introspection-unimplemented.c			\
 	introspection-unimplemented.h
 
diff --git a/tests/libpeas/introspection/introspection-properties-prerequisite.c b/tests/libpeas/introspection/introspection-properties-prerequisite.c
new file mode 100644
index 0000000..2ddb8c0
--- /dev/null
+++ b/tests/libpeas/introspection/introspection-properties-prerequisite.c
@@ -0,0 +1,52 @@
+/*
+ * introspection-properties-prerequisite.c
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2012 Garrett Regier
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "introspection-properties-prerequisite.h"
+
+G_DEFINE_INTERFACE(IntrospectionPropertiesPrerequisite,
+                   introspection_properties_prerequisite,
+                   G_TYPE_OBJECT)
+
+void
+introspection_properties_prerequisite_default_init (IntrospectionPropertiesPrerequisiteInterface *iface)
+{
+  static gboolean initialized = FALSE;
+
+#define DEFINE_PROP(name, flags) \
+  g_object_interface_install_property (iface, \
+                                       g_param_spec_string (name, name, \
+                                                            name, name, \
+                                                            G_PARAM_STATIC_STRINGS | \
+                                                            (flags)))
+
+  if (!initialized)
+    {
+      DEFINE_PROP ("prerequisite", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+      initialized = TRUE;
+    }
+
+#undef DEFINE_PROP
+}
diff --git a/tests/libpeas/introspection/introspection-properties-prerequisite.h b/tests/libpeas/introspection/introspection-properties-prerequisite.h
new file mode 100644
index 0000000..233a91b
--- /dev/null
+++ b/tests/libpeas/introspection/introspection-properties-prerequisite.h
@@ -0,0 +1,52 @@
+/*
+ * introspection-properties-prerequisite.h
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2012 - Garrett Regier
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __INTROSPECTION_PROPERTIES_PREREQUISITE_H__
+#define __INTROSPECTION_PROPERTIES_PREREQUISITE_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define INTROSPECTION_TYPE_PROPERTIES_PREREQUISITE             (introspection_properties_prerequisite_get_type ())
+#define INTROSPECTION_PROPERTIES_PREREQUISITE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), INTROSPECTION_TYPE_PROPERTIES_PREREQUISITE, IntrospectionProperties))
+#define INTROSPECTION_PROPERTIES_PREREQUISITE_IFACE(obj)       (G_TYPE_CHECK_CLASS_CAST ((obj), INTROSPECTION_TYPE_PROPERTIES_PREREQUISITE, IntrospectionPropertiesInterface))
+#define INTROSPECTION_IS_PROPERTIES_PREREQUISITE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INTROSPECTION_TYPE_PROPERTIES_PREREQUISITE))
+#define INTROSPECTION_PROPERTIES_PREREQUISITE_GET_IFACE(obj)   (G_TYPE_INSTANCE_GET_INTERFACE ((obj), INTROSPECTION_TYPE_PROPERTIES_PREREQUISITE, IntrospectionPropertiesInterface))
+
+typedef struct _IntrospectionPropertiesPrerequisite           IntrospectionPropertiesPrerequisite; /* dummy typedef */
+typedef struct _IntrospectionPropertiesPrerequisiteInterface  IntrospectionPropertiesPrerequisiteInterface;
+
+struct _IntrospectionPropertiesPrerequisiteInterface {
+  GTypeInterface g_iface;
+};
+
+/*
+ * Public methods
+ */
+GType introspection_properties_prerequisite_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __INTROSPECTION_PROPERTIES_PREREQUISITE_H__ */
diff --git a/tests/libpeas/introspection/introspection-properties.c b/tests/libpeas/introspection/introspection-properties.c
index d978faf..86132d5 100644
--- a/tests/libpeas/introspection/introspection-properties.c
+++ b/tests/libpeas/introspection/introspection-properties.c
@@ -25,7 +25,11 @@
 
 #include "introspection-properties.h"
 
-G_DEFINE_INTERFACE(IntrospectionProperties, introspection_properties, G_TYPE_OBJECT)
+#include "introspection-properties-prerequisite.h"
+
+G_DEFINE_INTERFACE(IntrospectionProperties,
+                   introspection_properties,
+                   INTROSPECTION_TYPE_PROPERTIES_PREREQUISITE)
 
 void
 introspection_properties_default_init (IntrospectionPropertiesInterface *iface)
diff --git a/tests/libpeas/plugins/extension-js/extension-js.js b/tests/libpeas/plugins/extension-js/extension-js.js
index d3c2291..27413a9 100644
--- a/tests/libpeas/plugins/extension-js/extension-js.js
+++ b/tests/libpeas/plugins/extension-js/extension-js.js
@@ -39,6 +39,7 @@ var extensions = {
   "IntrospectionBase": extension_js_plugin,
   "IntrospectionCallable": extension_js_plugin,
   "IntrospectionProperties": extension_js_plugin,
+  "IntrospectionPropertiesPrerequisite": extension_js_plugin,
   "IntrospectionHasPrerequisite": extension_js_plugin,
   "IntrospectionHasMissingPrerequisite": missing_prerequisite_extension
 };
diff --git a/tests/libpeas/plugins/extension-python/extension-python.py b/tests/libpeas/plugins/extension-python/extension-python.py
index 242fc3d..90c6296 100644
--- a/tests/libpeas/plugins/extension-python/extension-python.py
+++ b/tests/libpeas/plugins/extension-python/extension-python.py
@@ -5,6 +5,7 @@ from gi.repository import GObject, Introspection, Peas
 
 class ExtensionPythonPlugin(GObject.Object, Peas.Activatable,
                             Introspection.Base, Introspection.Callable,
+                            Introspection.PropertiesPrerequisite,
                             Introspection.Properties,
                             Introspection.HasPrerequisite):
 
@@ -14,6 +15,7 @@ class ExtensionPythonPlugin(GObject.Object, Peas.Activatable,
     read_only = GObject.property(type=str, default="read-only")
     write_only = GObject.property(type=str)
     readwrite = GObject.property(type=str, default="readwrite")
+    prerequisite = GObject.property(type=str)
 
     def do_activate(self):
         pass
diff --git a/tests/libpeas/testing/testing-extension.c b/tests/libpeas/testing/testing-extension.c
index f145eec..ea6ec9e 100644
--- a/tests/libpeas/testing/testing-extension.c
+++ b/tests/libpeas/testing/testing-extension.c
@@ -458,6 +458,25 @@ test_extension_properties_readwrite (PeasEngine     *engine,
   g_object_unref (extension);
 }
 
+static void
+test_extension_properties_prerequisite (PeasEngine     *engine,
+                                        PeasPluginInfo *info)
+{
+  PeasExtension *extension;
+  gchar *prerequisite;
+
+  extension = peas_engine_create_extension (engine, info,
+                                            INTROSPECTION_TYPE_PROPERTIES,
+                                            "prerequisite", "prerequisite",
+                                            NULL);
+
+  g_object_get (extension, "prerequisite", &prerequisite, NULL);
+  g_assert_cmpstr (prerequisite, ==, "prerequisite");
+  g_free (prerequisite);
+
+  g_object_unref (extension);
+}
+
 #define _EXTENSION_TEST(loader, path, ftest) \
   g_test_add (I_(g_strdup_printf ("/extension/%s/" path, loader)), \
               TestFixture, \
@@ -514,6 +533,7 @@ testing_extension_properties (const gchar *loader)
   _EXTENSION_TEST (loader, "properties-read-only", properties_read_only);
   _EXTENSION_TEST (loader, "properties-write-only", properties_write_only);
   _EXTENSION_TEST (loader, "properties-readwrite", properties_readwrite);
+  _EXTENSION_TEST (loader, "properties-prerequisite", properties_prerequisite);
 }
 
 void



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