summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Regier <garrettregier@gmail.com>2016-03-02 11:15:27 -0800
committerGarrett Regier <garrettregier@gmail.com>2017-03-24 21:27:15 -0700
commit47e286b64d67c006c25b640ed3f5d1a886ccb0a0 (patch)
tree65ef3810448291103fad8aba9c961715677dae3f
parentb74fd58972a99771d7cb3a1f19526a885f88a114 (diff)
downloadlibpeas-47e286b64d67c006c25b640ed3f5d1a886ccb0a0.tar.gz
Consider all an interfaces potential properties
An interface can have a prerequisite which is derived from GObject an as such is not an interface. https://bugzilla.gnome.org/show_bug.cgi?id=762899
-rw-r--r--libpeas/peas-utils.c66
-rw-r--r--tests/libpeas/introspection/Makefile.am2
-rw-r--r--tests/libpeas/introspection/introspection-has-prerequisite.c16
-rw-r--r--tests/libpeas/introspection/introspection-prerequisite.c111
-rw-r--r--tests/libpeas/introspection/introspection-prerequisite.h56
-rw-r--r--tests/libpeas/plugins/extension-c/extension-c-plugin.c3
-rw-r--r--tests/libpeas/plugins/extension-lua/extension-lua51.lua12
-rw-r--r--tests/libpeas/plugins/extension-python/extension-py.py.in2
-rw-r--r--tests/libpeas/testing/testing-extension.c7
9 files changed, 246 insertions, 29 deletions
diff --git a/libpeas/peas-utils.c b/libpeas/peas-utils.c
index 8237011..1051d20 100644
--- a/libpeas/peas-utils.c
+++ b/libpeas/peas-utils.c
@@ -3,6 +3,7 @@
* This file is part of libpeas
*
* Copyright (C) 2010 Steve Frécinaux
+ * Copyright (C) 2011-2017 Garrett Regier
*
* libpeas is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -49,37 +50,61 @@ G_STATIC_ASSERT (G_N_ELEMENTS (all_plugin_loader_modules) == PEAS_UTILS_N_LOADER
G_STATIC_ASSERT (G_N_ELEMENTS (conflicting_plugin_loaders) == PEAS_UTILS_N_LOADERS);
static void
-add_all_interfaces (GType iface_type,
- GPtrArray *type_structs)
+add_all_prerequisites (GType iface_type,
+ GType *base_type,
+ GPtrArray *ifaces)
{
GType *prereq;
guint n_prereq;
guint i;
- g_ptr_array_add (type_structs,
- g_type_default_interface_ref (iface_type));
+ g_ptr_array_add (ifaces, 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);
+ {
+ add_all_prerequisites (prereq[i], base_type, ifaces);
+ continue;
+ }
+
+ if (!G_TYPE_IS_OBJECT (prereq[i]))
+ continue;
+
+ if (*base_type != G_TYPE_INVALID)
+ {
+ /* We already have the descendant GType */
+ if (g_type_is_a (*base_type, prereq[i]))
+ continue;
+
+ /* Neither GType are descendant of the other, this is an
+ * error and GObject will not be able to create an object
+ */
+ g_warn_if_fail (g_type_is_a (prereq[i], *base_type));
+ }
+
+ *base_type = prereq[i];
}
g_free (prereq);
}
static GParamSpec *
-find_param_spec_in_interfaces (GPtrArray *type_structs,
- const gchar *name)
+find_param_spec_for_prerequisites (const gchar *name,
+ GObjectClass *klass,
+ GPtrArray *ifaces)
{
guint i;
GParamSpec *pspec = NULL;
- for (i = 0; i < type_structs->len && pspec == NULL; ++i)
+ if (klass != NULL)
+ pspec = g_object_class_find_property (klass, name);
+
+ for (i = 0; i < ifaces->len && pspec == NULL; ++i)
{
- gpointer iface = g_ptr_array_index (type_structs, i);
+ gpointer iface = g_ptr_array_index (ifaces, i);
pspec = g_object_interface_find_property (iface, name);
}
@@ -94,16 +119,21 @@ peas_utils_valist_to_parameter_list (GType iface_type,
GParameter **params,
guint *n_params)
{
- GPtrArray *type_structs;
+ GPtrArray *ifaces;
+ GType base_type = G_TYPE_INVALID;
+ GObjectClass *klass = NULL;
const gchar *name;
guint n_allocated_params;
g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_type), FALSE);
- type_structs = g_ptr_array_new ();
- g_ptr_array_set_free_func (type_structs,
+ ifaces = g_ptr_array_new ();
+ g_ptr_array_set_free_func (ifaces,
(GDestroyNotify) g_type_default_interface_unref);
- add_all_interfaces (iface_type, type_structs);
+ add_all_prerequisites (iface_type, &base_type, ifaces);
+
+ if (base_type != G_TYPE_INVALID)
+ klass = g_type_class_ref (base_type);
*n_params = 0;
n_allocated_params = 16;
@@ -113,7 +143,9 @@ peas_utils_valist_to_parameter_list (GType iface_type,
while (name)
{
gchar *error_msg = NULL;
- GParamSpec *pspec = find_param_spec_in_interfaces (type_structs, name);
+ GParamSpec *pspec;
+
+ pspec = find_param_spec_for_prerequisites (name, klass, ifaces);
if (!pspec)
{
@@ -146,7 +178,8 @@ peas_utils_valist_to_parameter_list (GType iface_type,
name = va_arg (args, gchar*);
}
- g_ptr_array_unref (type_structs);
+ g_ptr_array_unref (ifaces);
+ g_clear_pointer (&klass, g_type_class_unref);
return TRUE;
@@ -156,7 +189,8 @@ error:
g_value_unset (&(*params)[*n_params].value);
g_free (*params);
- g_ptr_array_unref (type_structs);
+ g_ptr_array_unref (ifaces);
+ g_clear_pointer (&klass, g_type_class_unref);
return FALSE;
}
diff --git a/tests/libpeas/introspection/Makefile.am b/tests/libpeas/introspection/Makefile.am
index 3cd8b41..930851b 100644
--- a/tests/libpeas/introspection/Makefile.am
+++ b/tests/libpeas/introspection/Makefile.am
@@ -19,6 +19,8 @@ libintrospection_1_0_la_SOURCES = \
introspection-callable.h \
introspection-has-prerequisite.c \
introspection-has-prerequisite.h \
+ introspection-prerequisite.c \
+ introspection-prerequisite.h \
introspection-unimplemented.c \
introspection-unimplemented.h
diff --git a/tests/libpeas/introspection/introspection-has-prerequisite.c b/tests/libpeas/introspection/introspection-has-prerequisite.c
index 145c8dd..f836f52 100644
--- a/tests/libpeas/introspection/introspection-has-prerequisite.c
+++ b/tests/libpeas/introspection/introspection-has-prerequisite.c
@@ -2,7 +2,7 @@
* introspection-has-prerequisite.h
* This file is part of libpeas
*
- * Copyright (C) 2011 Garrett Regier
+ * Copyright (C) 2011-2017 Garrett Regier
*
* libpeas is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,13 +23,19 @@
#include <config.h>
#endif
+#include "introspection-base.h"
+#include "introspection-callable.h"
#include "introspection-has-prerequisite.h"
-#include "introspection-base.h"
+#include "introspection-prerequisite.h"
-G_DEFINE_INTERFACE(IntrospectionHasPrerequisite,
- introspection_has_prerequisite,
- INTROSPECTION_TYPE_BASE)
+G_DEFINE_INTERFACE_WITH_CODE(IntrospectionHasPrerequisite,
+ introspection_has_prerequisite,
+ INTROSPECTION_TYPE_PREREQUISITE,
+ g_type_interface_add_prerequisite (g_define_type_id,
+ INTROSPECTION_TYPE_BASE);
+ g_type_interface_add_prerequisite (g_define_type_id,
+ INTROSPECTION_TYPE_CALLABLE);)
void
introspection_has_prerequisite_default_init (IntrospectionHasPrerequisiteInterface *iface)
diff --git a/tests/libpeas/introspection/introspection-prerequisite.c b/tests/libpeas/introspection/introspection-prerequisite.c
new file mode 100644
index 0000000..1fed47e
--- /dev/null
+++ b/tests/libpeas/introspection/introspection-prerequisite.c
@@ -0,0 +1,111 @@
+/*
+ * introspection-prerequisite.h
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2017 Garrett Regier
+ *
+ * libpeas is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * libpeas 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "introspection-prerequisite.h"
+
+typedef struct {
+ gint value;
+} IntrospectionPrerequisitePrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (IntrospectionPrerequisite,
+ introspection_prerequisite,
+ PEAS_TYPE_EXTENSION_BASE)
+
+#define GET_PRIV(o) \
+ (introspection_prerequisite_get_instance_private (o))
+
+enum {
+ PROP_0,
+ PROP_PREREQUISITE_PROPERTY,
+ N_PROPERTIES
+};
+
+static GParamSpec *properties[N_PROPERTIES] = { NULL };
+
+static void
+introspection_prerequisite_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IntrospectionPrerequisite *prereq = INTROSPECTION_PREREQUISITE (object);
+ IntrospectionPrerequisitePrivate *priv = GET_PRIV (prereq);
+
+ switch (prop_id)
+ {
+ case PROP_PREREQUISITE_PROPERTY:
+ g_value_set_int (value, priv->value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+introspection_prerequisite_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IntrospectionPrerequisite *prereq = INTROSPECTION_PREREQUISITE (object);
+ IntrospectionPrerequisitePrivate *priv = GET_PRIV (prereq);
+
+ switch (prop_id)
+ {
+ case PROP_PREREQUISITE_PROPERTY:
+ priv->value = g_value_get_int (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+introspection_prerequisite_class_init (IntrospectionPrerequisiteClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = introspection_prerequisite_get_property;
+ object_class->set_property = introspection_prerequisite_set_property;
+
+ properties[PROP_PREREQUISITE_PROPERTY] =
+ g_param_spec_int ("prerequisite-property",
+ "Prerequisite Property",
+ "The IntrospectionPrerequisite",
+ G_MININT,
+ G_MAXINT,
+ -1,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, N_PROPERTIES, properties);
+}
+
+static void
+introspection_prerequisite_init (IntrospectionPrerequisite *prereq)
+{
+}
diff --git a/tests/libpeas/introspection/introspection-prerequisite.h b/tests/libpeas/introspection/introspection-prerequisite.h
new file mode 100644
index 0000000..f600d9f
--- /dev/null
+++ b/tests/libpeas/introspection/introspection-prerequisite.h
@@ -0,0 +1,56 @@
+/*
+ * introspection-prerequisite.h
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2017 Garrett Regier
+ *
+ * libpeas is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * libpeas 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __INTROSPECTION_PREREQUISITE_H__
+#define __INTROSPECTION_PREREQUISITE_H__
+
+#include <libpeas/peas.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define INTROSPECTION_TYPE_PREREQUISITE (introspection_prerequisite_get_type ())
+#define INTROSPECTION_PREREQUISITE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INTROSPECTION_TYPE_PREREQUISITE, IntrospectionPrerequisite))
+#define INTROSPECTION_PREREQUISITE_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), INTROSPECTION_TYPE_PREREQUISITE, IntrospectionPrerequisiteClass))
+#define INTROSPECTION_IS_PREREQUISITE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INTROSPECTION_TYPE_PREREQUISITE))
+#define INTROSPECTION_PREREQUISITE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INTROSPECTION_TYPE_PREREQUISITE, IntrospectionPrerequisiteClass))
+
+typedef struct _IntrospectionPrerequisite IntrospectionPrerequisite;
+typedef struct _IntrospectionPrerequisiteClass IntrospectionPrerequisiteClass;
+
+struct _IntrospectionPrerequisite {
+ PeasExtensionBase parent;
+};
+
+struct _IntrospectionPrerequisiteClass {
+ PeasExtensionBaseClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType introspection_prerequisite_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __INTROSPECTION_PREREQUISITE_H__ */
diff --git a/tests/libpeas/plugins/extension-c/extension-c-plugin.c b/tests/libpeas/plugins/extension-c/extension-c-plugin.c
index 6b08995..3125de8 100644
--- a/tests/libpeas/plugins/extension-c/extension-c-plugin.c
+++ b/tests/libpeas/plugins/extension-c/extension-c-plugin.c
@@ -32,6 +32,7 @@
#include "introspection-base.h"
#include "introspection-callable.h"
#include "introspection-has-prerequisite.h"
+#include "introspection-prerequisite.h"
#include "extension-c-plugin.h"
@@ -44,7 +45,7 @@ static void introspection_has_prerequisite_iface_init (IntrospectionHasPrerequis
G_DEFINE_DYNAMIC_TYPE_EXTENDED (TestingExtensionCPlugin,
testing_extension_c_plugin,
- PEAS_TYPE_EXTENSION_BASE,
+ INTROSPECTION_TYPE_PREREQUISITE,
0,
G_IMPLEMENT_INTERFACE_DYNAMIC (INTROSPECTION_TYPE_BASE,
introspection_base_iface_init)
diff --git a/tests/libpeas/plugins/extension-lua/extension-lua51.lua b/tests/libpeas/plugins/extension-lua/extension-lua51.lua
index 4b97a30..69df5f7 100644
--- a/tests/libpeas/plugins/extension-lua/extension-lua51.lua
+++ b/tests/libpeas/plugins/extension-lua/extension-lua51.lua
@@ -22,12 +22,12 @@ local Introspection = lgi.Introspection
local Peas = lgi.Peas
-local ExtensionLuaPlugin = GObject.Object:derive('ExtensionLuaPlugin', {
- Peas.Activatable,
- Introspection.Base,
- Introspection.Callable,
- Introspection.HasPrerequisite
-})
+local ExtensionLuaPlugin =
+ Introspection.Prerequisite:derive('ExtensionLuaPlugin', {
+ Peas.Activatable,
+ Introspection.Base,
+ Introspection.Callable,
+ Introspection.HasPrerequisite })
ExtensionLuaPlugin._property.object =
GObject.ParamSpecObject('object', 'object', 'object',
diff --git a/tests/libpeas/plugins/extension-python/extension-py.py.in b/tests/libpeas/plugins/extension-python/extension-py.py.in
index 728b399..d5ea6fa 100644
--- a/tests/libpeas/plugins/extension-python/extension-py.py.in
+++ b/tests/libpeas/plugins/extension-python/extension-py.py.in
@@ -27,7 +27,7 @@ from gi.repository import GObject, Introspection, Peas
__all__ = [ 'ExtensionPythonPlugin' ]
-class ExtensionPythonPlugin(GObject.Object, Peas.Activatable,
+class ExtensionPythonPlugin(Introspection.Prerequisite, Peas.Activatable,
Introspection.Base, Introspection.Callable,
Introspection.HasPrerequisite):
diff --git a/tests/libpeas/testing/testing-extension.c b/tests/libpeas/testing/testing-extension.c
index 100d299..60e88f4 100644
--- a/tests/libpeas/testing/testing-extension.c
+++ b/tests/libpeas/testing/testing-extension.c
@@ -190,14 +190,21 @@ test_extension_create_with_prerequisite (PeasEngine *engine,
PeasPluginInfo *info)
{
PeasExtension *extension;
+ gint prerequisite_property = -1;
extension = peas_engine_create_extension (engine, info,
INTROSPECTION_TYPE_HAS_PREREQUISITE,
+ "prerequisite-property", 47,
NULL);
g_assert (INTROSPECTION_IS_HAS_PREREQUISITE (extension));
g_assert (INTROSPECTION_IS_CALLABLE (extension));
+ g_object_get (extension,
+ "prerequisite-property", &prerequisite_property,
+ NULL);
+ g_assert_cmpint (prerequisite_property, ==, 47);
+
g_object_unref (extension);
}