Skip to content

Fixes #173 - implementation for function breakpoints #176

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
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ public DebugAdapterClient(ChannelBase clientChannel)
{
}

public Task LaunchScript(string scriptFilePath)
public async Task LaunchScript(string scriptFilePath)
{
return this.SendRequest(
await this.SendRequest(
LaunchRequest.Type,
new LaunchRequestArguments
{
new LaunchRequestArguments {
Program = scriptFilePath
});

await this.SendRequest(ConfigurationDoneRequest.Type, null);
}

protected override async Task OnStart()
Expand Down
11 changes: 10 additions & 1 deletion src/PowerShellEditorServices.Protocol/DebugAdapter/Breakpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class Breakpoint

public string Source { get; set; }

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

public int? Column { get; set; }

Expand All @@ -41,5 +41,14 @@ public static Breakpoint Create(
Column = breakpointDetails.ColumnNumber
};
}

public static Breakpoint Create(
FunctionBreakpointDetails breakpointDetails)
{
return new Breakpoint {
Verified = breakpointDetails.Verified,
Message = breakpointDetails.Message
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;

namespace Microsoft.PowerShell.EditorServices.Protocol.DebugAdapter
{
public class ConfigurationDoneRequest
{
public static readonly
RequestType<object, object> Type =
RequestType<object, object>.Create("configurationDone");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;

namespace Microsoft.PowerShell.EditorServices.Protocol.DebugAdapter
{
public class SetFunctionBreakpointsRequest
{
public static readonly
RequestType<SetFunctionBreakpointsRequestArguments, SetBreakpointsResponseBody> Type =
RequestType<SetFunctionBreakpointsRequestArguments, SetBreakpointsResponseBody>.Create("setFunctionBreakpoints");
}

public class SetFunctionBreakpointsRequestArguments
{
public FunctionBreakpoint[] Breakpoints { get; set; }
}

public class FunctionBreakpoint
{
/// <summary>
/// Gets or sets the name of the function to break on when it is invoked.
/// </summary>
public string Name { get; set; }

public string Condition { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@
<ItemGroup>
<Compile Include="DebugAdapter\AttachRequest.cs" />
<Compile Include="DebugAdapter\Breakpoint.cs" />
<Compile Include="DebugAdapter\ConfigurationDoneRequest.cs" />
<Compile Include="DebugAdapter\ContinueRequest.cs" />
<Compile Include="DebugAdapter\SetFunctionBreakpointsRequest.cs" />
<Compile Include="LanguageServer\FindModuleRequest.cs" />
<Compile Include="LanguageServer\InstallModuleRequest.cs" />
<Compile Include="MessageProtocol\IMessageSender.cs" />
Expand Down
63 changes: 54 additions & 9 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 string scriptPathToLaunch;
private string arguments;

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

this.SetRequestHandler(LaunchRequest.Type, this.HandleLaunchRequest);
this.SetRequestHandler(AttachRequest.Type, this.HandleAttachRequest);
this.SetRequestHandler(ConfigurationDoneRequest.Type, this.HandleConfigurationDoneRequest);
this.SetRequestHandler(DisconnectRequest.Type, this.HandleDisconnectRequest);

this.SetRequestHandler(SetBreakpointsRequest.Type, this.HandleSetBreakpointsRequest);
this.SetRequestHandler(SetExceptionBreakpointsRequest.Type, this.HandleSetExceptionBreakpointsRequest);
this.SetRequestHandler(SetFunctionBreakpointsRequest.Type, this.HandleSetFunctionBreakpointsRequest);

this.SetRequestHandler(ContinueRequest.Type, this.HandleContinueRequest);
this.SetRequestHandler(NextRequest.Type, this.HandleNextRequest);
Expand Down Expand Up @@ -110,12 +114,35 @@ 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.
this.scriptPathToLaunch = launchParams.Program;
this.arguments = arguments;

await requestContext.SendResult(null);
}

protected Task HandleAttachRequest(
AttachRequestArguments attachParams,
RequestContext<object> requestContext)
{
// TODO: Implement this once we support attaching to processes
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(launchParams.Program, arguments)
.ExecuteScriptAtPath(this.scriptPathToLaunch, this.arguments)
.ContinueWith(
async (t) => {
Logger.Write(LogLevel.Verbose, "Execution completed, terminating...");
Expand All @@ -131,14 +158,6 @@ await requestContext.SendEvent(
await requestContext.SendResult(null);
}

protected Task HandleAttachRequest(
AttachRequestArguments attachParams,
RequestContext<object> requestContext)
{
// TODO: Implement this once we support attaching to processes
throw new NotImplementedException();
}

protected Task HandleDisconnectRequest(
object disconnectParams,
RequestContext<object> requestContext)
Expand Down Expand Up @@ -198,6 +217,32 @@ await requestContext.SendResult(
});
}

protected async Task HandleSetFunctionBreakpointsRequest(
SetFunctionBreakpointsRequestArguments setBreakpointsParams,
RequestContext<SetBreakpointsResponseBody> requestContext)
{
var breakpointDetails = new FunctionBreakpointDetails[setBreakpointsParams.Breakpoints.Length];
for (int i = 0; i < breakpointDetails.Length; i++)
{
FunctionBreakpoint funcBreakpoint = setBreakpointsParams.Breakpoints[i];
breakpointDetails[i] = FunctionBreakpointDetails.Create(
funcBreakpoint.Name,
funcBreakpoint.Condition);
}

FunctionBreakpointDetails[] breakpoints =
await editorSession.DebugService.SetCommandBreakpoints(
breakpointDetails);

await requestContext.SendResult(
new SetBreakpointsResponseBody {
Breakpoints =
breakpoints
.Select(Protocol.DebugAdapter.Breakpoint.Create)
.ToArray()
});
}

protected async Task HandleSetExceptionBreakpointsRequest(
SetExceptionBreakpointsRequestArguments setExceptionBreakpointsParams,
RequestContext<object> requestContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ await requestContext.SendEvent(
await requestContext.SendResult(
new InitializeResponseBody
{
SupportsConfigurationDoneRequest = true,
SupportsConditionalBreakpoints = true,
SupportsFunctionBreakpoints = true
});
}
}
Expand Down
21 changes: 2 additions & 19 deletions src/PowerShellEditorServices/Debugging/BreakpointDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,8 @@ namespace Microsoft.PowerShell.EditorServices
/// Provides details about a breakpoint that is set in the
/// PowerShell debugger.
/// </summary>
public class BreakpointDetails
public class BreakpointDetails : BreakpointDetailsBase
{
/// <summary>
/// Gets or sets a boolean indicator that if true, breakpoint could be set
/// (but not necessarily at the desired location).
/// </summary>
public bool Verified { get; set; }

/// <summary>
/// Gets or set an optional message about the state of the breakpoint. This is shown to the user
/// and can be used to explain why a breakpoint could not be verified.
/// </summary>
public string Message { get; set; }

/// <summary>
/// Gets the source where the breakpoint is located. Used only for debug purposes.
/// </summary>
Expand All @@ -42,11 +30,6 @@ public class BreakpointDetails
/// </summary>
public int? ColumnNumber { get; private set; }

/// <summary>
/// Gets the breakpoint condition string.
/// </summary>
public string Condition { get; private set; }

private BreakpointDetails()
{
}
Expand Down Expand Up @@ -91,7 +74,7 @@ public static BreakpointDetails Create(Breakpoint breakpoint)
if (lineBreakpoint == null)
{
throw new ArgumentException(
"Expected breakpoint type:" + breakpoint.GetType().Name);
"Unexpected breakpoint type: " + breakpoint.GetType().Name);
}

var breakpointDetails = new BreakpointDetails
Expand Down
31 changes: 31 additions & 0 deletions src/PowerShellEditorServices/Debugging/BreakpointDetailsBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

namespace Microsoft.PowerShell.EditorServices
{
/// <summary>
/// Provides details about a breakpoint that is set in the
/// PowerShell debugger.
/// </summary>
public abstract class BreakpointDetailsBase
{
/// <summary>
/// Gets or sets a boolean indicator that if true, breakpoint could be set
/// (but not necessarily at the desired location).
/// </summary>
public bool Verified { get; set; }

/// <summary>
/// Gets or set an optional message about the state of the breakpoint. This is shown to the user
/// and can be used to explain why a breakpoint could not be verified.
/// </summary>
public string Message { get; set; }

/// <summary>
/// Gets the breakpoint condition string.
/// </summary>
public string Condition { get; protected set; }
}
}
Loading