[gnome-builder] symbol-tree: make IdeSymbolNode location resolver async
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] symbol-tree: make IdeSymbolNode location resolver async
- Date: Wed, 19 Oct 2016 05:53:15 +0000 (UTC)
commit b9e2239d536c830a5a0220959a8010e4d48afdda
Author: Christian Hergert <chergert redhat com>
Date: Tue Oct 18 22:52:59 2016 -0700
symbol-tree: make IdeSymbolNode location resolver async
This changes IdeSymbolNode::get_location() to be asynchronous using
IdeSymbolNode::get_location_async() and ::get_location_finish(). This
breaks ABI, but we are the only consumers of this API currently so it's
fine.
libide/symbols/ide-symbol-node.c | 48 +++++++++++++++++---
libide/symbols/ide-symbol-node.h | 22 +++++++--
plugins/clang/ide-clang-symbol-node.c | 29 ++++++++++--
plugins/ctags/ide-ctags-symbol-node.c | 65 +++++++++++++++------------
plugins/symbol-tree/symbol-tree-builder.c | 57 ++++++++++++++++++-----
plugins/vala-pack/ide-vala-symbol-tree.vala | 2 +-
6 files changed, 163 insertions(+), 60 deletions(-)
---
diff --git a/libide/symbols/ide-symbol-node.c b/libide/symbols/ide-symbol-node.c
index aef8508..8a22bc2 100644
--- a/libide/symbols/ide-symbol-node.c
+++ b/libide/symbols/ide-symbol-node.c
@@ -41,10 +41,28 @@ enum {
static GParamSpec *properties [LAST_PROP];
+static void
+ide_symbol_node_real_get_location_async (IdeSymbolNode *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(GTask) task = NULL;
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, ide_symbol_node_get_location_async);
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ "Unsupported operation on symbol node");
+}
+
static IdeSourceLocation *
-ide_symbol_node_real_get_location (IdeSymbolNode *self)
+ide_symbol_node_real_get_location_finish (IdeSymbolNode *self,
+ GAsyncResult *result,
+ GError **error)
{
- return NULL;
+ return g_task_propagate_pointer (G_TASK (result), error);
}
static void
@@ -119,7 +137,8 @@ ide_symbol_node_class_init (IdeSymbolNodeClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- klass->get_location = ide_symbol_node_real_get_location;
+ klass->get_location_async = ide_symbol_node_real_get_location_async;
+ klass->get_location_finish = ide_symbol_node_real_get_location_finish;
object_class->finalize = ide_symbol_node_finalize;
object_class->get_property = ide_symbol_node_get_property;
@@ -186,17 +205,32 @@ ide_symbol_node_get_kind (IdeSymbolNode *self)
return priv->kind;
}
+void
+ide_symbol_node_get_location_async (IdeSymbolNode *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (IDE_IS_SYMBOL_NODE (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ IDE_SYMBOL_NODE_GET_CLASS (self)->get_location_async (self, cancellable, callback, user_data);
+}
+
/**
- * ide_symbol_node_get_location:
+ * ide_symbol_node_get_location_finish:
*
- * Gets the location for the symbol node.
+ * Completes the request to gets the location for the symbol node.
*
* Returns: (transfer full) (nullable): An #IdeSourceLocation or %NULL.
*/
IdeSourceLocation *
-ide_symbol_node_get_location (IdeSymbolNode *self)
+ide_symbol_node_get_location_finish (IdeSymbolNode *self,
+ GAsyncResult *result,
+ GError **error)
{
g_return_val_if_fail (IDE_IS_SYMBOL_NODE (self), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
- return IDE_SYMBOL_NODE_GET_CLASS (self)->get_location (self);
+ return IDE_SYMBOL_NODE_GET_CLASS (self)->get_location_finish (self, result, error);
}
diff --git a/libide/symbols/ide-symbol-node.h b/libide/symbols/ide-symbol-node.h
index 361a25a..892f0f7 100644
--- a/libide/symbols/ide-symbol-node.h
+++ b/libide/symbols/ide-symbol-node.h
@@ -34,7 +34,13 @@ struct _IdeSymbolNodeClass
{
IdeObjectClass parent;
- IdeSourceLocation *(*get_location) (IdeSymbolNode *self);
+ void (*get_location_async) (IdeSymbolNode *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ IdeSourceLocation *(*get_location_finish) (IdeSymbolNode *self,
+ GAsyncResult *result,
+ GError **error);
gpointer _reserved1;
gpointer _reserved2;
@@ -46,10 +52,16 @@ struct _IdeSymbolNodeClass
gpointer _reserved8;
};
-IdeSymbolKind ide_symbol_node_get_kind (IdeSymbolNode *self);
-IdeSymbolFlags ide_symbol_node_get_flags (IdeSymbolNode *self);
-const gchar *ide_symbol_node_get_name (IdeSymbolNode *self);
-IdeSourceLocation *ide_symbol_node_get_location (IdeSymbolNode *self);
+IdeSymbolKind ide_symbol_node_get_kind (IdeSymbolNode *self);
+IdeSymbolFlags ide_symbol_node_get_flags (IdeSymbolNode *self);
+const gchar *ide_symbol_node_get_name (IdeSymbolNode *self);
+void ide_symbol_node_get_location_async (IdeSymbolNode *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+IdeSourceLocation *ide_symbol_node_get_location_finish (IdeSymbolNode *self,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
diff --git a/plugins/clang/ide-clang-symbol-node.c b/plugins/clang/ide-clang-symbol-node.c
index f024e1a..f9e38a5 100644
--- a/plugins/clang/ide-clang-symbol-node.c
+++ b/plugins/clang/ide-clang-symbol-node.c
@@ -164,8 +164,11 @@ _ide_clang_symbol_node_get_cursor (IdeClangSymbolNode *self)
return self->cursor;
}
-static IdeSourceLocation *
-ide_clang_symbol_node_get_location (IdeSymbolNode *symbol_node)
+static void
+ide_clang_symbol_node_get_location_async (IdeSymbolNode *symbol_node,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
IdeClangSymbolNode *self = (IdeClangSymbolNode *)symbol_node;
IdeSourceLocation *ret;
@@ -178,8 +181,12 @@ ide_clang_symbol_node_get_location (IdeSymbolNode *symbol_node)
IdeFile *ifile;
guint line = 0;
guint line_offset = 0;
+ g_autoptr(GTask) task = NULL;
- g_return_val_if_fail (IDE_IS_CLANG_SYMBOL_NODE (self), NULL);
+ g_return_if_fail (IDE_IS_CLANG_SYMBOL_NODE (self));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, ide_clang_symbol_node_get_location_async);
cxloc = clang_getCursorLocation (self->cursor);
clang_getFileLocation (cxloc, &file, &line, &line_offset, NULL);
@@ -203,7 +210,18 @@ ide_clang_symbol_node_get_location (IdeSymbolNode *symbol_node)
g_clear_object (&gfile);
clang_disposeString (cxfilename);
- return ret;
+ g_task_return_pointer (task, ret, (GDestroyNotify)ide_source_location_unref);
+}
+
+static IdeSourceLocation *
+ide_clang_symbol_node_get_location_finish (IdeSymbolNode *symbol_node,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (IDE_IS_CLANG_SYMBOL_NODE (symbol_node), NULL);
+ g_return_val_if_fail (G_IS_TASK (result), NULL);
+
+ return g_task_propagate_pointer (G_TASK (result), error);
}
static void
@@ -211,7 +229,8 @@ ide_clang_symbol_node_class_init (IdeClangSymbolNodeClass *klass)
{
IdeSymbolNodeClass *node_class = IDE_SYMBOL_NODE_CLASS (klass);
- node_class->get_location = ide_clang_symbol_node_get_location;
+ node_class->get_location_async = ide_clang_symbol_node_get_location_async;
+ node_class->get_location_finish = ide_clang_symbol_node_get_location_finish;
}
static void
diff --git a/plugins/ctags/ide-ctags-symbol-node.c b/plugins/ctags/ide-ctags-symbol-node.c
index 97ad7cd..7232ce3 100644
--- a/plugins/ctags/ide-ctags-symbol-node.c
+++ b/plugins/ctags/ide-ctags-symbol-node.c
@@ -29,56 +29,62 @@ struct _IdeCtagsSymbolNode
GPtrArray *children;
};
-typedef struct
-{
- IdeSourceLocation *loc;
- gboolean done;
-} Completion;
-
G_DEFINE_TYPE (IdeCtagsSymbolNode, ide_ctags_symbol_node, IDE_TYPE_SYMBOL_NODE)
static void
-handle_location_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
+ide_ctags_symbol_node_get_location_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
{
IdeCtagsSymbolResolver *resolver = (IdeCtagsSymbolResolver *)object;
- Completion *comp = user_data;
+ g_autoptr(IdeSourceLocation) location = NULL;
+ g_autoptr(GTask) task = user_data;
g_autoptr(GError) error = NULL;
g_assert (IDE_IS_CTAGS_SYMBOL_RESOLVER (resolver));
- g_assert (comp != NULL);
- g_assert (comp->loc == NULL);
- g_assert (comp->done == FALSE);
+ g_assert (G_IS_TASK (task));
- comp->loc = ide_ctags_symbol_resolver_get_location_finish (resolver, result, &error);
- comp->done = TRUE;
+ location = ide_ctags_symbol_resolver_get_location_finish (resolver, result, &error);
- if (error != NULL)
- g_warning ("%s", error->message);
+ if (location == NULL)
+ g_task_return_error (task, g_steal_pointer (&error));
+ else
+ g_task_return_pointer (task,
+ g_steal_pointer (&location),
+ (GDestroyNotify)ide_source_location_unref);
}
-static IdeSourceLocation *
-ide_ctags_symbol_node_get_location (IdeSymbolNode *node)
+static void
+ide_ctags_symbol_node_get_location_async (IdeSymbolNode *node,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
IdeCtagsSymbolNode *self = (IdeCtagsSymbolNode *)node;
- Completion comp = { 0 };
+ g_autoptr(GTask) task = NULL;
- g_return_val_if_fail (IDE_IS_CTAGS_SYMBOL_NODE (self), NULL);
+ g_return_if_fail (IDE_IS_CTAGS_SYMBOL_NODE (self));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, ide_ctags_symbol_node_get_location_async);
ide_ctags_symbol_resolver_get_location_async (self->resolver,
self->index,
self->entry,
NULL,
- handle_location_cb,
- &comp);
-
- /* XXX: FIXME: TODO: ULTRA: Hack until we add async get_location() API */
+ ide_ctags_symbol_node_get_location_cb,
+ g_steal_pointer (&task));
+}
- while (!comp.done)
- gtk_main_iteration ();
+static IdeSourceLocation *
+ide_ctags_symbol_node_get_location_finish (IdeSymbolNode *node,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (IDE_IS_CTAGS_SYMBOL_NODE (node), NULL);
+ g_return_val_if_fail (G_IS_TASK (result), NULL);
- return comp.loc;
+ return g_task_propagate_pointer (G_TASK (result), error);
}
static void
@@ -101,7 +107,8 @@ ide_ctags_symbol_node_class_init (IdeCtagsSymbolNodeClass *klass)
object_class->finalize = ide_ctags_symbol_node_finalize;
- symbol_node_class->get_location = ide_ctags_symbol_node_get_location;
+ symbol_node_class->get_location_async = ide_ctags_symbol_node_get_location_async;
+ symbol_node_class->get_location_finish = ide_ctags_symbol_node_get_location_finish;
}
static void
diff --git a/plugins/symbol-tree/symbol-tree-builder.c b/plugins/symbol-tree/symbol-tree-builder.c
index 1977d67..e0e2a60 100644
--- a/plugins/symbol-tree/symbol-tree-builder.c
+++ b/plugins/symbol-tree/symbol-tree-builder.c
@@ -16,6 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#define G_LOG_DOMAIN "symbol-tree-builder"
+
#include <glib/gi18n.h>
#include <ide.h>
@@ -123,40 +125,69 @@ symbol_tree_builder_build_node (IdeTreeBuilder *builder,
}
}
-static gboolean
-symbol_tree_builder_node_activated (IdeTreeBuilder *builder,
- IdeTreeNode *node)
+static void
+symbol_tree_builder_get_location_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- SymbolTreeBuilder *self = (SymbolTreeBuilder *)builder;
+ IdeSymbolNode *node = (IdeSymbolNode *)object;
+ g_autoptr(SymbolTreeBuilder) self = user_data;
+ g_autoptr(IdeSourceLocation) location = NULL;
+ g_autoptr(GError) error = NULL;
IdePerspective *editor;
IdeWorkbench *workbench;
IdeTree *tree;
- GObject *item;
+
+ IDE_ENTRY;
g_assert (SYMBOL_IS_TREE_BUILDER (self));
- tree = ide_tree_builder_get_tree (builder);
+ location = ide_symbol_node_get_location_finish (node, result, &error);
+
+ if (location == NULL)
+ {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning ("%s", error->message);
+ IDE_EXIT;
+ }
+
+ tree = ide_tree_builder_get_tree (IDE_TREE_BUILDER (self));
workbench = ide_widget_get_workbench (GTK_WIDGET (tree));
editor = ide_workbench_get_perspective_by_name (workbench, "editor");
+ ide_editor_perspective_focus_location (IDE_EDITOR_PERSPECTIVE (editor), location);
+
+ IDE_EXIT;
+}
+
+static gboolean
+symbol_tree_builder_node_activated (IdeTreeBuilder *builder,
+ IdeTreeNode *node)
+{
+ SymbolTreeBuilder *self = (SymbolTreeBuilder *)builder;
+ GObject *item;
+
+ IDE_ENTRY;
+
+ g_assert (SYMBOL_IS_TREE_BUILDER (self));
+
item = ide_tree_node_get_item (node);
if (IDE_IS_SYMBOL_NODE (item))
{
g_autoptr(IdeSourceLocation) location = NULL;
- location = ide_symbol_node_get_location (IDE_SYMBOL_NODE (item));
+ ide_symbol_node_get_location_async (IDE_SYMBOL_NODE (item),
+ NULL,
+ symbol_tree_builder_get_location_cb,
+ g_object_ref (self));
- if (location != NULL)
- {
- ide_editor_perspective_focus_location (IDE_EDITOR_PERSPECTIVE (editor), location);
- return TRUE;
- }
+ IDE_RETURN (TRUE);
}
g_warning ("IdeSymbolNode did not create a source location");
- return FALSE;
+ IDE_RETURN (FALSE);
}
static void
diff --git a/plugins/vala-pack/ide-vala-symbol-tree.vala b/plugins/vala-pack/ide-vala-symbol-tree.vala
index 272f12f..d227b45 100644
--- a/plugins/vala-pack/ide-vala-symbol-tree.vala
+++ b/plugins/vala-pack/ide-vala-symbol-tree.vala
@@ -142,7 +142,7 @@ namespace Ide
this.kind = Ide.SymbolKind.FIELD;
}
- public override Ide.SourceLocation? get_location ()
+ public override async Ide.SourceLocation? get_location_async (GLib.Cancellable? cancellable)
{
var source_reference = this.node.source_reference;
var file = (source_reference.file as Ide.ValaSourceFile).file;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]