[gnome-builder/wip/symbol-tree: 6/9] symbol-tree: add plumbing for symbol tree abstraction



commit a19637451afef32d0c52edcfd11fe87a42ba0fb0
Author: Christian Hergert <christian hergert me>
Date:   Thu Jun 18 04:23:07 2015 -0700

    symbol-tree: add plumbing for symbol tree abstraction
    
    The current symbol abstraction only allows for getting an array of
    symbols. This isn't entirely useful going forward as we support more
    complex languages.
    
    This provides the interface and stub implementation for clang to
    extract the symbols into a tree like interface.
    
    You will notice that the IdeSymbolTree interface is as vague as possible.
    This is meant to avoid inflating symbol objects until necessary, and
    allow them to be released as early as possible.
    
    Some impelementations may choose to hold onto a translation unit in the
    IdeSymbolTree subclass and inflate from internal strings on demand.

 libide/Makefile.am                        |    4 +
 libide/clang/ide-clang-symbol-resolver.c  |  112 ++++++++++++++++++
 libide/clang/ide-clang-translation-unit.c |   39 +++++++
 libide/clang/ide-clang-translation-unit.h |    9 ++
 libide/ide-symbol-node.c                  |  178 +++++++++++++++++++++++++++++
 libide/ide-symbol-node.h                  |   41 +++++++
 libide/ide-symbol-resolver.c              |   31 +++++
 libide/ide-symbol-resolver.h              |   20 ++++
 libide/ide-symbol-tree.c                  |   62 ++++++++++
 libide/ide-symbol-tree.h                  |   51 ++++++++
 10 files changed, 547 insertions(+), 0 deletions(-)
---
diff --git a/libide/Makefile.am b/libide/Makefile.am
index 4a69b90..0ddcf27 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -151,6 +151,10 @@ libide_1_0_la_public_sources = \
        ide-symbol-resolver.h \
        ide-symbol.c \
        ide-symbol.h \
+       ide-symbol-node.c \
+       ide-symbol-node.h \
+       ide-symbol-tree.c \
+       ide-symbol-tree.h \
        ide-target.c \
        ide-target.h \
        ide-test-case.c \
diff --git a/libide/clang/ide-clang-symbol-resolver.c b/libide/clang/ide-clang-symbol-resolver.c
index ee200ea..6a983f4 100644
--- a/libide/clang/ide-clang-symbol-resolver.c
+++ b/libide/clang/ide-clang-symbol-resolver.c
@@ -211,6 +211,116 @@ ide_clang_symbol_resolver_get_symbols_finish (IdeSymbolResolver  *resolver,
 }
 
 static void
+ide_clang_symbol_resolver_get_symbol_tree_cb2 (GObject      *object,
+                                               GAsyncResult *result,
+                                               gpointer      user_data)
+{
+  IdeClangTranslationUnit *unit = (IdeClangTranslationUnit *)object;
+  IdeSymbolTree *ret;
+  GError *error = NULL;
+  g_autoptr(GTask) task = user_data;
+
+  if (!(ret = ide_clang_translation_unit_get_symbol_tree_finish (unit, result, &error)))
+    g_task_return_error (task, error);
+  else
+    g_task_return_pointer (task, ret, g_object_unref);
+}
+
+static void
+ide_clang_symbol_resolver_get_symbol_tree_cb (GObject      *object,
+                                              GAsyncResult *result,
+                                              gpointer      user_data)
+{
+  IdeClangService *service = (IdeClangService *)object;
+  g_autoptr(IdeClangTranslationUnit) unit = NULL;
+  g_autoptr(GTask) task = user_data;
+  GFile *file;
+  GError *error = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_CLANG_SERVICE (service));
+  g_assert (G_IS_TASK (task));
+
+  unit = ide_clang_service_get_translation_unit_finish (service, result, &error);
+
+  if (unit == NULL)
+    {
+      g_task_return_error (task, error);
+      IDE_EXIT;
+    }
+
+  file = g_task_get_task_data (task);
+  g_assert (G_IS_FILE (file));
+
+  ide_clang_translation_unit_get_symbol_tree_async (unit,
+                                                    file,
+                                                    g_task_get_cancellable (task),
+                                                    ide_clang_symbol_resolver_get_symbol_tree_cb2,
+                                                    g_object_ref (task));
+
+  IDE_EXIT;
+}
+
+static void
+ide_clang_symbol_resolver_get_symbol_tree_async (IdeSymbolResolver   *resolver,
+                                                 GFile               *file,
+                                                 GCancellable        *cancellable,
+                                                 GAsyncReadyCallback  callback,
+                                                 gpointer             user_data)
+{
+  IdeClangSymbolResolver *self = (IdeClangSymbolResolver *)resolver;
+  g_autoptr(GTask) task = NULL;
+  IdeContext *context;
+  IdeClangService *service;
+  g_autoptr(IdeFile) ifile = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_CLANG_SYMBOL_RESOLVER (self));
+  g_assert (G_IS_FILE (file));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  context = ide_object_get_context (IDE_OBJECT (self));
+  service = ide_context_get_service_typed (context, IDE_TYPE_CLANG_SERVICE);
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_task_data (task, g_object_ref (file), g_object_unref);
+
+  ifile = g_object_new (IDE_TYPE_FILE,
+                        "file", file,
+                        "context", context,
+                        NULL);
+
+  ide_clang_service_get_translation_unit_async (service,
+                                                ifile,
+                                                0,
+                                                cancellable,
+                                                ide_clang_symbol_resolver_get_symbol_tree_cb,
+                                                g_object_ref (task));
+
+  IDE_EXIT;
+}
+
+static IdeSymbolTree *
+ide_clang_symbol_resolver_get_symbol_tree_finish (IdeSymbolResolver  *resolver,
+                                                  GAsyncResult       *result,
+                                                  GError            **error)
+{
+  IdeSymbolTree *ret;
+  GTask *task = (GTask *)result;
+
+  IDE_ENTRY;
+
+  g_return_val_if_fail (IDE_IS_CLANG_SYMBOL_RESOLVER (resolver), NULL);
+  g_return_val_if_fail (G_IS_TASK (task), NULL);
+
+  ret = g_task_propagate_pointer (task, error);
+
+  IDE_RETURN (ret);
+}
+
+static void
 ide_clang_symbol_resolver_class_init (IdeClangSymbolResolverClass *klass)
 {
   IdeSymbolResolverClass *symbol_resolver_class = IDE_SYMBOL_RESOLVER_CLASS (klass);
@@ -219,6 +329,8 @@ ide_clang_symbol_resolver_class_init (IdeClangSymbolResolverClass *klass)
   symbol_resolver_class->lookup_symbol_finish = ide_clang_symbol_resolver_lookup_symbol_finish;
   symbol_resolver_class->get_symbols_async = ide_clang_symbol_resolver_get_symbols_async;
   symbol_resolver_class->get_symbols_finish = ide_clang_symbol_resolver_get_symbols_finish;
+  symbol_resolver_class->get_symbol_tree_async = ide_clang_symbol_resolver_get_symbol_tree_async;
+  symbol_resolver_class->get_symbol_tree_finish = ide_clang_symbol_resolver_get_symbol_tree_finish;
 }
 
 static void
diff --git a/libide/clang/ide-clang-translation-unit.c b/libide/clang/ide-clang-translation-unit.c
index 98c6e60..9a59096 100644
--- a/libide/clang/ide-clang-translation-unit.c
+++ b/libide/clang/ide-clang-translation-unit.c
@@ -1052,3 +1052,42 @@ ide_clang_translation_unit_get_symbols (IdeClangTranslationUnit *self,
 
   return state.ar;
 }
+
+void
+ide_clang_translation_unit_get_symbol_tree_async (IdeClangTranslationUnit *self,
+                                                  GFile                   *file,
+                                                  GCancellable            *cancellable,
+                                                  GAsyncReadyCallback      callback,
+                                                  gpointer                 user_data)
+{
+  g_autoptr(GTask) task = NULL;
+
+  g_return_if_fail (IDE_IS_CLANG_TRANSLATION_UNIT (self));
+  g_return_if_fail (G_IS_FILE (file));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_task_data (task, g_object_ref (file), g_object_unref);
+
+  /*
+   * TODO: implement IdeClangSymbolTree
+   */
+
+  g_task_return_new_error (task,
+                           G_IO_ERROR,
+                           G_IO_ERROR_NOT_SUPPORTED,
+                           "Not yet supported");
+}
+
+IdeSymbolTree *
+ide_clang_translation_unit_get_symbol_tree_finish (IdeClangTranslationUnit  *self,
+                                                   GAsyncResult             *result,
+                                                   GError                  **error)
+{
+  GTask *task = (GTask *)result;
+
+  g_return_val_if_fail (IDE_IS_CLANG_TRANSLATION_UNIT (self), NULL);
+  g_return_val_if_fail (G_IS_TASK (task), NULL);
+
+  return g_task_propagate_pointer (task, error);
+}
diff --git a/libide/clang/ide-clang-translation-unit.h b/libide/clang/ide-clang-translation-unit.h
index 244307a..213734f 100644
--- a/libide/clang/ide-clang-translation-unit.h
+++ b/libide/clang/ide-clang-translation-unit.h
@@ -23,6 +23,7 @@
 
 #include "ide-object.h"
 #include "ide-highlight-index.h"
+#include "ide-symbol-tree.h"
 
 G_BEGIN_DECLS
 
@@ -43,6 +44,14 @@ void               ide_clang_translation_unit_code_complete_async      (IdeClang
 GPtrArray         *ide_clang_translation_unit_code_complete_finish     (IdeClangTranslationUnit  *self,
                                                                         GAsyncResult             *result,
                                                                         GError                  **error);
+void               ide_clang_translation_unit_get_symbol_tree_async    (IdeClangTranslationUnit  *self,
+                                                                        GFile                    *file,
+                                                                        GCancellable             
*cancellable,
+                                                                        GAsyncReadyCallback       callback,
+                                                                        gpointer                  user_data);
+IdeSymbolTree     *ide_clang_translation_unit_get_symbol_tree_finish   (IdeClangTranslationUnit  *self,
+                                                                        GAsyncResult             *result,
+                                                                        GError                  **error);
 IdeHighlightIndex *ide_clang_translation_unit_get_index                (IdeClangTranslationUnit  *self);
 IdeSymbol         *ide_clang_translation_unit_lookup_symbol            (IdeClangTranslationUnit  *self,
                                                                         IdeSourceLocation        *location,
diff --git a/libide/ide-symbol-node.c b/libide/ide-symbol-node.c
new file mode 100644
index 0000000..9e1b02a
--- /dev/null
+++ b/libide/ide-symbol-node.c
@@ -0,0 +1,178 @@
+/* ide-symbol-node.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#include <glib/gi18n.h>
+
+#include "ide-enums.h"
+#include "ide-symbol.h"
+#include "ide-symbol-node.h"
+
+typedef struct
+{
+  gchar          *name;
+  IdeSymbolFlags  flags;
+  IdeSymbolKind   kind;
+} IdeSymbolNodePrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (IdeSymbolNode, ide_symbol_node, G_TYPE_OBJECT)
+
+enum {
+  PROP_0,
+  PROP_FLAGS,
+  PROP_KIND,
+  PROP_NAME,
+  LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+static void
+ide_symbol_node_finalize (GObject *object)
+{
+  IdeSymbolNode *self = (IdeSymbolNode *)object;
+  IdeSymbolNodePrivate *priv = ide_symbol_node_get_instance_private (self);
+
+  g_clear_pointer (&priv->name, g_free);
+
+  G_OBJECT_CLASS (ide_symbol_node_parent_class)->finalize (object);
+}
+
+static void
+ide_symbol_node_get_property (GObject    *object,
+                              guint       prop_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+  IdeSymbolNode *self = IDE_SYMBOL_NODE (object);
+
+  switch (prop_id)
+    {
+    case PROP_NAME:
+      g_value_set_string (value, ide_symbol_node_get_name (self));
+      break;
+
+    case PROP_KIND:
+      g_value_set_enum (value, ide_symbol_node_get_kind (self));
+      break;
+
+    case PROP_FLAGS:
+      g_value_set_flags (value, ide_symbol_node_get_flags (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_symbol_node_set_property (GObject      *object,
+                              guint         prop_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+  IdeSymbolNode *self = IDE_SYMBOL_NODE (object);
+  IdeSymbolNodePrivate *priv = ide_symbol_node_get_instance_private (self);
+
+  switch (prop_id)
+    {
+    case PROP_NAME:
+      priv->name = g_value_dup_string (value);
+      break;
+
+    case PROP_KIND:
+      priv->kind = g_value_get_enum (value);
+      break;
+
+    case PROP_FLAGS:
+      priv->flags = g_value_get_flags (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_symbol_node_class_init (IdeSymbolNodeClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = ide_symbol_node_finalize;
+  object_class->get_property = ide_symbol_node_get_property;
+  object_class->set_property = ide_symbol_node_set_property;
+
+  gParamSpecs [PROP_NAME] =
+    g_param_spec_string ("name",
+                         _("Name"),
+                         _("Name"),
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  gParamSpecs [PROP_KIND] =
+    g_param_spec_enum ("kind",
+                       _("Kind"),
+                       _("Kind"),
+                       IDE_TYPE_SYMBOL_KIND,
+                       IDE_SYMBOL_NONE,
+                       (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  gParamSpecs [PROP_FLAGS] =
+    g_param_spec_flags ("flags",
+                        _("Flags"),
+                        _("Flags"),
+                        IDE_TYPE_SYMBOL_FLAGS,
+                        IDE_SYMBOL_FLAGS_NONE,
+                        (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+}
+
+static void
+ide_symbol_node_init (IdeSymbolNode *self)
+{
+}
+
+const gchar *
+ide_symbol_node_get_name (IdeSymbolNode *self)
+{
+  IdeSymbolNodePrivate *priv = ide_symbol_node_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_SYMBOL_NODE (self), NULL);
+
+  return priv->name;
+}
+
+IdeSymbolFlags
+ide_symbol_node_get_flags (IdeSymbolNode *self)
+{
+  IdeSymbolNodePrivate *priv = ide_symbol_node_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_SYMBOL_NODE (self), IDE_SYMBOL_FLAGS_NONE);
+
+  return priv->flags;
+}
+
+IdeSymbolKind
+ide_symbol_node_get_kind (IdeSymbolNode *self)
+{
+  IdeSymbolNodePrivate *priv = ide_symbol_node_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_SYMBOL_NODE (self), IDE_SYMBOL_NONE);
+
+  return priv->kind;
+}
diff --git a/libide/ide-symbol-node.h b/libide/ide-symbol-node.h
new file mode 100644
index 0000000..feb2afe
--- /dev/null
+++ b/libide/ide-symbol-node.h
@@ -0,0 +1,41 @@
+/* ide-symbol-node.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#ifndef IDE_SYMBOL_NODE_H
+#define IDE_SYMBOL_NODE_H
+
+#include "ide-symbol.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_SYMBOL_NODE (ide_symbol_node_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (IdeSymbolNode, ide_symbol_node, IDE, SYMBOL_NODE, GObject)
+
+struct _IdeSymbolNodeClass
+{
+  GObjectClass parent;
+};
+
+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);
+
+G_END_DECLS
+
+#endif /* IDE_SYMBOL_NODE_H */
diff --git a/libide/ide-symbol-resolver.c b/libide/ide-symbol-resolver.c
index 0bb0703..2e9cdda 100644
--- a/libide/ide-symbol-resolver.c
+++ b/libide/ide-symbol-resolver.c
@@ -114,3 +114,34 @@ ide_symbol_resolver_get_symbols_finish (IdeSymbolResolver  *self,
 
   return IDE_SYMBOL_RESOLVER_GET_CLASS (self)->get_symbols_finish (self, result, error);
 }
+
+void
+ide_symbol_resolver_get_symbol_tree_async (IdeSymbolResolver   *self,
+                                           GFile               *file,
+                                           GCancellable        *cancellable,
+                                           GAsyncReadyCallback  callback,
+                                           gpointer             user_data)
+{
+  g_return_if_fail (IDE_IS_SYMBOL_RESOLVER (self));
+  g_return_if_fail (G_IS_FILE (file));
+
+  IDE_SYMBOL_RESOLVER_GET_CLASS (self)->get_symbol_tree_async (self, file, cancellable, callback, user_data);
+}
+
+/**
+ * ide_symbol_resolver_get_symbol_tree_finish:
+ *
+ * Completes an asynchronous request to get the symbol tree for the requested file.
+ *
+ * Returns: (transfer full): An #IdeSymbolTree; otherwise %NULL and @error is set.
+ */
+IdeSymbolTree *
+ide_symbol_resolver_get_symbol_tree_finish (IdeSymbolResolver  *self,
+                                            GAsyncResult       *result,
+                                            GError            **error)
+{
+  g_return_val_if_fail (IDE_IS_SYMBOL_RESOLVER (self), NULL);
+  g_return_val_if_fail (!result || G_IS_ASYNC_RESULT (result), NULL);
+
+  return IDE_SYMBOL_RESOLVER_GET_CLASS (self)->get_symbol_tree_finish (self, result, error);
+}
diff --git a/libide/ide-symbol-resolver.h b/libide/ide-symbol-resolver.h
index 2eb1da3..00fefcd 100644
--- a/libide/ide-symbol-resolver.h
+++ b/libide/ide-symbol-resolver.h
@@ -21,6 +21,8 @@
 
 #include "ide-object.h"
 
+#include "ide-symbol-tree.h"
+
 G_BEGIN_DECLS
 
 #define IDE_TYPE_SYMBOL_RESOLVER (ide_symbol_resolver_get_type())
@@ -47,6 +49,15 @@ struct _IdeSymbolResolverClass
   GPtrArray *(*get_symbols_finish)   (IdeSymbolResolver    *self,
                                       GAsyncResult         *result,
                                       GError              **error);
+
+  void           (*get_symbol_tree_async)  (IdeSymbolResolver    *self,
+                                            GFile                *file,
+                                            GCancellable         *cancellable,
+                                            GAsyncReadyCallback   callback,
+                                            gpointer              user_data);
+  IdeSymbolTree *(*get_symbol_tree_finish) (IdeSymbolResolver    *self,
+                                            GAsyncResult         *result,
+                                            GError              **error);
 };
 
 void       ide_symbol_resolver_lookup_symbol_async  (IdeSymbolResolver    *self,
@@ -66,6 +77,15 @@ GPtrArray *ide_symbol_resolver_get_symbols_finish   (IdeSymbolResolver    *self,
                                                      GAsyncResult         *result,
                                                      GError              **error);
 
+void           ide_symbol_resolver_get_symbol_tree_async  (IdeSymbolResolver    *self,
+                                                           GFile                *file,
+                                                           GCancellable         *cancellable,
+                                                           GAsyncReadyCallback   callback,
+                                                           gpointer              user_data);
+IdeSymbolTree *ide_symbol_resolver_get_symbol_tree_finish (IdeSymbolResolver  *self,
+                                                           GAsyncResult       *result,
+                                                           GError            **error);
+
 G_END_DECLS
 
 #endif /* IDE_SYMBOL_RESOLVER_H */
diff --git a/libide/ide-symbol-tree.c b/libide/ide-symbol-tree.c
new file mode 100644
index 0000000..2836de2
--- /dev/null
+++ b/libide/ide-symbol-tree.c
@@ -0,0 +1,62 @@
+/* ide-symbol-tree.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#include "ide-symbol-tree.h"
+
+G_DEFINE_INTERFACE (IdeSymbolTree, ide_symbol_tree, G_TYPE_OBJECT)
+
+static void
+ide_symbol_tree_default_init (IdeSymbolTreeInterface *iface)
+{
+}
+
+/**
+ * ide_symbol_tree_get_n_children:
+ *
+ * Get the number of children of @node. If @node is NULL, the root node
+ * is assumed.
+ *
+ * Returns: An unsigned integer containing the number of children.
+ */
+guint
+ide_symbol_tree_get_n_children (IdeSymbolTree *self,
+                                IdeSymbolNode *node)
+{
+  g_return_val_if_fail (IDE_IS_SYMBOL_TREE (self), 0);
+  g_return_val_if_fail (!node || IDE_IS_SYMBOL_NODE (node), 0);
+
+  return IDE_SYMBOL_TREE_GET_IFACE (self)->get_n_children (self, node);
+}
+
+/**
+ * ide_symbol_tree_get_nth_child:
+ *
+ * Gets the @nth child node of @node.
+ *
+ * Returns: (transfer full) (nullable): A #IdeSymbolNode or %NULL.
+ */
+IdeSymbolNode *
+ide_symbol_tree_get_nth_child (IdeSymbolTree *self,
+                               IdeSymbolNode *node,
+                               guint          nth)
+{
+  g_return_val_if_fail (IDE_IS_SYMBOL_TREE (self), NULL);
+  g_return_val_if_fail (!node || IDE_IS_SYMBOL_NODE (node), NULL);
+
+  return IDE_SYMBOL_TREE_GET_IFACE (self)->get_nth_child (self, node, nth);
+}
diff --git a/libide/ide-symbol-tree.h b/libide/ide-symbol-tree.h
new file mode 100644
index 0000000..508d2bb
--- /dev/null
+++ b/libide/ide-symbol-tree.h
@@ -0,0 +1,51 @@
+/* ide-symbol-tree.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#ifndef IDE_SYMBOL_TREE_H
+#define IDE_SYMBOL_TREE_H
+
+#include <glib-object.h>
+
+#include "ide-symbol-node.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_SYMBOL_TREE (ide_symbol_tree_get_type ())
+
+G_DECLARE_INTERFACE (IdeSymbolTree, ide_symbol_tree, IDE, SYMBOL_TREE, GObject)
+
+struct _IdeSymbolTreeInterface
+{
+  GTypeInterface parent;
+
+  guint          (*get_n_children) (IdeSymbolTree *self,
+                                    IdeSymbolNode *node);
+  IdeSymbolNode *(*get_nth_child)  (IdeSymbolTree *self,
+                                    IdeSymbolNode *node,
+                                    guint          nth);
+};
+
+guint          ide_symbol_tree_get_n_children (IdeSymbolTree *self,
+                                               IdeSymbolNode *node);
+IdeSymbolNode *ide_symbol_tree_get_nth_child  (IdeSymbolTree *self,
+                                               IdeSymbolNode *node,
+                                               guint          nth);
+
+G_END_DECLS
+
+#endif /* IDE_SYMBOL_TREE_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]