[gnome-builder] buildsystem: Allow fetching flags for multiple files together



commit 1d32646d50bbba3e72e33b9aa630c418cb0cad8a
Author: Anoop Chandu <anoopchandu96 gmail com>
Date:   Fri Aug 18 04:53:44 2017 +0530

    buildsystem: Allow fetching flags for multiple files together
    
    Using get_build_flags_for_files in IdeBuildSystem, build flags for multiple
    files can be retrieved at a time.
    
    Build systems can implement this optimize their parsing and lookup of flags
    which can have a performance impact on features such as the code indexing
    engine.
    
    If a build system does not implement this feature, a fallback is provided to
    lookup flags individually using get_build_flags_async().

 libide/buildsystem/ide-build-system.c |  156 ++++++++++++++++++++++++++++++++-
 libide/buildsystem/ide-build-system.h |  112 ++++++++++++++----------
 2 files changed, 219 insertions(+), 49 deletions(-)
---
diff --git a/libide/buildsystem/ide-build-system.c b/libide/buildsystem/ide-build-system.c
index d17f736..a548811 100644
--- a/libide/buildsystem/ide-build-system.c
+++ b/libide/buildsystem/ide-build-system.c
@@ -36,8 +36,23 @@ enum {
   N_PROPS
 };
 
+typedef struct
+{
+  GPtrArray   *files;
+  GHashTable  *flags;
+  gsize        index;
+} GetBuildFlagsData;
+
 static GParamSpec *properties [N_PROPS];
 
+static void
+get_build_flags_data_free (GetBuildFlagsData *data)
+{
+  g_clear_pointer (&data->files, g_ptr_array_unref);
+  g_clear_pointer (&data->flags, g_hash_table_unref);
+  g_slice_free (GetBuildFlagsData, data);
+}
+
 gint
 ide_build_system_get_priority (IdeBuildSystem *self)
 {
@@ -78,6 +93,91 @@ ide_build_system_real_get_build_flags_finish (IdeBuildSystem  *self,
 }
 
 static void
+get_build_flags_cb (GObject      *object,
+                    GAsyncResult *result,
+                    gpointer      user_data)
+{
+  IdeBuildSystem *self = (IdeBuildSystem *)object;
+  g_auto(GStrv) flags = NULL;
+  g_autoptr(GError) error = NULL;
+  g_autoptr(GTask) task = user_data;
+  GetBuildFlagsData *data;
+
+  g_assert (IDE_IS_BUILD_SYSTEM (self));
+  g_assert (G_IS_TASK (task));
+
+  flags = ide_build_system_get_build_flags_finish (self, result, &error);
+
+  data = g_task_get_task_data (task);
+
+  if (flags != NULL)
+    g_hash_table_insert (data->flags,
+                         g_object_ref (g_ptr_array_index (data->files, data->index)),
+                         g_steal_pointer (&flags));
+
+  data->index++;
+
+  if (data->index < data->files->len)
+    {
+      GCancellable *cancellable;
+
+      cancellable = g_task_get_cancellable (task);
+
+      ide_build_system_get_build_flags_async (self,
+                                              g_ptr_array_index (data->files, data->index),
+                                              cancellable,
+                                              get_build_flags_cb,
+                                              g_steal_pointer (&task));
+    }
+  else
+    {
+      g_task_return_pointer (task,
+                             g_steal_pointer (&data->flags),
+                             (GDestroyNotify)g_hash_table_unref);
+    }
+}
+
+static void
+ide_build_system_real_get_build_flags_for_files_async (IdeBuildSystem       *self,
+                                                       GPtrArray            *files,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data)
+{
+  g_autoptr(GTask) task = NULL;
+  GetBuildFlagsData *data;
+
+  g_return_if_fail (IDE_IS_BUILD_SYSTEM (self));
+  g_return_if_fail (files != NULL);
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+
+  data = g_slice_new0 (GetBuildFlagsData);
+  data->files = g_ptr_array_ref (files);
+  data->flags = g_hash_table_new_full ((GHashFunc)ide_file_hash,
+                                       (GEqualFunc)ide_file_equal,
+                                       g_object_unref,
+                                       (GDestroyNotify)g_strfreev);
+
+  g_task_set_task_data (task, data, (GDestroyNotify)get_build_flags_data_free);
+
+  ide_build_system_get_build_flags_async (self,
+                                          g_ptr_array_index (files, 0),
+                                          cancellable,
+                                          get_build_flags_cb,
+                                          g_steal_pointer (&task));
+}
+
+static GHashTable *
+ide_build_system_real_get_build_flags_for_files_finish (IdeBuildSystem       *self,
+                                                        GAsyncResult         *result,
+                                                        GError              **error)
+{
+  return g_task_propagate_pointer (G_TASK (result), error);
+}
+
+static void
 ide_build_system_real_get_build_targets_async (IdeBuildSystem      *self,
                                                GCancellable        *cancellable,
                                                GAsyncReadyCallback  callback,
@@ -105,7 +205,8 @@ ide_build_system_default_init (IdeBuildSystemInterface *iface)
 {
   iface->get_build_flags_async = ide_build_system_real_get_build_flags_async;
   iface->get_build_flags_finish = ide_build_system_real_get_build_flags_finish;
-  iface->get_build_targets_finish = ide_build_system_real_get_build_targets_finish;
+  iface->get_build_flags_for_files_async = ide_build_system_real_get_build_flags_for_files_async;
+  iface->get_build_flags_for_files_finish = ide_build_system_real_get_build_flags_for_files_finish;
   iface->get_build_targets_async = ide_build_system_real_get_build_targets_async;
   iface->get_build_targets_finish = ide_build_system_real_get_build_targets_finish;
 
@@ -259,6 +360,59 @@ ide_build_system_get_build_flags_finish (IdeBuildSystem  *self,
   IDE_RETURN (ret);
 }
 
+/**
+ * ide_build_system_get_build_flags_for_files_async:
+ * @self: An #IdeBuildSystem instance.
+ * @files: (element-type Ide.File): array of files whose build flags has to be retrieved.
+ * @cancellable: (allow-none): A #GCancellable to cancel getting build flags.
+ * @callback: function to be called after getting build flags.
+ * @user_data: data to pass to @callback.
+ *
+ * This function will get build flags for all files and returns
+ * map of file and its build flags as #GHashTable.
+ */
+void
+ide_build_system_get_build_flags_for_files_async (IdeBuildSystem       *self,
+                                                  GPtrArray            *files,
+                                                  GCancellable         *cancellable,
+                                                  GAsyncReadyCallback   callback,
+                                                  gpointer              user_data)
+{
+  IDE_ENTRY;
+
+  g_return_if_fail (IDE_IS_BUILD_SYSTEM (self));
+  g_return_if_fail ( files != NULL);
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  IDE_BUILD_SYSTEM_GET_IFACE (self)->
+      get_build_flags_for_files_async (self, files, cancellable, callback, user_data);
+
+  IDE_EXIT;
+}
+
+/**
+ * ide_build_system_get_build_flags_for_files_finish:
+ *
+ * Returns: (transfer full): Returns #GHashTable which has a map
+ *   of files and its build flags.
+ */
+GHashTable *
+ide_build_system_get_build_flags_for_files_finish (IdeBuildSystem       *self,
+                                                   GAsyncResult         *result,
+                                                   GError              **error)
+{
+  GHashTable *ret;
+
+  IDE_ENTRY;
+
+  g_return_val_if_fail (IDE_IS_BUILD_SYSTEM (self), NULL);
+  g_return_val_if_fail (G_IS_TASK (result), NULL);
+
+  ret = IDE_BUILD_SYSTEM_GET_IFACE (self)->get_build_flags_for_files_finish (self, result, error);
+
+  IDE_RETURN (ret);
+}
+
 void
 ide_build_system_get_build_targets_async (IdeBuildSystem      *self,
                                           GCancellable        *cancellable,
diff --git a/libide/buildsystem/ide-build-system.h b/libide/buildsystem/ide-build-system.h
index abc62af..0d24093 100644
--- a/libide/buildsystem/ide-build-system.h
+++ b/libide/buildsystem/ide-build-system.h
@@ -33,56 +33,72 @@ struct _IdeBuildSystemInterface
 {
   GTypeInterface parent_iface;
 
-  gint        (*get_priority)             (IdeBuildSystem       *self);
-  void        (*get_build_flags_async)    (IdeBuildSystem       *self,
-                                           IdeFile              *file,
-                                           GCancellable         *cancellable,
-                                           GAsyncReadyCallback   callback,
-                                           gpointer              user_data);
-  gchar     **(*get_build_flags_finish)   (IdeBuildSystem       *self,
-                                           GAsyncResult         *result,
-                                           GError              **error);
-  void        (*get_build_targets_async)  (IdeBuildSystem       *self,
-                                           GCancellable         *cancellable,
-                                           GAsyncReadyCallback   callback,
-                                           gpointer              user_data);
-  GPtrArray  *(*get_build_targets_finish) (IdeBuildSystem       *self,
-                                           GAsyncResult         *result,
-                                           GError              **error);
-  gchar      *(*get_builddir)             (IdeBuildSystem       *self,
-                                           IdeConfiguration     *configuration);
-  gchar      *(*get_id)                   (IdeBuildSystem       *self);
-  gchar      *(*get_display_name)         (IdeBuildSystem       *self);
+  gint        (*get_priority)                      (IdeBuildSystem       *self);
+  void        (*get_build_flags_async)             (IdeBuildSystem       *self,
+                                                    IdeFile              *file,
+                                                    GCancellable         *cancellable,
+                                                    GAsyncReadyCallback   callback,
+                                                    gpointer              user_data);
+  gchar     **(*get_build_flags_finish)            (IdeBuildSystem       *self,
+                                                    GAsyncResult         *result,
+                                                    GError              **error);
+  void        (*get_build_flags_for_files_async)   (IdeBuildSystem       *self,
+                                                    GPtrArray            *files,
+                                                    GCancellable         *cancellable,
+                                                    GAsyncReadyCallback   callback,
+                                                    gpointer              user_data);
+  GHashTable *(*get_build_flags_for_files_finish)  (IdeBuildSystem       *self,
+                                                    GAsyncResult         *result,
+                                                    GError              **error);
+  void        (*get_build_targets_async)           (IdeBuildSystem       *self,
+                                                    GCancellable         *cancellable,
+                                                    GAsyncReadyCallback   callback,
+                                                    gpointer              user_data);
+  GPtrArray  *(*get_build_targets_finish)          (IdeBuildSystem       *self,
+                                                    GAsyncResult         *result,
+                                                    GError              **error);
+  gchar      *(*get_builddir)                      (IdeBuildSystem       *self,
+                                                    IdeConfiguration     *configuration);
+  gchar      *(*get_id)                            (IdeBuildSystem       *self);
+  gchar      *(*get_display_name)                  (IdeBuildSystem       *self);
 };
 
-gchar          *ide_build_system_get_id                   (IdeBuildSystem       *self);
-gchar          *ide_build_system_get_display_name         (IdeBuildSystem       *self);
-void            ide_build_system_new_async                (IdeContext           *context,
-                                                           GFile                *project_file,
-                                                           const gchar          *build_system_hint,
-                                                           GCancellable         *cancellable,
-                                                           GAsyncReadyCallback   callback,
-                                                           gpointer              user_data);
-IdeBuildSystem *ide_build_system_new_finish               (GAsyncResult         *result,
-                                                           GError              **error);
-gint            ide_build_system_get_priority             (IdeBuildSystem       *self);
-gchar          *ide_build_system_get_builddir             (IdeBuildSystem       *self,
-                                                           IdeConfiguration     *configuration);
-void            ide_build_system_get_build_flags_async    (IdeBuildSystem       *self,
-                                                           IdeFile              *file,
-                                                           GCancellable         *cancellable,
-                                                           GAsyncReadyCallback   callback,
-                                                           gpointer              user_data);
-gchar         **ide_build_system_get_build_flags_finish   (IdeBuildSystem       *self,
-                                                           GAsyncResult         *result,
-                                                           GError              **error);
-void            ide_build_system_get_build_targets_async  (IdeBuildSystem       *self,
-                                                           GCancellable         *cancellable,
-                                                           GAsyncReadyCallback   callback,
-                                                           gpointer              user_data);
-GPtrArray      *ide_build_system_get_build_targets_finish (IdeBuildSystem       *self,
-                                                           GAsyncResult         *result,
-                                                           GError              **error);
+gchar          *ide_build_system_get_id                            (IdeBuildSystem       *self);
+gchar          *ide_build_system_get_display_name                  (IdeBuildSystem       *self);
+void            ide_build_system_new_async                         (IdeContext           *context,
+                                                                    GFile                *project_file,
+                                                                    const gchar          *build_system_hint,
+                                                                    GCancellable         *cancellable,
+                                                                    GAsyncReadyCallback   callback,
+                                                                    gpointer              user_data);
+IdeBuildSystem *ide_build_system_new_finish                        (GAsyncResult         *result,
+                                                                    GError              **error);
+gint            ide_build_system_get_priority                      (IdeBuildSystem       *self);
+gchar          *ide_build_system_get_builddir                      (IdeBuildSystem       *self,
+                                                                    IdeConfiguration     *configuration);
+void            ide_build_system_get_build_flags_async             (IdeBuildSystem       *self,
+                                                                    IdeFile              *file,
+                                                                    GCancellable         *cancellable,
+                                                                    GAsyncReadyCallback   callback,
+                                                                    gpointer              user_data);
+gchar         **ide_build_system_get_build_flags_finish            (IdeBuildSystem       *self,
+                                                                    GAsyncResult         *result,
+                                                                    GError              **error);
+void            ide_build_system_get_build_flags_for_files_async   (IdeBuildSystem       *self,
+                                                                    GPtrArray            *files,
+                                                                    GCancellable         *cancellable,
+                                                                    GAsyncReadyCallback   callback,
+                                                                    gpointer              user_data);
+GHashTable     *ide_build_system_get_build_flags_for_files_finish  (IdeBuildSystem       *self,
+                                                                    GAsyncResult         *result,
+                                                                    GError              **error);
+void            ide_build_system_get_build_targets_async           (IdeBuildSystem       *self,
+                                                                    GCancellable         *cancellable,
+                                                                    GAsyncReadyCallback   callback,
+                                                                    gpointer              user_data);
+GPtrArray      *ide_build_system_get_build_targets_finish          (IdeBuildSystem       *self,
+                                                                    GAsyncResult         *result,
+                                                                    GError              **error);
 
 G_END_DECLS
 


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