Skip to content

Commit ca7045a

Browse files
working attach handler
1 parent 0e8e815 commit ca7045a

File tree

3 files changed

+217
-159
lines changed

3 files changed

+217
-159
lines changed

src/PowerShellEditorServices.Engine/Server/PsesDebugServer.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ public async Task StartAsync(IServiceProvider languageServerServiceProvider)
4545
options.Services = new ServiceCollection()
4646
.AddSingleton(languageServerServiceProvider.GetService<PowerShellContextService>())
4747
.AddSingleton<DebugService>()
48-
.AddSingleton<DebugStateService>();
48+
.AddSingleton<DebugStateService>()
49+
.AddSingleton<DebugEventHandlerService>();
4950

5051
options
5152
.WithInput(_inputStream)
@@ -55,7 +56,8 @@ public async Task StartAsync(IServiceProvider languageServerServiceProvider)
5556

5657
options
5758
.WithHandler<InitializeHandler>()
58-
.WithHandler<LaunchAndAttachHandler>();
59+
.WithHandler<LaunchHandler>()
60+
.WithHandler<AttachHandler>();
5961

6062
logger.LogInformation("Handlers added");
6163
});
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
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 System.Management.Automation;
7+
using Microsoft.Extensions.Logging;
8+
using Microsoft.PowerShell.EditorServices.Engine.Services.DebugAdapter;
9+
using Microsoft.PowerShell.EditorServices.Engine.Services.PowerShellContext;
10+
using Microsoft.PowerShell.EditorServices.Utility;
11+
using OmniSharp.Extensions.DebugAdapter.Protocol.Events;
12+
using OmniSharp.Extensions.JsonRpc;
13+
14+
namespace Microsoft.PowerShell.EditorServices.Engine.Services
15+
{
16+
public class DebugEventHandlerService
17+
{
18+
private readonly ILogger<DebugEventHandlerService> _logger;
19+
private readonly PowerShellContextService _powerShellContextService;
20+
private readonly DebugService _debugService;
21+
private readonly DebugStateService _debugStateService;
22+
private readonly IJsonRpcServer _jsonRpcServer;
23+
24+
public DebugEventHandlerService(
25+
ILoggerFactory factory,
26+
PowerShellContextService powerShellContextService,
27+
DebugService debugService,
28+
DebugStateService debugStateService,
29+
IJsonRpcServer jsonRpcServer)
30+
{
31+
_logger = factory.CreateLogger<DebugEventHandlerService>();
32+
_powerShellContextService = powerShellContextService;
33+
_debugService = debugService;
34+
_debugStateService = debugStateService;
35+
_jsonRpcServer = jsonRpcServer;
36+
}
37+
38+
internal void RegisterEventHandlers()
39+
{
40+
_powerShellContextService.RunspaceChanged += PowerShellContext_RunspaceChangedAsync;
41+
_debugService.BreakpointUpdated += DebugService_BreakpointUpdatedAsync;
42+
_debugService.DebuggerStopped += DebugService_DebuggerStoppedAsync;
43+
_powerShellContextService.DebuggerResumed += PowerShellContext_DebuggerResumedAsync;
44+
}
45+
46+
internal void UnregisterEventHandlers()
47+
{
48+
_powerShellContextService.RunspaceChanged -= PowerShellContext_RunspaceChangedAsync;
49+
_debugService.BreakpointUpdated -= DebugService_BreakpointUpdatedAsync;
50+
_debugService.DebuggerStopped -= DebugService_DebuggerStoppedAsync;
51+
_powerShellContextService.DebuggerResumed -= PowerShellContext_DebuggerResumedAsync;
52+
}
53+
54+
#region Event Handlers
55+
56+
private void DebugService_DebuggerStoppedAsync(object sender, DebuggerStoppedEventArgs e)
57+
{
58+
// Provide the reason for why the debugger has stopped script execution.
59+
// See https://github.com/Microsoft/vscode/issues/3648
60+
// The reason is displayed in the breakpoints viewlet. Some recommended reasons are:
61+
// "step", "breakpoint", "function breakpoint", "exception" and "pause".
62+
// We don't support exception breakpoints and for "pause", we can't distinguish
63+
// between stepping and the user pressing the pause/break button in the debug toolbar.
64+
string debuggerStoppedReason = "step";
65+
if (e.OriginalEvent.Breakpoints.Count > 0)
66+
{
67+
debuggerStoppedReason =
68+
e.OriginalEvent.Breakpoints[0] is CommandBreakpoint
69+
? "function breakpoint"
70+
: "breakpoint";
71+
}
72+
73+
_jsonRpcServer.SendNotification(EventNames.Stopped,
74+
new StoppedEvent
75+
{
76+
ThreadId = 1,
77+
Reason = debuggerStoppedReason
78+
});
79+
}
80+
81+
private void PowerShellContext_RunspaceChangedAsync(object sender, RunspaceChangedEventArgs e)
82+
{
83+
if (_debugStateService.WaitingForAttach &&
84+
e.ChangeAction == RunspaceChangeAction.Enter &&
85+
e.NewRunspace.Context == RunspaceContext.DebuggedRunspace)
86+
{
87+
// Send the InitializedEvent so that the debugger will continue
88+
// sending configuration requests
89+
_debugStateService.WaitingForAttach = false;
90+
_jsonRpcServer.SendNotification(EventNames.Initialized);
91+
}
92+
else if (
93+
e.ChangeAction == RunspaceChangeAction.Exit &&
94+
(_powerShellContextService.IsDebuggerStopped))
95+
{
96+
// Exited the session while the debugger is stopped,
97+
// send a ContinuedEvent so that the client changes the
98+
// UI to appear to be running again
99+
_jsonRpcServer.SendNotification(EventNames.Continued,
100+
new ContinuedEvent
101+
{
102+
ThreadId = 1,
103+
AllThreadsContinued = true
104+
});
105+
}
106+
}
107+
108+
private void PowerShellContext_DebuggerResumedAsync(object sender, DebuggerResumeAction e)
109+
{
110+
_jsonRpcServer.SendNotification(EventNames.Continued,
111+
new ContinuedEvent
112+
{
113+
AllThreadsContinued = true,
114+
ThreadId = 1
115+
});
116+
}
117+
118+
private void DebugService_BreakpointUpdatedAsync(object sender, BreakpointUpdatedEventArgs e)
119+
{
120+
string reason = "changed";
121+
122+
if (_debugStateService.SetBreakpointInProgress)
123+
{
124+
// Don't send breakpoint update notifications when setting
125+
// breakpoints on behalf of the client.
126+
return;
127+
}
128+
129+
switch (e.UpdateType)
130+
{
131+
case BreakpointUpdateType.Set:
132+
reason = "new";
133+
break;
134+
135+
case BreakpointUpdateType.Removed:
136+
reason = "removed";
137+
break;
138+
}
139+
140+
OmniSharp.Extensions.DebugAdapter.Protocol.Models.Breakpoint breakpoint;
141+
if (e.Breakpoint is LineBreakpoint)
142+
{
143+
breakpoint = LspBreakpointUtils.CreateBreakpoint(BreakpointDetails.Create(e.Breakpoint));
144+
}
145+
else if (e.Breakpoint is CommandBreakpoint)
146+
{
147+
_logger.LogTrace("Function breakpoint updated event is not supported yet");
148+
return;
149+
}
150+
else
151+
{
152+
_logger.LogError($"Unrecognized breakpoint type {e.Breakpoint.GetType().FullName}");
153+
return;
154+
}
155+
156+
breakpoint.Verified = e.UpdateType != BreakpointUpdateType.Disabled;
157+
158+
_jsonRpcServer.SendNotification(EventNames.Breakpoint,
159+
new BreakpointEvent
160+
{
161+
Reason = reason,
162+
Breakpoint = breakpoint
163+
});
164+
}
165+
166+
#endregion
167+
}
168+
}

0 commit comments

Comments
 (0)