[gnome-builder/wip/highlight] clang: generate a highlight index when parsing translation unit



commit d569c736224bded97ba68e63f13cfc2b0bb188ea
Author: Christian Hergert <christian hergert me>
Date:   Thu Mar 26 15:11:06 2015 -0700

    clang: generate a highlight index when parsing translation unit

 libide/clang/ide-clang-private.h          |    2 +
 libide/clang/ide-clang-service.c          |  114 ++++++++++++++++++++++++++++-
 libide/clang/ide-clang-service.h          |    2 +
 libide/clang/ide-clang-translation-unit.c |   50 ++++++++++++-
 libide/clang/ide-clang-translation-unit.h |    7 +-
 5 files changed, 171 insertions(+), 4 deletions(-)
---
diff --git a/libide/clang/ide-clang-private.h b/libide/clang/ide-clang-private.h
index 1ce5da4..334310f 100644
--- a/libide/clang/ide-clang-private.h
+++ b/libide/clang/ide-clang-private.h
@@ -25,12 +25,14 @@
 
 #include "ide-clang-service.h"
 #include "ide-clang-translation-unit.h"
+#include "ide-highlight-index.h"
 
 G_BEGIN_DECLS
 
 IdeClangTranslationUnit *_ide_clang_translation_unit_new (IdeContext        *context,
                                                           CXTranslationUnit  tu,
                                                           GFile             *file,
+                                                          IdeHighlightIndex *index,
                                                           gint64             sequence);
 
 G_END_DECLS
diff --git a/libide/clang/ide-clang-service.c b/libide/clang/ide-clang-service.c
index f840169..1633ffc 100644
--- a/libide/clang/ide-clang-service.c
+++ b/libide/clang/ide-clang-service.c
@@ -27,6 +27,7 @@
 #include "ide-context.h"
 #include "ide-debug.h"
 #include "ide-file.h"
+#include "ide-highlight-index.h"
 #include "ide-unsaved-file.h"
 #include "ide-unsaved-files.h"
 
@@ -51,6 +52,13 @@ typedef struct
   guint       options;
 } ParseRequest;
 
+typedef struct
+{
+  IdeHighlightIndex *index;
+  CXFile             file;
+  const gchar       *filename;
+} IndexRequest;
+
 G_DEFINE_TYPE (IdeClangService, ide_clang_service, IDE_TYPE_SERVICE)
 
 static void
@@ -65,6 +73,79 @@ parse_request_free (gpointer data)
   g_slice_free (ParseRequest, request);
 }
 
+static enum CXChildVisitResult
+ide_clang_service_build_index_visitor (CXCursor     cursor,
+                                       CXCursor     parent,
+                                       CXClientData user_data)
+{
+  IndexRequest *request = user_data;
+  enum CXCursorKind kind;
+  const gchar *word;
+  CXString cxstr;
+
+  g_assert (request != NULL);
+
+  kind = clang_getCursorKind (cursor);
+
+  switch (kind)
+    {
+    case CXCursor_TypedefDecl:
+    case CXCursor_TypeAliasDecl:
+      cxstr = clang_getCursorSpelling (cursor);
+      word = clang_getCString (cxstr);
+      ide_highlight_index_insert (request->index, word, IDE_HIGHLIGHT_KIND_TYPE_NAME);
+      break;
+
+    case CXCursor_FunctionDecl:
+      cxstr = clang_getCursorSpelling (cursor);
+      word = clang_getCString (cxstr);
+      ide_highlight_index_insert (request->index, word, IDE_HIGHLIGHT_KIND_FUNCTION_NAME);
+      break;
+
+    case CXCursor_MacroDefinition:
+    case CXCursor_MacroExpansion:
+      cxstr = clang_getCursorSpelling (cursor);
+      word = clang_getCString (cxstr);
+      ide_highlight_index_insert (request->index, word, IDE_HIGHLIGHT_KIND_MACRO_NAME);
+      break;
+
+    default:
+      break;
+    }
+
+  return CXChildVisit_Continue;
+}
+
+static IdeHighlightIndex *
+ide_clang_service_build_index (IdeClangService   *self,
+                               CXTranslationUnit  tu,
+                               ParseRequest      *request)
+{
+  IdeHighlightIndex *index;
+  IndexRequest client_data;
+  CXCursor cursor;
+  CXFile file;
+
+  g_assert (IDE_IS_CLANG_SERVICE (self));
+  g_assert (tu != NULL);
+  g_assert (request != NULL);
+
+  file = clang_getFile (tu, request->source_filename);
+  if (file == NULL)
+    return NULL;
+
+  index = ide_highlight_index_new ();
+
+  client_data.index = index;
+  client_data.file = file;
+  client_data.filename = request->source_filename;
+
+  cursor = clang_getTranslationUnitCursor (tu);
+  clang_visitChildren (cursor, ide_clang_service_build_index_visitor, &client_data);
+
+  return index;
+}
+
 static void
 ide_clang_service_parse_worker (GTask        *task,
                                 gpointer      source_object,
@@ -72,6 +153,7 @@ ide_clang_service_parse_worker (GTask        *task,
                                 GCancellable *cancellable)
 {
   g_autoptr(IdeClangTranslationUnit) ret = NULL;
+  g_autoptr(IdeHighlightIndex) index = NULL;
   IdeClangService *self = source_object;
   CXTranslationUnit tu = NULL;
   ParseRequest *request = task_data;
@@ -121,6 +203,10 @@ ide_clang_service_parse_worker (GTask        *task,
   switch (code)
     {
     case CXError_Success:
+      index = ide_clang_service_build_index (self, tu, request);
+#ifndef IDE_DISABLE_TRACE
+      ide_highlight_index_dump (index);
+#endif
       break;
 
     case CXError_Failure:
@@ -155,7 +241,7 @@ ide_clang_service_parse_worker (GTask        *task,
 
   context = ide_object_get_context (source_object);
   gfile = ide_file_get_file (request->file);
-  ret = _ide_clang_translation_unit_new (context, tu, gfile, request->sequence);
+  ret = _ide_clang_translation_unit_new (context, tu, gfile, index, request->sequence);
 
   g_rw_lock_writer_lock (&self->cached_rwlock);
   g_hash_table_replace (self->cached_units,
@@ -382,3 +468,29 @@ ide_clang_service_init (IdeClangService *self)
                                               g_object_unref,
                                               g_object_unref);
 }
+
+/**
+ * ide_clang_service_get_cached_translation_unit:
+ * @self: A #IdeClangService.
+ *
+ * Gets a cached translation unit if one exists for the file.
+ *
+ * Returns: (transfer full) (nullable): An #IdeClangTranslationUnit or %NULL.
+ */
+IdeClangTranslationUnit *
+ide_clang_service_get_cached_translation_unit (IdeClangService *self,
+                                               IdeFile         *file)
+{
+  IdeClangTranslationUnit *cached;
+
+  g_return_val_if_fail (IDE_IS_CLANG_SERVICE (self), NULL);
+  g_return_val_if_fail (IDE_IS_FILE (file), NULL);
+
+  g_rw_lock_reader_lock (&self->cached_rwlock);
+  cached = g_hash_table_lookup (self->cached_units, file);
+  if (cached)
+    g_object_ref (cached);
+  g_rw_lock_reader_unlock (&self->cached_rwlock);
+
+  return cached;
+}
diff --git a/libide/clang/ide-clang-service.h b/libide/clang/ide-clang-service.h
index 8d75d72..a7046bc 100644
--- a/libide/clang/ide-clang-service.h
+++ b/libide/clang/ide-clang-service.h
@@ -38,6 +38,8 @@ void                     ide_clang_service_get_translation_unit_async  (IdeClang
 IdeClangTranslationUnit *ide_clang_service_get_translation_unit_finish (IdeClangService      *self,
                                                                         GAsyncResult         *result,
                                                                         GError              **error);
+IdeClangTranslationUnit *ide_clang_service_get_cached_translation_unit (IdeClangService      *self,
+                                                                        IdeFile              *file);
 
 G_END_DECLS
 
diff --git a/libide/clang/ide-clang-translation-unit.c b/libide/clang/ide-clang-translation-unit.c
index 07637ed..d08f1ce 100644
--- a/libide/clang/ide-clang-translation-unit.c
+++ b/libide/clang/ide-clang-translation-unit.c
@@ -21,6 +21,7 @@
 
 #include "ide-context.h"
 #include "ide-clang-completion-item.h"
+#include "ide-clang-private.h"
 #include "ide-clang-translation-unit.h"
 #include "ide-diagnostic.h"
 #include "ide-diagnostics.h"
@@ -41,6 +42,7 @@ struct _IdeClangTranslationUnit
   gint64             sequence;
   IdeDiagnostics    *diagnostics;
   GFile             *file;
+  IdeHighlightIndex *index;
 };
 
 typedef struct
@@ -56,6 +58,7 @@ G_DEFINE_TYPE (IdeClangTranslationUnit, ide_clang_translation_unit, IDE_TYPE_OBJ
 enum {
   PROP_0,
   PROP_FILE,
+  PROP_INDEX,
   PROP_SEQUENCE,
   LAST_PROP
 };
@@ -75,6 +78,32 @@ code_complete_state_free (gpointer data)
     }
 }
 
+/**
+ * ide_clang_translation_unit_get_index:
+ * @self: A #IdeClangTranslationUnit.
+ *
+ * Gets the highlight index for the translation unit.
+ *
+ * Returns: (transfer none) (nullable): An #IdeHighlightIndex or %NULL.
+ */
+IdeHighlightIndex *
+ide_clang_translation_unit_get_index (IdeClangTranslationUnit *self)
+{
+  g_return_val_if_fail (IDE_IS_CLANG_TRANSLATION_UNIT (self), NULL);
+
+  return self->index;
+}
+
+static void
+ide_clang_translation_unit_set_index (IdeClangTranslationUnit *self,
+                                      IdeHighlightIndex       *index)
+{
+  g_assert (IDE_IS_CLANG_TRANSLATION_UNIT (self));
+
+  if (index != NULL)
+    self->index = ide_highlight_index_ref (index);
+}
+
 GFile *
 ide_clang_translation_unit_get_file (IdeClangTranslationUnit *self)
 {
@@ -98,6 +127,7 @@ IdeClangTranslationUnit *
 _ide_clang_translation_unit_new (IdeContext        *context,
                                  CXTranslationUnit  tu,
                                  GFile             *file,
+                                 IdeHighlightIndex *index,
                                  gint64             sequence)
 {
   IdeClangTranslationUnit *ret;
@@ -107,8 +137,9 @@ _ide_clang_translation_unit_new (IdeContext        *context,
   g_return_val_if_fail (!file || G_IS_FILE (file), NULL);
 
   ret = g_object_new (IDE_TYPE_CLANG_TRANSLATION_UNIT,
-                      "file", file,
                       "context", context,
+                      "file", file,
+                      "index", index,
                       NULL);
 
   ret->tu = tu;
@@ -413,6 +444,7 @@ ide_clang_translation_unit_finalize (GObject *object)
   clang_disposeTranslationUnit (self->tu);
   g_clear_pointer (&self->diagnostics, ide_diagnostics_unref);
   g_clear_object (&self->file);
+  g_clear_pointer (&self->index, ide_highlight_index_unref);
 
   G_OBJECT_CLASS (ide_clang_translation_unit_parent_class)->finalize (object);
 }
@@ -431,6 +463,10 @@ ide_clang_translation_unit_get_property (GObject    *object,
       g_value_set_object (value, ide_clang_translation_unit_get_file (self));
       break;
 
+    case PROP_INDEX:
+      g_value_set_boxed (value, ide_clang_translation_unit_get_index (self));
+      break;
+
     case PROP_SEQUENCE:
       g_value_set_int64 (value, ide_clang_translation_unit_get_sequence (self));
       break;
@@ -454,6 +490,10 @@ ide_clang_translation_unit_set_property (GObject      *object,
       ide_clang_translation_unit_set_file (self, g_value_get_object (value));
       break;
 
+    case PROP_INDEX:
+      ide_clang_translation_unit_set_index (self, g_value_get_boxed (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -476,6 +516,14 @@ ide_clang_translation_unit_class_init (IdeClangTranslationUnitClass *klass)
                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (object_class, PROP_FILE, gParamSpecs [PROP_FILE]);
 
+  gParamSpecs [PROP_INDEX] =
+    g_param_spec_boxed ("index",
+                         _("Index"),
+                         _("The highlight index for the translation unit."),
+                         IDE_TYPE_HIGHLIGHT_INDEX,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_INDEX, gParamSpecs [PROP_INDEX]);
+
   gParamSpecs [PROP_SEQUENCE] =
     g_param_spec_int64 ("sequence",
                         _("Sequence"),
diff --git a/libide/clang/ide-clang-translation-unit.h b/libide/clang/ide-clang-translation-unit.h
index 4d59c9c..4b9cad2 100644
--- a/libide/clang/ide-clang-translation-unit.h
+++ b/libide/clang/ide-clang-translation-unit.h
@@ -19,10 +19,11 @@
 #ifndef IDE_CLANG_TRANSLATION_UNIT_H
 #define IDE_CLANG_TRANSLATION_UNIT_H
 
-#include "ide-object.h"
-
 #include <gtk/gtk.h>
 
+#include "ide-object.h"
+#include "ide-highlight-index.h"
+
 G_BEGIN_DECLS
 
 #define IDE_TYPE_CLANG_TRANSLATION_UNIT (ide_clang_translation_unit_get_type())
@@ -40,6 +41,8 @@ void            ide_clang_translation_unit_code_complete_async  (IdeClangTransla
 GPtrArray      *ide_clang_translation_unit_code_complete_finish (IdeClangTranslationUnit  *self,
                                                                  GAsyncResult             *result,
                                                                  GError                  **error);
+IdeHighlightIndex *
+                ide_clang_translation_unit_get_index            (IdeClangTranslationUnit  *self);
 
 G_END_DECLS
 


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