summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpeas/peas-engine.c33
-rw-r--r--libpeas/peas-extension-set.c18
-rw-r--r--libpeas/peas-extension.c32
-rw-r--r--libpeas/peas-introspection.c29
-rw-r--r--libpeas/peas-introspection.h4
-rw-r--r--libpeas/peas-object-module.c116
-rw-r--r--libpeas/peas-object-module.h10
-rw-r--r--libpeas/peas-utils.c40
-rw-r--r--libpeas/peas-utils.h2
-rw-r--r--tests/libpeas/introspection/Makefile.am2
-rw-r--r--tests/libpeas/introspection/introspection-abstract.c132
-rw-r--r--tests/libpeas/introspection/introspection-abstract.h60
-rw-r--r--tests/libpeas/plugins/extension-c/Makefile.am4
-rw-r--r--tests/libpeas/plugins/extension-c/extension-c-abstract.c55
-rw-r--r--tests/libpeas/plugins/extension-c/extension-c-abstract.h52
-rw-r--r--tests/libpeas/plugins/extension-c/extension-c-plugin.c7
-rw-r--r--tests/libpeas/plugins/extension-lua/extension-lua51.lua6
-rw-r--r--tests/libpeas/plugins/extension-python/extension-py.py.in6
-rw-r--r--tests/libpeas/testing/testing-extension.c51
19 files changed, 548 insertions, 111 deletions
diff --git a/libpeas/peas-engine.c b/libpeas/peas-engine.c
index 3b35145..5713cb0 100644
--- a/libpeas/peas-engine.c
+++ b/libpeas/peas-engine.c
@@ -57,6 +57,9 @@
* plugins and their extensions from within your application.</para>
* </listitem>
* </itemizedlist>
+ *
+ * Since libpeas 1.22, @extension_type can be an Abstract #GType
+ * and not just an Interface #GType.
**/
/* Signals */
@@ -1274,6 +1277,9 @@ peas_engine_unload_plugin (PeasEngine *engine,
* Returns if @info provides an extension for @extension_type.
* If the @info is not loaded than %FALSE will always be returned.
*
+ * Since libpeas 1.22, @extension_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* Returns: if @info provides an extension for @extension_type.
*/
gboolean
@@ -1285,7 +1291,8 @@ peas_engine_provides_extension (PeasEngine *engine,
g_return_val_if_fail (PEAS_IS_ENGINE (engine), FALSE);
g_return_val_if_fail (info != NULL, FALSE);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type) ||
+ G_TYPE_IS_ABSTRACT (extension_type), FALSE);
if (!peas_plugin_info_is_loaded (info))
return FALSE;
@@ -1303,10 +1310,13 @@ peas_engine_provides_extension (PeasEngine *engine,
* @parameters: (allow-none) (array length=n_parameters):
* an array of #GParameter.
*
- * If the plugin identified by @info implements the @extension_type interface,
+ * If the plugin identified by @info implements the @extension_type,
* then this function will return a new instance of this implementation,
* wrapped in a new #PeasExtension instance. Otherwise, it will return %NULL.
*
+ * Since libpeas 1.22, @extension_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* See peas_engine_create_extension() for more information.
*
* Returns: (transfer full): a new instance of #PeasExtension wrapping
@@ -1324,8 +1334,9 @@ peas_engine_create_extensionv (PeasEngine *engine,
g_return_val_if_fail (PEAS_IS_ENGINE (engine), NULL);
g_return_val_if_fail (info != NULL, NULL);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type) ||
+ G_TYPE_IS_ABSTRACT (extension_type), NULL);
g_return_val_if_fail (peas_plugin_info_is_loaded (info), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type), FALSE);
loader = get_plugin_loader (engine, info->loader_id);
extension = peas_plugin_loader_create_extension (loader, info, extension_type,
@@ -1351,10 +1362,13 @@ peas_engine_create_extensionv (PeasEngine *engine,
* @var_args: the value of the first property, followed optionally by more
* name/value pairs, followed by %NULL.
*
- * If the plugin identified by @info implements the @extension_type interface,
+ * If the plugin identified by @info implements the @extension_type,
* then this function will return a new instance of this implementation,
* wrapped in a new #PeasExtension instance. Otherwise, it will return %NULL.
*
+ * Since libpeas 1.22, @extension_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* See peas_engine_create_extension() for more information.
*
* Returns: a new instance of #PeasExtension wrapping
@@ -1374,7 +1388,8 @@ peas_engine_create_extension_valist (PeasEngine *engine,
g_return_val_if_fail (PEAS_IS_ENGINE (engine), NULL);
g_return_val_if_fail (info != NULL, NULL);
g_return_val_if_fail (peas_plugin_info_is_loaded (info), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type) ||
+ G_TYPE_IS_ABSTRACT (extension_type), FALSE);
if (!peas_utils_valist_to_parameter_list (extension_type, first_property,
var_args, &parameters,
@@ -1403,7 +1418,7 @@ peas_engine_create_extension_valist (PeasEngine *engine,
* @...: the value of the first property, followed optionally by more
* name/value pairs, followed by %NULL.
*
- * If the plugin identified by @info implements the @extension_type interface,
+ * If the plugin identified by @info implements the @extension_type,
* then this function will return a new instance of this implementation,
* wrapped in a new #PeasExtension instance. Otherwise, it will return %NULL.
*
@@ -1416,6 +1431,9 @@ peas_engine_create_extension_valist (PeasEngine *engine,
* principle of never giving you the actual object (also because it might as
* well *not* be an actual object).
*
+ * Since libpeas 1.22, @extension_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* Returns: a new instance of #PeasExtension wrapping
* the @extension_type instance, or %NULL.
*/
@@ -1432,7 +1450,8 @@ peas_engine_create_extension (PeasEngine *engine,
g_return_val_if_fail (PEAS_IS_ENGINE (engine), NULL);
g_return_val_if_fail (info != NULL, NULL);
g_return_val_if_fail (peas_plugin_info_is_loaded (info), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type) ||
+ G_TYPE_IS_ABSTRACT (extension_type), FALSE);
va_start (var_args, first_property);
exten = peas_engine_create_extension_valist (engine, info, extension_type,
diff --git a/libpeas/peas-extension-set.c b/libpeas/peas-extension-set.c
index cb3f9cc..a4e0f3f 100644
--- a/libpeas/peas-extension-set.c
+++ b/libpeas/peas-extension-set.c
@@ -615,6 +615,9 @@ peas_extension_set_foreach (PeasExtensionSet *set,
*
* If @engine is %NULL, then the default engine will be used.
*
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* See peas_extension_set_new() for more information.
*
* Returns: (transfer full): a new instance of #PeasExtensionSet.
@@ -628,7 +631,8 @@ peas_extension_set_newv (PeasEngine *engine,
PeasParameterArray construct_properties = { n_parameters, parameters };
g_return_val_if_fail (engine == NULL || PEAS_IS_ENGINE (engine), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type), NULL);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type), NULL);
return PEAS_EXTENSION_SET (g_object_new (PEAS_TYPE_EXTENSION_SET,
"engine", engine,
@@ -649,6 +653,9 @@ peas_extension_set_newv (PeasEngine *engine,
*
* If @engine is %NULL, then the default engine will be used.
*
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* See peas_extension_set_new() for more information.
*
* Returns: a new instance of #PeasExtensionSet.
@@ -664,7 +671,8 @@ peas_extension_set_new_valist (PeasEngine *engine,
PeasExtensionSet *set;
g_return_val_if_fail (engine == NULL || PEAS_IS_ENGINE (engine), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type), NULL);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type), NULL);
if (!peas_utils_valist_to_parameter_list (exten_type, first_property,
var_args, &parameters,
@@ -702,6 +710,9 @@ peas_extension_set_new_valist (PeasEngine *engine,
*
* If @engine is %NULL, then the default engine will be used.
*
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* See peas_engine_create_extension() for more information.
*
* Returns: a new instance of #PeasExtensionSet.
@@ -716,7 +727,8 @@ peas_extension_set_new (PeasEngine *engine,
PeasExtensionSet *set;
g_return_val_if_fail (engine == NULL || PEAS_IS_ENGINE (engine), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type), NULL);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type), NULL);
va_start (var_args, first_property);
set = peas_extension_set_new_valist (engine, exten_type, first_property, var_args);
diff --git a/libpeas/peas-extension.c b/libpeas/peas-extension.c
index 773d9f2..8e46920 100644
--- a/libpeas/peas-extension.c
+++ b/libpeas/peas-extension.c
@@ -37,8 +37,8 @@
* loaded plugins.
*
* To properly use the proxy instances, you will need GObject-introspection
- * data for the #GInterface or #GObjectClass you want to use as an extension
- * point. For instance, if you wish to use #PeasActivatable, you will need to
+ * data for the #GType you want to use as an extension point.
+ * For instance, if you wish to use #PeasActivatable, you will need to
* put the following code excerpt in the engine initialization code, in order
* to load the required "Peas" typelib:
*
@@ -47,7 +47,7 @@
* "Peas", "1.0", 0, NULL);
* ]|
*
- * You should proceed the same way for any namespace which provides interfaces
+ * You should proceed the same way for any namespace which provides types
* you want to use as extension points. GObject-introspection data is required
* for all the supported languages, even for C.
*
@@ -72,7 +72,7 @@ G_DEFINE_QUARK (peas-extension-type, extension_type)
static GICallableInfo *
get_method_info (PeasExtension *exten,
const gchar *method_name,
- GType *interface)
+ GType *gtype)
{
guint i;
GType exten_type;
@@ -85,8 +85,8 @@ get_method_info (PeasExtension *exten,
if (method_info != NULL)
{
- if (interface != NULL)
- *interface = exten_type;
+ if (gtype != NULL)
+ *gtype = exten_type;
return method_info;
}
@@ -99,15 +99,15 @@ get_method_info (PeasExtension *exten,
if (method_info != NULL)
{
- if (interface != NULL)
- *interface = interfaces[i];
+ if (gtype != NULL)
+ *gtype = interfaces[i];
break;
}
}
if (method_info == NULL)
- g_warning ("Could not find the interface for method '%s'", method_name);
+ g_warning ("Could not find the GType for method '%s'", method_name);
g_free (interfaces);
return method_info;
@@ -117,7 +117,7 @@ get_method_info (PeasExtension *exten,
* peas_extension_get_extension_type:
* @exten: A #PeasExtension.
*
- * Get the type of the extension interface of the object proxied by @exten.
+ * Get the #GType of the extension proxied by @exten.
*
* Return value: The #GType proxied by @exten.
*
@@ -154,7 +154,7 @@ peas_extension_get_extension_type (PeasExtension *exten)
*
* Return value: %TRUE on successful call.
*
- * Deprecated: 1.2: Use the interface directly instead.
+ * Deprecated: 1.2: Use the object directly instead.
*/
gboolean
peas_extension_call (PeasExtension *exten,
@@ -186,7 +186,7 @@ peas_extension_call (PeasExtension *exten,
*
* Return value: %TRUE on successful call.
*
- * Deprecated: 1.2: Use the interface directly instead.
+ * Deprecated: 1.2: Use the object directly instead.
*/
gboolean
peas_extension_call_valist (PeasExtension *exten,
@@ -241,7 +241,7 @@ peas_extension_call_valist (PeasExtension *exten,
*
* Return value: %TRUE on successful call.
*
- * Deprecated: 1.2: Use the interface directly instead.
+ * Deprecated: 1.2: Use the object directly instead.
*/
gboolean
peas_extension_callv (PeasExtension *exten,
@@ -250,19 +250,19 @@ peas_extension_callv (PeasExtension *exten,
GIArgument *return_value)
{
GICallableInfo *method_info;
- GType interface;
+ GType gtype;
gboolean success;
g_return_val_if_fail (PEAS_IS_EXTENSION (exten), FALSE);
g_return_val_if_fail (method_name != NULL, FALSE);
- method_info = get_method_info (exten, method_name, &interface);
+ method_info = get_method_info (exten, method_name, &gtype);
/* Already warned */
if (method_info == NULL)
return FALSE;
- success = peas_gi_method_call (G_OBJECT (exten), method_info, interface,
+ success = peas_gi_method_call (G_OBJECT (exten), method_info, gtype,
method_name, args, return_value);
g_base_info_unref (method_info);
diff --git a/libpeas/peas-introspection.c b/libpeas/peas-introspection.c
index 89aa41e..49ac178 100644
--- a/libpeas/peas-introspection.c
+++ b/libpeas/peas-introspection.c
@@ -239,44 +239,44 @@ peas_gi_argument_to_pointer (GITypeInfo *type_info,
}
GICallableInfo *
-peas_gi_get_method_info (GType iface_type,
+peas_gi_get_method_info (GType gtype,
const gchar *method_name)
{
GIRepository *repo;
- GIBaseInfo *iface_info;
+ GIBaseInfo *type_info;
GIFunctionInfo *func_info;
repo = g_irepository_get_default ();
- iface_info = g_irepository_find_by_gtype (repo, iface_type);
- if (iface_info == NULL)
+ type_info = g_irepository_find_by_gtype (repo, gtype);
+ if (type_info == NULL)
{
g_warning ("Type not found in introspection: '%s'",
- g_type_name (iface_type));
+ g_type_name (gtype));
return NULL;
}
- switch (g_base_info_get_type (iface_info))
+ switch (g_base_info_get_type (type_info))
{
case GI_INFO_TYPE_OBJECT:
- func_info = g_object_info_find_method ((GIObjectInfo *) iface_info,
+ func_info = g_object_info_find_method ((GIObjectInfo *) type_info,
method_name);
break;
case GI_INFO_TYPE_INTERFACE:
- func_info = g_interface_info_find_method ((GIInterfaceInfo *) iface_info,
+ func_info = g_interface_info_find_method ((GIInterfaceInfo *) type_info,
method_name);
break;
default:
func_info = NULL;
}
- g_base_info_unref (iface_info);
+ g_base_info_unref (type_info);
return (GICallableInfo *) func_info;
}
gboolean
peas_gi_method_call (GObject *instance,
GICallableInfo *func_info,
- GType iface_type,
+ GType gtype,
const gchar *method_name,
GIArgument *args,
GIArgument *return_value)
@@ -289,8 +289,9 @@ peas_gi_method_call (GObject *instance,
g_return_val_if_fail (G_IS_OBJECT (instance), FALSE);
g_return_val_if_fail (func_info != NULL, FALSE);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_type), FALSE);
- g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (instance, iface_type),
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (gtype) ||
+ G_TYPE_IS_ABSTRACT (gtype), FALSE);
+ g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (instance, gtype),
FALSE);
g_return_val_if_fail (method_name != NULL, FALSE);
@@ -311,14 +312,14 @@ peas_gi_method_call (GObject *instance,
n_in_args++;
g_debug ("Calling '%s.%s' on '%p'",
- g_type_name (iface_type), method_name, instance);
+ g_type_name (gtype), method_name, instance);
ret = g_function_info_invoke (func_info, in_args, n_in_args, out_args,
n_out_args, return_value, &error);
if (!ret)
{
g_warning ("Error while calling '%s.%s': %s",
- g_type_name (iface_type), method_name, error->message);
+ g_type_name (gtype), method_name, error->message);
g_error_free (error);
}
diff --git a/libpeas/peas-introspection.h b/libpeas/peas-introspection.h
index 53af722..e5f3bbd 100644
--- a/libpeas/peas-introspection.h
+++ b/libpeas/peas-introspection.h
@@ -27,7 +27,7 @@
G_BEGIN_DECLS
-GICallableInfo *peas_gi_get_method_info (GType iface_type,
+GICallableInfo *peas_gi_get_method_info (GType gtype,
const gchar *method_name);
void peas_gi_valist_to_arguments (GICallableInfo *callable_info,
@@ -39,7 +39,7 @@ void peas_gi_argument_to_pointer (GITypeInfo *type_info,
gpointer ptr);
gboolean peas_gi_method_call (GObject *instance,
GICallableInfo *method_info,
- GType iface_type,
+ GType gtype,
const gchar *method_name,
GIArgument *args,
GIArgument *return_value);
diff --git a/libpeas/peas-object-module.c b/libpeas/peas-object-module.c
index fbd81f2..6711667 100644
--- a/libpeas/peas-object-module.c
+++ b/libpeas/peas-object-module.c
@@ -40,6 +40,9 @@
* of extensions. It will be used by C extensions implementors to register
* extension implementations from within the peas_register_types module
* function.
+ *
+ * Since libpeas 1.22, @extension_type can be an Abstract #GType
+ * and not just an Interface #GType.
**/
typedef void (*PeasObjectModuleRegisterFunc) (PeasObjectModule *module);
@@ -57,11 +60,11 @@ enum {
static GParamSpec *properties[N_PROPERTIES] = { NULL };
typedef struct {
- GType iface_type;
+ GType exten_type;
PeasFactoryFunc func;
gpointer user_data;
GDestroyNotify destroy_func;
-} InterfaceImplementation;
+} ExtensionImplementation;
struct _PeasObjectModulePrivate {
GModule *library;
@@ -171,7 +174,7 @@ peas_object_module_unload (GTypeModule *gmodule)
{
PeasObjectModule *module = PEAS_OBJECT_MODULE (gmodule);
PeasObjectModulePrivate *priv = GET_PRIV (module);
- InterfaceImplementation *impls;
+ ExtensionImplementation *impls;
guint i;
g_module_close (priv->library);
@@ -179,7 +182,7 @@ peas_object_module_unload (GTypeModule *gmodule)
priv->library = NULL;
priv->register_func = NULL;
- impls = (InterfaceImplementation *) priv->implementations->data;
+ impls = (ExtensionImplementation *) priv->implementations->data;
for (i = 0; i < priv->implementations->len; ++i)
{
if (impls[i].destroy_func != NULL)
@@ -196,7 +199,7 @@ peas_object_module_init (PeasObjectModule *module)
PeasObjectModulePrivate *priv = GET_PRIV (module);
priv->implementations = g_array_new (FALSE, FALSE,
- sizeof (InterfaceImplementation));
+ sizeof (ExtensionImplementation));
}
static void
@@ -433,36 +436,38 @@ peas_object_module_new_embedded (const gchar *module_name,
/**
* peas_object_module_create_object: (skip)
* @module: A #PeasObjectModule.
- * @interface: The #GType of the extension interface.
+ * @exten_type: The #GType of the extension.
* @n_parameters: The number of paramteters.
* @parameters: (array length=n_parameters): The parameters.
*
- * Creates an object for the @interface passing @n_parameters
+ * Creates an object for the @exten_type passing @n_parameters
* and @parameters to the #PeasFactoryFunc. If @module does
- * not provide a #PeasFactoryFunc for @interface then
+ * not provide a #PeasFactoryFunc for @exten_type then
* %NULL is returned.
*
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* Return value: (transfer full): The created object, or %NULL.
*/
GObject *
peas_object_module_create_object (PeasObjectModule *module,
- GType interface,
+ GType exten_type,
guint n_parameters,
GParameter *parameters)
{
PeasObjectModulePrivate *priv = GET_PRIV (module);
guint i;
- InterfaceImplementation *impls;
+ ExtensionImplementation *impls;
g_return_val_if_fail (PEAS_IS_OBJECT_MODULE (module), NULL);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type), NULL);
- if (interface != PEAS_TYPE_PLUGIN_LOADER)
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), NULL);
-
- impls = (InterfaceImplementation *) priv->implementations->data;
+ impls = (ExtensionImplementation *) priv->implementations->data;
for (i = 0; i < priv->implementations->len; ++i)
{
- if (impls[i].iface_type == interface)
+ if (impls[i].exten_type == exten_type)
return impls[i].func (n_parameters, parameters, impls[i].user_data);
}
@@ -472,29 +477,31 @@ peas_object_module_create_object (PeasObjectModule *module,
/**
* peas_object_module_provides_object: (skip)
* @module: A #PeasObjectModule.
- * @interface: The #GType of the extension interface.
+ * @exten_type: The #GType of the extension.
*
- * Determines if the module provides an extension for @interface.
+ * Determines if the module provides an extension for @exten_type.
*
- * Return value: if the module provides an extension for @interface.
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
+ * Return value: if the module provides an extension for @exten_type.
*/
gboolean
peas_object_module_provides_object (PeasObjectModule *module,
- GType interface)
+ GType exten_type)
{
PeasObjectModulePrivate *priv = GET_PRIV (module);
guint i;
- InterfaceImplementation *impls;
+ ExtensionImplementation *impls;
g_return_val_if_fail (PEAS_IS_OBJECT_MODULE (module), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type), FALSE);
- if (interface != PEAS_TYPE_PLUGIN_LOADER)
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), FALSE);
-
- impls = (InterfaceImplementation *) priv->implementations->data;
+ impls = (ExtensionImplementation *) priv->implementations->data;
for (i = 0; i < priv->implementations->len; ++i)
{
- if (impls[i].iface_type == interface)
+ if (impls[i].exten_type == exten_type)
return TRUE;
}
@@ -578,8 +585,8 @@ peas_object_module_get_library (PeasObjectModule *module)
/**
* peas_object_module_register_extension_factory:
* @module: Your plugin's #PeasObjectModule.
- * @iface_type: The #GType of the extension interface you implement.
- * @factory_func: The #PeasFactoryFunc that will create the @iface_type
+ * @exten_type: The #GType of the extension you implement.
+ * @factory_func: The #PeasFactoryFunc that will create the @exten_type
* instance when requested.
* @user_data: Data to pass to @func calls.
* @destroy_func: A #GDestroyNotify for @user_data.
@@ -592,27 +599,29 @@ peas_object_module_get_library (PeasObjectModule *module)
* creating native types which cannot be instantiated correctly using
* g_object_new(). For other uses, you will usually prefer relying on
* peas_object_module_register_extension_type().
+ *
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
*/
void
peas_object_module_register_extension_factory (PeasObjectModule *module,
- GType iface_type,
+ GType exten_type,
PeasFactoryFunc factory_func,
gpointer user_data,
GDestroyNotify destroy_func)
{
PeasObjectModulePrivate *priv = GET_PRIV (module);
- InterfaceImplementation impl = { iface_type, factory_func, user_data, destroy_func };
+ ExtensionImplementation impl = { exten_type, factory_func, user_data, destroy_func };
g_return_if_fail (PEAS_IS_OBJECT_MODULE (module));
- g_return_if_fail (!peas_object_module_provides_object (module, iface_type));
+ g_return_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type));
+ g_return_if_fail (!peas_object_module_provides_object (module, exten_type));
g_return_if_fail (factory_func != NULL);
- if (iface_type != PEAS_TYPE_PLUGIN_LOADER)
- g_return_if_fail (G_TYPE_IS_INTERFACE (iface_type));
-
g_array_append_val (priv->implementations, impl);
- g_debug ("Registered extension for type '%s'", g_type_name (iface_type));
+ g_debug ("Registered extension for type '%s'", g_type_name (exten_type));
}
static GObject *
@@ -620,15 +629,15 @@ create_gobject_from_type (guint n_parameters,
GParameter *parameters,
gpointer user_data)
{
- GType exten_type = GPOINTER_TO_SIZE (user_data);
+ GType impl_type = GPOINTER_TO_SIZE (user_data);
/* We should be called with a "plugin-info" property appended
* to the parameters. Let's get rid of it if the actual type
* doesn't have such a property as it would cause a warning.
*/
- if ((exten_type & TYPE_MISSING_PLUGIN_INFO_PROPERTY) != 0)
+ if ((impl_type & TYPE_MISSING_PLUGIN_INFO_PROPERTY) != 0)
{
- exten_type &= ~TYPE_MISSING_PLUGIN_INFO_PROPERTY;
+ impl_type &= ~TYPE_MISSING_PLUGIN_INFO_PROPERTY;
if (n_parameters > 0)
{
@@ -642,44 +651,45 @@ create_gobject_from_type (guint n_parameters,
}
}
- return G_OBJECT (g_object_newv (exten_type, n_parameters, parameters));
+ return G_OBJECT (g_object_newv (impl_type, n_parameters, parameters));
}
/**
* peas_object_module_register_extension_type:
* @module: Your plugin's #PeasObjectModule.
- * @iface_type: The #GType of the extension interface you implement.
- * @extension_type: The #GType of your implementation of @iface_type.
+ * @exten_type: The #GType of the extension you implement.
+ * @impl_type: The #GType of your implementation of @exten_type.
*
- * Register an extension type which implements the extension interface
- * @iface_type.
+ * Register @impl_type as an extension which implements @extension_type.
+ *
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
*/
void
peas_object_module_register_extension_type (PeasObjectModule *module,
- GType iface_type,
- GType extension_type)
+ GType exten_type,
+ GType impl_type)
{
GObjectClass *cls;
GParamSpec *pspec;
g_return_if_fail (PEAS_IS_OBJECT_MODULE (module));
- g_return_if_fail (!peas_object_module_provides_object (module, iface_type));
- g_return_if_fail (g_type_is_a (extension_type, iface_type));
-
- if (iface_type != PEAS_TYPE_PLUGIN_LOADER)
- g_return_if_fail (G_TYPE_IS_INTERFACE (iface_type));
+ g_return_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type));
+ g_return_if_fail (!peas_object_module_provides_object (module, exten_type));
+ g_return_if_fail (g_type_is_a (impl_type, exten_type));
- cls = g_type_class_ref (extension_type);
+ cls = g_type_class_ref (impl_type);
pspec = g_object_class_find_property (cls, "plugin-info");
/* Avoid checking for this each time in the factory function */
if (pspec == NULL || pspec->value_type != PEAS_TYPE_PLUGIN_INFO)
- extension_type |= TYPE_MISSING_PLUGIN_INFO_PROPERTY;
+ impl_type |= TYPE_MISSING_PLUGIN_INFO_PROPERTY;
peas_object_module_register_extension_factory (module,
- iface_type,
+ exten_type,
create_gobject_from_type,
- GSIZE_TO_POINTER (extension_type),
+ GSIZE_TO_POINTER (impl_type),
NULL);
g_type_class_unref (cls);
diff --git a/libpeas/peas-object-module.h b/libpeas/peas-object-module.h
index 70a0265..08c5d6b 100644
--- a/libpeas/peas-object-module.h
+++ b/libpeas/peas-object-module.h
@@ -95,11 +95,11 @@ PeasObjectModule *peas_object_module_new_embedded (const gchar
const gchar *symbol);
GObject *peas_object_module_create_object (PeasObjectModule *module,
- GType interface,
+ GType exten_type,
guint n_parameters,
GParameter *parameters);
gboolean peas_object_module_provides_object (PeasObjectModule *module,
- GType interface);
+ GType exten_type);
const gchar *peas_object_module_get_path (PeasObjectModule *module);
const gchar *peas_object_module_get_module_name (PeasObjectModule *module);
@@ -109,14 +109,14 @@ GModule *peas_object_module_get_library (PeasObjectModule
void peas_object_module_register_extension_factory
(PeasObjectModule *module,
- GType iface_type,
+ GType exten_type,
PeasFactoryFunc factory_func,
gpointer user_data,
GDestroyNotify destroy_func);
void peas_object_module_register_extension_type
(PeasObjectModule *module,
- GType iface_type,
- GType extension_type);
+ GType exten_type,
+ GType impl_type);
G_END_DECLS
diff --git a/libpeas/peas-utils.c b/libpeas/peas-utils.c
index 1051d20..7d3bd91 100644
--- a/libpeas/peas-utils.c
+++ b/libpeas/peas-utils.c
@@ -91,6 +91,34 @@ add_all_prerequisites (GType iface_type,
g_free (prereq);
}
+static GPtrArray *
+find_base_type_and_interfaces (GType exten_type,
+ GType *base_type)
+{
+ GPtrArray *ifaces;
+ GType *interfaces;
+ gint i;
+
+ ifaces = g_ptr_array_new ();
+ g_ptr_array_set_free_func (ifaces,
+ (GDestroyNotify) g_type_default_interface_unref);
+
+ if (G_TYPE_IS_INTERFACE (exten_type))
+ {
+ add_all_prerequisites (exten_type, base_type, ifaces);
+ return ifaces;
+ }
+
+ interfaces = g_type_interfaces (exten_type, NULL);
+ for (i = 0; interfaces[i] != G_TYPE_INVALID; ++i)
+ add_all_prerequisites (exten_type, base_type, ifaces);
+
+ *base_type = exten_type;
+
+ g_free (interfaces);
+ return ifaces;
+}
+
static GParamSpec *
find_param_spec_for_prerequisites (const gchar *name,
GObjectClass *klass,
@@ -113,7 +141,7 @@ find_param_spec_for_prerequisites (const gchar *name,
}
gboolean
-peas_utils_valist_to_parameter_list (GType iface_type,
+peas_utils_valist_to_parameter_list (GType exten_type,
const gchar *first_property,
va_list args,
GParameter **params,
@@ -125,12 +153,10 @@ peas_utils_valist_to_parameter_list (GType iface_type,
const gchar *name;
guint n_allocated_params;
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_type), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_OBJECT (exten_type), FALSE);
- ifaces = g_ptr_array_new ();
- g_ptr_array_set_free_func (ifaces,
- (GDestroyNotify) g_type_default_interface_unref);
- add_all_prerequisites (iface_type, &base_type, ifaces);
+ ifaces = find_base_type_and_interfaces (exten_type, &base_type);
if (base_type != G_TYPE_INVALID)
klass = g_type_class_ref (base_type);
@@ -150,7 +176,7 @@ peas_utils_valist_to_parameter_list (GType iface_type,
if (!pspec)
{
g_warning ("%s: type '%s' has no property named '%s'",
- G_STRFUNC, g_type_name (iface_type), name);
+ G_STRFUNC, g_type_name (exten_type), name);
goto error;
}
diff --git a/libpeas/peas-utils.h b/libpeas/peas-utils.h
index adca711..5a19ba0 100644
--- a/libpeas/peas-utils.h
+++ b/libpeas/peas-utils.h
@@ -27,7 +27,7 @@
#define PEAS_UTILS_C_LOADER_ID 0
#define PEAS_UTILS_N_LOADERS 4
-gboolean peas_utils_valist_to_parameter_list (GType iface_type,
+gboolean peas_utils_valist_to_parameter_list (GType exten_type,
const gchar *first_property,
va_list var_args,
GParameter **params,
diff --git a/tests/libpeas/introspection/Makefile.am b/tests/libpeas/introspection/Makefile.am
index 930851b..3ea3758 100644
--- a/tests/libpeas/introspection/Makefile.am
+++ b/tests/libpeas/introspection/Makefile.am
@@ -13,6 +13,8 @@ libintrospection_1_0_la_LIBADD = \
$(top_builddir)/libpeas/libpeas-1.0.la
libintrospection_1_0_la_SOURCES = \
+ introspection-abstract.c \
+ introspection-abstract.h \
introspection-base.c \
introspection-base.h \
introspection-callable.c \
diff --git a/tests/libpeas/introspection/introspection-abstract.c b/tests/libpeas/introspection/introspection-abstract.c
new file mode 100644
index 0000000..0363d0a
--- /dev/null
+++ b/tests/libpeas/introspection/introspection-abstract.c
@@ -0,0 +1,132 @@
+/*
+ * introspection-abstract.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-abstract.h"
+
+typedef struct {
+ gint value;
+} IntrospectionAbstractPrivate;
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (IntrospectionAbstract,
+ introspection_abstract,
+ PEAS_TYPE_EXTENSION_BASE)
+
+#define GET_PRIV(o) \
+ (introspection_abstract_get_instance_private (o))
+
+enum {
+ PROP_0,
+ PROP_ABSTRACT_PROPERTY,
+ N_PROPERTIES
+};
+
+static GParamSpec *properties[N_PROPERTIES] = { NULL };
+
+static void
+introspection_abstract_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IntrospectionAbstract *abstract = INTROSPECTION_ABSTRACT (object);
+ IntrospectionAbstractPrivate *priv = GET_PRIV (abstract);
+
+ switch (prop_id)
+ {
+ case PROP_ABSTRACT_PROPERTY:
+ g_value_set_int (value, priv->value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+introspection_abstract_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IntrospectionAbstract *abstract = INTROSPECTION_ABSTRACT (object);
+ IntrospectionAbstractPrivate *priv = GET_PRIV (abstract);
+
+ switch (prop_id)
+ {
+ case PROP_ABSTRACT_PROPERTY:
+ priv->value = g_value_get_int (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+introspection_abstract_class_init (IntrospectionAbstractClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = introspection_abstract_get_property;
+ object_class->set_property = introspection_abstract_set_property;
+
+ properties[PROP_ABSTRACT_PROPERTY] =
+ g_param_spec_int ("abstract-property",
+ "Abstract Property",
+ "The IntrospectionAbstract",
+ 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_abstract_init (IntrospectionAbstract *prereq)
+{
+}
+
+gint
+introspection_abstract_get_value (IntrospectionAbstract *abstract)
+{
+ IntrospectionAbstractPrivate *priv = GET_PRIV (abstract);
+
+ g_return_val_if_fail (INTROSPECTION_IS_ABSTRACT (abstract), -1);
+
+ return priv->value;
+}
+
+void
+introspection_abstract_set_value (IntrospectionAbstract *abstract,
+ gint value)
+{
+ IntrospectionAbstractPrivate *priv = GET_PRIV (abstract);
+
+ g_return_if_fail (INTROSPECTION_IS_ABSTRACT (abstract));
+
+ priv->value = value;
+}
diff --git a/tests/libpeas/introspection/introspection-abstract.h b/tests/libpeas/introspection/introspection-abstract.h
new file mode 100644
index 0000000..bfff2c4
--- /dev/null
+++ b/tests/libpeas/introspection/introspection-abstract.h
@@ -0,0 +1,60 @@
+/*
+ * introspection-abstract.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_ABSTRACT_H__
+#define __INTROSPECTION_ABSTRACT_H__
+
+#include <libpeas/peas.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define INTROSPECTION_TYPE_ABSTRACT (introspection_abstract_get_type ())
+#define INTROSPECTION_ABSTRACT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INTROSPECTION_TYPE_ABSTRACT, IntrospectionAbstract))
+#define INTROSPECTION_ABSTRACT_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), INTROSPECTION_TYPE_ABSTRACT, IntrospectionAbstractClass))
+#define INTROSPECTION_IS_ABSTRACT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INTROSPECTION_TYPE_ABSTRACT))
+#define INTROSPECTION_ABSTRACT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INTROSPECTION_TYPE_ABSTRACT, IntrospectionAbstractClass))
+
+typedef struct _IntrospectionAbstract IntrospectionAbstract;
+typedef struct _IntrospectionAbstractClass IntrospectionAbstractClass;
+
+struct _IntrospectionAbstract {
+ PeasExtensionBase parent;
+};
+
+struct _IntrospectionAbstractClass {
+ PeasExtensionBaseClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType introspection_abstract_get_type (void) G_GNUC_CONST;
+
+gint introspection_abstract_get_value (IntrospectionAbstract *abstract);
+void introspection_abstract_set_value (IntrospectionAbstract *abstract,
+ gint value);
+
+G_END_DECLS
+
+#endif /* __INTROSPECTION_ABSTRACT_H__ */
diff --git a/tests/libpeas/plugins/extension-c/Makefile.am b/tests/libpeas/plugins/extension-c/Makefile.am
index 751b68b..24effac 100644
--- a/tests/libpeas/plugins/extension-c/Makefile.am
+++ b/tests/libpeas/plugins/extension-c/Makefile.am
@@ -12,7 +12,9 @@ noinst_LTLIBRARIES = \
libextension-c-missing-symbol.la
libextension_c_la_SOURCES = \
- extension-c-plugin.c \
+ extension-c-abstract.c \
+ extension-c-abstract.h \
+ extension-c-plugin.c \
extension-c-plugin.h
libextension_c_la_LDFLAGS = $(TEST_PLUGIN_LIBTOOL_FLAGS)
diff --git a/tests/libpeas/plugins/extension-c/extension-c-abstract.c b/tests/libpeas/plugins/extension-c/extension-c-abstract.c
new file mode 100644
index 0000000..c6f767e
--- /dev/null
+++ b/tests/libpeas/plugins/extension-c/extension-c-abstract.c
@@ -0,0 +1,55 @@
+/*
+ * extension-c-abstract.c
+ * 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 <glib-object.h>
+
+#include <libpeas/peas.h>
+
+#include "extension-c-abstract.h"
+
+G_DEFINE_DYNAMIC_TYPE (TestingExtensionCAbstract,
+ testing_extension_c_abstract,
+ INTROSPECTION_TYPE_ABSTRACT)
+
+static void
+testing_extension_c_abstract_init (TestingExtensionCAbstract *abstract)
+{
+}
+
+static void
+testing_extension_c_abstract_class_init (TestingExtensionCAbstractClass *klass)
+{
+}
+
+static void
+testing_extension_c_abstract_class_finalize (TestingExtensionCAbstractClass *klass)
+{
+}
+
+void
+testing_extension_c_abstract_register (GTypeModule *module)
+{
+ testing_extension_c_abstract_register_type (module);
+}
diff --git a/tests/libpeas/plugins/extension-c/extension-c-abstract.h b/tests/libpeas/plugins/extension-c/extension-c-abstract.h
new file mode 100644
index 0000000..57d35c3
--- /dev/null
+++ b/tests/libpeas/plugins/extension-c/extension-c-abstract.h
@@ -0,0 +1,52 @@
+/*
+ * extension-c-abstract.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 __EXTENSION_C_ABSTRACT_H__
+#define __EXTENSION_C_ABSTRACT_H__
+
+#include "introspection-abstract.h"
+
+G_BEGIN_DECLS
+
+#define TESTING_TYPE_EXTENSION_C_ABSTRACT (testing_extension_c_abstract_get_type ())
+#define TESTING_EXTENSION_C_ABSTRACT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TESTING_TYPE_EXTENSION_C_ABSTRACT, TestingExtensionCAbstract))
+#define TESTING_EXTENSION_C_ABSTRACT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), TESTING_TYPE_EXTENSION_C_ABSTRACT, TestingExtensionCAbstract))
+#define TESTING_IS_EXTENSION_C_ABSTRACT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TESTING_TYPE_EXTENSION_C_ABSTRACT))
+#define TESTING_IS_EXTENSION_C_ABSTRACT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TESTING_TYPE_EXTENSION_C_ABSTRACT))
+#define TESTING_EXTENSION_C_ABSTRACT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TESTING_TYPE_EXTENSION_C_ABSTRACT, TestingExtensionCAbstractClass))
+
+typedef struct _TestingExtensionCAbstract TestingExtensionCAbstract;
+typedef struct _TestingExtensionCAbstractClass TestingExtensionCAbstractClass;
+
+struct _TestingExtensionCAbstract {
+ IntrospectionAbstract parent_instance;
+};
+
+struct _TestingExtensionCAbstractClass {
+ IntrospectionAbstractClass parent_class;
+};
+
+GType testing_extension_c_abstract_get_type (void) G_GNUC_CONST;
+void testing_extension_c_abstract_register (GTypeModule *module);
+
+G_END_DECLS
+
+#endif /* __EXTENSION_C_ABSTRACT_H__ */
diff --git a/tests/libpeas/plugins/extension-c/extension-c-plugin.c b/tests/libpeas/plugins/extension-c/extension-c-plugin.c
index 3125de8..1e4b283 100644
--- a/tests/libpeas/plugins/extension-c/extension-c-plugin.c
+++ b/tests/libpeas/plugins/extension-c/extension-c-plugin.c
@@ -29,11 +29,13 @@
#include <libpeas/peas.h>
+#include "introspection-abstract.h"
#include "introspection-base.h"
#include "introspection-callable.h"
#include "introspection-has-prerequisite.h"
#include "introspection-prerequisite.h"
+#include "extension-c-abstract.h"
#include "extension-c-plugin.h"
/* Used by the local linkage test */
@@ -175,9 +177,14 @@ testing_extension_c_plugin_class_finalize (TestingExtensionCPluginClass *klass)
G_MODULE_EXPORT void
peas_register_types (PeasObjectModule *module)
{
+ testing_extension_c_abstract_register (G_TYPE_MODULE (module));
testing_extension_c_plugin_register_type (G_TYPE_MODULE (module));
peas_object_module_register_extension_type (module,
+ INTROSPECTION_TYPE_ABSTRACT,
+ TESTING_TYPE_EXTENSION_C_ABSTRACT);
+
+ peas_object_module_register_extension_type (module,
INTROSPECTION_TYPE_BASE,
TESTING_TYPE_EXTENSION_C_PLUGIN);
peas_object_module_register_extension_type (module,
diff --git a/tests/libpeas/plugins/extension-lua/extension-lua51.lua b/tests/libpeas/plugins/extension-lua/extension-lua51.lua
index 69df5f7..66ee571 100644
--- a/tests/libpeas/plugins/extension-lua/extension-lua51.lua
+++ b/tests/libpeas/plugins/extension-lua/extension-lua51.lua
@@ -22,6 +22,10 @@ local Introspection = lgi.Introspection
local Peas = lgi.Peas
+local ExtensionLuaAbstract =
+ Introspection.Abstract:derive('ExtensionLuaAbstract')
+
+
local ExtensionLuaPlugin =
Introspection.Prerequisite:derive('ExtensionLuaPlugin', {
Peas.Activatable,
@@ -100,6 +104,6 @@ assert(pcall(function()
__STRICT = true
end))
-return { ExtensionLuaPlugin }
+return { ExtensionLuaAbstract, ExtensionLuaPlugin }
-- ex:set ts=4 et sw=4 ai:
diff --git a/tests/libpeas/plugins/extension-python/extension-py.py.in b/tests/libpeas/plugins/extension-python/extension-py.py.in
index d5ea6fa..59070c4 100644
--- a/tests/libpeas/plugins/extension-python/extension-py.py.in
+++ b/tests/libpeas/plugins/extension-python/extension-py.py.in
@@ -24,7 +24,11 @@ import threading
from gi.repository import GObject, Introspection, Peas
-__all__ = [ 'ExtensionPythonPlugin' ]
+__all__ = [ 'ExtensionPythonAbstract', 'ExtensionPythonPlugin' ]
+
+
+class ExtensionPythonAbstract(Introspection.Abstract):
+ pass
class ExtensionPythonPlugin(Introspection.Prerequisite, Peas.Activatable,
diff --git a/tests/libpeas/testing/testing-extension.c b/tests/libpeas/testing/testing-extension.c
index 60e88f4..e00588b 100644
--- a/tests/libpeas/testing/testing-extension.c
+++ b/tests/libpeas/testing/testing-extension.c
@@ -33,6 +33,7 @@
#include "testing.h"
#include "testing-extension.h"
+#include "introspection-abstract.h"
#include "introspection-base.h"
#include "introspection-callable.h"
#include "introspection-has-prerequisite.h"
@@ -264,6 +265,29 @@ test_extension_get_settings (PeasEngine *engine,
g_object_unref (extension);
}
+static void
+test_extension_abstract (PeasEngine *engine,
+ PeasPluginInfo *info)
+{
+ PeasExtension *extension;
+ IntrospectionAbstract *abstract;
+
+ g_assert (peas_engine_load_plugin (engine, info));
+
+ extension = peas_engine_create_extension (engine, info,
+ INTROSPECTION_TYPE_ABSTRACT,
+ "abstract-property", 47,
+ NULL);
+
+ abstract = INTROSPECTION_ABSTRACT (extension);
+
+ g_assert_cmpint (introspection_abstract_get_value (abstract), ==, 47);
+ introspection_abstract_set_value (abstract, -22);
+ g_assert_cmpint (introspection_abstract_get_value (abstract), ==, -22);
+
+ g_object_unref (extension);
+}
+
static gint
run_in_multiple_threads (GFunc func,
gpointer user_data)
@@ -479,6 +503,30 @@ test_extension_call_multi_args (PeasEngine *engine,
g_object_unref (extension);
}
+static void
+test_extension_call_abstract (PeasEngine *engine,
+ PeasPluginInfo *info)
+{
+ PeasExtension *extension;
+ gint value = 0;
+
+ g_assert (peas_engine_load_plugin (engine, info));
+
+ extension = peas_engine_create_extension (engine, info,
+ INTROSPECTION_TYPE_ABSTRACT,
+ "abstract-property", 47,
+ NULL);
+
+ g_assert (peas_extension_call (extension, "get_value", &value));
+ g_assert_cmpint (value, ==, 47);
+
+ g_assert (peas_extension_call (extension, "set_value", -22));
+ g_assert (peas_extension_call (extension, "get_value", &value));
+ g_assert_cmpint (value, ==, -22);
+
+ g_object_unref (extension);
+}
+
#define _EXTENSION_TEST(loader, path, ftest) \
G_STMT_START { \
gchar *full_path = g_strdup_printf (EXTENSION_TEST_NAME (%s, "%s"), \
@@ -533,6 +581,8 @@ testing_extension_basic (const gchar *loader_)
_EXTENSION_TEST (loader, "plugin-info", plugin_info);
_EXTENSION_TEST (loader, "get-settings", get_settings);
+ _EXTENSION_TEST (loader, "abstract", abstract);
+
_EXTENSION_TEST (loader, "multiple-threads/global-loaders",
multiple_threads_global_loaders);
_EXTENSION_TEST (loader, "multiple-threads/nonglobal-loaders",
@@ -553,6 +603,7 @@ testing_extension_callable (const gchar *loader)
_EXTENSION_TEST (loader, "call-with-return", call_with_return);
_EXTENSION_TEST (loader, "call-single-arg", call_single_arg);
_EXTENSION_TEST (loader, "call-multi-args", call_multi_args);
+ _EXTENSION_TEST (loader, "call-abstract", call_abstract);
}
void