[gnome-builder] clang: when diagnosing, prefer translation unit from .c over .h



commit 8969393ba0919e01598bf00ca997f8c08494e76e
Author: Christian Hergert <christian hergert me>
Date:   Wed Apr 1 00:55:43 2015 -0700

    clang: when diagnosing, prefer translation unit from .c over .h
    
    This should work for C++ as well, but has not yet been tested.
    Now, working on headers should be more useful since we'll use the
    translation unit for the .c file if it exists. This does have the
    caveat that your .c file needs to include the header. But it really
    isn't much worse than we have today, which is non-optimal.

 libide/clang/ide-clang-diagnostic-provider.c |   89 ++++++++++++++++++++++----
 1 files changed, 77 insertions(+), 12 deletions(-)
---
diff --git a/libide/clang/ide-clang-diagnostic-provider.c b/libide/clang/ide-clang-diagnostic-provider.c
index 42c0acc..f1121e1 100644
--- a/libide/clang/ide-clang-diagnostic-provider.c
+++ b/libide/clang/ide-clang-diagnostic-provider.c
@@ -23,6 +23,7 @@
 #include "ide-clang-translation-unit.h"
 #include "ide-context.h"
 #include "ide-diagnostics.h"
+#include "ide-file.h"
 
 G_DEFINE_TYPE (IdeClangDiagnosticProvider, ide_clang_diagnostic_provider,
                IDE_TYPE_DIAGNOSTIC_PROVIDER)
@@ -36,6 +37,8 @@ get_translation_unit_cb (GObject      *object,
   g_autoptr(IdeClangTranslationUnit) tu = NULL;
   g_autoptr(GTask) task = user_data;
   IdeDiagnostics *diagnostics;
+  IdeFile *target;
+  GFile *gfile;
   GError *error = NULL;
 
   tu = ide_clang_service_get_translation_unit_finish (service, result, &error);
@@ -46,40 +49,102 @@ get_translation_unit_cb (GObject      *object,
       return;
     }
 
-  diagnostics = ide_clang_translation_unit_get_diagnostics (tu);
+  target = g_task_get_task_data (task);
+  g_assert (IDE_IS_FILE (target));
+
+  gfile = ide_file_get_file (target);
+  g_assert (G_IS_FILE (gfile));
+
+  diagnostics = ide_clang_translation_unit_get_diagnostics_for_file (tu, gfile);
 
   g_task_return_pointer (task,
                          ide_diagnostics_ref (diagnostics),
                          (GDestroyNotify)ide_diagnostics_unref);
 }
 
+static gboolean
+is_header (IdeFile *file)
+{
+  const gchar *path;
+
+  g_assert (IDE_IS_FILE (file));
+
+  path = ide_file_get_path (file);
+
+  return (g_str_has_suffix (path, ".h") ||
+          g_str_has_suffix (path, ".hh") ||
+          g_str_has_suffix (path, ".hxx") ||
+          g_str_has_suffix (path, ".hpp"));
+}
+
 static void
-ide_clang_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
-                                              IdeFile               *file,
-                                              GCancellable          *cancellable,
-                                              GAsyncReadyCallback    callback,
-                                              gpointer               user_data)
+ide_clang_diagnostic_provider_diagnose__file_find_other_cb (GObject      *object,
+                                                            GAsyncResult *result,
+                                                            gpointer      user_data)
 {
-  IdeClangDiagnosticProvider *self = (IdeClangDiagnosticProvider *)provider;
-  g_autoptr(GTask) task = NULL;
+  IdeFile *file = (IdeFile *)object;
+  g_autoptr(IdeFile) other = NULL;
+  g_autoptr(GTask) task = user_data;
   IdeClangService *service;
   IdeContext *context;
 
-  g_return_if_fail (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (self));
+  g_assert (IDE_IS_FILE (file));
 
-  task = g_task_new (self, cancellable, callback, user_data);
+  other = ide_file_find_other_finish (file, result, NULL);
 
-  context = ide_object_get_context (IDE_OBJECT (provider));
+  if (other != NULL)
+    file = other;
+
+  context = ide_object_get_context (IDE_OBJECT (file));
   service = ide_context_get_service_typed (context, IDE_TYPE_CLANG_SERVICE);
 
   ide_clang_service_get_translation_unit_async (service,
                                                 file,
                                                 0,
-                                                cancellable,
+                                                g_task_get_cancellable (task),
                                                 get_translation_unit_cb,
                                                 g_object_ref (task));
 }
 
+static void
+ide_clang_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
+                                              IdeFile               *file,
+                                              GCancellable          *cancellable,
+                                              GAsyncReadyCallback    callback,
+                                              gpointer               user_data)
+{
+  IdeClangDiagnosticProvider *self = (IdeClangDiagnosticProvider *)provider;
+  g_autoptr(GTask) task = NULL;
+
+  g_return_if_fail (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (self));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_task_data (task, g_object_ref (file), g_object_unref);
+
+  if (is_header (file))
+    {
+      ide_file_find_other_async (file,
+                                 cancellable,
+                                 ide_clang_diagnostic_provider_diagnose__file_find_other_cb,
+                                 g_object_ref (task));
+    }
+  else
+    {
+      IdeClangService *service;
+      IdeContext *context;
+
+      context = ide_object_get_context (IDE_OBJECT (provider));
+      service = ide_context_get_service_typed (context, IDE_TYPE_CLANG_SERVICE);
+
+      ide_clang_service_get_translation_unit_async (service,
+                                                    file,
+                                                    0,
+                                                    cancellable,
+                                                    get_translation_unit_cb,
+                                                    g_object_ref (task));
+    }
+}
+
 static IdeDiagnostics *
 ide_clang_diagnostic_provider_diagnose_finish (IdeDiagnosticProvider  *provider,
                                                GAsyncResult           *result,


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