[gnome-builder/beautifier: 1/2] diagnostics-provider: fix unsaved file having diagnostics after save



commit 8d2ace5b64c874c2a3441025b1ced9d73ad7528b
Author: Sebastien Lafargue <slafargue gnome org>
Date:   Sat Nov 12 17:40:07 2016 +0100

    diagnostics-provider: fix unsaved file having diagnostics after save
    
    To reproduce:
    
    - create a new unsaved file with the new file button
    - save it with an extension (.c for example )
    
    It should get some diagnostics providers
    
    Things gets complicated by the fact that when saving it,
    the buffer:language and buffer:file properties both change,
    triggering notify events in the wrong order, that is
    the buffer:file change but notify:language is triggered
    before we get time to update to group_by_file table

 libide/buffers/ide-buffer-manager.c          |   15 ++++++-
 libide/diagnostics/ide-diagnostics-manager.c |   64 ++++++++++++++++++--------
 libide/diagnostics/ide-diagnostics-manager.h |    3 +
 libide/editor/ide-editor-view-actions.c      |    2 -
 4 files changed, 62 insertions(+), 22 deletions(-)
---
diff --git a/libide/buffers/ide-buffer-manager.c b/libide/buffers/ide-buffer-manager.c
index 098d2c4..eeeaf7c 100644
--- a/libide/buffers/ide-buffer-manager.c
+++ b/libide/buffers/ide-buffer-manager.c
@@ -30,6 +30,7 @@
 #include "buffers/ide-buffer-manager.h"
 #include "buffers/ide-buffer.h"
 #include "buffers/ide-unsaved-files.h"
+#include "diagnostics/ide-diagnostics-manager.h"
 #include "diagnostics/ide-source-location.h"
 #include "diagnostics/ide-source-range.h"
 #include "files/ide-file-settings.h"
@@ -926,8 +927,10 @@ ide_buffer_manager_save_file__save_cb (GObject      *object,
   IdeBufferManager *self;
   IdeUnsavedFiles *unsaved_files;
   IdeContext *context;
+  IdeDiagnosticsManager *diagnostics_manager;
   IdeFile *file;
   GFile *gfile;
+  GFile *old_gfile;
   SaveState *state;
   GError *error = NULL;
 
@@ -958,8 +961,16 @@ ide_buffer_manager_save_file__save_cb (GObject      *object,
   /* Remove the unsaved files state */
   context = ide_object_get_context (IDE_OBJECT (self));
   unsaved_files = ide_context_get_unsaved_files (context);
+  old_gfile = ide_file_get_file (file);
+  ide_unsaved_files_remove (unsaved_files, old_gfile);
+
+  /* Update the buffer and the diagnostics manager with the backing file
+   * so that there are in sync before signals and properties dispatch.
+   */
   gfile = ide_file_get_file (state->file);
-  ide_unsaved_files_remove (unsaved_files, gfile);
+  diagnostics_manager = ide_context_get_diagnostics_manager (context);
+  ide_diagnostics_manager_update_group_by_file (diagnostics_manager, state->buffer, gfile);
+  ide_buffer_set_file (state->buffer, state->file);
 
   /* Notify signal handlers that the file is saved */
   g_signal_emit (self, signals [BUFFER_SAVED], 0, state->buffer);
@@ -1408,6 +1419,7 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
    *
    * This signal is emitted when a request has been made to save a buffer. Connect to this signal
    * if you'd like to perform mutation of the buffer before it is persisted to storage.
+   * Till the "buffer-saved" signal is emmited, the buffer:file property point to the current file.
    */
   signals [SAVE_BUFFER] = g_signal_new ("save-buffer",
                                          G_TYPE_FROM_CLASS (klass),
@@ -1426,6 +1438,7 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
    * This signal is emitted when a buffer has finished saving to storage. You might connect to
    * this signal if you want to know when the modifications have successfully been written to
    * storage.
+   * The buffer:file property point to the saved file.
    */
   signals [BUFFER_SAVED] = g_signal_new ("buffer-saved",
                                           G_TYPE_FROM_CLASS (klass),
diff --git a/libide/diagnostics/ide-diagnostics-manager.c b/libide/diagnostics/ide-diagnostics-manager.c
index 6c1e16f..a078889 100644
--- a/libide/diagnostics/ide-diagnostics-manager.c
+++ b/libide/diagnostics/ide-diagnostics-manager.c
@@ -45,7 +45,7 @@ typedef struct
   /*
    * This is our identifier for the diagnostics. We use this as the key in
    * the hash table so that we can quickly find the target buffer. If the
-   * IdeBuffer:file property changes, we will have to fallback to a the
+   * IdeBuffer:file property changes, we will have to fallback to the
    * buffer to clear old entries.
    */
   GFile *file;
@@ -868,27 +868,34 @@ ide_diagnostics_manager_buffer_notify_language (IdeDiagnosticsManager *self,
   if (language != NULL)
     language_id = gtk_source_language_get_id (language);
   group = ide_diagnostics_manager_find_group_from_buffer (self, buffer);
-  ide_extension_set_adapter_set_value (group->adapter, language_id);
+  IdeFile *ifile;
+  GFile *gfile;
+
+  g_assert (IDE_IS_DIAGNOSTICS_MANAGER (self));
+  g_assert (IDE_IS_BUFFER (buffer));
+
+  ifile = ide_buffer_get_file (buffer);
+  gfile = ide_file_get_file (ifile);
+
+  if (group->adapter != NULL)
+    ide_extension_set_adapter_set_value (group->adapter, language_id);
 
   IDE_EXIT;
 }
 
-static void
-ide_diagnostics_manager_buffer_notify_file (IdeDiagnosticsManager *self,
-                                            GParamSpec            *pspec,
-                                            IdeBuffer             *buffer)
+void
+ide_diagnostics_manager_update_group_by_file (IdeDiagnosticsManager *self,
+                                              IdeBuffer             *buffer,
+                                              GFile                 *new_file)
 {
   GHashTableIter iter;
-  IdeFile *ifile;
-  GFile *gfile;
   gpointer value;
 
-  IDE_ENTRY;
-
   g_assert (IDE_IS_DIAGNOSTICS_MANAGER (self));
-  g_assert (pspec != NULL);
-  g_assert (g_str_equal (pspec->name, "file"));
   g_assert (IDE_IS_BUFFER (buffer));
+  g_assert (G_IS_FILE (new_file));
+
+  IDE_ENTRY;
 
   /*
    * The goal here is to steal the group that is in the hash table using
@@ -896,10 +903,6 @@ ide_diagnostics_manager_buffer_notify_file (IdeDiagnosticsManager *self,
    * the group from the hashtable, changing the file field, and then
    * reinserting with our new file key.
    */
-
-  ifile = ide_buffer_get_file (buffer);
-  gfile = ide_file_get_file (ifile);
-
   g_hash_table_iter_init (&iter, self->groups_by_file);
 
   while (g_hash_table_iter_next (&iter, NULL, &value))
@@ -909,9 +912,13 @@ ide_diagnostics_manager_buffer_notify_file (IdeDiagnosticsManager *self,
 
       if (buffer == group_buffer)
         {
-          g_hash_table_steal (self->groups_by_file, group->file);
-          g_set_object (&group->file, gfile);
-          g_hash_table_insert (self->groups_by_file, group->file, group);
+          if (!g_file_equal (new_file, group->file))
+            {
+              g_hash_table_steal (self->groups_by_file, group->file);
+              g_set_object (&group->file, new_file);
+              g_hash_table_insert (self->groups_by_file, group->file, group);
+            }
+
           IDE_EXIT;
         }
     }
@@ -922,6 +929,25 @@ ide_diagnostics_manager_buffer_notify_file (IdeDiagnosticsManager *self,
 }
 
 static void
+ide_diagnostics_manager_buffer_notify_file (IdeDiagnosticsManager *self,
+                                            GParamSpec            *pspec,
+                                            IdeBuffer             *buffer)
+{
+  IdeFile *ifile;
+  GFile *gfile;
+
+  g_assert (IDE_IS_DIAGNOSTICS_MANAGER (self));
+  g_assert (IDE_IS_BUFFER (buffer));
+  g_assert (pspec != NULL);
+  g_assert (g_str_equal (pspec->name, "file"));
+
+  ifile = ide_buffer_get_file (buffer);
+  gfile = ide_file_get_file (ifile);
+
+  ide_diagnostics_manager_update_group_by_file (self, buffer, gfile);
+}
+
+static void
 ide_diagnostics_manager_buffer_loaded (IdeDiagnosticsManager *self,
                                        IdeBuffer             *buffer,
                                        IdeBufferManager      *buffer_manager)
diff --git a/libide/diagnostics/ide-diagnostics-manager.h b/libide/diagnostics/ide-diagnostics-manager.h
index 19d5c4a..61b9be9 100644
--- a/libide/diagnostics/ide-diagnostics-manager.h
+++ b/libide/diagnostics/ide-diagnostics-manager.h
@@ -34,6 +34,9 @@ IdeDiagnostics *ide_diagnostics_manager_get_diagnostics_for_file (IdeDiagnostics
                                                                   GFile                 *file);
 guint           ide_diagnostics_manager_get_sequence_for_file    (IdeDiagnosticsManager *self,
                                                                   GFile                 *file);
+void            ide_diagnostics_manager_update_group_by_file     (IdeDiagnosticsManager *self,
+                                                                  IdeBuffer             *buffer,
+                                                                  GFile                 *new_file);
 
 G_END_DECLS
 
diff --git a/libide/editor/ide-editor-view-actions.c b/libide/editor/ide-editor-view-actions.c
index a54624b..f3de1c9 100644
--- a/libide/editor/ide-editor-view-actions.c
+++ b/libide/editor/ide-editor-view-actions.c
@@ -257,8 +257,6 @@ save_temp_response (GtkWidget *widget,
       buffer_manager = ide_context_get_buffer_manager (context);
       file = ide_project_get_project_file (project, target);
 
-      ide_buffer_set_file (buffer, file);
-
       ide_buffer_manager_save_file_async (buffer_manager,
                                           buffer,
                                           file,


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