Skip to content

Commit bf58eb6

Browse files
committed
Add BreakpointEvent to be sent when breakpoints change in session
This change adds the BreakpointEvent message type to the debug adapter and wires it up to be sent anytime breakpoints change in the editing session. This allows the user to call Set-PSBreakpoint in the integrated console to add new breakpoints and then see them be set in the editor UI. Resolves PowerShell/vscode-powershell#660
1 parent 34ee536 commit bf58eb6

File tree

5 files changed

+95
-12
lines changed

5 files changed

+95
-12
lines changed

src/PowerShellEditorServices.Protocol/DebugAdapter/Breakpoint.cs

+9-6
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,21 @@ namespace Microsoft.PowerShell.EditorServices.Protocol.DebugAdapter
99
{
1010
public class Breakpoint
1111
{
12+
public int? Id { get; set; }
13+
1214
/// <summary>
13-
/// Gets an boolean indicator that if true, breakpoint could be set
14-
/// (but not necessarily at the desired location).
15+
/// Gets an boolean indicator that if true, breakpoint could be set
16+
/// (but not necessarily at the desired location).
1517
/// </summary>
1618
public bool Verified { get; set; }
1719

1820
/// <summary>
19-
/// Gets an optional message about the state of the breakpoint. This is shown to the user
21+
/// Gets an optional message about the state of the breakpoint. This is shown to the user
2022
/// and can be used to explain why a breakpoint could not be verified.
2123
/// </summary>
2224
public string Message { get; set; }
2325

24-
public string Source { get; set; }
26+
public Source Source { get; set; }
2527

2628
public int? Line { get; set; }
2729

@@ -38,9 +40,10 @@ public static Breakpoint Create(
3840

3941
return new Breakpoint
4042
{
43+
Id = breakpointDetails.Id,
4144
Verified = breakpointDetails.Verified,
4245
Message = breakpointDetails.Message,
43-
Source = breakpointDetails.Source,
46+
Source = new Source { Path = breakpointDetails.Source },
4447
Line = breakpointDetails.LineNumber,
4548
Column = breakpointDetails.ColumnNumber
4649
};
@@ -70,7 +73,7 @@ public static Breakpoint Create(
7073
return new Breakpoint {
7174
Verified = verified,
7275
Message = message,
73-
Source = source,
76+
Source = new Source { Path = source },
7477
Line = sourceBreakpoint.Line,
7578
Column = sourceBreakpoint.Column
7679
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
//
5+
6+
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;
7+
8+
namespace Microsoft.PowerShell.EditorServices.Protocol.DebugAdapter
9+
{
10+
public class BreakpointEvent
11+
{
12+
public static readonly
13+
NotificationType<BreakpointEvent, object> Type =
14+
NotificationType<BreakpointEvent, object>.Create("breakpoint");
15+
16+
public string Reason { get; set; }
17+
18+
public Breakpoint Breakpoint { get; set; }
19+
}
20+
}

src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs

+57-4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class DebugAdapter
3636
private IMessageSender messageSender;
3737
private IMessageHandlers messageHandlers;
3838
private bool isInteractiveDebugSession;
39+
private bool setBreakpointInProgress;
3940
private RequestContext<object> disconnectRequestContext = null;
4041

4142
public DebugAdapter(
@@ -522,10 +523,24 @@ await requestContext.SendResult(
522523
BreakpointDetails[] updatedBreakpointDetails = breakpointDetails;
523524
if (!this.noDebug)
524525
{
525-
updatedBreakpointDetails =
526-
await editorSession.DebugService.SetLineBreakpoints(
527-
scriptFile,
528-
breakpointDetails);
526+
this.setBreakpointInProgress = true;
527+
528+
try
529+
{
530+
updatedBreakpointDetails =
531+
await editorSession.DebugService.SetLineBreakpoints(
532+
scriptFile,
533+
breakpointDetails);
534+
}
535+
catch (Exception e)
536+
{
537+
// Log whatever the error is
538+
Logger.WriteException("Caught error while setting breakpoints in SetBreakpoints handler", e);
539+
}
540+
finally
541+
{
542+
this.setBreakpointInProgress = false;
543+
}
529544
}
530545

531546
await requestContext.SendResult(
@@ -855,13 +870,15 @@ await this.messageSender.SendEvent(
855870
private void RegisterEventHandlers()
856871
{
857872
this.editorSession.PowerShellContext.RunspaceChanged += this.powerShellContext_RunspaceChanged;
873+
this.editorSession.DebugService.BreakpointUpdated += DebugService_BreakpointUpdated;
858874
this.editorSession.DebugService.DebuggerStopped += this.DebugService_DebuggerStopped;
859875
this.editorSession.PowerShellContext.DebuggerResumed += this.powerShellContext_DebuggerResumed;
860876
}
861877

862878
private void UnregisterEventHandlers()
863879
{
864880
this.editorSession.PowerShellContext.RunspaceChanged -= this.powerShellContext_RunspaceChanged;
881+
this.editorSession.DebugService.BreakpointUpdated -= DebugService_BreakpointUpdated;
865882
this.editorSession.DebugService.DebuggerStopped -= this.DebugService_DebuggerStopped;
866883
this.editorSession.PowerShellContext.DebuggerResumed -= this.powerShellContext_DebuggerResumed;
867884
}
@@ -940,6 +957,42 @@ await this.messageSender.SendEvent(
940957
});
941958
}
942959

960+
private async void DebugService_BreakpointUpdated(object sender, BreakpointUpdatedEventArgs e)
961+
{
962+
string reason = "changed";
963+
964+
if (this.setBreakpointInProgress)
965+
{
966+
// Don't send breakpoint update notifications when setting
967+
// breakpoints on behalf of the client.
968+
return;
969+
}
970+
971+
switch (e.UpdateType)
972+
{
973+
case BreakpointUpdateType.Set:
974+
reason = "new";
975+
break;
976+
977+
case BreakpointUpdateType.Removed:
978+
reason = "removed";
979+
break;
980+
}
981+
982+
var breakpoint = Protocol.DebugAdapter.Breakpoint.Create(
983+
BreakpointDetails.Create(e.Breakpoint));
984+
985+
breakpoint.Verified = e.UpdateType != BreakpointUpdateType.Disabled;
986+
987+
await this.messageSender.SendEvent(
988+
BreakpointEvent.Type,
989+
new BreakpointEvent
990+
{
991+
Reason = reason,
992+
Breakpoint = breakpoint
993+
});
994+
}
995+
943996
#endregion
944997

945998
#region Events

src/PowerShellEditorServices/Debugging/BreakpointDetails.cs

+7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ namespace Microsoft.PowerShell.EditorServices
1515
/// </summary>
1616
public class BreakpointDetails : BreakpointDetailsBase
1717
{
18+
/// <summary>
19+
/// Gets the unique ID of the breakpoint.
20+
/// </summary>
21+
/// <returns></returns>
22+
public int Id { get; private set; }
23+
1824
/// <summary>
1925
/// Gets the source where the breakpoint is located. Used only for debug purposes.
2026
/// </summary>
@@ -83,6 +89,7 @@ public static BreakpointDetails Create(Breakpoint breakpoint)
8389

8490
var breakpointDetails = new BreakpointDetails
8591
{
92+
Id = breakpoint.Id,
8693
Verified = true,
8794
Source = lineBreakpoint.Script,
8895
LineNumber = lineBreakpoint.Line,

src/PowerShellEditorServices/Debugging/DebugService.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ public async Task<BreakpointDetails[]> SetLineBreakpoints(
195195
psCommand.AddParameter("Line", breakpoint.LineNumber);
196196

197197
// Check if the user has specified the column number for the breakpoint.
198-
if (breakpoint.ColumnNumber.HasValue)
198+
if (breakpoint.ColumnNumber.HasValue && breakpoint.ColumnNumber.Value > 0)
199199
{
200200
// It bums me out that PowerShell will silently ignore a breakpoint
201201
// where either the line or the column is invalid. I'd rather have an
@@ -368,7 +368,7 @@ public VariableDetailsBase[] GetVariables(int variableReferenceId)
368368
logger.Write(LogLevel.Warning, $"Received request for variableReferenceId {variableReferenceId} that is out of range of valid indices.");
369369
return new VariableDetailsBase[0];
370370
}
371-
371+
372372
VariableDetailsBase parentVariable = this.variables[variableReferenceId];
373373
if (parentVariable.IsExpandable)
374374
{

0 commit comments

Comments
 (0)