[gnome-builder/wip/chergert/bug1: 35/101] debugger: add IdeDebugManager



commit 60f798a849862d65d59781c16d30622a6c0cfc98
Author: Christian Hergert <chergert redhat com>
Date:   Thu Aug 24 21:30:56 2017 -0700

    debugger: add IdeDebugManager
    
    The debug manager is a helper for us to bind the IdeDebugger plugin
    class to the run handler system.

 libide/debugger/ide-debug-manager.c |  389 +++++++++++++++++++++++++++++++++++
 libide/debugger/ide-debug-manager.h |   35 +++
 libide/debugger/ide-debugger.c      |   50 +++++-
 libide/debugger/ide-debugger.h      |   35 +++-
 libide/ide-context.c                |   22 ++
 libide/ide.h                        |    1 +
 libide/meson.build                  |    2 +
 7 files changed, 522 insertions(+), 12 deletions(-)
---
diff --git a/libide/debugger/ide-debug-manager.c b/libide/debugger/ide-debug-manager.c
new file mode 100644
index 0000000..ee7f6a9
--- /dev/null
+++ b/libide/debugger/ide-debug-manager.c
@@ -0,0 +1,389 @@
+/* ide-debug-manager.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-debug-manager"
+
+#include <dazzle.h>
+#include <glib/gi18n.h>
+
+#include "ide-debug.h"
+
+#include "debugger/ide-debug-manager.h"
+#include "debugger/ide-debugger.h"
+#include "plugins/ide-extension-util.h"
+#include "runner/ide-runner.h"
+
+struct _IdeDebugManager
+{
+  IdeObject           parent_instance;
+
+  IdeDebugger        *debugger;
+  DzlBindingGroup    *debugger_bindings;
+  DzlSignalGroup     *debugger_signals;
+  IdeRunner          *runner;
+
+  guint               active : 1;
+};
+
+typedef struct
+{
+  IdeDebugger *debugger;
+  IdeRunner   *runner;
+  gint         priority;
+} DebuggerLookup;
+
+enum {
+  PROP_0,
+  PROP_ACTIVE,
+  PROP_DEBUGGER,
+  N_PROPS
+};
+
+enum {
+  BREAKPOINT_ADDED,
+  BREAKPOINT_REMOVED,
+  BREAKPOINT_REACHED,
+  N_SIGNALS
+};
+
+static GParamSpec *properties [N_PROPS];
+static guint signals [N_SIGNALS];
+
+G_DEFINE_TYPE (IdeDebugManager, ide_debug_manager, IDE_TYPE_OBJECT)
+
+static void
+ide_debug_manager_set_active (IdeDebugManager *self,
+                              gboolean         active)
+{
+  g_assert (IDE_IS_DEBUG_MANAGER (self));
+
+  active = !!active;
+
+  if (active != self->active)
+    {
+      self->active = active;
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ACTIVE]);
+    }
+}
+
+static void
+ide_debug_manager_debugger_stopped (IdeDebugManager       *self,
+                                    IdeDebuggerStopReason  stop_reason,
+                                    IdeDebuggerBreakpoint *breakpoint,
+                                    IdeDebugger           *debugger)
+{
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_DEBUG_MANAGER (self));
+  g_assert (IDE_IS_DEBUGGER_STOP_REASON (stop_reason));
+  g_assert (!breakpoint || IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
+  g_assert (IDE_IS_DEBUGGER (debugger));
+
+  switch (stop_reason)
+    {
+    case IDE_DEBUGGER_STOP_EXITED:
+    case IDE_DEBUGGER_STOP_EXITED_NORMALLY:
+    case IDE_DEBUGGER_STOP_EXITED_SIGNALED:
+      /* Cleanup any lingering debugger process */
+      if (self->runner != NULL)
+        ide_runner_force_quit (self->runner);
+      break;
+
+    case IDE_DEBUGGER_STOP_BREAKPOINT_HIT:
+    case IDE_DEBUGGER_STOP_FUNCTION_FINISHED:
+    case IDE_DEBUGGER_STOP_LOCATION_REACHED:
+    case IDE_DEBUGGER_STOP_SIGNAL_RECEIVED:
+    case IDE_DEBUGGER_STOP_CATCH:
+    case IDE_DEBUGGER_STOP_UNKNOWN:
+      if (breakpoint != NULL)
+        {
+          IDE_TRACE_MSG ("Emitting breakpoint-reached");
+          g_signal_emit (self, signals [BREAKPOINT_REACHED], 0, breakpoint);
+        }
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+
+  IDE_EXIT;
+}
+
+static void
+ide_debug_manager_finalize (GObject *object)
+{
+  IdeDebugManager *self = (IdeDebugManager *)object;
+
+  g_clear_object (&self->debugger);
+  g_clear_object (&self->debugger_bindings);
+  g_clear_object (&self->debugger_signals);
+  g_clear_object (&self->runner);
+
+  G_OBJECT_CLASS (ide_debug_manager_parent_class)->finalize (object);
+}
+
+static void
+ide_debug_manager_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  IdeDebugManager *self = IDE_DEBUG_MANAGER (object);
+
+  switch (prop_id)
+    {
+    case PROP_ACTIVE:
+      g_value_set_boolean (value, self->active);
+      break;
+
+    case PROP_DEBUGGER:
+      g_value_set_object (value, self->debugger);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_debug_manager_class_init (IdeDebugManagerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = ide_debug_manager_finalize;
+  object_class->get_property = ide_debug_manager_get_property;
+
+  /**
+   * IdeDebugManager:active:
+   *
+   * If the debugger is active.
+   *
+   * This can be used to determine if the controls should be made visible
+   * in the workbench.
+   */
+  properties [PROP_ACTIVE] =
+    g_param_spec_boolean ("active",
+                          "Active",
+                          "If the debugger is running",
+                          FALSE,
+                          (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_DEBUGGER] =
+    g_param_spec_object ("debugger",
+                         "Debugger",
+                         "The current debugger being used",
+                         IDE_TYPE_DEBUGGER,
+                         (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+
+  signals [BREAKPOINT_ADDED] =
+    g_signal_new ("breakpoint-added",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL, NULL,
+                  G_TYPE_NONE, 1, IDE_TYPE_DEBUGGER_BREAKPOINT);
+
+  signals [BREAKPOINT_REMOVED] =
+    g_signal_new ("breakpoint-removed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL, NULL,
+                  G_TYPE_NONE, 1, IDE_TYPE_DEBUGGER_BREAKPOINT);
+
+  signals [BREAKPOINT_REACHED] =
+    g_signal_new ("breakpoint-reached",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL, NULL,
+                  G_TYPE_NONE, 1, IDE_TYPE_DEBUGGER_BREAKPOINT);
+}
+
+static void
+ide_debug_manager_init (IdeDebugManager *self)
+{
+  self->debugger_signals = dzl_signal_group_new (IDE_TYPE_DEBUGGER);
+
+  dzl_signal_group_connect_object (self->debugger_signals,
+                                   "stopped",
+                                   G_CALLBACK (ide_debug_manager_debugger_stopped),
+                                   self,
+                                   G_CONNECT_SWAPPED);
+}
+
+static void
+debugger_lookup (PeasExtensionSet *set,
+                 PeasPluginInfo   *plugin_info,
+                 PeasExtension    *exten,
+                 gpointer          user_data)
+{
+  DebuggerLookup *lookup = user_data;
+  IdeDebugger *debugger = (IdeDebugger *)exten;
+  gint priority = G_MAXINT;
+
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+  g_assert (IDE_IS_DEBUGGER (debugger));
+  g_assert (lookup != NULL);
+
+  if (ide_debugger_supports_runner (debugger, lookup->runner, &priority))
+    {
+      if (lookup->debugger == NULL || priority < lookup->priority)
+        {
+          g_set_object (&lookup->debugger, debugger);
+          lookup->priority = priority;
+        }
+    }
+}
+
+/**
+ * ide_debug_manager_find_debugger:
+ * @self: a #IdeDebugManager
+ * @runner: An #IdeRunner
+ *
+ * Locates a debugger for the given runner, or %NULL if no debugger
+ * supports the runner.
+ *
+ * Returns: (transfer full) (nullable): An #IdeDebugger or %NULL
+ */
+IdeDebugger *
+ide_debug_manager_find_debugger (IdeDebugManager *self,
+                                 IdeRunner       *runner)
+{
+  g_autoptr(PeasExtensionSet) set = NULL;
+  IdeContext *context;
+  DebuggerLookup lookup;
+
+  g_return_val_if_fail (IDE_IS_DEBUG_MANAGER (self), NULL);
+  g_return_val_if_fail (IDE_IS_RUNNER (runner), NULL);
+
+  context = ide_object_get_context (IDE_OBJECT (runner));
+
+  lookup.debugger = NULL;
+  lookup.runner = runner;
+  lookup.priority = G_MAXINT;
+
+  set = ide_extension_set_new (peas_engine_get_default (),
+                               IDE_TYPE_DEBUGGER,
+                               "context", context,
+                               NULL);
+
+  peas_extension_set_foreach (set, debugger_lookup, &lookup);
+
+  return lookup.debugger;
+}
+
+static void
+ide_debug_manager_runner_exited (IdeDebugManager *self,
+                                 IdeRunner       *runner)
+{
+  g_assert (IDE_IS_DEBUG_MANAGER (self));
+  g_assert (IDE_IS_RUNNER (runner));
+
+  g_clear_object (&self->runner);
+  g_clear_object (&self->debugger);
+
+  ide_debug_manager_set_active (self, FALSE);
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_DEBUGGER]);
+}
+
+/**
+ * ide_debug_manager_start:
+ * @self: an #IdeDebugManager
+ * @runner: an #IdeRunner
+ * @error: A location for an @error
+ *
+ * Attempts to start a runner using a discovered debugger backend.
+ *
+ * Returns: %TRUE if successful; otherwise %FALSE and @error is set.
+ */
+gboolean
+ide_debug_manager_start (IdeDebugManager  *self,
+                         IdeRunner        *runner,
+                         GError          **error)
+{
+  g_autoptr(IdeDebugger) debugger = NULL;
+  gboolean ret = FALSE;
+
+  IDE_ENTRY;
+
+  g_return_val_if_fail (IDE_IS_DEBUG_MANAGER (self), FALSE);
+  g_return_val_if_fail (IDE_IS_RUNNER (runner), FALSE);
+
+  debugger = ide_debug_manager_find_debugger (self, runner);
+
+  if (debugger == NULL)
+    {
+      ide_runner_set_failed (runner, TRUE);
+      g_set_error (error,
+                   G_IO_ERROR,
+                   G_IO_ERROR_NOT_SUPPORTED,
+                   _("A suitable debugger could not be found."));
+      IDE_GOTO (failure);
+    }
+
+  ide_debugger_prepare (debugger, runner);
+
+  g_signal_connect_object (runner,
+                           "exited",
+                           G_CALLBACK (ide_debug_manager_runner_exited),
+                           self,
+                           G_CONNECT_SWAPPED);
+
+  self->runner = g_object_ref (runner);
+  self->debugger = g_steal_pointer (&debugger);
+
+  dzl_binding_group_set_source (self->debugger_bindings, self->debugger);
+  dzl_signal_group_set_target (self->debugger_signals, self->debugger);
+
+  ide_debug_manager_set_active (self, TRUE);
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_DEBUGGER]);
+
+  ret = TRUE;
+
+failure:
+  IDE_RETURN (ret);
+}
+
+void
+ide_debug_manager_stop (IdeDebugManager *self)
+{
+  g_return_if_fail (IDE_IS_DEBUG_MANAGER (self));
+
+  dzl_binding_group_set_source (self->debugger_bindings, NULL);
+  dzl_signal_group_set_target (self->debugger_signals, NULL);
+
+  if (self->runner != NULL)
+    {
+      ide_runner_force_quit (self->runner);
+      g_clear_object (&self->runner);
+    }
+
+  g_clear_object (&self->debugger);
+  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_DEBUGGER]);
+}
+
+gboolean
+ide_debug_manager_get_active (IdeDebugManager *self)
+{
+  g_return_val_if_fail (IDE_IS_DEBUG_MANAGER (self), FALSE);
+
+  return self->active;
+}
diff --git a/libide/debugger/ide-debug-manager.h b/libide/debugger/ide-debug-manager.h
new file mode 100644
index 0000000..e0bdbf7
--- /dev/null
+++ b/libide/debugger/ide-debug-manager.h
@@ -0,0 +1,35 @@
+/* ide-debug-manager.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "ide-object.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_DEBUG_MANAGER (ide_debug_manager_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeDebugManager, ide_debug_manager, IDE, DEBUG_MANAGER, IdeObject)
+
+gboolean ide_debug_manager_get_active (IdeDebugManager  *self);
+gboolean ide_debug_manager_start      (IdeDebugManager  *self,
+                                       IdeRunner        *runner,
+                                       GError          **error);
+void     ide_debug_manager_stop       (IdeDebugManager  *self);
+
+G_END_DECLS
diff --git a/libide/debugger/ide-debugger.c b/libide/debugger/ide-debugger.c
index 7ebf0f5..05b3eb3 100644
--- a/libide/debugger/ide-debugger.c
+++ b/libide/debugger/ide-debugger.c
@@ -50,7 +50,7 @@ typedef struct
   guint                  is_running : 1;
 } IdeDebuggerPrivate;
 
-G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeDebugger, ide_debugger, G_TYPE_OBJECT,
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeDebugger, ide_debugger, IDE_TYPE_OBJECT,
                                   G_ADD_PRIVATE (IdeDebugger)
                                   G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP,
                                                          _ide_debugger_class_init_actions))
@@ -1946,3 +1946,51 @@ ide_debugger_disassemble_finish (IdeDebugger   *self,
 
   return IDE_DEBUGGER_GET_CLASS (self)->disassemble_finish (self, result, error);
 }
+
+/**
+ * ide_debugger_supports_runner:
+ * @self: an #IdeDebugger
+ * @runner: an #IdeRunner
+ * @priority: (out): A location for a priority
+ *
+ * Checks if the debugger supports a given runner. The debugger may need
+ * to check if the binary type matches it's expectation.
+ *
+ * Returns: %TRUE if the #IdeDebugger supports the runner.
+ */
+gboolean
+ide_debugger_supports_runner (IdeDebugger *self,
+                              IdeRunner   *runner,
+                              gint        *priority)
+{
+  gint dummy = 0;
+
+  g_return_val_if_fail (IDE_IS_DEBUGGER (self), FALSE);
+  g_return_val_if_fail (IDE_IS_RUNNER (runner), FALSE);
+
+  if (priority == NULL)
+    priority = &dummy;
+  else
+    *priority = 0;
+
+  return IDE_DEBUGGER_GET_CLASS (self)->supports_runner (self, runner, priority);
+}
+
+/**
+ * ide_debugger_prepare:
+ * @self: an #IdeDebugger
+ * @runner: an #IdeRunner
+ *
+ * Prepares the runner to launch a debugger and target process.
+ *
+ * Since: 3.26
+ */
+void
+ide_debugger_prepare (IdeDebugger *self,
+                      IdeRunner   *runner)
+{
+  g_return_if_fail (IDE_IS_DEBUGGER (self));
+  g_return_if_fail (IDE_IS_RUNNER (runner));
+
+  IDE_DEBUGGER_GET_CLASS (self)->prepare (self, runner);
+}
diff --git a/libide/debugger/ide-debugger.h b/libide/debugger/ide-debugger.h
index c24fa1e..335fc6d 100644
--- a/libide/debugger/ide-debugger.h
+++ b/libide/debugger/ide-debugger.h
@@ -20,25 +20,28 @@
 
 #include <gio/gio.h>
 
-#include "ide-debugger-breakpoint.h"
-#include "ide-debugger-frame.h"
-#include "ide-debugger-instruction.h"
-#include "ide-debugger-library.h"
-#include "ide-debugger-register.h"
-#include "ide-debugger-thread-group.h"
-#include "ide-debugger-thread.h"
-#include "ide-debugger-types.h"
-#include "ide-debugger-variable.h"
+#include "ide-object.h"
+
+#include "debugger/ide-debugger-breakpoint.h"
+#include "debugger/ide-debugger-frame.h"
+#include "debugger/ide-debugger-instruction.h"
+#include "debugger/ide-debugger-library.h"
+#include "debugger/ide-debugger-register.h"
+#include "debugger/ide-debugger-thread-group.h"
+#include "debugger/ide-debugger-thread.h"
+#include "debugger/ide-debugger-types.h"
+#include "debugger/ide-debugger-variable.h"
+#include "runner/ide-runner.h"
 
 G_BEGIN_DECLS
 
 #define IDE_TYPE_DEBUGGER (ide_debugger_get_type())
 
-G_DECLARE_DERIVABLE_TYPE (IdeDebugger, ide_debugger, IDE, DEBUGGER, GObject)
+G_DECLARE_DERIVABLE_TYPE (IdeDebugger, ide_debugger, IDE, DEBUGGER, IdeObject)
 
 struct _IdeDebuggerClass
 {
-  GObjectClass parent_class;
+  IdeObjectClass parent_class;
 
   /* Signals */
 
@@ -76,6 +79,11 @@ struct _IdeDebuggerClass
 
   /* Virtual Functions */
 
+  gboolean   (*supports_runner)          (IdeDebugger                  *self,
+                                          IdeRunner                    *runner,
+                                          gint                         *priority);
+  void       (*prepare)                  (IdeDebugger                  *self,
+                                          IdeRunner                    *runner);
   gboolean   (*get_can_move)             (IdeDebugger                  *self,
                                           IdeDebuggerMovement           movement);
   void       (*move_async)               (IdeDebugger                  *self,
@@ -210,6 +218,11 @@ struct _IdeDebuggerClass
   gpointer _reserved32;
 };
 
+gboolean           ide_debugger_supports_runner           (IdeDebugger                    *self,
+                                                           IdeRunner                      *runner,
+                                                           gint                           *priority);
+void               ide_debugger_prepare                   (IdeDebugger                    *self,
+                                                           IdeRunner                      *runner);
 GListModel        *ide_debugger_get_breakpoints           (IdeDebugger                    *self);
 const gchar       *ide_debugger_get_display_name          (IdeDebugger                    *self);
 void               ide_debugger_set_display_name          (IdeDebugger                    *self,
diff --git a/libide/ide-context.c b/libide/ide-context.c
index c3787b0..11d3d31 100644
--- a/libide/ide-context.c
+++ b/libide/ide-context.c
@@ -36,6 +36,7 @@
 #include "buildsystem/ide-build-system-discovery.h"
 #include "buildsystem/ide-configuration-manager.h"
 #include "diagnostics/ide-diagnostics-manager.h"
+#include "debugger/ide-debug-manager.h"
 #include "devices/ide-device-manager.h"
 #include "doap/ide-doap.h"
 #include "history/ide-back-forward-list-private.h"
@@ -69,6 +70,7 @@ struct _IdeContext
   IdeBuildSystem           *build_system;
   gchar                    *build_system_hint;
   IdeConfigurationManager  *configuration_manager;
+  IdeDebugManager          *debug_manager;
   IdeDiagnosticsManager    *diagnostics_manager;
   IdeDeviceManager         *device_manager;
   IdeDoap                  *doap;
@@ -849,6 +851,10 @@ ide_context_init (IdeContext *self)
                                       "context", self,
                                       NULL);
 
+  self->debug_manager = g_object_new (IDE_TYPE_DEBUG_MANAGER,
+                                      "context", self,
+                                      NULL);
+
   self->diagnostics_manager = g_object_new (IDE_TYPE_DIAGNOSTICS_MANAGER,
                                             "context", self,
                                             NULL);
@@ -2482,3 +2488,19 @@ ide_context_get_diagnostics_manager (IdeContext *self)
 
   return self->diagnostics_manager;
 }
+
+/**
+ * ide_context_get_debug_manager:
+ * @self: An #IdeContext
+ *
+ * Gets the debug manager for the context.
+ *
+ * Returns: (transfer none): An #IdeDebugManager
+ */
+IdeDebugManager *
+ide_context_get_debug_manager (IdeContext *self)
+{
+  g_return_val_if_fail (IDE_IS_CONTEXT (self), NULL);
+
+  return self->debug_manager;
+}
diff --git a/libide/ide.h b/libide/ide.h
index a35264c..7727364 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -62,6 +62,7 @@ G_BEGIN_DECLS
 #include "buildsystem/ide-configuration-provider.h"
 #include "buildsystem/ide-environment-variable.h"
 #include "buildsystem/ide-environment.h"
+#include "debugger/ide-debug-manager.h"
 #include "debugger/ide-debugger-breakpoint.h"
 #include "debugger/ide-debugger-frame.h"
 #include "debugger/ide-debugger-instruction.h"
diff --git a/libide/meson.build b/libide/meson.build
index 909a155..7809d5d 100644
--- a/libide/meson.build
+++ b/libide/meson.build
@@ -85,6 +85,7 @@ libide_public_headers = [
   'buildsystem/ide-configuration-provider.h',
   'buildsystem/ide-environment-variable.h',
   'buildsystem/ide-environment.h',
+  'debugger/ide-debug-manager.h',
   'debugger/ide-debugger-breakpoint.h',
   'debugger/ide-debugger-frame.h',
   'debugger/ide-debugger-instruction.h',
@@ -300,6 +301,7 @@ libide_public_sources = [
   'buildsystem/ide-configuration-provider.c',
   'buildsystem/ide-environment-variable.c',
   'buildsystem/ide-environment.c',
+  'debugger/ide-debug-manager.c',
   'debugger/ide-debugger-breakpoint.c',
   'debugger/ide-debugger-frame.c',
   'debugger/ide-debugger-instruction.c',


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