Skip to content

This is a *proposed* change to address the issue that the launch requ… #178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 51 additions & 30 deletions src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public class DebugAdapter : DebugAdapterBase
{
private EditorSession editorSession;
private OutputDebouncer outputDebouncer;
private bool isConfigurationDoneRequestComplete;
private bool isLaunchRequestComplete;
private string scriptPathToLaunch;
private string arguments;

Expand Down Expand Up @@ -65,6 +67,23 @@ protected override void Initialize()
this.SetRequestHandler(EvaluateRequest.Type, this.HandleEvaluateRequest);
}

protected Task LaunchScript(RequestContext<object> requestContext)
{
return editorSession.PowerShellContext
.ExecuteScriptAtPath(this.scriptPathToLaunch, this.arguments)
.ContinueWith(
async (t) => {
Logger.Write(LogLevel.Verbose, "Execution completed, terminating...");

await requestContext.SendEvent(
TerminatedEvent.Type,
null);

// Stop the server
this.Stop();
});
}

protected override void Shutdown()
{
// Make sure remaining output is flushed before exiting
Expand All @@ -81,6 +100,23 @@ protected override void Shutdown()

#region Built-in Message Handlers

protected async Task HandleConfigurationDoneRequest(
object args,
RequestContext<object> requestContext)
{
// The order of debug protocol messages apparently isn't as guaranteed as we might like.
// Need to be able to handle the case where we get the configurationDone request after the
// launch request.
if (this.isLaunchRequestComplete)
{
this.LaunchScript(requestContext);
}

this.isConfigurationDoneRequestComplete = true;

await requestContext.SendResult(null);
}

protected async Task HandleLaunchRequest(
LaunchRequestArguments launchParams,
RequestContext<object> requestContext)
Expand Down Expand Up @@ -114,14 +150,24 @@ protected async Task HandleLaunchRequest(
Logger.Write(LogLevel.Verbose, "Script arguments are: " + arguments);
}

// NOTE: We don't actually launch the script in response to this
// request. We wait until we receive the configurationDone request
// to actually launch the script under the debugger. This gives
// us and VSCode a chance to finish configuring all the types of
// breakpoints.
// We may not actually launch the script in response to this
// request unless it comes after the configurationDone request.
// If the launch request comes first, then stash the launch
// params so that the subsequent configurationDone request handler
// can launch the script.
this.scriptPathToLaunch = launchParams.Program;
this.arguments = arguments;

// The order of debug protocol messages apparently isn't as guaranteed as we might like.
// Need to be able to handle the case where we get the launch request after the
// configurationDone request.
if (this.isConfigurationDoneRequestComplete)
{
this.LaunchScript(requestContext);
}

this.isLaunchRequestComplete = true;

await requestContext.SendResult(null);
}

Expand All @@ -133,31 +179,6 @@ protected Task HandleAttachRequest(
throw new NotImplementedException();
}

protected async Task HandleConfigurationDoneRequest(
object args,
RequestContext<object> requestContext)
{
// Execute the given PowerShell script and send the response.
// Note that we aren't waiting for execution to complete here
// because the debugger could stop while the script executes.
Task executeTask =
editorSession.PowerShellContext
.ExecuteScriptAtPath(this.scriptPathToLaunch, this.arguments)
.ContinueWith(
async (t) => {
Logger.Write(LogLevel.Verbose, "Execution completed, terminating...");

await requestContext.SendEvent(
TerminatedEvent.Type,
null);

// Stop the server
this.Stop();
});

await requestContext.SendResult(null);
}

protected Task HandleDisconnectRequest(
object disconnectParams,
RequestContext<object> requestContext)
Expand Down