[gnome-builder] clang: add very simple IdeClangSymboProvider



commit da3113fd458c001ad2bce92f398316ff57dad88b
Author: Christian Hergert <christian hergert me>
Date:   Fri Mar 27 03:24:45 2015 -0700

    clang: add very simple IdeClangSymboProvider
    
    Nothing fancy yet, doesn't even attach the source location to the
    symbol instance.

 libide/clang/ide-clang-symbol-resolver.c  |  101 +++++++++++++++++++++++++++++
 libide/clang/ide-clang-translation-unit.c |   47 +++++++++++++
 libide/clang/ide-clang-translation-unit.h |    3 +
 3 files changed, 151 insertions(+), 0 deletions(-)
---
diff --git a/libide/clang/ide-clang-symbol-resolver.c b/libide/clang/ide-clang-symbol-resolver.c
index 963d60c..34b2876 100644
--- a/libide/clang/ide-clang-symbol-resolver.c
+++ b/libide/clang/ide-clang-symbol-resolver.c
@@ -16,7 +16,14 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#define G_LOG_DOMAIN "clang-symbol-resolver"
+
+#include "ide-context.h"
+#include "ide-clang-service.h"
 #include "ide-clang-symbol-resolver.h"
+#include "ide-debug.h"
+#include "ide-source-location.h"
+#include "ide-symbol.h"
 
 struct _IdeClangSymbolResolver
 {
@@ -26,8 +33,102 @@ struct _IdeClangSymbolResolver
 G_DEFINE_TYPE (IdeClangSymbolResolver, ide_clang_symbol_resolver, IDE_TYPE_SYMBOL_RESOLVER)
 
 static void
+ide_clang_symbol_resolver_lookup_symbol_cb (GObject      *object,
+                                            GAsyncResult *result,
+                                            gpointer      user_data)
+{
+  IdeClangService *service = (IdeClangService *)object;
+  g_autoptr(IdeClangTranslationUnit) unit = NULL;
+  g_autoptr(GTask) task = user_data;
+  g_autoptr(IdeSymbol) symbol = NULL;
+  IdeSourceLocation *location;
+  GError *error = NULL;
+
+  g_assert (IDE_IS_CLANG_SERVICE (service));
+  g_assert (G_IS_TASK (task));
+
+  location = g_task_get_task_data (task);
+
+  unit = ide_clang_service_get_translation_unit_finish (service, result, &error);
+
+  if (unit == NULL)
+    {
+      g_task_return_error (task, error);
+      return;
+    }
+
+  symbol = ide_clang_translation_unit_lookup_symbol (unit, location, &error);
+
+  if (symbol == NULL)
+    {
+      g_task_return_error (task, error);
+      return;
+    }
+
+  g_task_return_pointer (task, ide_symbol_ref (symbol), (GDestroyNotify)ide_symbol_unref);
+}
+
+static void
+ide_clang_symbol_resolver_lookup_symbol_async (IdeSymbolResolver   *resolver,
+                                               IdeSourceLocation   *location,
+                                               GCancellable        *cancellable,
+                                               GAsyncReadyCallback  callback,
+                                               gpointer             user_data)
+{
+  IdeClangSymbolResolver *self = (IdeClangSymbolResolver *)resolver;
+  IdeClangService *service = NULL;
+  IdeContext *context;
+  IdeFile *file;
+  g_autoptr(GTask) task = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_CLANG_SYMBOL_RESOLVER (self));
+  g_assert (location != NULL);
+
+  context = ide_object_get_context (IDE_OBJECT (self));
+  service = ide_context_get_service_typed (context, IDE_TYPE_CLANG_SERVICE);
+  file = ide_source_location_get_file (location);
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_task_data (task, ide_source_location_ref (location),
+                        (GDestroyNotify)ide_source_location_unref);
+
+  ide_clang_service_get_translation_unit_async (service,
+                                                file,
+                                                0,
+                                                cancellable,
+                                                ide_clang_symbol_resolver_lookup_symbol_cb,
+                                                g_object_ref (task));
+
+  IDE_EXIT;
+}
+
+static IdeSymbol *
+ide_clang_symbol_resolver_lookup_symbol_finish (IdeSymbolResolver  *resolver,
+                                                GAsyncResult       *result,
+                                                GError            **error)
+{
+  IdeSymbol *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);
+
+  symbol_resolver_class->lookup_symbol_async = ide_clang_symbol_resolver_lookup_symbol_async;
+  symbol_resolver_class->lookup_symbol_finish = ide_clang_symbol_resolver_lookup_symbol_finish;
 }
 
 static void
diff --git a/libide/clang/ide-clang-translation-unit.c b/libide/clang/ide-clang-translation-unit.c
index 9e84ab1..c69ab2d 100644
--- a/libide/clang/ide-clang-translation-unit.c
+++ b/libide/clang/ide-clang-translation-unit.c
@@ -707,3 +707,50 @@ ide_clang_translation_unit_code_complete_finish (IdeClangTranslationUnit  *self,
 
   return g_task_propagate_pointer (task, error);
 }
+
+IdeSymbol *
+ide_clang_translation_unit_lookup_symbol (IdeClangTranslationUnit  *self,
+                                          IdeSourceLocation        *location,
+                                          GError                  **error)
+{
+  g_autofree gchar *filename = NULL;
+  g_auto(CXString) cxstr = { 0 };
+  CXSourceLocation cxlocation;
+  CXCursor cursor;
+  CXFile cxfile;
+  IdeSymbol *ret = NULL;
+  IdeFile *file;
+  GFile *gfile;
+  guint line;
+  guint line_offset;
+
+  IDE_ENTRY;
+
+  g_return_val_if_fail (IDE_IS_CLANG_TRANSLATION_UNIT (self), NULL);
+  g_return_val_if_fail (location != NULL, NULL);
+
+  line = ide_source_location_get_line (location);
+  line_offset = ide_source_location_get_line_offset (location);
+
+  if (!(file = ide_source_location_get_file (location)) ||
+      !(gfile = ide_file_get_file (file)) ||
+      !(filename = g_file_get_path (gfile)) ||
+      !(cxfile = clang_getFile (self->tu, filename)))
+    IDE_RETURN (NULL);
+
+  cxlocation = clang_getLocation (self->tu, cxfile, line + 1, line_offset + 1);
+
+  cursor = clang_getCursor (self->tu, cxlocation);
+  if (clang_Cursor_isNull (cursor))
+    IDE_RETURN (NULL);
+
+  cxstr = clang_getCursorDisplayName (cursor);
+  ret = _ide_symbol_new (clang_getCString (cxstr));
+
+  /*
+   * TODO: We should also get information about the defintion of the symbol.
+   *       Possibly more.
+   */
+
+  IDE_RETURN (ret);
+}
diff --git a/libide/clang/ide-clang-translation-unit.h b/libide/clang/ide-clang-translation-unit.h
index 4b9cad2..3eb8286 100644
--- a/libide/clang/ide-clang-translation-unit.h
+++ b/libide/clang/ide-clang-translation-unit.h
@@ -43,6 +43,9 @@ GPtrArray      *ide_clang_translation_unit_code_complete_finish (IdeClangTransla
                                                                  GError                  **error);
 IdeHighlightIndex *
                 ide_clang_translation_unit_get_index            (IdeClangTranslationUnit  *self);
+IdeSymbol      *ide_clang_translation_unit_lookup_symbol        (IdeClangTranslationUnit  *self,
+                                                                 IdeSourceLocation        *location,
+                                                                 GError                  **error);
 
 G_END_DECLS
 


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