[gnome-builder/wip/gtk4-port] plugins/clang: use load/unload to avoid service lookup for diagnostics



commit 9db7daea233cf41184cfbb24939af6835b020090
Author: Christian Hergert <chergert redhat com>
Date:   Tue Apr 26 14:22:54 2022 -0700

    plugins/clang: use load/unload to avoid service lookup for diagnostics
    
    This does what we did for the symbol resolver, but for the diagnostic
    provider as well. It can save a bunch of runtime warnings when the whole
    project is torn down during active operations.

 src/plugins/clang/ide-clang-diagnostic-provider.c | 98 ++++++++++++++++++++---
 1 file changed, 86 insertions(+), 12 deletions(-)
---
diff --git a/src/plugins/clang/ide-clang-diagnostic-provider.c 
b/src/plugins/clang/ide-clang-diagnostic-provider.c
index b7f6a2ed0..2c553cd94 100644
--- a/src/plugins/clang/ide-clang-diagnostic-provider.c
+++ b/src/plugins/clang/ide-clang-diagnostic-provider.c
@@ -31,9 +31,32 @@
 
 struct _IdeClangDiagnosticProvider
 {
-  IdeObject parent_instance;
+  IdeObject       parent_instance;
+  IdeBuildSystem *build_system;
+  IdeClangClient *client;
 };
 
+static gboolean
+ide_clang_diagnostic_provider_check_status (IdeClangDiagnosticProvider *self,
+                                            IdeTask                    *task)
+{
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (self));
+  g_assert (IDE_IS_TASK (task));
+
+  if (self->client == NULL || self->build_system == NULL)
+    {
+      ide_task_return_new_error (task,
+                                 G_IO_ERROR,
+                                 G_IO_ERROR_CANCELLED,
+                                 "Operation cancelled");
+      IDE_RETURN (FALSE);
+    }
+
+  IDE_RETURN (TRUE);
+}
+
 static void
 ide_clang_diagnostic_provider_diagnose_cb (GObject      *object,
                                            GAsyncResult *result,
@@ -67,10 +90,10 @@ diagnose_get_build_flags_cb (GObject      *object,
 {
   IdeBuildSystem *build_system = (IdeBuildSystem *)object;
   g_autoptr(IdeTask) task = user_data;
-  g_autoptr(IdeClangClient) client = NULL;
+  g_autoptr(GError) error = NULL;
   g_auto(GStrv) flags = NULL;
+  IdeClangDiagnosticProvider *self;
   GCancellable *cancellable;
-  IdeContext *context;
   GFile *file;
 
   IDE_ENTRY;
@@ -79,13 +102,27 @@ diagnose_get_build_flags_cb (GObject      *object,
   g_assert (G_IS_ASYNC_RESULT (result));
   g_assert (IDE_IS_TASK (task));
 
-  flags = ide_build_system_get_build_flags_finish (build_system, result, NULL);
-  context = ide_object_get_context (IDE_OBJECT (build_system));
-  client = ide_object_ensure_child_typed (IDE_OBJECT (context), IDE_TYPE_CLANG_CLIENT);
+  self = ide_task_get_source_object (task);
   file = ide_task_get_task_data (task);
   cancellable = ide_task_get_cancellable (task);
 
-  ide_clang_client_diagnose_async (client,
+  g_assert (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (self));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+  g_assert (!file || G_IS_FILE (file));
+
+  if (!(flags = ide_build_system_get_build_flags_finish (build_system, result, &error)))
+    {
+      if (!ide_error_ignore (error))
+        {
+          ide_task_return_error (task, g_steal_pointer (&error));
+          IDE_EXIT;
+        }
+    }
+
+  if (!ide_clang_diagnostic_provider_check_status (self, task))
+    IDE_EXIT;
+
+  ide_clang_client_diagnose_async (self->client,
                                    file,
                                    (const gchar * const *)flags,
                                    cancellable,
@@ -106,8 +143,6 @@ ide_clang_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
 {
   IdeClangDiagnosticProvider *self = (IdeClangDiagnosticProvider *)provider;
   g_autoptr(IdeTask) task = NULL;
-  IdeBuildSystem *build_system;
-  IdeContext *context;
 
   IDE_ENTRY;
 
@@ -118,10 +153,10 @@ ide_clang_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
   ide_task_set_task_data (task, g_object_ref (file), g_object_unref);
   ide_task_set_kind (task, IDE_TASK_KIND_COMPILER);
 
-  context = ide_object_get_context (IDE_OBJECT (self));
-  build_system = ide_build_system_from_context (context);
+  if (!ide_clang_diagnostic_provider_check_status (self, task))
+    IDE_EXIT;
 
-  ide_build_system_get_build_flags_async (build_system,
+  ide_build_system_get_build_flags_async (self->build_system,
                                           file,
                                           cancellable,
                                           diagnose_get_build_flags_cb,
@@ -147,9 +182,48 @@ ide_clang_diagnostic_provider_diagnose_finish (IdeDiagnosticProvider  *provider,
   IDE_RETURN (ret);
 }
 
+static void
+ide_clang_diagnostic_provider_load (IdeDiagnosticProvider *provider)
+{
+  IdeClangDiagnosticProvider *self = (IdeClangDiagnosticProvider *)provider;
+  IdeBuildSystem *build_system;
+  IdeClangClient *client;
+  IdeContext *context;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (self));
+
+  context = ide_object_get_context (IDE_OBJECT (self));
+  client = ide_object_ensure_child_typed (IDE_OBJECT (context), IDE_TYPE_CLANG_CLIENT);
+  build_system = ide_build_system_from_context (context);
+
+  g_set_object (&self->client, client);
+  g_set_object (&self->build_system, build_system);
+
+  IDE_EXIT;
+}
+
+static void
+ide_clang_diagnostic_provider_unload (IdeDiagnosticProvider *provider)
+{
+  IdeClangDiagnosticProvider *self = (IdeClangDiagnosticProvider *)provider;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (self));
+
+  g_clear_object (&self->client);
+  g_clear_object (&self->build_system);
+
+  IDE_EXIT;
+}
+
 static void
 diagnostic_provider_iface_init (IdeDiagnosticProviderInterface *iface)
 {
+  iface->load = ide_clang_diagnostic_provider_load;
+  iface->unload = ide_clang_diagnostic_provider_unload;
   iface->diagnose_async = ide_clang_diagnostic_provider_diagnose_async;
   iface->diagnose_finish = ide_clang_diagnostic_provider_diagnose_finish;
 }


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