Skip to content

Commit a21652a

Browse files
committed
Catch up merge from master.
2 parents 3699310 + dca0f2d commit a21652a

File tree

16 files changed

+620
-46
lines changed

16 files changed

+620
-46
lines changed

src/PowerShellEditorServices.Channel.WebSocket/WebsocketServerChannel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public class LanguageServerWebSocketConnection : EditorServiceWebSocketConnectio
139139
{
140140
public LanguageServerWebSocketConnection()
141141
{
142-
Server = new LanguageServer(Channel);
142+
Server = new LanguageServer(null, Channel);
143143
}
144144
}
145145

@@ -150,7 +150,7 @@ public class DebugAdapterWebSocketConnection : EditorServiceWebSocketConnection
150150
{
151151
public DebugAdapterWebSocketConnection()
152152
{
153-
Server = new DebugAdapter(Channel);
153+
Server = new DebugAdapter(null, Channel);
154154
}
155155
}
156156

src/PowerShellEditorServices.Host/Program.cs

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55

66
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;
77
using Microsoft.PowerShell.EditorServices.Protocol.Server;
8+
using Microsoft.PowerShell.EditorServices.Session;
89
using Microsoft.PowerShell.EditorServices.Utility;
910
using System;
1011
using System.Diagnostics;
1112
using System.Linq;
12-
using System.Threading;
1313

1414
namespace Microsoft.PowerShell.EditorServices.Host
1515
{
@@ -78,21 +78,63 @@ static void Main(string[] args)
7878
"/debugAdapter",
7979
StringComparison.InvariantCultureIgnoreCase));
8080

81-
// Catch unhandled exceptions for logging purposes
82-
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
81+
string hostProfileId = null;
82+
string hostProfileIdArgument =
83+
args.FirstOrDefault(
84+
arg =>
85+
arg.StartsWith(
86+
"/hostProfileId:",
87+
StringComparison.InvariantCultureIgnoreCase));
88+
89+
if (!string.IsNullOrEmpty(hostProfileIdArgument))
90+
{
91+
hostProfileId = hostProfileIdArgument.Substring(15).Trim('"');
92+
}
93+
94+
string hostName = null;
95+
string hostNameArgument =
96+
args.FirstOrDefault(
97+
arg =>
98+
arg.StartsWith(
99+
"/hostName:",
100+
StringComparison.InvariantCultureIgnoreCase));
83101

84-
ProtocolEndpoint server = null;
85-
if (runDebugAdapter)
102+
if (!string.IsNullOrEmpty(hostNameArgument))
86103
{
87-
logPath = logPath ?? "DebugAdapter.log";
88-
server = new DebugAdapter();
104+
hostName = hostNameArgument.Substring(10).Trim('"');
89105
}
90-
else
106+
107+
Version hostVersion = null;
108+
string hostVersionArgument =
109+
args.FirstOrDefault(
110+
arg =>
111+
arg.StartsWith(
112+
"/hostVersion:",
113+
StringComparison.InvariantCultureIgnoreCase));
114+
115+
if (!string.IsNullOrEmpty(hostVersionArgument))
91116
{
92-
logPath = logPath ?? "EditorServices.log";
93-
server = new LanguageServer();
117+
hostVersion =
118+
new Version(
119+
hostVersionArgument.Substring(13).Trim('"'));
94120
}
95121

122+
// Create the host details from parameters
123+
HostDetails hostDetails =
124+
new HostDetails(
125+
hostName,
126+
hostProfileId,
127+
hostVersion);
128+
129+
// Catch unhandled exceptions for logging purposes
130+
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
131+
132+
// Use a default log path filename if one isn't specified
133+
logPath =
134+
runDebugAdapter
135+
? logPath ?? "DebugAdapter.log"
136+
: logPath ?? "EditorServices.log";
137+
96138
// Start the logger with the specified log path and level
97139
Logger.Initialize(logPath, logLevel);
98140

@@ -103,9 +145,20 @@ static void Main(string[] args)
103145
Logger.Write(
104146
LogLevel.Normal,
105147
string.Format(
106-
"PowerShell Editor Services Host v{0} starting (pid {1})...",
148+
"PowerShell Editor Services Host v{0} starting (pid {1})...\r\n\r\n" +
149+
" Host application details:\r\n\r\n" +
150+
" Name: {2}\r\n ProfileId: {3}\r\n Version: {4}",
107151
fileVersionInfo.FileVersion,
108-
Process.GetCurrentProcess().Id));
152+
Process.GetCurrentProcess().Id,
153+
hostDetails.Name,
154+
hostDetails.ProfileId,
155+
hostDetails.Version));
156+
157+
// Create the appropriate server type
158+
ProtocolEndpoint server =
159+
runDebugAdapter
160+
? (ProtocolEndpoint) new DebugAdapter(hostDetails)
161+
: (ProtocolEndpoint) new LanguageServer(hostDetails);
109162

110163
// Start the server
111164
server.Start().Wait();

src/PowerShellEditorServices.Protocol/DebugAdapter/Breakpoint.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
44
//
55

6+
using Microsoft.PowerShell.EditorServices.Utility;
7+
68
namespace Microsoft.PowerShell.EditorServices.Protocol.DebugAdapter
79
{
810
public class Breakpoint
@@ -32,6 +34,8 @@ private Breakpoint()
3234
public static Breakpoint Create(
3335
BreakpointDetails breakpointDetails)
3436
{
37+
Validate.IsNotNull(nameof(breakpointDetails), breakpointDetails);
38+
3539
return new Breakpoint
3640
{
3741
Verified = breakpointDetails.Verified,
@@ -45,10 +49,31 @@ public static Breakpoint Create(
4549
public static Breakpoint Create(
4650
CommandBreakpointDetails breakpointDetails)
4751
{
52+
Validate.IsNotNull(nameof(breakpointDetails), breakpointDetails);
53+
4854
return new Breakpoint {
4955
Verified = breakpointDetails.Verified,
5056
Message = breakpointDetails.Message
5157
};
5258
}
59+
60+
public static Breakpoint Create(
61+
SourceBreakpoint sourceBreakpoint,
62+
string source,
63+
string message,
64+
bool verified = false)
65+
{
66+
Validate.IsNotNull(nameof(sourceBreakpoint), sourceBreakpoint);
67+
Validate.IsNotNull(nameof(source), source);
68+
Validate.IsNotNull(nameof(message), message);
69+
70+
return new Breakpoint {
71+
Verified = verified,
72+
Message = message,
73+
Source = source,
74+
Line = sourceBreakpoint.Line,
75+
Column = sourceBreakpoint.Column
76+
};
77+
}
5378
}
5479
}

src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.PowerShell.EditorServices.Protocol.DebugAdapter;
77
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;
88
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol.Channel;
9+
using Microsoft.PowerShell.EditorServices.Session;
910
using Microsoft.PowerShell.EditorServices.Utility;
1011
using System;
1112
using System.Collections.Generic;
@@ -25,14 +26,16 @@ public class DebugAdapter : DebugAdapterBase
2526
private string scriptPathToLaunch;
2627
private string arguments;
2728

28-
public DebugAdapter() : this(new StdioServerChannel())
29+
public DebugAdapter(HostDetails hostDetails)
30+
: this(hostDetails, new StdioServerChannel())
2931
{
3032
}
3133

32-
public DebugAdapter(ChannelBase serverChannel) : base(serverChannel)
34+
public DebugAdapter(HostDetails hostDetails, ChannelBase serverChannel)
35+
: base(serverChannel)
3336
{
3437
this.editorSession = new EditorSession();
35-
this.editorSession.StartSession();
38+
this.editorSession.StartSession(hostDetails);
3639
this.editorSession.DebugService.DebuggerStopped += this.DebugService_DebuggerStopped;
3740
this.editorSession.ConsoleService.OutputWritten += this.powerShellContext_OutputWritten;
3841

@@ -208,9 +211,32 @@ protected async Task HandleSetBreakpointsRequest(
208211
SetBreakpointsRequestArguments setBreakpointsParams,
209212
RequestContext<SetBreakpointsResponseBody> requestContext)
210213
{
211-
ScriptFile scriptFile =
212-
editorSession.Workspace.GetFile(
213-
setBreakpointsParams.Source.Path);
214+
ScriptFile scriptFile;
215+
216+
// Fix for issue #195 - user can change name of file outside of VSCode in which case
217+
// VSCode sends breakpoint requests with the original filename that doesn't exist anymore.
218+
try
219+
{
220+
scriptFile = editorSession.Workspace.GetFile(setBreakpointsParams.Source.Path);
221+
}
222+
catch (FileNotFoundException)
223+
{
224+
Logger.Write(
225+
LogLevel.Warning,
226+
$"Attempted to set breakpoints on a non-existing file: {setBreakpointsParams.Source.Path}");
227+
228+
var srcBreakpoints = setBreakpointsParams.Breakpoints
229+
.Select(srcBkpt => Protocol.DebugAdapter.Breakpoint.Create(
230+
srcBkpt, setBreakpointsParams.Source.Path, "Source does not exist, breakpoint not set."));
231+
232+
// Return non-verified breakpoint message.
233+
await requestContext.SendResult(
234+
new SetBreakpointsResponseBody {
235+
Breakpoints = srcBreakpoints.ToArray()
236+
});
237+
238+
return;
239+
}
214240

215241
var breakpointDetails = new BreakpointDetails[setBreakpointsParams.Breakpoints.Length];
216242
for (int i = 0; i < breakpointDetails.Length; i++)

src/PowerShellEditorServices.Protocol/Server/DebugAdapterBase.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,18 @@ private async Task HandleInitializeRequest(
5454
object shutdownParams,
5555
RequestContext<InitializeResponseBody> requestContext)
5656
{
57-
// Send the Initialized event first so that we get breakpoints
58-
await requestContext.SendEvent(
59-
InitializedEvent.Type,
60-
null);
61-
6257
// Now send the Initialize response to continue setup
6358
await requestContext.SendResult(
64-
new InitializeResponseBody
65-
{
59+
new InitializeResponseBody {
6660
SupportsConfigurationDoneRequest = true,
6761
SupportsConditionalBreakpoints = true,
6862
SupportsFunctionBreakpoints = true
6963
});
64+
65+
// Send the Initialized event so that we get breakpoints
66+
await requestContext.SendEvent(
67+
InitializedEvent.Type,
68+
null);
7069
}
7170
}
7271
}
73-

src/PowerShellEditorServices/PowerShellEditorServices.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
<Compile Include="Console\ChoiceDetails.cs" />
9999
<Compile Include="Session\EditorSession.cs" />
100100
<Compile Include="Console\IConsoleHost.cs" />
101+
<Compile Include="Session\HostDetails.cs" />
101102
<Compile Include="Session\IVersionSpecificOperations.cs" />
102103
<Compile Include="Session\OutputType.cs" />
103104
<Compile Include="Session\OutputWrittenEventArgs.cs" />
@@ -107,6 +108,7 @@
107108
<Compile Include="Session\PowerShellExecutionResult.cs" />
108109
<Compile Include="Session\PowerShellContext.cs" />
109110
<Compile Include="Session\PowerShellContextState.cs" />
111+
<Compile Include="Session\ProfilePaths.cs" />
110112
<Compile Include="Session\ProgressDetails.cs" />
111113
<Compile Include="Session\RunspaceHandle.cs" />
112114
<Compile Include="Session\SessionPSHost.cs" />

src/PowerShellEditorServices/Session/EditorSession.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//
55

66
using Microsoft.PowerShell.EditorServices.Console;
7+
using Microsoft.PowerShell.EditorServices.Session;
78
using Microsoft.PowerShell.EditorServices.Utility;
89
using System.IO;
910

@@ -56,9 +57,21 @@ public class EditorSession
5657
/// for the ConsoleService.
5758
/// </summary>
5859
public void StartSession()
60+
{
61+
this.StartSession(null);
62+
}
63+
64+
/// <summary>
65+
/// Starts the session using the provided IConsoleHost implementation
66+
/// for the ConsoleService.
67+
/// </summary>
68+
/// <param name="hostDetails">
69+
/// Provides details about the host application.
70+
/// </param>
71+
public void StartSession(HostDetails hostDetails)
5972
{
6073
// Initialize all services
61-
this.PowerShellContext = new PowerShellContext();
74+
this.PowerShellContext = new PowerShellContext(hostDetails);
6275
this.LanguageService = new LanguageService(this.PowerShellContext);
6376
this.DebugService = new DebugService(this.PowerShellContext);
6477
this.ConsoleService = new ConsoleService(this.PowerShellContext);

0 commit comments

Comments
 (0)