[gnome-builder/wip/chergert/gjs-in-c] wip
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/gjs-in-c] wip
- Date: Mon, 9 May 2022 19:05:22 +0000 (UTC)
commit 55ada0f5e0fa7819adc849d4f986a8d31afc8934
Author: Christian Hergert <chergert redhat com>
Date: Mon Apr 25 14:24:20 2022 -0700
wip
src/plugins/gjs-symbols/gbp-gjs-code-indexer.c | 50 +++
src/plugins/gjs-symbols/gbp-gjs-code-indexer.h | 31 ++
src/plugins/gjs-symbols/gbp-gjs-symbol-node.c | 420 +++++++++++++++++++++
src/plugins/gjs-symbols/gbp-gjs-symbol-node.h | 38 ++
src/plugins/gjs-symbols/gbp-gjs-symbol-resolver.c | 207 ++++++++++
src/plugins/gjs-symbols/gbp-gjs-symbol-resolver.h | 31 ++
src/plugins/gjs-symbols/gbp-gjs-symbol-tree.c | 110 ++++++
src/plugins/gjs-symbols/gbp-gjs-symbol-tree.h | 33 ++
src/plugins/gjs-symbols/gjs-symbols-plugin.c | 41 ++
src/plugins/gjs-symbols/gjs-symbols.gresource.xml | 7 +
.../{gjs_symbols.plugin => gjs-symbols.plugin} | 7 +-
src/plugins/gjs-symbols/gjs_symbols.py | 129 +++----
src/plugins/gjs-symbols/meson.build | 22 +-
src/plugins/gjs-symbols/parse.js | 14 +
14 files changed, 1051 insertions(+), 89 deletions(-)
---
diff --git a/src/plugins/gjs-symbols/gbp-gjs-code-indexer.c b/src/plugins/gjs-symbols/gbp-gjs-code-indexer.c
new file mode 100644
index 000000000..eeb491875
--- /dev/null
+++ b/src/plugins/gjs-symbols/gbp-gjs-code-indexer.c
@@ -0,0 +1,50 @@
+/* gbp-gjs-code-indexer.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gbp-gjs-code-indexer"
+
+#include "config.h"
+
+#include <libide-code.h>
+
+#include "gbp-gjs-code-indexer.h"
+
+struct _GbpGjsCodeIndexer
+{
+ IdeObject parent_instance;
+};
+
+static void
+code_indexer_iface_init (IdeCodeIndexerInterface *iface)
+{
+}
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (GbpGjsCodeIndexer, gbp_gjs_code_indexer, IDE_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_CODE_INDEXER, code_indexer_iface_init))
+
+static void
+gbp_gjs_code_indexer_class_init (GbpGjsCodeIndexerClass *klass)
+{
+}
+
+static void
+gbp_gjs_code_indexer_init (GbpGjsCodeIndexer *self)
+{
+}
diff --git a/src/plugins/gjs-symbols/gbp-gjs-code-indexer.h b/src/plugins/gjs-symbols/gbp-gjs-code-indexer.h
new file mode 100644
index 000000000..f8a4356fc
--- /dev/null
+++ b/src/plugins/gjs-symbols/gbp-gjs-code-indexer.h
@@ -0,0 +1,31 @@
+/* gbp-gjs-code-indexer.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libide-core.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_GJS_CODE_INDEXER (gbp_gjs_code_indexer_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpGjsCodeIndexer, gbp_gjs_code_indexer, GBP, GJS_CODE_INDEXER, IdeObject)
+
+G_END_DECLS
diff --git a/src/plugins/gjs-symbols/gbp-gjs-symbol-node.c b/src/plugins/gjs-symbols/gbp-gjs-symbol-node.c
new file mode 100644
index 000000000..d095eb1ef
--- /dev/null
+++ b/src/plugins/gjs-symbols/gbp-gjs-symbol-node.c
@@ -0,0 +1,420 @@
+/* gbp-gjs-symbol-node.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gbp-gjs-symbol-node"
+
+#include "config.h"
+
+#include "gbp-gjs-symbol-node.h"
+
+struct _GbpGjsSymbolNode
+{
+ IdeSymbolNode parent_instance;
+
+ GPtrArray *children;
+
+ guint line;
+ guint line_offset;
+};
+
+G_DEFINE_FINAL_TYPE (GbpGjsSymbolNode, gbp_gjs_symbol_node, IDE_TYPE_SYMBOL_NODE)
+
+static void
+gbp_gjs_symbol_node_dispose (GObject *object)
+{
+ GbpGjsSymbolNode *self = (GbpGjsSymbolNode *)object;
+
+ g_clear_pointer (&self->children, g_ptr_array_unref);
+
+ G_OBJECT_CLASS (gbp_gjs_symbol_node_parent_class)->dispose (object);
+}
+
+static void
+gbp_gjs_symbol_node_class_init (GbpGjsSymbolNodeClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = gbp_gjs_symbol_node_dispose;
+}
+
+static void
+gbp_gjs_symbol_node_init (GbpGjsSymbolNode *self)
+{
+}
+
+G_GNUC_NULL_TERMINATED
+static JsonNode *
+get_node_at_path (JsonObject *object,
+ const char *first_child,
+ ...)
+{
+ const char *child = first_child;
+ JsonNode *ret = NULL;
+ va_list args;
+
+ va_start (args, first_child);
+ while (child != NULL)
+ {
+ JsonNode *node = json_object_get_member (object, child);
+ child = va_arg (args, const char *);
+
+ if (node == NULL)
+ break;
+
+ if (child == NULL && node != NULL)
+ {
+ ret = node;
+ break;
+ }
+
+ if (!JSON_NODE_HOLDS_OBJECT (node))
+ break;
+
+ object = json_node_get_object (node);
+ }
+ va_end (args);
+
+ return ret;
+}
+
+static gboolean
+get_line_and_column (JsonObject *object,
+ guint *line,
+ guint *column)
+{
+ JsonNode *node;
+
+ g_assert (object != NULL);
+ g_assert (line != NULL);
+ g_assert (column != NULL);
+
+ if (!(node = get_node_at_path (object, "loc", "start", "line", NULL)))
+ return FALSE;
+ *line = MAX (1, json_node_get_int (node)) - 1;
+
+ if (!(node = get_node_at_path (object, "loc", "start", "column", NULL)))
+ return FALSE;
+ *column = MAX (0, json_node_get_int (node));
+
+ return TRUE;
+}
+
+static gboolean
+string_equal_to_node_value (const char *string,
+ JsonNode *node)
+{
+ const char *value;
+
+ if (node == NULL || !JSON_NODE_HOLDS_VALUE (node))
+ return FALSE;
+
+ if (!(value = json_node_get_string (node)))
+ return FALSE;
+
+ return g_strcmp0 (string, value) == 0;
+}
+
+static const char *
+get_node_string (JsonNode *node)
+{
+ if (node == NULL || !JSON_NODE_HOLDS_VALUE (node))
+ return NULL;
+ return json_node_get_string (node);
+}
+
+static gboolean
+is_module_import (JsonObject *object)
+{
+ if (object == NULL)
+ return FALSE;
+
+ return string_equal_to_node_value ("imports",
+ get_node_at_path (object, "init", "object", "name", NULL)) ||
+ string_equal_to_node_value ("imports",
+ get_node_at_path (object, "init", "object", "object", "name", NULL)) ||
+ string_equal_to_node_value ("require",
+ get_node_at_path (object, "init", "callee", "name", NULL));
+}
+
+static gboolean
+is_gobject_class (JsonObject *object)
+{
+ const char *name;
+ const char *pname;
+
+ if (object == NULL)
+ return FALSE;
+
+ if (!(name = get_node_string (get_node_at_path (object, "init", "callee", "object", "name", NULL))) ||
+ !(pname = get_node_string (get_node_at_path (object, "init", "callee", "property", "name", NULL))))
+ return FALSE;
+
+ return strcasecmp (name, "gobject") == 0 && ide_str_equal0 (pname, "registerClass");
+}
+
+static gboolean
+is_legacy_gobject_class (JsonObject *object)
+{
+ const char *name;
+ const char *pname;
+
+ if (object == NULL)
+ return FALSE;
+
+ if (!(name = get_node_string (get_node_at_path (object, "init", "callee", "object", "name", NULL))) ||
+ !(pname = get_node_string (get_node_at_path (object, "init", "callee", "property", "name", NULL))))
+ return FALSE;
+
+ return (strcasecmp (name, "gobject") == 0 ||
+ strcasecmp (name, "lang") == 0) &&
+ ide_str_equal0 (pname, "Class");
+}
+
+static gboolean
+is_module_exports (JsonObject *object)
+{
+ JsonNode *left;
+
+ if (object == NULL)
+ return FALSE;
+
+ if (!string_equal_to_node_value ("AssignmentExpression",
+ get_node_at_path (object, "expression", "type", NULL)))
+ return FALSE;
+
+ if (!(left = get_node_at_path (object, "expression", "left", NULL)))
+ return FALSE;
+
+ if (!string_equal_to_node_value ("MemberExpression",
+ get_node_at_path (object, "expression", "left", "type", NULL)))
+ return FALSE;
+
+ if (!string_equal_to_node_value ("Identifiier",
+ get_node_at_path (object, "expression", "left", "object", "type", NULL)))
+ return FALSE;
+
+ if (!string_equal_to_node_value ("module",
+ get_node_at_path (object, "expression", "left", "object", "name", NULL)))
+ return FALSE;
+
+ if (!string_equal_to_node_value ("Identifiier",
+ get_node_at_path (object, "expression", "left", "property", "type",
NULL)))
+ return FALSE;
+
+ if (!string_equal_to_node_value ("exports",
+ get_node_at_path (object, "expression", "left", "property", "name",
NULL)))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+gbp_gjs_symbol_node_extract (GbpGjsSymbolNode *self,
+ JsonObject *object)
+{
+ IdeSymbolKind kind = IDE_SYMBOL_KIND_NONE;
+ const char *name = NULL;
+ const char *type;
+ JsonNode *body = NULL;
+
+ g_assert (GBP_IS_GJS_SYMBOL_NODE (self));
+ g_assert (object != NULL);
+
+ if (!(type = json_object_get_string_member (object, "type")))
+ return FALSE;
+
+ if (!get_line_and_column (object, &self->line, &self->line_offset))
+ return FALSE;
+
+ self->children = g_ptr_array_new_with_free_func (g_object_unref);
+
+ if (0) {}
+ else if (g_str_equal (type, "Program"))
+ {
+ kind = IDE_SYMBOL_KIND_PACKAGE;
+ name = get_node_string (get_node_at_path (object, "loc", "source", NULL));
+ }
+ else if (g_str_equal (type, "FunctionDeclaration"))
+ {
+ kind = IDE_SYMBOL_KIND_FUNCTION;
+ name = get_node_string (get_node_at_path (object, "id", "name", NULL));
+ }
+ else if (g_str_equal (type, "Property"))
+ {
+ const char *propkind;
+
+ if (!string_equal_to_node_value ("FunctionExpression",
+ get_node_at_path (object, "value", "type", NULL)))
+ return FALSE;
+
+ kind = IDE_SYMBOL_KIND_METHOD;
+ name = get_node_string (get_node_at_path (object, "key", "name", NULL));
+ propkind = get_node_string (get_node_at_path (object, "kind", NULL));
+
+ if (ide_str_equal0 (name, "_init") ||
+ ide_str_equal0 (propkind, "get") ||
+ ide_str_equal0 (propkind, "set"))
+ return FALSE;
+
+ }
+ else if (g_str_equal (type, "VariableDeclaration"))
+ {
+ JsonArray *decls_ar;
+ JsonNode *decls;
+ guint n_decls;
+
+ if (!(decls = get_node_at_path (object, "declarations", NULL)) ||
+ !JSON_NODE_HOLDS_ARRAY (decls) ||
+ !(decls_ar = json_node_get_array (decls)) ||
+ !(n_decls = json_array_get_length (decls_ar)))
+ return FALSE;
+
+ for (guint i = 0; i < n_decls; i++)
+ {
+ JsonNode *decl;
+ JsonObject *decl_obj;
+
+ if (!(decl = json_array_get_element (decls_ar, i)) ||
+ !JSON_NODE_HOLDS_OBJECT (decl) ||
+ !(decl_obj = json_node_get_object (decl)))
+ continue;
+
+ if (!string_equal_to_node_value ("Identifier",
+ get_node_at_path (decl_obj, "id", "type", NULL)))
+ continue;
+
+ name = get_node_string (get_node_at_path (decl_obj, "id", "name", NULL));
+ kind = IDE_SYMBOL_KIND_VARIABLE;
+
+ if (is_module_import (decl_obj))
+ kind = IDE_SYMBOL_KIND_MODULE;
+ }
+ }
+ else if (g_str_equal (type, "ClassStatement"))
+ {
+ kind = IDE_SYMBOL_KIND_CLASS;
+ name = get_node_string (get_node_at_path (object, "id", "name", NULL));
+ body = get_node_at_path (object, "body", NULL);
+ }
+ else if (g_str_equal (type, "ClassMethod"))
+ {
+ const char *classkind;
+
+ kind = IDE_SYMBOL_KIND_METHOD;
+ name = get_node_string (get_node_at_path (object, "name", "name", NULL));
+ classkind = get_node_string (get_node_at_path (object, "kind", NULL));
+
+ if (ide_str_equal0 (name, "constructed") ||
+ ide_str_equal0 (name, "_init") ||
+ ide_str_equal0 (classkind, "get") ||
+ ide_str_equal0 (classkind, "set"))
+ return FALSE;
+ }
+ else if (g_str_equal (type, "ExpressionStatement"))
+ {
+ JsonNode *right;
+ JsonObject *class;
+
+ if (!string_equal_to_node_value ("ClassExpression",
+ get_node_at_path (object, "expression", "right", "type", NULL)))
+ return FALSE;
+
+ if (!(right = get_node_at_path (object, "expression", "right", NULL)) ||
+ !JSON_NODE_HOLDS_OBJECT (right) ||
+ !(class = json_node_get_object (right)))
+ return FALSE;
+
+ if (!get_line_and_column (class, &self->line, &self->line_offset))
+ return FALSE;
+
+ body = get_node_at_path (class, "body", NULL);
+ name = get_node_string (get_node_at_path (class, "id", "name", NULL));
+ kind = IDE_SYMBOL_KIND_CLASS;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ g_object_set (self,
+ "kind", kind,
+ "name", name,
+ NULL);
+
+ if (body != NULL && JSON_NODE_HOLDS_ARRAY (body))
+ {
+ JsonArray *ar = json_node_get_array (body);
+ guint n_items = json_array_get_length (ar);
+
+ for (guint i = 0; i < n_items; i++)
+ {
+ g_autoptr(GbpGjsSymbolNode) symbol_node = NULL;
+ JsonNode *child_node = json_array_get_element (ar, i);
+
+ if (!JSON_NODE_HOLDS_OBJECT (child_node) ||
+ !(symbol_node = gbp_gjs_symbol_node_new (object)))
+ continue;
+
+ g_ptr_array_add (self->children, g_steal_pointer (&symbol_node));
+ }
+ }
+
+ if (self->children->len == 0)
+ g_clear_pointer (&self->children, g_ptr_array_unref);
+
+ return TRUE;
+}
+
+GbpGjsSymbolNode *
+gbp_gjs_symbol_node_new (JsonObject *object)
+{
+ g_autoptr(GbpGjsSymbolNode) self = NULL;
+
+ g_return_val_if_fail (object != NULL, NULL);
+
+ self = g_object_new (GBP_TYPE_GJS_SYMBOL_NODE, NULL);
+ if (!gbp_gjs_symbol_node_extract (self, object))
+ return NULL;
+
+ return g_steal_pointer (&self);
+}
+
+guint
+gbp_gjs_symbol_node_get_n_children (GbpGjsSymbolNode *self)
+{
+ g_return_val_if_fail (GBP_IS_GJS_SYMBOL_NODE (self), 0);
+
+ if (self->children == NULL)
+ return 0;
+
+ return self->children->len;
+}
+
+IdeSymbolNode *
+gbp_gjs_symbol_node_get_nth_child (GbpGjsSymbolNode *self,
+ guint nth_child)
+{
+ g_return_val_if_fail (GBP_IS_GJS_SYMBOL_NODE (self), NULL);
+
+ if (self->children == NULL || nth_child >= self->children->len)
+ return NULL;
+
+ return g_object_ref (g_ptr_array_index (self->children, nth_child));
+}
diff --git a/src/plugins/gjs-symbols/gbp-gjs-symbol-node.h b/src/plugins/gjs-symbols/gbp-gjs-symbol-node.h
new file mode 100644
index 000000000..36731e488
--- /dev/null
+++ b/src/plugins/gjs-symbols/gbp-gjs-symbol-node.h
@@ -0,0 +1,38 @@
+/* gbp-gjs-symbol-node.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <json-glib/json-glib.h>
+
+#include <libide-code.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_GJS_SYMBOL_NODE (gbp_gjs_symbol_node_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpGjsSymbolNode, gbp_gjs_symbol_node, GBP, GJS_SYMBOL_NODE, IdeSymbolNode)
+
+GbpGjsSymbolNode *gbp_gjs_symbol_node_new (JsonObject *object);
+guint gbp_gjs_symbol_node_get_n_children (GbpGjsSymbolNode *self);
+IdeSymbolNode *gbp_gjs_symbol_node_get_nth_child (GbpGjsSymbolNode *self,
+ guint nth_child);
+
+G_END_DECLS
diff --git a/src/plugins/gjs-symbols/gbp-gjs-symbol-resolver.c
b/src/plugins/gjs-symbols/gbp-gjs-symbol-resolver.c
new file mode 100644
index 000000000..eda8ae68e
--- /dev/null
+++ b/src/plugins/gjs-symbols/gbp-gjs-symbol-resolver.c
@@ -0,0 +1,207 @@
+/* gbp-gjs-symbol-resolver.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gbp-gjs-symbol-resolver"
+
+#include "config.h"
+
+#include <errno.h>
+#include <json-glib/json-glib.h>
+#include <unistd.h>
+
+#include <libide-code.h>
+#include <libide-foundry.h>
+#include <libide-threading.h>
+
+#include "gbp-gjs-symbol-resolver.h"
+#include "gbp-gjs-symbol-tree.h"
+
+struct _GbpGjsSymbolResolver
+{
+ IdeObject parent_instance;
+};
+
+static void
+gbp_gjs_symbol_resolver_get_symbol_tree_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeSubprocess *subprocess = (IdeSubprocess *)object;
+ g_autoptr(GbpGjsSymbolNode) node = NULL;
+ g_autoptr(JsonParser) parser = NULL;
+ g_autoptr(IdeTask) task = user_data;
+ g_autoptr(GError) error = NULL;
+ g_autofree char *stdout_buf = NULL;
+ JsonObject *obj;
+ JsonNode *root;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_SUBPROCESS (subprocess));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (IDE_IS_TASK (task));
+
+ if (!ide_subprocess_communicate_utf8_finish (subprocess, result, &stdout_buf, NULL, &error))
+ {
+ ide_task_return_error (task, g_steal_pointer (&error));
+ IDE_EXIT;
+ }
+
+ parser = json_parser_new ();
+
+ if (!json_parser_load_from_data (parser, stdout_buf, -1, &error))
+ {
+ ide_task_return_error (task, g_steal_pointer (&error));
+ IDE_EXIT;
+ }
+
+ if (!(root = json_parser_get_root (parser)) ||
+ !JSON_NODE_HOLDS_OBJECT (root) ||
+ !(obj = json_node_get_object (root)) ||
+ !(node = gbp_gjs_symbol_node_new (obj)))
+ {
+ ide_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_DATA,
+ "Reflect.parse() returned invalid data");
+ IDE_EXIT;
+ }
+
+ ide_task_return_object (task, gbp_gjs_symbol_tree_new (node));
+
+ IDE_EXIT;
+}
+
+static void
+gbp_gjs_symbol_resolver_get_symbol_tree_async (IdeSymbolResolver *resolver,
+ GFile *file,
+ GBytes *contents,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+ g_autoptr(IdeSubprocess) subprocess = NULL;
+ g_autoptr(IdeContext) context = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GBytes) script = NULL;
+ g_autoptr(IdeTask) task = NULL;
+ g_autofree char *name = NULL;
+ int fd;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_GJS_SYMBOL_RESOLVER (resolver));
+ g_assert (G_IS_FILE (file));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = ide_task_new (resolver, cancellable, callback, user_data);
+ ide_task_set_source_tag (task, gbp_gjs_symbol_resolver_get_symbol_tree_async);
+
+ script = g_resources_lookup_data ("/plugins/gjs-symbols/parse.js", 0, NULL);
+ name = g_file_get_basename (file);
+
+ g_assert (script != NULL);
+ g_assert (name != NULL);
+
+ if (!(context = ide_object_ref_context (IDE_OBJECT (resolver))) ||
+ !(launcher = ide_foundry_get_launcher_for_context (context, "gjs", "/usr/bin/gjs", NULL)))
+ {
+ ide_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ "A working `gjs` could not be found");
+ IDE_EXIT;
+ }
+
+ if (contents != NULL)
+ fd = ide_foundry_bytes_to_memfd (contents, "gjs-symbols-data");
+ else
+ fd = ide_foundry_file_to_memfd (file, "gjs-symbols-data");
+
+ if (fd < 0)
+ {
+ ide_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Failed to open temporary file: %s",
+ g_strerror (errno));
+ IDE_EXIT;
+ }
+
+ ide_subprocess_launcher_set_flags (launcher,
+ (G_SUBPROCESS_FLAGS_STDOUT_PIPE |
+ G_SUBPROCESS_FLAGS_STDERR_SILENCE));
+ ide_subprocess_launcher_take_fd (launcher, fd, 3);
+ ide_subprocess_launcher_push_argv (launcher, "-c");
+ ide_subprocess_launcher_push_argv (launcher, (const char *)g_bytes_get_data (script, NULL));
+ ide_subprocess_launcher_push_argv (launcher, name);
+
+ if (!(subprocess = ide_subprocess_launcher_spawn (launcher, NULL, &error)))
+ {
+ ide_task_return_error (task, g_steal_pointer (&error));
+ IDE_EXIT;
+ }
+
+ ide_subprocess_communicate_utf8_async (subprocess,
+ NULL,
+ cancellable,
+ gbp_gjs_symbol_resolver_get_symbol_tree_cb,
+ g_steal_pointer (&task));
+
+ IDE_EXIT;
+}
+
+static IdeSymbolTree *
+gbp_gjs_symbol_resolver_get_symbol_tree_finish (IdeSymbolResolver *resolver,
+ GAsyncResult *result,
+ GError **error)
+{
+ IdeSymbolTree *ret;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_GJS_SYMBOL_RESOLVER (resolver));
+ g_assert (IDE_IS_TASK (result));
+
+ ret = ide_task_propagate_object (IDE_TASK (result), error);
+
+ IDE_RETURN (ret);
+}
+
+static void
+symbol_resolver_iface_init (IdeSymbolResolverInterface *iface)
+{
+ iface->get_symbol_tree_async = gbp_gjs_symbol_resolver_get_symbol_tree_async;
+ iface->get_symbol_tree_finish = gbp_gjs_symbol_resolver_get_symbol_tree_finish;
+}
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (GbpGjsSymbolResolver, gbp_gjs_symbol_resolver, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_SYMBOL_RESOLVER, symbol_resolver_iface_init))
+
+static void
+gbp_gjs_symbol_resolver_class_init (GbpGjsSymbolResolverClass *klass)
+{
+}
+
+static void
+gbp_gjs_symbol_resolver_init (GbpGjsSymbolResolver *self)
+{
+}
diff --git a/src/plugins/gjs-symbols/gbp-gjs-symbol-resolver.h
b/src/plugins/gjs-symbols/gbp-gjs-symbol-resolver.h
new file mode 100644
index 000000000..4e7f8e618
--- /dev/null
+++ b/src/plugins/gjs-symbols/gbp-gjs-symbol-resolver.h
@@ -0,0 +1,31 @@
+/* gbp-gjs-symbol-resolver.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libide-core.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_GJS_SYMBOL_RESOLVER (gbp_gjs_symbol_resolver_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpGjsSymbolResolver, gbp_gjs_symbol_resolver, GBP, GJS_SYMBOL_RESOLVER, IdeObject)
+
+G_END_DECLS
diff --git a/src/plugins/gjs-symbols/gbp-gjs-symbol-tree.c b/src/plugins/gjs-symbols/gbp-gjs-symbol-tree.c
new file mode 100644
index 000000000..4b36d9738
--- /dev/null
+++ b/src/plugins/gjs-symbols/gbp-gjs-symbol-tree.c
@@ -0,0 +1,110 @@
+/* gbp-gjs-symbol-tree.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gbp-gjs-symbol-tree"
+
+#include "config.h"
+
+#include <libide-code.h>
+
+#include "gbp-gjs-symbol-tree.h"
+
+struct _GbpGjsSymbolTree
+{
+ GObject parent_instance;
+ GbpGjsSymbolNode *root;
+};
+
+static guint
+gbp_gjs_symbol_tree_get_n_children (IdeSymbolTree *tree,
+ IdeSymbolNode *node)
+{
+ GbpGjsSymbolTree *self = (GbpGjsSymbolTree *)tree;
+
+ g_assert (GBP_IS_GJS_SYMBOL_TREE (self));
+ g_assert (!node || GBP_IS_GJS_SYMBOL_NODE (node));
+
+ if (node == NULL)
+ return gbp_gjs_symbol_node_get_n_children (self->root);
+ else
+ return gbp_gjs_symbol_node_get_n_children (GBP_GJS_SYMBOL_NODE (node));
+}
+
+static IdeSymbolNode *
+gbp_gjs_symbol_tree_get_nth_child (IdeSymbolTree *tree,
+ IdeSymbolNode *node,
+ guint nth_child)
+{
+ GbpGjsSymbolTree *self = (GbpGjsSymbolTree *)tree;
+
+ g_assert (GBP_IS_GJS_SYMBOL_TREE (self));
+ g_assert (!node || GBP_IS_GJS_SYMBOL_NODE (node));
+
+ if (node == NULL)
+ return gbp_gjs_symbol_node_get_nth_child (self->root, nth_child);
+ else
+ return gbp_gjs_symbol_node_get_nth_child (GBP_GJS_SYMBOL_NODE (node), nth_child);
+}
+
+static void
+symbol_tree_iface_init (IdeSymbolTreeInterface *iface)
+{
+ iface->get_n_children = gbp_gjs_symbol_tree_get_n_children;
+ iface->get_nth_child = gbp_gjs_symbol_tree_get_nth_child;
+}
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (GbpGjsSymbolTree, gbp_gjs_symbol_tree, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_SYMBOL_TREE, symbol_tree_iface_init))
+
+static void
+gbp_gjs_symbol_tree_finalize (GObject *object)
+{
+ GbpGjsSymbolTree *self = (GbpGjsSymbolTree *)object;
+
+ g_clear_object (&self->root);
+
+ G_OBJECT_CLASS (gbp_gjs_symbol_tree_parent_class)->finalize (object);
+}
+
+static void
+gbp_gjs_symbol_tree_class_init (GbpGjsSymbolTreeClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gbp_gjs_symbol_tree_finalize;
+}
+
+static void
+gbp_gjs_symbol_tree_init (GbpGjsSymbolTree *self)
+{
+}
+
+GbpGjsSymbolTree *
+gbp_gjs_symbol_tree_new (GbpGjsSymbolNode *root)
+{
+ GbpGjsSymbolTree *self;
+
+ g_return_val_if_fail (GBP_IS_GJS_SYMBOL_NODE (root), NULL);
+
+ self = g_object_new (GBP_TYPE_GJS_SYMBOL_TREE, NULL);
+ self->root = g_object_ref (root);
+
+ return self;
+}
diff --git a/src/plugins/gjs-symbols/gbp-gjs-symbol-tree.h b/src/plugins/gjs-symbols/gbp-gjs-symbol-tree.h
new file mode 100644
index 000000000..b6fb38544
--- /dev/null
+++ b/src/plugins/gjs-symbols/gbp-gjs-symbol-tree.h
@@ -0,0 +1,33 @@
+/* gbp-gjs-symbol-tree.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "gbp-gjs-symbol-node.h"
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_GJS_SYMBOL_TREE (gbp_gjs_symbol_tree_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpGjsSymbolTree, gbp_gjs_symbol_tree, GBP, GJS_SYMBOL_TREE, GObject)
+
+GbpGjsSymbolTree *gbp_gjs_symbol_tree_new (GbpGjsSymbolNode *root);
+
+G_END_DECLS
diff --git a/src/plugins/gjs-symbols/gjs-symbols-plugin.c b/src/plugins/gjs-symbols/gjs-symbols-plugin.c
new file mode 100644
index 000000000..b9d6d5be0
--- /dev/null
+++ b/src/plugins/gjs-symbols/gjs-symbols-plugin.c
@@ -0,0 +1,41 @@
+/* gjs-symbols-plugin.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gjs-symbols-plugin"
+
+#include "config.h"
+
+#include <libpeas/peas.h>
+
+#include <libide-code.h>
+
+#include "gbp-gjs-code-indexer.h"
+#include "gbp-gjs-symbol-resolver.h"
+
+_IDE_EXTERN void
+_gbp_gjs_symbols_register_types (PeasObjectModule *module)
+{
+ peas_object_module_register_extension_type (module,
+ IDE_TYPE_SYMBOL_RESOLVER,
+ GBP_TYPE_GJS_SYMBOL_RESOLVER);
+ peas_object_module_register_extension_type (module,
+ IDE_TYPE_CODE_INDEXER,
+ GBP_TYPE_GJS_CODE_INDEXER);
+}
diff --git a/src/plugins/gjs-symbols/gjs-symbols.gresource.xml
b/src/plugins/gjs-symbols/gjs-symbols.gresource.xml
new file mode 100644
index 000000000..3d773032c
--- /dev/null
+++ b/src/plugins/gjs-symbols/gjs-symbols.gresource.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/plugins/gjs-symbols">
+ <file>gjs-symbols.plugin</file>
+ <file>parse.js</file>
+ </gresource>
+</gresources>
diff --git a/src/plugins/gjs-symbols/gjs_symbols.plugin b/src/plugins/gjs-symbols/gjs-symbols.plugin
similarity index 67%
rename from src/plugins/gjs-symbols/gjs_symbols.plugin
rename to src/plugins/gjs-symbols/gjs-symbols.plugin
index c715af17c..ff9aba2c9 100644
--- a/src/plugins/gjs-symbols/gjs_symbols.plugin
+++ b/src/plugins/gjs-symbols/gjs-symbols.plugin
@@ -1,13 +1,12 @@
[Plugin]
Authors=Patrick Griffis <tingping tingping se>
Builtin=true
-Copyright=Copyright © 2017 Patrick Griffis
+Copyright=Copyright © 2017 Patrick Griffis, Copyright © 2022 Christian Hergert
Description=Provides a symbol resolver for JavaScript using GJS.
-Loader=python3
-Module=gjs_symbols
+Embedded=_gbp_gjs_symbol_register_types
+Module=gjs-symbols
Name=GJS Symbol Resolver
X-Code-Indexer-Languages-Priority=0
X-Code-Indexer-Languages=js
X-Symbol-Resolver-Languages-Priority=0
X-Symbol-Resolver-Languages=js
-X-Builder-ABI=@PACKAGE_ABI@
diff --git a/src/plugins/gjs-symbols/gjs_symbols.py b/src/plugins/gjs-symbols/gjs_symbols.py
index e06353f3c..16b31c785 100644
--- a/src/plugins/gjs-symbols/gjs_symbols.py
+++ b/src/plugins/gjs-symbols/gjs_symbols.py
@@ -43,7 +43,7 @@ class JsSymbolNode(Ide.SymbolNode):
self.children = children
def do_get_location_async(self, cancellable, callback, user_data=None):
- task = Gio.Task.new(self, cancellable, callback)
+ task = Ide.Task.new(self, cancellable, callback)
task.return_boolean(True)
def do_get_location_finish(self, result):
@@ -251,98 +251,73 @@ try {
data = ARGV[0];
}
print(JSON.stringify(Reflect.parse(data, {source: '%s'})));
+
+ subprocess =
} catch (e) {
imports.system.exit(1);
}
""".replace('\n', ' ')
+def _get_launcher(context, file_):
+ file_path = file_.get_path()
+ script = JS_SCRIPT % file_path.replace('\\', '\\\\').replace("'", "\\'")
+ unsaved_file = Ide.UnsavedFiles.from_context(context).get_unsaved_file(file_)
+ srcdir = context.ref_workdir().get_path()
+ launcher = None
-class GjsSymbolProvider(Ide.Object, Ide.SymbolResolver):
- def __init__(self):
- super().__init__()
+ if context.has_project():
+ pipeline = Ide.BuildManager.from_context(context).get_pipeline()
+ if pipeline is not None and pipeline.contains_program_in_path('gjs'):
+ launcher = pipeline.create_launcher()
+ srcdir = pipeline.get_srcdir()
- @staticmethod
- def _get_launcher(context, file_):
- file_path = file_.get_path()
- script = JS_SCRIPT % file_path.replace('\\', '\\\\').replace("'", "\\'")
- unsaved_file = Ide.UnsavedFiles.from_context(context).get_unsaved_file(file_)
- srcdir = context.ref_workdir().get_path()
- launcher = None
-
- if context.has_project():
- pipeline = Ide.BuildManager.from_context(context).get_pipeline()
- if pipeline is not None and pipeline.contains_program_in_path('gjs'):
- launcher = pipeline.create_launcher()
- srcdir = pipeline.get_srcdir()
-
- if launcher is None:
- launcher = Ide.SubprocessLauncher.new(0)
-
- launcher.set_cwd(srcdir)
- launcher.set_flags(Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_SILENCE)
- launcher.push_args(('gjs', '-c', script))
-
- if unsaved_file is not None:
- launcher.push_argv(unsaved_file.get_content().get_data().decode('utf-8'))
- else:
- launcher.push_args(('--file', file_path))
+ if launcher is None:
+ launcher = Ide.SubprocessLauncher.new(0)
- return launcher
+ launcher.set_cwd(srcdir)
+ launcher.set_flags(Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_SILENCE)
+ launcher.push_args(('gjs', '-c', script))
- def do_lookup_symbol_async(self, location, cancellable, callback, user_data=None):
- task = Gio.Task.new(self, cancellable, callback)
- task.return_error(GLib.Error('Not implemented'))
+ if unsaved_file is not None:
+ launcher.push_argv(unsaved_file.get_content().get_data().decode('utf-8'))
+ else:
+ launcher.push_args(('--file', file_path))
- def do_lookup_symbol_finish(self, result):
- result.propagate_boolean()
- return None
-
- def do_get_symbol_tree_async(self, file_, buffer_, cancellable, callback, user_data=None):
- task = Gio.Task.new(self, cancellable, callback)
- launcher = self._get_launcher(self.get_context(), file_)
+ return launcher
- threading.Thread(target=self._get_tree_thread, args=(task, launcher, file_),
- name='gjs-symbols-thread').start()
+def _get_tree_thread(task, launcher, file_):
+ try:
+ proc = launcher.spawn()
+ success, stdout, stderr = proc.communicate_utf8(None, None)
- def _get_tree_thread(self, task, launcher, file_):
- try:
- proc = launcher.spawn()
- success, stdout, stderr = proc.communicate_utf8(None, None)
-
- if not success:
- task.return_error(GLib.Error('Failed to run gjs'))
- return
-
- task.symbol_tree = JsSymbolTree(json.loads(stdout), file_)
- except GLib.Error as err:
- task.return_error(err)
- except (json.JSONDecodeError, UnicodeDecodeError) as e:
- task.return_error(GLib.Error('Failed to decode gjs json: {}'.format(e)))
- except (IndexError, KeyError) as e:
- task.return_error(GLib.Error('Failed to extract information from ast: {}'.format(e)))
- else:
- task.return_boolean(True)
+ if not success:
+ task.return_error(GLib.Error('Failed to run gjs'))
+ return
- def do_get_symbol_tree_finish(self, result):
- if result.propagate_boolean():
- return result.symbol_tree
+ task.symbol_tree = JsSymbolTree(json.loads(stdout), file_)
+ except GLib.Error as err:
+ task.return_error(err)
+ except (json.JSONDecodeError, UnicodeDecodeError) as e:
+ task.return_error(GLib.Error('Failed to decode gjs json: {}'.format(e)))
+ except (IndexError, KeyError) as e:
+ task.return_error(GLib.Error('Failed to extract information from ast: {}'.format(e)))
+ else:
+ task.return_boolean(True)
- def do_load(self):
- pass
- def do_find_references_async(self, location, language_id, cancellable, callback, user_data=None):
- task = Gio.Task.new(self, cancellable, callback)
- task.return_error(GLib.Error('Not implemented'))
+class GjsSymbolProvider(Ide.Object, Ide.SymbolResolver):
- def do_find_references_finish(self, result):
- return result.propagate_boolean()
+ def do_get_symbol_tree_async(self, file_, buffer_, cancellable, callback, data):
+ task = Ide.Task.new(self, cancellable, callback)
+ launcher = _get_launcher(self.get_context(), file_)
- def do_find_nearest_scope_async(self, location, cancellable, callback, user_data=None):
- task = Gio.Task.new(self, cancellable, callback)
- task.return_error(GLib.Error('Not implemented'))
+ threading.Thread(target=_get_tree_thread,
+ args=(task, launcher, file_),
+ name='gjs-symbols-thread').start()
- def do_find_nearest_scope_finish(self, result):
- return result.propagate_boolean()
+ def do_get_symbol_tree_finish(self, result):
+ if result.propagate_boolean():
+ return result.symbol_tree
class JsCodeIndexEntries(GObject.Object, Ide.CodeIndexEntries):
@@ -435,7 +410,7 @@ class GjsCodeIndexer(Ide.Object, Ide.CodeIndexer):
self.active = False
def do_index_file_async(self, file_, build_flags, cancellable, callback, data):
- task = Gio.Task.new(self, cancellable, callback)
+ task = Ide.Task.new(self, cancellable, callback)
task.entries = None
task.file = file_
@@ -455,7 +430,7 @@ class GjsCodeIndexer(Ide.Object, Ide.CodeIndexer):
def do_generate_key_async(self, location, flags, cancellable, callback, user_data=None):
# print('generate key')
- task = Gio.Task.new(self, cancellable, callback)
+ task = Ide.Task.new(self, cancellable, callback)
task.return_error(GLib.Error('Not implemented'))
def do_generate_key_finish(self, result):
diff --git a/src/plugins/gjs-symbols/meson.build b/src/plugins/gjs-symbols/meson.build
index 43ccc9724..51d8dae87 100644
--- a/src/plugins/gjs-symbols/meson.build
+++ b/src/plugins/gjs-symbols/meson.build
@@ -1,13 +1,19 @@
if get_option('plugin_gjs_symbols')
-install_data('gjs_symbols.py', install_dir: plugindir)
-
-configure_file(
- input: 'gjs_symbols.plugin',
- output: 'gjs_symbols.plugin',
- configuration: config_h,
- install: true,
- install_dir: plugindir,
+plugins_sources += files([
+ 'gjs-symbols-plugin.c',
+ 'gbp-gjs-symbol-resolver.c',
+ 'gbp-gjs-symbol-node.c',
+ 'gbp-gjs-symbol-tree.c',
+ 'gbp-gjs-code-indexer.c',
+])
+
+plugin_gjs_symbols_resources = gnome.compile_resources(
+ 'gjs-symbols-resources',
+ 'gjs-symbols.gresource.xml',
+ c_name: 'gbp_gjs_symbols',
)
+plugins_sources += plugin_gjs_symbols_resources
+
endif
diff --git a/src/plugins/gjs-symbols/parse.js b/src/plugins/gjs-symbols/parse.js
new file mode 100644
index 000000000..4efdc0192
--- /dev/null
+++ b/src/plugins/gjs-symbols/parse.js
@@ -0,0 +1,14 @@
+try {
+ const DATA_FD = 0;
+ const Gio = imports.gi.Gio;
+ const GLib = imports.gi.GLib;
+
+ let input = Gio.UnixInputStream.new(DATA_FD, true);
+ let reader = Gio.DataInputStream.new(input);
+ let [data, len] = reader.read_upto("", -1, null);
+
+ print(JSON.stringify(Reflect.parse(data, {source: ARGV[1]})));
+} catch (e) {
+ print(e);
+ imports.system.exit(1);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]