From 076a253d6a0d2317ae30703cba54af073799efd2 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 2 Oct 2019 13:38:46 -0700 Subject: [PATCH 1/2] implement powerShell/startDebugger --- .../Server/PsesDebugServer.cs | 10 ++++++++- .../Services/DebugAdapter/DebugService.cs | 2 +- .../Handlers/ConfigurationDoneHandler.cs | 15 ++++++++++--- .../PowerShellContextService.cs | 22 +++++++++++++++++-- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/PowerShellEditorServices/Server/PsesDebugServer.cs b/src/PowerShellEditorServices/Server/PsesDebugServer.cs index b3bf2edba..45ecc16d5 100644 --- a/src/PowerShellEditorServices/Server/PsesDebugServer.cs +++ b/src/PowerShellEditorServices/Server/PsesDebugServer.cs @@ -23,6 +23,7 @@ public class PsesDebugServer : IDisposable private readonly Stream _outputStream; private IJsonRpcServer _jsonRpcServer; + private PowerShellContextService _powerShellContextService; public PsesDebugServer( ILoggerFactory factory, @@ -42,8 +43,14 @@ public async Task StartAsync(IServiceProvider languageServerServiceProvider) options.Reciever = new DapReciever(); options.LoggerFactory = _loggerFactory; ILogger logger = options.LoggerFactory.CreateLogger("DebugOptionsStartup"); + + // We need to let the PowerShell Context Service know that we are in a debug session + // so that it doesn't send the powerShell/startDebugger message. + _powerShellContextService = languageServerServiceProvider.GetService(); + _powerShellContextService.IsDebugServerActive = true; + options.Services = new ServiceCollection() - .AddSingleton(languageServerServiceProvider.GetService()) + .AddSingleton(_powerShellContextService) .AddSingleton(languageServerServiceProvider.GetService()) .AddSingleton(languageServerServiceProvider.GetService()) .AddSingleton(this) @@ -85,6 +92,7 @@ public async Task StartAsync(IServiceProvider languageServerServiceProvider) public void Dispose() { + _powerShellContextService.IsDebugServerActive = false; _jsonRpcServer.Dispose(); } diff --git a/src/PowerShellEditorServices/Services/DebugAdapter/DebugService.cs b/src/PowerShellEditorServices/Services/DebugAdapter/DebugService.cs index c8d566b12..dbde29254 100644 --- a/src/PowerShellEditorServices/Services/DebugAdapter/DebugService.cs +++ b/src/PowerShellEditorServices/Services/DebugAdapter/DebugService.cs @@ -1191,7 +1191,7 @@ private string TrimScriptListingLine(PSObject scriptLineObj, ref int prefixLengt /// public event EventHandler DebuggerStopped; - private async void OnDebuggerStopAsync(object sender, DebuggerStopEventArgs e) + internal async void OnDebuggerStopAsync(object sender, DebuggerStopEventArgs e) { bool noScriptName = false; string localScriptPath = e.InvocationInfo.ScriptName; diff --git a/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/ConfigurationDoneHandler.cs b/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/ConfigurationDoneHandler.cs index 03cdf7fde..addf829a1 100644 --- a/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/ConfigurationDoneHandler.cs +++ b/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/ConfigurationDoneHandler.cs @@ -73,9 +73,18 @@ public Task Handle(ConfigurationDoneArguments request if (_debugService.IsDebuggerStopped) { - // If this is an interactive session and there's a pending breakpoint, - // send that information along to the debugger client - _debugEventHandlerService.TriggerDebuggerStopped(_debugService.CurrentDebuggerStoppedEventArgs); + if (_debugService.CurrentDebuggerStoppedEventArgs != null) + { + // If this is an interactive session and there's a pending breakpoint, + // send that information along to the debugger client + _debugEventHandlerService.TriggerDebuggerStopped(_debugService.CurrentDebuggerStoppedEventArgs); + } + else + { + // If this is an interactive session and there's a pending breakpoint that has not been propagated through + // the debug service, fire the debug service's OnDebuggerStop event. + _debugService.OnDebuggerStopAsync(null, _powerShellContextService.CurrentDebuggerStopEventArgs); + } } } diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs index c0effd3be..f46b5cfba 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs @@ -137,6 +137,10 @@ public RunspaceDetails CurrentRunspace /// public string InitialWorkingDirectory { get; private set; } + internal bool IsDebugServerActive { get; set; } + + internal DebuggerStopEventArgs CurrentDebuggerStopEventArgs { get; private set; } + #endregion #region Constructors @@ -2296,6 +2300,15 @@ private void StartCommandLoopOnRunspaceAvailable() private void OnDebuggerStop(object sender, DebuggerStopEventArgs e) { + // We maintain the current stop event args so that we can use it in the DebugServer to fire the "stopped" event + // when the DebugServer is fully started. + CurrentDebuggerStopEventArgs = e; + + if (!IsDebugServerActive) + { + _languageServer.SendNotification("powerShell/startDebugger"); + } + if (CurrentRunspace.Context == RunspaceContext.Original) { StartCommandLoopOnRunspaceAvailable(); @@ -2361,6 +2374,9 @@ private void OnDebuggerStop(object sender, DebuggerStopEventArgs e) e.ResumeAction = localDebuggerStoppedTask.GetAwaiter().GetResult(); this.logger.LogTrace("Received debugger resume action " + e.ResumeAction.ToString()); + // Since we are no longer at a breakpoint, we set this to null. + CurrentDebuggerStopEventArgs = null; + // Notify listeners that the debugger has resumed this.DebuggerResumed?.Invoke(this, e.ResumeAction); @@ -2398,6 +2414,9 @@ private void OnDebuggerStop(object sender, DebuggerStopEventArgs e) this.PromptNest, this.CurrentRunspace.Runspace)) { + // Since we are no longer at a breakpoint, we set this to null. + CurrentDebuggerStopEventArgs = null; + if (this.CurrentRunspace.Context == RunspaceContext.DebuggedRunspace) { // Notify listeners that the debugger has resumed @@ -2436,8 +2455,7 @@ private void OnBreakpointUpdated(object sender, BreakpointUpdatedEventArgs e) private void ConfigureRunspaceCapabilities(RunspaceDetails runspaceDetails) { - // TODO: Bring this back - //DscBreakpointCapability.CheckForCapability(this.CurrentRunspace, this, this.logger); + DscBreakpointCapability.CheckForCapability(this.CurrentRunspace, this, this.logger); } private void PushRunspace(RunspaceDetails newRunspaceDetails) From ecf79c4f29b7313f81846428377213622695317a Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 3 Oct 2019 13:29:31 -0700 Subject: [PATCH 2/2] add line Co-Authored-By: Patrick Meinecke --- src/PowerShellEditorServices/Server/PsesDebugServer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PowerShellEditorServices/Server/PsesDebugServer.cs b/src/PowerShellEditorServices/Server/PsesDebugServer.cs index 45ecc16d5..860dbc845 100644 --- a/src/PowerShellEditorServices/Server/PsesDebugServer.cs +++ b/src/PowerShellEditorServices/Server/PsesDebugServer.cs @@ -23,6 +23,7 @@ public class PsesDebugServer : IDisposable private readonly Stream _outputStream; private IJsonRpcServer _jsonRpcServer; + private PowerShellContextService _powerShellContextService; public PsesDebugServer(