Skip to content

Commit 3c27ec3

Browse files
Merge pull request #1532 from PowerShell/andschwa/debugger
Make `ExecuteCommandAsync` cancellable
2 parents e29979c + 6a19daf commit 3c27ec3

14 files changed

+69
-60
lines changed

src/PowerShellEditorServices/Server/PsesDebugServer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ public async Task StartAsync()
137137
public void Dispose()
138138
{
139139
_powerShellContextService.IsDebugServerActive = false;
140+
// TODO: If the debugger has stopped, should we clear the breakpoints?
140141
_debugAdapterServer.Dispose();
141142
_inputStream.Dispose();
142143
_outputStream.Dispose();

src/PowerShellEditorServices/Services/DebugAdapter/BreakpointService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ public async Task<IEnumerable<BreakpointDetails>> SetBreakpointsAsync(string esc
135135
IEnumerable<Breakpoint> setBreakpoints =
136136
await _powerShellContextService.ExecuteCommandAsync<Breakpoint>(psCommand).ConfigureAwait(false);
137137
configuredBreakpoints.AddRange(
138-
setBreakpoints.Select(BreakpointDetails.Create));
138+
setBreakpoints.Select((breakpoint) => BreakpointDetails.Create(breakpoint))
139+
);
139140
}
140141

141142
return configuredBreakpoints;

src/PowerShellEditorServices/Services/DebugAdapter/DebugEventHandlerService.cs

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ e.OriginalEvent.Breakpoints[0] is CommandBreakpoint
8181
new StoppedEvent
8282
{
8383
ThreadId = 1,
84+
AllThreadsStopped = true,
8485
Reason = debuggerStoppedReason
8586
});
8687
}
@@ -117,59 +118,47 @@ private void PowerShellContext_DebuggerResumed(object sender, DebuggerResumeActi
117118
_debugAdapterServer.SendNotification(EventNames.Continued,
118119
new ContinuedEvent
119120
{
120-
AllThreadsContinued = true,
121-
ThreadId = 1
121+
ThreadId = 1,
122+
AllThreadsContinued = true
122123
});
123124
}
124125

125126
private void DebugService_BreakpointUpdated(object sender, BreakpointUpdatedEventArgs e)
126127
{
127-
string reason = "changed";
128-
128+
// Don't send breakpoint update notifications when setting
129+
// breakpoints on behalf of the client.
129130
if (_debugStateService.IsSetBreakpointInProgress)
130131
{
131-
// Don't send breakpoint update notifications when setting
132-
// breakpoints on behalf of the client.
133132
return;
134133
}
135134

136-
switch (e.UpdateType)
137-
{
138-
case BreakpointUpdateType.Set:
139-
reason = "new";
140-
break;
141-
142-
case BreakpointUpdateType.Removed:
143-
reason = "removed";
144-
break;
145-
}
146-
147-
var breakpoint = new OmniSharp.Extensions.DebugAdapter.Protocol.Models.Breakpoint
148-
{
149-
Verified = e.UpdateType != BreakpointUpdateType.Disabled
150-
};
151-
152135
if (e.Breakpoint is LineBreakpoint)
153136
{
154-
breakpoint = LspDebugUtils.CreateBreakpoint(BreakpointDetails.Create(e.Breakpoint));
137+
var breakpoint = LspDebugUtils.CreateBreakpoint(
138+
BreakpointDetails.Create(e.Breakpoint, e.UpdateType)
139+
);
140+
141+
string reason = (e.UpdateType) switch {
142+
BreakpointUpdateType.Set => BreakpointEventReason.New,
143+
BreakpointUpdateType.Removed => BreakpointEventReason.Removed,
144+
BreakpointUpdateType.Enabled => BreakpointEventReason.Changed,
145+
BreakpointUpdateType.Disabled => BreakpointEventReason.Changed,
146+
_ => "InvalidBreakpointUpdateTypeEnum"
147+
};
148+
149+
_debugAdapterServer.SendNotification(
150+
EventNames.Breakpoint,
151+
new BreakpointEvent { Breakpoint = breakpoint, Reason = reason }
152+
);
155153
}
156154
else if (e.Breakpoint is CommandBreakpoint)
157155
{
158156
_logger.LogTrace("Function breakpoint updated event is not supported yet");
159-
return;
160157
}
161158
else
162159
{
163160
_logger.LogError($"Unrecognized breakpoint type {e.Breakpoint.GetType().FullName}");
164-
return;
165161
}
166-
167-
_debugAdapterServer.SendNotification(EventNames.Breakpoint,
168-
new BreakpointEvent
169-
{
170-
Reason = reason,
171-
Breakpoint = breakpoint
172-
});
173162
}
174163

175164
#endregion

src/PowerShellEditorServices/Services/DebugAdapter/Debugging/BreakpointDetails.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,11 @@ internal static BreakpointDetails Create(
7777
/// PowerShell Breakpoint object.
7878
/// </summary>
7979
/// <param name="breakpoint">The Breakpoint instance from which details will be taken.</param>
80+
/// <param name="updateType">The BreakpointUpdateType to determine if the breakpoint is verified.</param>
8081
/// <returns>A new instance of the BreakpointDetails class.</returns>
81-
internal static BreakpointDetails Create(Breakpoint breakpoint)
82+
internal static BreakpointDetails Create(
83+
Breakpoint breakpoint,
84+
BreakpointUpdateType updateType = BreakpointUpdateType.Set)
8285
{
8386
Validate.IsNotNull("breakpoint", breakpoint);
8487

@@ -91,7 +94,7 @@ internal static BreakpointDetails Create(Breakpoint breakpoint)
9194
var breakpointDetails = new BreakpointDetails
9295
{
9396
Id = breakpoint.Id,
94-
Verified = true,
97+
Verified = updateType != BreakpointUpdateType.Disabled,
9598
Source = lineBreakpoint.Script,
9699
LineNumber = lineBreakpoint.Line,
97100
ColumnNumber = lineBreakpoint.Column,

src/PowerShellEditorServices/Services/DebugAdapter/Handlers/LaunchAndAttachHandler.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,13 @@ await _powerShellContextService.ExecuteScriptStringAsync(
303303
string debugRunspaceCmd;
304304
if (request.RunspaceName != null)
305305
{
306-
IEnumerable<int?> ids = await _powerShellContextService.ExecuteCommandAsync<int?>(new PSCommand()
307-
.AddCommand("Microsoft.PowerShell.Utility\\Get-Runspace")
308-
.AddParameter("Name", request.RunspaceName)
309-
.AddCommand("Microsoft.PowerShell.Utility\\Select-Object")
310-
.AddParameter("ExpandProperty", "Id")).ConfigureAwait(false);
306+
IEnumerable<int?> ids = await _powerShellContextService.ExecuteCommandAsync<int?>(
307+
new PSCommand()
308+
.AddCommand("Microsoft.PowerShell.Utility\\Get-Runspace")
309+
.AddParameter("Name", request.RunspaceName)
310+
.AddCommand("Microsoft.PowerShell.Utility\\Select-Object")
311+
.AddParameter("ExpandProperty", "Id"), cancellationToken: cancellationToken).ConfigureAwait(false);
312+
311313
foreach (var id in ids)
312314
{
313315
_debugStateService.RunspaceId = id;

src/PowerShellEditorServices/Services/DebugAdapter/Handlers/ThreadsHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public Task<ThreadsResponse> Handle(ThreadsArguments request, CancellationToken
2020
{
2121
// TODO: OmniSharp supports multithreaded debugging (where
2222
// multiple threads can be debugged at once), but we don't. This
23-
// means we always need to set AllThreadsStoppped and
23+
// means we always need to set AllThreadsStopped and
2424
// AllThreadsContinued in our events. But if we one day support
2525
// multithreaded debugging, we'd need a way to associate
2626
// debugged runspaces with .NET threads in a consistent way.

src/PowerShellEditorServices/Services/PowerShellContext/Console/ConsoleReadLine.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,8 @@ internal async Task<string> InvokeLegacyReadLineAsync(bool isCommandLine, Cancel
208208
command.AddParameter("CursorColumn", currentCursorIndex);
209209
command.AddParameter("Options", null);
210210

211-
var results = await this.powerShellContext
212-
.ExecuteCommandAsync<CommandCompletion>(command, sendOutputToHost: false, sendErrorToHost: false)
213-
.ConfigureAwait(false);
211+
var results = await this.powerShellContext.ExecuteCommandAsync<CommandCompletion>(
212+
command, sendOutputToHost: false, sendErrorToHost: false, cancellationToken).ConfigureAwait(false);
214213

215214
currentCompletion = results.FirstOrDefault();
216215
}
@@ -327,8 +326,8 @@ internal async Task<string> InvokeLegacyReadLineAsync(bool isCommandLine, Cancel
327326
PSCommand command = new PSCommand();
328327
command.AddCommand("Get-History");
329328

330-
currentHistory = await this.powerShellContext.ExecuteCommandAsync<PSObject>(command, sendOutputToHost: false, sendErrorToHost: false)
331-
.ConfigureAwait(false)
329+
currentHistory = await this.powerShellContext.ExecuteCommandAsync<PSObject>(
330+
command, sendOutputToHost: false, sendErrorToHost: false, cancellationToken).ConfigureAwait(false)
332331
as Collection<PSObject>;
333332

334333
if (currentHistory != null)

src/PowerShellEditorServices/Services/PowerShellContext/Handlers/ExpandAliasHandler.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ function __Expand-Alias {
6969
.AddStatement()
7070
.AddCommand("__Expand-Alias")
7171
.AddArgument(request.Text);
72-
var result = await _powerShellContextService.ExecuteCommandAsync<string>(psCommand).ConfigureAwait(false);
72+
var result = await _powerShellContextService.ExecuteCommandAsync<string>(
73+
psCommand, cancellationToken: cancellationToken).ConfigureAwait(false);
7374

7475
return new ExpandAliasResult
7576
{

src/PowerShellEditorServices/Services/PowerShellContext/Handlers/GetCommandHandler.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ public async Task<List<PSCommandMessage>> Handle(GetCommandParams request, Cance
5353
.AddCommand("Microsoft.PowerShell.Utility\\Sort-Object")
5454
.AddParameter("Property", "Name");
5555

56-
IEnumerable<CommandInfo> result = await _powerShellContextService.ExecuteCommandAsync<CommandInfo>(psCommand).ConfigureAwait(false);
56+
IEnumerable<CommandInfo> result = await _powerShellContextService.ExecuteCommandAsync<CommandInfo>(
57+
psCommand, cancellationToken: cancellationToken).ConfigureAwait(false);
5758

5859
var commandList = new List<PSCommandMessage>();
5960
if (result != null)

src/PowerShellEditorServices/Services/PowerShellContext/Handlers/PSHostProcessAndRunspaceHandlers.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ public async Task<RunspaceResponse[]> Handle(GetRunspaceParams request, Cancella
8787
var psCommand = new PSCommand().AddCommand("Microsoft.PowerShell.Utility\\Get-Runspace");
8888
var sb = new StringBuilder();
8989
// returns (not deserialized) Runspaces. For simpler code, we use PSObject and rely on dynamic later.
90-
runspaces = await _powerShellContextService.ExecuteCommandAsync<PSObject>(psCommand, sb).ConfigureAwait(false);
90+
runspaces = await _powerShellContextService.ExecuteCommandAsync<PSObject>(
91+
psCommand, sb, cancellationToken: cancellationToken).ConfigureAwait(false);
9192
}
9293

9394
var runspaceResponses = new List<RunspaceResponse>();

0 commit comments

Comments
 (0)