Skip to content

Commit 420d747

Browse files
authored
Merge pull request #467 from daviwil/runspace-creation
Refactor runspace creation to enable more design improvements
2 parents 304c1b1 + 28233de commit 420d747

File tree

18 files changed

+329
-209
lines changed

18 files changed

+329
-209
lines changed

.vscode/tasks.json

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
"version": "0.1.0",
2+
"version": "2.0.0",
33

44
"windows": {
5-
"command": "${env.windir}\\sysnative\\windowspowershell\\v1.0\\PowerShell.exe",
5+
"command": "powershell.exe",
66
"args": [ "-NoProfile", "-ExecutionPolicy", "Bypass" ]
77
},
88
"linux": {
@@ -14,7 +14,6 @@
1414
"args": [ "-NoProfile" ]
1515
},
1616

17-
"isShellCommand": true,
1817
"showOutput": "always",
1918

2019
// Associate with test task runner
@@ -35,6 +34,18 @@
3534
"suppressTaskName": true,
3635
"isTestCommand": true,
3736
"args": [ "Invoke-Build Test" ]
37+
},
38+
{
39+
"taskName": "Test Language Service",
40+
"suppressTaskName": true,
41+
"isTestCommand": true,
42+
"args": [ "Invoke-Build TestServer" ]
43+
},
44+
{
45+
"taskName": "Test Host",
46+
"suppressTaskName": true,
47+
"isTestCommand": true,
48+
"args": [ "Invoke-Build TestHost" ]
3849
}
3950
]
4051
}

README.md

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,38 @@
11
# PowerShell Editor Services
22

3-
PowerShell Editor Services provides common functionality that is needed
4-
to enable a consistent and robust PowerShell development experience
5-
across multiple editors.
3+
PowerShell Editor Services is a PowerShell module that provides common
4+
functionality needed to enable a consistent and robust PowerShell development
5+
experience in almost any editor or integrated development environment (IDE).
66

77
## Features
88

99
- The Language Service provides common editor features for the PowerShell language:
1010
- Code navigation actions (find references, go to definition)
1111
- Statement completions (IntelliSense)
1212
- Real-time semantic analysis of scripts using PowerShell Script Analyzer
13-
- Basic script evaluation
1413
- The Debugging Service simplifies interaction with the PowerShell debugger (breakpoints, variables, call stack, etc)
15-
- The Console Service provides a simplified interactive console interface which implements a rich PSHost implementation:
16-
- Interactive command execution support, including basic use of native console applications
17-
- Choice prompt support
18-
- Input prompt support
19-
- Get-Credential support (coming soon)
20-
- The Extension Service provides a generalized extensibility model that allows you to
21-
write new functionality for any host editor that uses PowerShell Editor Services
14+
- The [$psEditor API](http://powershell.github.io/PowerShellEditorServices/guide/extensions.html) enables scripting of the host editor
15+
- A full, terminal-based Integrated Console experience for interactive development and debugging
2216

23-
The core Editor Services library is intended to be consumed in any type of host application, whether
24-
it is a WPF UI, console application, or web service. A standard console application host is included
25-
so that you can easily consume Editor Services functionality in any editor using the JSON API that it
26-
exposes.
17+
### Important note regarding the .NET APIs in Microsoft.PowerShell.EditorServices.dll
2718

28-
## Build status of master branches
19+
With the 1.0 release of PowerShell Editor Services, we have deprecated the public APIs
20+
of the following classes:
21+
22+
- EditorSession
23+
- LanguageService
24+
- DebugService
25+
- ConsoleService
26+
- AnalysisService
27+
- ExtensionService
28+
- TemplateService
29+
30+
The intended usage model is now to host PowerShell Editor Services within powershell.exe
31+
and communicate with it over TCP sockets via the [Language Server Protocol](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md)
32+
and [Debug Adapter Protocol](https://github.com/Microsoft/vscode-debugadapter-node/blob/master/protocol/src/debugProtocol.ts).
33+
Detailed usage documentation for this module is coming soon!
34+
35+
## Build Status
2936

3037
| AppVeyor (Windows) | Travis CI (Linux / macOS) |
3138
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -43,13 +50,13 @@ how to use this project. You can also read our plans for future feature developm
4350

4451
## Development
4552

46-
4753
### 1. Install PowerShell if necessary
4854

4955
If you are using Windows, skip this step. If you are using Linux or macOS, you will need to
5056
install PowerShell by following [these instructions](https://github.com/PowerShell/PowerShell#get-powershell).
5157

52-
If you are using macOS you will need to download the latest version of OpenSSL. The easiest way to get this is from [Homebrew](http://brew.sh/). After installing Homebrew execute the following commands:
58+
If you are using macOS you will need to download the latest version of OpenSSL. The easiest way to get this is from
59+
[Homebrew](http://brew.sh/). After installing Homebrew execute the following commands:
5360

5461
```
5562
brew update

module/PowerShellEditorServices/PowerShellEditorServices.psm1

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -63,34 +63,28 @@ function Start-EditorServicesHost {
6363
$editorServicesHost = $null
6464
$hostDetails = New-Object Microsoft.PowerShell.EditorServices.Session.HostDetails @($HostName, $HostProfileId, (New-Object System.Version @($HostVersion)))
6565

66-
try {
67-
$editorServicesHost =
68-
New-Object Microsoft.PowerShell.EditorServices.Host.EditorServicesHost @(
69-
$hostDetails,
70-
$BundledModulesPath,
71-
$EnableConsoleRepl.IsPresent,
72-
$WaitForDebugger.IsPresent,
73-
$FeatureFlags)
74-
75-
# Build the profile paths using the root paths of the current $profile variable
76-
$profilePaths = New-Object Microsoft.PowerShell.EditorServices.Session.ProfilePaths @(
77-
$hostDetails.ProfileId,
78-
[System.IO.Path]::GetDirectoryName($profile.AllUsersAllHosts),
79-
[System.IO.Path]::GetDirectoryName($profile.CurrentUserAllHosts));
80-
81-
$editorServicesHost.StartLogging($LogPath, $LogLevel);
82-
83-
if ($DebugServiceOnly.IsPresent) {
84-
$editorServicesHost.StartDebugService($DebugServicePort, $profilePaths, $false);
85-
}
86-
else {
87-
$editorServicesHost.StartLanguageService($LanguageServicePort, $profilePaths);
88-
$editorServicesHost.StartDebugService($DebugServicePort, $profilePaths, $true);
89-
}
66+
$editorServicesHost =
67+
New-Object Microsoft.PowerShell.EditorServices.Host.EditorServicesHost @(
68+
$hostDetails,
69+
$BundledModulesPath,
70+
$EnableConsoleRepl.IsPresent,
71+
$WaitForDebugger.IsPresent,
72+
$FeatureFlags)
73+
74+
# Build the profile paths using the root paths of the current $profile variable
75+
$profilePaths = New-Object Microsoft.PowerShell.EditorServices.Session.ProfilePaths @(
76+
$hostDetails.ProfileId,
77+
[System.IO.Path]::GetDirectoryName($profile.AllUsersAllHosts),
78+
[System.IO.Path]::GetDirectoryName($profile.CurrentUserAllHosts));
79+
80+
$editorServicesHost.StartLogging($LogPath, $LogLevel);
81+
82+
if ($DebugServiceOnly.IsPresent) {
83+
$editorServicesHost.StartDebugService($DebugServicePort, $profilePaths, $false);
9084
}
91-
catch {
92-
Write-Error "PowerShell Editor Services host initialization failed, terminating."
93-
Write-Error $_.Exception
85+
else {
86+
$editorServicesHost.StartLanguageService($LanguageServicePort, $profilePaths);
87+
$editorServicesHost.StartDebugService($DebugServicePort, $profilePaths, $true);
9488
}
9589

9690
return $editorServicesHost

src/PowerShellEditorServices.Host/EditorServicesHost.cs

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

6+
using Microsoft.PowerShell.EditorServices.Console;
67
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol.Channel;
78
using Microsoft.PowerShell.EditorServices.Protocol.Server;
89
using Microsoft.PowerShell.EditorServices.Session;
910
using Microsoft.PowerShell.EditorServices.Utility;
1011
using System;
1112
using System.Collections.Generic;
1213
using System.Diagnostics;
14+
using System.Management.Automation.Runspaces;
15+
using System.Management.Automation.Host;
1316
using System.Reflection;
1417
using System.Threading;
18+
using Microsoft.PowerShell.EditorServices.Extensions;
1519

1620
namespace Microsoft.PowerShell.EditorServices.Host
1721
{
@@ -34,6 +38,7 @@ public class EditorServicesHost
3438
private HostDetails hostDetails;
3539
private string bundledModulesPath;
3640
private DebugAdapter debugAdapter;
41+
private EditorSession editorSession;
3742
private HashSet<string> featureFlags;
3843
private LanguageServer languageServer;
3944

@@ -82,7 +87,7 @@ public EditorServicesHost(
8287
else
8388
{
8489
Debugger.Launch();
85-
}
90+
}
8691
}
8792
#endif
8893

@@ -148,11 +153,15 @@ public void StartLogging(string logFilePath, LogLevel logLevel)
148153
/// <param name="profilePaths">The object containing the profile paths to load for this session.</param>
149154
public void StartLanguageService(int languageServicePort, ProfilePaths profilePaths)
150155
{
156+
this.editorSession =
157+
CreateSession(
158+
this.hostDetails,
159+
profilePaths,
160+
this.enableConsoleRepl);
161+
151162
this.languageServer =
152163
new LanguageServer(
153-
hostDetails,
154-
profilePaths,
155-
this.enableConsoleRepl,
164+
this.editorSession,
156165
new TcpSocketServerChannel(languageServicePort));
157166

158167
this.languageServer.Start().Wait();
@@ -177,17 +186,23 @@ public void StartDebugService(
177186
{
178187
this.debugAdapter =
179188
new DebugAdapter(
180-
this.languageServer.EditorSession,
181-
new TcpSocketServerChannel(debugServicePort));
189+
this.editorSession,
190+
new TcpSocketServerChannel(debugServicePort),
191+
false);
182192
}
183193
else
184194
{
195+
EditorSession debugSession =
196+
this.CreateDebugSession(
197+
this.hostDetails,
198+
profilePaths,
199+
this.languageServer.EditorOperations);
200+
185201
this.debugAdapter =
186202
new DebugAdapter(
187-
hostDetails,
188-
profilePaths,
203+
debugSession,
189204
new TcpSocketServerChannel(debugServicePort),
190-
this.languageServer?.EditorOperations);
205+
true);
191206
}
192207

193208
this.debugAdapter.SessionEnded +=
@@ -253,6 +268,55 @@ public void WaitForCompletion()
253268

254269
#region Private Methods
255270

271+
private EditorSession CreateSession(
272+
HostDetails hostDetails,
273+
ProfilePaths profilePaths,
274+
bool enableConsoleRepl)
275+
{
276+
EditorSession editorSession = new EditorSession();
277+
PowerShellContext powerShellContext = new PowerShellContext();
278+
279+
ConsoleServicePSHost psHost =
280+
new ConsoleServicePSHost(
281+
powerShellContext,
282+
hostDetails,
283+
enableConsoleRepl);
284+
285+
Runspace initialRunspace = PowerShellContext.CreateRunspace(psHost);
286+
powerShellContext.Initialize(profilePaths, initialRunspace, true, psHost.ConsoleService);
287+
288+
editorSession.StartSession(
289+
powerShellContext,
290+
psHost.ConsoleService);
291+
292+
return editorSession;
293+
}
294+
295+
private EditorSession CreateDebugSession(
296+
HostDetails hostDetails,
297+
ProfilePaths profilePaths,
298+
IEditorOperations editorOperations)
299+
{
300+
EditorSession editorSession = new EditorSession();
301+
PowerShellContext powerShellContext = new PowerShellContext();
302+
303+
ConsoleServicePSHost psHost =
304+
new ConsoleServicePSHost(
305+
powerShellContext,
306+
hostDetails,
307+
enableConsoleRepl);
308+
309+
Runspace initialRunspace = PowerShellContext.CreateRunspace(psHost);
310+
powerShellContext.Initialize(profilePaths, initialRunspace, true, psHost.ConsoleService);
311+
312+
editorSession.StartDebugSession(
313+
powerShellContext,
314+
psHost.ConsoleService,
315+
editorOperations);
316+
317+
return editorSession;
318+
}
319+
256320
#if !CoreCLR
257321
static void CurrentDomain_UnhandledException(
258322
object sender,

src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,40 +37,17 @@ public class DebugAdapter : DebugAdapterBase
3737
private bool isInteractiveDebugSession;
3838
private RequestContext<object> disconnectRequestContext = null;
3939

40-
public DebugAdapter(HostDetails hostDetails, ProfilePaths profilePaths)
41-
: this(hostDetails, profilePaths, new StdioServerChannel(), null)
42-
{
43-
}
44-
45-
public DebugAdapter(EditorSession editorSession, ChannelBase serverChannel)
46-
: base(serverChannel)
47-
{
48-
this.editorSession = editorSession;
49-
}
50-
5140
public DebugAdapter(
52-
HostDetails hostDetails,
53-
ProfilePaths profilePaths,
41+
EditorSession editorSession,
5442
ChannelBase serverChannel,
55-
IEditorOperations editorOperations)
56-
: this(hostDetails, profilePaths, serverChannel, editorOperations, false)
43+
bool ownsEditorSession)
44+
: base(serverChannel)
5745
{
46+
this.editorSession = editorSession;
47+
this.ownsEditorSession = ownsEditorSession;
48+
this.enableConsoleRepl = editorSession.UsesConsoleHost;
5849
}
5950

60-
public DebugAdapter(
61-
HostDetails hostDetails,
62-
ProfilePaths profilePaths,
63-
ChannelBase serverChannel,
64-
IEditorOperations editorOperations,
65-
bool enableConsoleRepl)
66-
: base(serverChannel)
67-
{
68-
this.ownsEditorSession = true;
69-
this.editorSession = new EditorSession();
70-
this.editorSession.StartDebugSession(hostDetails, profilePaths, editorOperations);
71-
this.enableConsoleRepl = enableConsoleRepl;
72-
}
73-
7451
protected override void Initialize()
7552
{
7653
// Register all supported message types
@@ -325,6 +302,7 @@ protected async Task HandleLaunchRequest(
325302

326303
if (this.editorSession.ConsoleService.EnableConsoleRepl)
327304
{
305+
// TODO: Write this during DebugSession init
328306
await this.WriteUseIntegratedConsoleMessage();
329307
}
330308

0 commit comments

Comments
 (0)