3
3
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4
4
//
5
5
6
- using Microsoft . PowerShell . EditorServices . Console ;
6
+ using Microsoft . PowerShell . EditorServices . Extensions ;
7
+ using Microsoft . PowerShell . EditorServices . Protocol . MessageProtocol ;
7
8
using Microsoft . PowerShell . EditorServices . Protocol . MessageProtocol . Channel ;
8
9
using Microsoft . PowerShell . EditorServices . Protocol . Server ;
9
10
using Microsoft . PowerShell . EditorServices . Session ;
12
13
using System . Collections . Generic ;
13
14
using System . Diagnostics ;
14
15
using System . Management . Automation . Runspaces ;
15
- using System . Management . Automation . Host ;
16
16
using System . Reflection ;
17
- using System . Threading ;
18
- using Microsoft . PowerShell . EditorServices . Extensions ;
17
+ using System . Threading . Tasks ;
19
18
20
19
namespace Microsoft . PowerShell . EditorServices . Host
21
20
{
@@ -36,12 +35,18 @@ public class EditorServicesHost
36
35
37
36
private bool enableConsoleRepl ;
38
37
private HostDetails hostDetails ;
38
+ private ProfilePaths profilePaths ;
39
39
private string bundledModulesPath ;
40
40
private DebugAdapter debugAdapter ;
41
41
private EditorSession editorSession ;
42
42
private HashSet < string > featureFlags ;
43
43
private LanguageServer languageServer ;
44
44
45
+ private TcpSocketServerListener languageServiceListener ;
46
+ private TcpSocketServerListener debugServiceListener ;
47
+
48
+ private TaskCompletionSource < bool > serverCompletedTask ;
49
+
45
50
#endregion
46
51
47
52
#region Properties
@@ -152,25 +157,40 @@ public void StartLogging(string logFilePath, LogLevel logLevel)
152
157
/// <param name="languageServicePort">The port number for the language service.</param>
153
158
/// <param name="profilePaths">The object containing the profile paths to load for this session.</param>
154
159
public void StartLanguageService ( int languageServicePort , ProfilePaths profilePaths )
160
+ {
161
+ this . profilePaths = profilePaths ;
162
+
163
+ this . languageServiceListener =
164
+ new TcpSocketServerListener (
165
+ MessageProtocolType . LanguageServer ,
166
+ languageServicePort ) ;
167
+
168
+ this . languageServiceListener . ClientConnect += this . OnLanguageServiceClientConnect ;
169
+ this . languageServiceListener . Start ( ) ;
170
+
171
+ Logger . Write (
172
+ LogLevel . Normal ,
173
+ string . Format (
174
+ "Language service started, listening on port {0}" ,
175
+ languageServicePort ) ) ;
176
+ }
177
+
178
+ private async void OnLanguageServiceClientConnect (
179
+ object sender ,
180
+ TcpSocketServerChannel serverChannel )
155
181
{
156
182
this . editorSession =
157
183
CreateSession (
158
184
this . hostDetails ,
159
- profilePaths ,
185
+ this . profilePaths ,
160
186
this . enableConsoleRepl ) ;
161
187
162
188
this . languageServer =
163
189
new LanguageServer (
164
190
this . editorSession ,
165
- new TcpSocketServerChannel ( languageServicePort ) ) ;
166
-
167
- this . languageServer . Start ( ) . Wait ( ) ;
191
+ serverChannel ) ;
168
192
169
- Logger . Write (
170
- LogLevel . Normal ,
171
- string . Format (
172
- "Language service started, listening on port {0}" ,
173
- languageServicePort ) ) ;
193
+ await this . languageServer . Start ( ) ;
174
194
}
175
195
176
196
/// <summary>
@@ -182,12 +202,29 @@ public void StartDebugService(
182
202
ProfilePaths profilePaths ,
183
203
bool useExistingSession )
184
204
{
185
- if ( this . enableConsoleRepl && useExistingSession )
205
+ this . debugServiceListener =
206
+ new TcpSocketServerListener (
207
+ MessageProtocolType . LanguageServer ,
208
+ debugServicePort ) ;
209
+
210
+ this . debugServiceListener . ClientConnect += OnDebugServiceClientConnect ;
211
+ this . debugServiceListener . Start ( ) ;
212
+
213
+ Logger . Write (
214
+ LogLevel . Normal ,
215
+ string . Format (
216
+ "Debug service started, listening on port {0}" ,
217
+ debugServicePort ) ) ;
218
+ }
219
+
220
+ private async void OnDebugServiceClientConnect ( object sender , TcpSocketServerChannel serverChannel )
221
+ {
222
+ if ( this . enableConsoleRepl )
186
223
{
187
224
this . debugAdapter =
188
225
new DebugAdapter (
189
226
this . editorSession ,
190
- new TcpSocketServerChannel ( debugServicePort ) ,
227
+ serverChannel ,
191
228
false ) ;
192
229
}
193
230
else
@@ -196,42 +233,26 @@ public void StartDebugService(
196
233
this . CreateDebugSession (
197
234
this . hostDetails ,
198
235
profilePaths ,
199
- this . languageServer . EditorOperations ) ;
236
+ this . languageServer ? . EditorOperations ) ;
200
237
201
238
this . debugAdapter =
202
239
new DebugAdapter (
203
240
debugSession ,
204
- new TcpSocketServerChannel ( debugServicePort ) ,
241
+ serverChannel ,
205
242
true ) ;
206
243
}
207
244
208
245
this . debugAdapter . SessionEnded +=
209
246
( obj , args ) =>
210
247
{
211
- // Only restart if we're reusing the existing session
212
- // or if we're not using the console REPL, otherwise
213
- // the process should terminate
214
- if ( useExistingSession )
215
- {
216
- Logger . Write (
217
- LogLevel . Normal ,
218
- "Previous debug session ended, restarting debug service..." ) ;
219
-
220
- this . StartDebugService ( debugServicePort , profilePaths , true ) ;
221
- }
222
- else if ( ! this . enableConsoleRepl )
223
- {
224
- this . StartDebugService ( debugServicePort , profilePaths , false ) ;
225
- }
226
- } ;
248
+ Logger . Write (
249
+ LogLevel . Normal ,
250
+ "Previous debug session ended, restarting debug service listener..." ) ;
227
251
228
- this . debugAdapter . Start ( ) . Wait ( ) ;
252
+ this . debugServiceListener . Start ( ) ;
253
+ } ;
229
254
230
- Logger . Write (
231
- LogLevel . Normal ,
232
- string . Format (
233
- "Debug service started, listening on port {0}" ,
234
- debugServicePort ) ) ;
255
+ await this . debugAdapter . Start ( ) ;
235
256
}
236
257
237
258
/// <summary>
@@ -251,17 +272,9 @@ public void StopServices()
251
272
/// </summary>
252
273
public void WaitForCompletion ( )
253
274
{
254
- // Wait based on which server is started. If the language server
255
- // hasn't been started then we may only need to wait on the debug
256
- // adapter to complete.
257
- if ( this . languageServer != null )
258
- {
259
- this . languageServer . WaitForExit ( ) ;
260
- }
261
- else if ( this . debugAdapter != null )
262
- {
263
- this . debugAdapter . WaitForExit ( ) ;
264
- }
275
+ // TODO: We need a way to know when to complete this task!
276
+ this . serverCompletedTask = new TaskCompletionSource < bool > ( ) ;
277
+ this . serverCompletedTask . Task . Wait ( ) ;
265
278
}
266
279
267
280
#endregion
0 commit comments