Skip to content

Commit 3605e55

Browse files
committed
Merge pull request #176 from rkeithhill/rkeithhill/is173-impl-func-breakpoints
Fixes #173 - implementation for function breakpoints
2 parents 3e525a1 + 06f5756 commit 3605e55

File tree

15 files changed

+470
-131
lines changed

15 files changed

+470
-131
lines changed

src/PowerShellEditorServices.Protocol/Client/DebugAdapterClientBase.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@ public DebugAdapterClient(ChannelBase clientChannel)
1717
{
1818
}
1919

20-
public Task LaunchScript(string scriptFilePath)
20+
public async Task LaunchScript(string scriptFilePath)
2121
{
22-
return this.SendRequest(
22+
await this.SendRequest(
2323
LaunchRequest.Type,
24-
new LaunchRequestArguments
25-
{
24+
new LaunchRequestArguments {
2625
Program = scriptFilePath
2726
});
27+
28+
await this.SendRequest(ConfigurationDoneRequest.Type, null);
2829
}
2930

3031
protected override async Task OnStart()

src/PowerShellEditorServices.Protocol/DebugAdapter/Breakpoint.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class Breakpoint
2121

2222
public string Source { get; set; }
2323

24-
public int Line { get; set; }
24+
public int? Line { get; set; }
2525

2626
public int? Column { get; set; }
2727

@@ -41,5 +41,14 @@ public static Breakpoint Create(
4141
Column = breakpointDetails.ColumnNumber
4242
};
4343
}
44+
45+
public static Breakpoint Create(
46+
FunctionBreakpointDetails breakpointDetails)
47+
{
48+
return new Breakpoint {
49+
Verified = breakpointDetails.Verified,
50+
Message = breakpointDetails.Message
51+
};
52+
}
4453
}
4554
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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 ConfigurationDoneRequest
11+
{
12+
public static readonly
13+
RequestType<object, object> Type =
14+
RequestType<object, object>.Create("configurationDone");
15+
}
16+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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 SetFunctionBreakpointsRequest
11+
{
12+
public static readonly
13+
RequestType<SetFunctionBreakpointsRequestArguments, SetBreakpointsResponseBody> Type =
14+
RequestType<SetFunctionBreakpointsRequestArguments, SetBreakpointsResponseBody>.Create("setFunctionBreakpoints");
15+
}
16+
17+
public class SetFunctionBreakpointsRequestArguments
18+
{
19+
public FunctionBreakpoint[] Breakpoints { get; set; }
20+
}
21+
22+
public class FunctionBreakpoint
23+
{
24+
/// <summary>
25+
/// Gets or sets the name of the function to break on when it is invoked.
26+
/// </summary>
27+
public string Name { get; set; }
28+
29+
public string Condition { get; set; }
30+
}
31+
}

src/PowerShellEditorServices.Protocol/PowerShellEditorServices.Protocol.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@
5050
<ItemGroup>
5151
<Compile Include="DebugAdapter\AttachRequest.cs" />
5252
<Compile Include="DebugAdapter\Breakpoint.cs" />
53+
<Compile Include="DebugAdapter\ConfigurationDoneRequest.cs" />
5354
<Compile Include="DebugAdapter\ContinueRequest.cs" />
55+
<Compile Include="DebugAdapter\SetFunctionBreakpointsRequest.cs" />
5456
<Compile Include="LanguageServer\FindModuleRequest.cs" />
5557
<Compile Include="LanguageServer\InstallModuleRequest.cs" />
5658
<Compile Include="MessageProtocol\IMessageSender.cs" />

src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public class DebugAdapter : DebugAdapterBase
2020
{
2121
private EditorSession editorSession;
2222
private OutputDebouncer outputDebouncer;
23+
private string scriptPathToLaunch;
24+
private string arguments;
2325

2426
public DebugAdapter() : this(new StdioServerChannel())
2527
{
@@ -42,10 +44,12 @@ protected override void Initialize()
4244

4345
this.SetRequestHandler(LaunchRequest.Type, this.HandleLaunchRequest);
4446
this.SetRequestHandler(AttachRequest.Type, this.HandleAttachRequest);
47+
this.SetRequestHandler(ConfigurationDoneRequest.Type, this.HandleConfigurationDoneRequest);
4548
this.SetRequestHandler(DisconnectRequest.Type, this.HandleDisconnectRequest);
4649

4750
this.SetRequestHandler(SetBreakpointsRequest.Type, this.HandleSetBreakpointsRequest);
4851
this.SetRequestHandler(SetExceptionBreakpointsRequest.Type, this.HandleSetExceptionBreakpointsRequest);
52+
this.SetRequestHandler(SetFunctionBreakpointsRequest.Type, this.HandleSetFunctionBreakpointsRequest);
4953

5054
this.SetRequestHandler(ContinueRequest.Type, this.HandleContinueRequest);
5155
this.SetRequestHandler(NextRequest.Type, this.HandleNextRequest);
@@ -110,12 +114,35 @@ protected async Task HandleLaunchRequest(
110114
Logger.Write(LogLevel.Verbose, "Script arguments are: " + arguments);
111115
}
112116

117+
// NOTE: We don't actually launch the script in response to this
118+
// request. We wait until we receive the configurationDone request
119+
// to actually launch the script under the debugger. This gives
120+
// us and VSCode a chance to finish configuring all the types of
121+
// breakpoints.
122+
this.scriptPathToLaunch = launchParams.Program;
123+
this.arguments = arguments;
124+
125+
await requestContext.SendResult(null);
126+
}
127+
128+
protected Task HandleAttachRequest(
129+
AttachRequestArguments attachParams,
130+
RequestContext<object> requestContext)
131+
{
132+
// TODO: Implement this once we support attaching to processes
133+
throw new NotImplementedException();
134+
}
135+
136+
protected async Task HandleConfigurationDoneRequest(
137+
object args,
138+
RequestContext<object> requestContext)
139+
{
113140
// Execute the given PowerShell script and send the response.
114141
// Note that we aren't waiting for execution to complete here
115142
// because the debugger could stop while the script executes.
116143
Task executeTask =
117144
editorSession.PowerShellContext
118-
.ExecuteScriptAtPath(launchParams.Program, arguments)
145+
.ExecuteScriptAtPath(this.scriptPathToLaunch, this.arguments)
119146
.ContinueWith(
120147
async (t) => {
121148
Logger.Write(LogLevel.Verbose, "Execution completed, terminating...");
@@ -131,14 +158,6 @@ await requestContext.SendEvent(
131158
await requestContext.SendResult(null);
132159
}
133160

134-
protected Task HandleAttachRequest(
135-
AttachRequestArguments attachParams,
136-
RequestContext<object> requestContext)
137-
{
138-
// TODO: Implement this once we support attaching to processes
139-
throw new NotImplementedException();
140-
}
141-
142161
protected Task HandleDisconnectRequest(
143162
object disconnectParams,
144163
RequestContext<object> requestContext)
@@ -198,6 +217,32 @@ await requestContext.SendResult(
198217
});
199218
}
200219

220+
protected async Task HandleSetFunctionBreakpointsRequest(
221+
SetFunctionBreakpointsRequestArguments setBreakpointsParams,
222+
RequestContext<SetBreakpointsResponseBody> requestContext)
223+
{
224+
var breakpointDetails = new FunctionBreakpointDetails[setBreakpointsParams.Breakpoints.Length];
225+
for (int i = 0; i < breakpointDetails.Length; i++)
226+
{
227+
FunctionBreakpoint funcBreakpoint = setBreakpointsParams.Breakpoints[i];
228+
breakpointDetails[i] = FunctionBreakpointDetails.Create(
229+
funcBreakpoint.Name,
230+
funcBreakpoint.Condition);
231+
}
232+
233+
FunctionBreakpointDetails[] breakpoints =
234+
await editorSession.DebugService.SetCommandBreakpoints(
235+
breakpointDetails);
236+
237+
await requestContext.SendResult(
238+
new SetBreakpointsResponseBody {
239+
Breakpoints =
240+
breakpoints
241+
.Select(Protocol.DebugAdapter.Breakpoint.Create)
242+
.ToArray()
243+
});
244+
}
245+
201246
protected async Task HandleSetExceptionBreakpointsRequest(
202247
SetExceptionBreakpointsRequestArguments setExceptionBreakpointsParams,
203248
RequestContext<object> requestContext)

src/PowerShellEditorServices.Protocol/Server/DebugAdapterBase.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ await requestContext.SendEvent(
6363
await requestContext.SendResult(
6464
new InitializeResponseBody
6565
{
66+
SupportsConfigurationDoneRequest = true,
6667
SupportsConditionalBreakpoints = true,
68+
SupportsFunctionBreakpoints = true
6769
});
6870
}
6971
}

src/PowerShellEditorServices/Debugging/BreakpointDetails.cs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,8 @@ namespace Microsoft.PowerShell.EditorServices
1313
/// Provides details about a breakpoint that is set in the
1414
/// PowerShell debugger.
1515
/// </summary>
16-
public class BreakpointDetails
16+
public class BreakpointDetails : BreakpointDetailsBase
1717
{
18-
/// <summary>
19-
/// Gets or sets a boolean indicator that if true, breakpoint could be set
20-
/// (but not necessarily at the desired location).
21-
/// </summary>
22-
public bool Verified { get; set; }
23-
24-
/// <summary>
25-
/// Gets or set an optional message about the state of the breakpoint. This is shown to the user
26-
/// and can be used to explain why a breakpoint could not be verified.
27-
/// </summary>
28-
public string Message { get; set; }
29-
3018
/// <summary>
3119
/// Gets the source where the breakpoint is located. Used only for debug purposes.
3220
/// </summary>
@@ -42,11 +30,6 @@ public class BreakpointDetails
4230
/// </summary>
4331
public int? ColumnNumber { get; private set; }
4432

45-
/// <summary>
46-
/// Gets the breakpoint condition string.
47-
/// </summary>
48-
public string Condition { get; private set; }
49-
5033
private BreakpointDetails()
5134
{
5235
}
@@ -91,7 +74,7 @@ public static BreakpointDetails Create(Breakpoint breakpoint)
9174
if (lineBreakpoint == null)
9275
{
9376
throw new ArgumentException(
94-
"Expected breakpoint type:" + breakpoint.GetType().Name);
77+
"Unexpected breakpoint type: " + breakpoint.GetType().Name);
9578
}
9679

9780
var breakpointDetails = new BreakpointDetails
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
namespace Microsoft.PowerShell.EditorServices
7+
{
8+
/// <summary>
9+
/// Provides details about a breakpoint that is set in the
10+
/// PowerShell debugger.
11+
/// </summary>
12+
public abstract class BreakpointDetailsBase
13+
{
14+
/// <summary>
15+
/// Gets or sets a boolean indicator that if true, breakpoint could be set
16+
/// (but not necessarily at the desired location).
17+
/// </summary>
18+
public bool Verified { get; set; }
19+
20+
/// <summary>
21+
/// Gets or set an optional message about the state of the breakpoint. This is shown to the user
22+
/// and can be used to explain why a breakpoint could not be verified.
23+
/// </summary>
24+
public string Message { get; set; }
25+
26+
/// <summary>
27+
/// Gets the breakpoint condition string.
28+
/// </summary>
29+
public string Condition { get; protected set; }
30+
}
31+
}

0 commit comments

Comments
 (0)