[gnome-builder/wip/libide] libide: add IdeGjsContext to load javascript scripts
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/libide] libide: add IdeGjsContext to load javascript scripts
- Date: Mon, 16 Feb 2015 06:40:46 +0000 (UTC)
commit 3e0bf68c628f008f8ff37c5ce60c6a01853a49d5
Author: Christian Hergert <christian hergert me>
Date: Sun Feb 15 22:30:26 2015 -0800
libide: add IdeGjsContext to load javascript scripts
You can create scripts now by placing .js files in
~/.config/gnome-builder/scripts/. "Context" in the script is the loaded
IdeContext.
For example:
let Project = Context.get_project();
let Vcs = Context.get_vcs();
let BuildSystem = Context.get_build_system();
print("Project Name: " + Project.get_name());
print("Vcs: " + Vcs);
print("Build System: " + BuildSystem);
configure.ac | 15 +++-
libide/gjs/ide-gjs-script.cpp | 224 +++++++++++++++++++++--------------------
libide/ide.c | 6 +
3 files changed, 134 insertions(+), 111 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 258f345..208c362 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,8 +25,6 @@ AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["$GETTEXT_PACKAGE"],
[GETTEXT package name])
AM_GLIB_GNU_GETTEXT
-AC_PROG_CXX
-
# Initlize libtool and things that go with it.
m4_include([build/autotools/autoconf.d/pre-lt.m4])
m4_include([build/autotools/autoconf.d/setup_libtool.m4])
@@ -40,6 +38,19 @@ AM_INIT_AUTOMAKE([foreign subdir-objects tar-ustar no-dist-gzip dist-xz])
AM_MAINTAINER_MODE([enable])
m4_include([build/autotools/autoconf.d/post-am.m4])
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_CXX
+AC_ISC_POSIX
+AC_HEADER_STDC
+
+AM_PROG_LIBTOOL
+
+AC_C_CONST
+
+GNOME_CXX_WARNINGS([maximum])
+GNOME_MAINTAINER_MODE_DEFINES
+
# If we are using gtk-doc, enable it.
# We would put this in a file but gtkdocize requires it.
m4_ifdef([GTK_DOC_CHECK],[
diff --git a/libide/gjs/ide-gjs-script.cpp b/libide/gjs/ide-gjs-script.cpp
index 03848fc..e5f18f6 100644
--- a/libide/gjs/ide-gjs-script.cpp
+++ b/libide/gjs/ide-gjs-script.cpp
@@ -25,102 +25,69 @@
#include <jsapi.h>
+#include "ide-context.h"
#include "ide-gjs-script.h"
struct _IdeGjsScript
{
- IdeScript parent_instance;
-
- GFile *file;
+ IdeScript parent_instance;
GjsContext *gjs;
};
-G_DEFINE_TYPE (IdeGjsScript, ide_gjs_script, IDE_TYPE_SCRIPT)
-
-enum {
- PROP_0,
- PROP_FILE,
- LAST_PROP
-};
-
-static GParamSpec *gParamSpecs [LAST_PROP];
-
-/**
- * ide_gjs_script_get_file:
- *
- * Retrieves the #GFile containing the script to be loaded in the context.
- *
- * Returns: (transfer none): A #GFile.
- */
-GFile *
-ide_gjs_script_get_file (IdeGjsScript *self)
-{
- g_return_val_if_fail (IDE_IS_GJS_SCRIPT (self), NULL);
-
- return self->file;
-}
-
-static void
-ide_gjs_script_set_file (IdeGjsScript *self,
- GFile *file)
-{
- g_return_if_fail (IDE_IS_GJS_SCRIPT (self));
- g_return_if_fail (G_IS_FILE (file));
- g_return_if_fail (!self->file);
-
- self->file = (GFile *)g_object_ref (file);
-}
-
-static void
-set_global (GjsContext *context,
- const gchar *name,
- GObject *value)
-{
- JSContext *jscontext;
- JSObject *jsglobal;
- jsval jsvalue;
+static void async_initable_iface_init (GAsyncInitableIface *iface);
- jscontext = (JSContext *)gjs_context_get_native_context (context);
- jsglobal = (JSObject *)gjs_get_global_object (jscontext);
- jsvalue.setObject (*gjs_object_from_g_object (jscontext, value));
+G_DEFINE_TYPE_EXTENDED (IdeGjsScript, ide_gjs_script, IDE_TYPE_SCRIPT, 0,
+ G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
+ async_initable_iface_init))
- if (!JS_SetProperty (jscontext, jsglobal, "Context", &jsvalue))
- {
- g_warning (_("Failed to set IdeContext in JavaScript runtime."));
- return;
- }
-}
+static const char *init_js_code = "imports.gi.Ide;\n";
static void
ide_gjs_script_load (IdeScript *script)
{
IdeGjsScript *self = (IdeGjsScript *)script;
IdeContext *context;
+ GjsContext *old_current;
g_autoptr(GError) error = NULL;
g_autoptr(gchar) contents = NULL;
g_autoptr(gchar) path;
+ g_autoptr(GFile) parent;
+ gchar **search_path;
+ GFile *file;
gsize len;
int exit_status = 0;
g_return_if_fail (IDE_IS_GJS_SCRIPT (self));
g_return_if_fail (!self->gjs);
- g_return_if_fail (G_IS_FILE (self->file));
- if (!self->file)
+ file = ide_script_get_file (IDE_SCRIPT (script));
+
+ if (!file)
{
g_warning (_("Attempt to load a GJS script with no filename."));
return;
}
- path = g_file_get_basename (self->file);
+ path = g_file_get_basename (file);
- if (!g_file_load_contents (self->file, NULL, &contents, &len, NULL, &error))
+ if (!g_file_load_contents (file, NULL, &contents, &len, NULL, &error))
{
g_warning ("%s", error->message);
return;
}
- self->gjs = gjs_context_new ();
+ old_current = gjs_context_get_current ();
+ if (old_current)
+ gjs_context_make_current (NULL);
+
+ parent = g_file_get_parent (file);
+ search_path = g_new0 (gchar*, 2);
+ search_path[0] = g_file_get_path (parent);
+ search_path[1] = NULL;
+ self->gjs = (GjsContext *)g_object_new (GJS_TYPE_CONTEXT,
+ "search-path", search_path,
+ NULL);
+ g_strfreev (search_path);
if (!self->gjs)
{
@@ -129,7 +96,29 @@ ide_gjs_script_load (IdeScript *script)
}
context = ide_object_get_context (IDE_OBJECT (self));
- set_global (self->gjs, "Context", G_OBJECT (context));
+
+ JSContext *jscontext;
+ JSObject *jsglobal;
+
+ jscontext = (JSContext *)gjs_context_get_native_context (self->gjs);
+ jsglobal = (JSObject *)gjs_get_global_object (jscontext);
+
+ JSAutoCompartment ac(jscontext, jsglobal);
+ JSAutoRequest ar(jscontext);
+ jsval jsvalue;
+
+ g_assert (IDE_IS_CONTEXT (context));
+ g_assert (jscontext);
+
+ jsvalue.setObject (*gjs_object_from_g_object (jscontext, G_OBJECT (context)));
+
+ gjs_context_eval (self->gjs, init_js_code, strlen(init_js_code), "<init>", NULL, NULL);
+
+ if (!JS_SetProperty (jscontext, jsglobal, "Context", &jsvalue))
+ {
+ g_warning (_("Failed to set IdeContext in JavaScript runtime."));
+ return;
+ }
if (!gjs_context_eval (self->gjs, contents, len, path, &exit_status, &error))
{
@@ -137,7 +126,11 @@ ide_gjs_script_load (IdeScript *script)
return;
}
- g_info ("GJS script \"%s\" loaded.", path);
+ if (old_current != NULL)
+ {
+ gjs_context_make_current (NULL);
+ gjs_context_make_current (old_current);
+ }
}
static void
@@ -151,75 +144,88 @@ ide_gjs_script_finalize (GObject *object)
{
IdeGjsScript *self = (IdeGjsScript *)object;
- g_clear_object (&self->file);
+ g_clear_object (&self->gjs);
G_OBJECT_CLASS (ide_gjs_script_parent_class)->finalize (object);
}
static void
-ide_gjs_script_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+ide_gjs_script_class_init (IdeGjsScriptClass *klass)
{
- IdeGjsScript *self = IDE_GJS_SCRIPT (object);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ IdeScriptClass *script_class = IDE_SCRIPT_CLASS (klass);
- switch (prop_id)
- {
- case PROP_FILE:
- g_value_set_object (value, ide_gjs_script_get_file (self));
- break;
+ object_class->finalize = ide_gjs_script_finalize;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
+ script_class->load = ide_gjs_script_load;
+ script_class->unload = ide_gjs_script_unload;
+}
+
+static void
+ide_gjs_script_init (IdeGjsScript *self)
+{
}
static void
-ide_gjs_script_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+ide_gjs_script_init_async (GAsyncInitable *initable,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- IdeGjsScript *self = IDE_GJS_SCRIPT (object);
+ IdeGjsScript *self = (IdeGjsScript *)initable;
+ g_autoptr(GTask) task = NULL;
+ g_autoptr(gchar) path = NULL;
+ GFile *file;
- switch (prop_id)
+ g_return_if_fail (IDE_IS_GJS_SCRIPT (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+
+ file = ide_script_get_file (IDE_SCRIPT (self));
+
+ if (!file)
{
- case PROP_FILE:
- ide_gjs_script_set_file (self, (GFile *)g_value_get_object (value));
- break;
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_FILENAME,
+ _("The filename for the script was not provided."));
+ return;
+ }
+
+ path = g_file_get_path (file);
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ if (!path)
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_FILENAME,
+ _("The script must be on a local filesystem."));
+ return;
}
+
+ ide_script_load (IDE_SCRIPT (self));
+
+ g_task_return_boolean (task, TRUE);
}
-static void
-ide_gjs_script_class_init (IdeGjsScriptClass *klass)
+static gboolean
+ide_gjs_script_init_finish (GAsyncInitable *initable,
+ GAsyncResult *result,
+ GError **error)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- IdeScriptClass *script_class = IDE_SCRIPT_CLASS (klass);
+ GTask *task = (GTask *)result;
- object_class->finalize = ide_gjs_script_finalize;
- object_class->get_property = ide_gjs_script_get_property;
- object_class->set_property = ide_gjs_script_set_property;
+ g_return_val_if_fail (IDE_IS_GJS_SCRIPT (initable), FALSE);
+ g_return_val_if_fail (G_IS_TASK (task), FALSE);
- script_class->load = ide_gjs_script_load;
- script_class->unload = ide_gjs_script_unload;
-
- gParamSpecs [PROP_FILE] =
- g_param_spec_object ("file",
- _("File"),
- _("The file containing the script contents."),
- G_TYPE_FILE,
- (GParamFlags)(G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_FILE,
- gParamSpecs [PROP_FILE]);
+ return g_task_propagate_boolean (task, error);
}
static void
-ide_gjs_script_init (IdeGjsScript *self)
+async_initable_iface_init (GAsyncInitableIface *iface)
{
+ iface->init_async = ide_gjs_script_init_async;
+ iface->init_finish = ide_gjs_script_init_finish;
}
diff --git a/libide/ide.c b/libide/ide.c
index 059d833..2a2d37a 100644
--- a/libide/ide.c
+++ b/libide/ide.c
@@ -32,6 +32,7 @@
#include "ide-gca-service.h"
#include "ide-git-vcs.h"
#include "ide-gsettings-file-settings.h"
+#include "ide-gjs-script.h"
static gboolean gProgramNameRead;
static const gchar *gProgramName = "libide";
@@ -93,6 +94,11 @@ ide_init_ctor (void)
IDE_LANGUAGE_EXTENSION_POINT".c",
-100);
+ g_io_extension_point_implement (IDE_SCRIPT_EXTENSION_POINT,
+ IDE_TYPE_GJS_SCRIPT,
+ IDE_SCRIPT_EXTENSION_POINT".gjs",
+ -100);
+
g_io_extension_point_implement (IDE_SERVICE_EXTENSION_POINT,
IDE_TYPE_CLANG_SERVICE,
IDE_SERVICE_EXTENSION_POINT".clang",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]