Skip to content

Commit e39f2b3

Browse files
committed
Eliminate API leakage of some PowerShell types
This change introduces new types that wrap/replace the types from System.Management.Automation which should not be exposed outside of the core Editor Services library. The reasoning is that a consumer of our higher-level service types through an EditorSession should not have to take a dependency on the System.Management.Automation assembly (since this may become more complicated in the future). This also gives us a chance to reshape the information that we return from API calls so that we can provide extra value in some places and remove unneeded information in others. Going forward we will carefully monitor any new function signatures to ensure that core PowerShell types aren't being exposed through the abstraction unnecessarily.
1 parent 772317a commit e39f2b3

26 files changed

+570
-137
lines changed

src/PowerShellEditorServices.Transport.Stdio/Event/DiagnosticEvent.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ public static DiagnosticEventBody Create(
6363
Text = diagnosticMarker.Message,
6464
Start = new Location
6565
{
66-
Line = diagnosticMarker.Extent.StartLineNumber,
67-
Offset = diagnosticMarker.Extent.StartColumnNumber
66+
Line = diagnosticMarker.ScriptRegion.StartLineNumber,
67+
Offset = diagnosticMarker.ScriptRegion.StartColumnNumber
6868
},
6969
End = new Location
7070
{
71-
Line = diagnosticMarker.Extent.EndLineNumber,
72-
Offset = diagnosticMarker.Extent.EndColumnNumber
71+
Line = diagnosticMarker.ScriptRegion.EndLineNumber,
72+
Offset = diagnosticMarker.ScriptRegion.EndColumnNumber
7373
}
7474
});
7575
}

src/PowerShellEditorServices.Transport.Stdio/Event/ReplPromptChoiceEvent.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +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.Console;
67
using Microsoft.PowerShell.EditorServices.Transport.Stdio.Message;
7-
using System.Management.Automation.Host;
88

99
namespace Microsoft.PowerShell.EditorServices.Transport.Stdio.Event
1010
{
@@ -33,12 +33,12 @@ public class ReplPromptChoiceDetails
3333
public string Label { get; set; }
3434

3535
public static ReplPromptChoiceDetails FromChoiceDescription(
36-
ChoiceDescription choiceDescription)
36+
ChoiceDetails choiceDetails)
3737
{
3838
return new ReplPromptChoiceDetails
3939
{
40-
Label = choiceDescription.Label,
41-
HelpMessage = choiceDescription.HelpMessage
40+
Label = choiceDetails.Label,
41+
HelpMessage = choiceDetails.HelpMessage
4242
};
4343
}
4444
}

src/PowerShellEditorServices.Transport.Stdio/PowerShellEditorServices.Transport.Stdio.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
<Reference Include="Microsoft.CSharp" />
5858
<Reference Include="System.Data" />
5959
<Reference Include="System.Xml" />
60-
<Reference Include="System.Management.Automation" />
6160
</ItemGroup>
6261
<ItemGroup>
6362
<Compile Include="Constants.cs" />

src/PowerShellEditorServices.Transport.Stdio/Request/CompletionsRequest.cs

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

6+
using Microsoft.PowerShell.EditorServices.Language;
67
using Microsoft.PowerShell.EditorServices.Session;
78
using Microsoft.PowerShell.EditorServices.Transport.Stdio.Message;
89
using Microsoft.PowerShell.EditorServices.Transport.Stdio.Response;
9-
using System.Management.Automation;
1010

1111
namespace Microsoft.PowerShell.EditorServices.Transport.Stdio.Request
1212
{
@@ -19,7 +19,7 @@ public override void ProcessMessage(
1919
{
2020
ScriptFile scriptFile = this.GetScriptFile(editorSession);
2121

22-
CommandCompletion completions =
22+
CompletionResults completions =
2323
editorSession.LanguageService.GetCompletionsInFile(
2424
scriptFile,
2525
this.Arguments.Line,

src/PowerShellEditorServices.Transport.Stdio/Response/CompletionsResponse.cs

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

6+
using Microsoft.PowerShell.EditorServices.Language;
67
using Microsoft.PowerShell.EditorServices.Transport.Stdio.Message;
78
using System.Collections.Generic;
8-
using System.Management.Automation;
99

1010
namespace Microsoft.PowerShell.EditorServices.Transport.Stdio.Response
1111
{
1212
[MessageTypeName("completions")]
1313
public class CompletionsResponse : ResponseBase<CompletionEntry[]>
1414
{
15-
public static CompletionsResponse Create(CommandCompletion commandCompletion)
15+
public static CompletionsResponse Create(CompletionResults completionResults)
1616
{
1717
List<CompletionEntry> completionResult = new List<CompletionEntry>();
1818

19-
foreach (var completion in commandCompletion.CompletionMatches)
19+
foreach (var completion in completionResults.Completions)
2020
{
2121
completionResult.Add(
2222
new CompletionEntry
2323
{
2424
Name = completion.CompletionText,
25-
Kind = GetCompletionKind(completion.ResultType),
25+
Kind = GetCompletionKind(completion.CompletionType),
2626
});
2727
}
2828

@@ -32,12 +32,12 @@ public static CompletionsResponse Create(CommandCompletion commandCompletion)
3232
};
3333
}
3434

35-
private static string GetCompletionKind(CompletionResultType resultType)
35+
private static string GetCompletionKind(CompletionType completionType)
3636
{
37-
switch (resultType)
37+
switch (completionType)
3838
{
39-
case CompletionResultType.Command:
40-
case CompletionResultType.Method:
39+
case CompletionType.Command:
40+
case CompletionType.Method:
4141
return "method";
4242
default:
4343
// TODO: Better default

src/PowerShellEditorServices.Transport.Stdio/Response/ResponseBase.cs

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

6+
using Microsoft.PowerShell.EditorServices.Language;
67
using Microsoft.PowerShell.EditorServices.Transport.Stdio.Message;
78
using Newtonsoft.Json;
8-
using System.Management.Automation;
99
using System.Text.RegularExpressions;
1010

1111
namespace Microsoft.PowerShell.EditorServices.Transport.Stdio.Response
@@ -48,35 +48,34 @@ public class CompletionEntry
4848

4949
public class CompletionEntryDetails
5050
{
51-
public CompletionEntryDetails(CompletionResult completionResult, string entryName)
51+
public CompletionEntryDetails(CompletionDetails completionDetails, string entryName)
5252
{
53-
5453
Kind = null;
5554
KindModifiers = null;
5655
DisplayParts = null;
5756
Documentation = null;
5857
DocString = null;
5958

6059
// if the result type is a command return null
61-
if (!(completionResult.ResultType.Equals(CompletionResultType.Command)))
60+
if (!(completionDetails.CompletionType.Equals(CompletionType.Command)))
6261
{
6362
//find matches on square brackets in the the tool tip
64-
var matches = Regex.Matches(completionResult.ToolTip, @"^\[(.+)\]");
63+
var matches = Regex.Matches(completionDetails.ToolTipText, @"^\[(.+)\]");
6564
string strippedEntryName = Regex.Replace(entryName, @"^[$_-]","").Replace("{","").Replace("}","");
6665

6766
if (matches.Count > 0 && matches[0].Groups.Count > 1)
6867
{
6968
Name = matches[0].Groups[1].Value;
7069
}
7170
// if there are nobracets and the only content is the completion name
72-
else if (completionResult.ToolTip.Equals(strippedEntryName))
71+
else if (completionDetails.ToolTipText.Equals(strippedEntryName))
7372
{
7473
Name = null;
7574
}
7675
else
7776
{
7877
Name = null;
79-
DocString = completionResult.ToolTip;
78+
DocString = completionDetails.ToolTipText;
8079
}
8180
}
8281

src/PowerShellEditorServices.Transport.Stdio/StdioConsoleHost.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
using System;
1111
using System.Collections.Generic;
1212
using System.Linq;
13-
using System.Management.Automation.Host;
1413
using System.Text;
1514
using System.Threading.Tasks;
1615

@@ -63,7 +62,7 @@ void IConsoleHost.WriteOutput(
6362
Task<int> IConsoleHost.PromptForChoice(
6463
string caption,
6564
string message,
66-
IEnumerable<ChoiceDescription> choices,
65+
IEnumerable<ChoiceDetails> choices,
6766
int defaultChoice)
6867
{
6968
// Create and store a TaskCompletionSource that will be
@@ -103,7 +102,7 @@ void IConsoleHost.PromptForChoiceResult(
103102

104103
void IConsoleHost.UpdateProgress(
105104
long sourceId,
106-
System.Management.Automation.ProgressRecord progressRecord)
105+
ProgressDetails progressDetails)
107106
{
108107
// TODO: Implement message for this
109108
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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.Host;
7+
8+
namespace Microsoft.PowerShell.EditorServices.Console
9+
{
10+
/// <summary>
11+
/// Contains the details about a choice that should be displayed
12+
/// to the user. This class is meant to be serializable to the
13+
/// user's UI.
14+
/// </summary>
15+
public class ChoiceDetails
16+
{
17+
#region Properties
18+
19+
/// <summary>
20+
/// Gets or sets the label for the choice.
21+
/// </summary>
22+
public string Label { get; set; }
23+
24+
/// <summary>
25+
/// Gets or sets the help string that describes the choice.
26+
/// </summary>
27+
public string HelpMessage { get; set; }
28+
29+
#endregion
30+
31+
#region Constructors
32+
33+
/// <summary>
34+
/// Creates a new instance of the ChoicePromptDetails class
35+
/// based on a ChoiceDescription from the PowerShell layer.
36+
/// </summary>
37+
/// <param name="choiceDescription">
38+
/// A ChoiceDescription on which this instance will be based.
39+
/// </param>
40+
/// <returns>A new ChoicePromptDetails instance.</returns>
41+
public static ChoiceDetails Create(ChoiceDescription choiceDescription)
42+
{
43+
return new ChoiceDetails
44+
{
45+
Label = choiceDescription.Label,
46+
HelpMessage = choiceDescription.HelpMessage
47+
};
48+
}
49+
50+
#endregion
51+
}
52+
}

src/PowerShellEditorServices/Console/ConsoleServicePSHostUserInterface.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Collections.ObjectModel;
99
using System.Management.Automation;
1010
using System.Management.Automation.Host;
11+
using System.Linq;
1112
using System.Security;
1213
using System.Threading.Tasks;
1314

@@ -65,7 +66,7 @@ public override int PromptForChoice(
6566
.PromptForChoice(
6667
promptCaption,
6768
promptMessage,
68-
choiceDescriptions,
69+
choiceDescriptions.Select(ChoiceDetails.Create),
6970
defaultChoice);
7071

7172
// This will synchronously block on the async PromptForChoice
@@ -193,7 +194,7 @@ public override void WriteProgress(
193194
{
194195
this.consoleHost.UpdateProgress(
195196
sourceId,
196-
record);
197+
ProgressDetails.Create(record));
197198
}
198199

199200
#endregion

src/PowerShellEditorServices/Console/IConsoleHost.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void WriteOutput(
5353
/// <param name="promptMessage">
5454
/// The descriptive message which will be displayed to the user.
5555
/// </param>
56-
/// <param name="choiceDescriptions">
56+
/// <param name="choices">
5757
/// The list of choices from which the user will select.
5858
/// </param>
5959
/// <param name="defaultChoice">
@@ -66,7 +66,7 @@ void WriteOutput(
6666
Task<int> PromptForChoice(
6767
string promptCaption,
6868
string promptMessage,
69-
IEnumerable<ChoiceDescription> choiceDescriptions,
69+
IEnumerable<ChoiceDetails> choices,
7070
int defaultChoice);
7171

7272
// TODO: Get rid of this method! Leaky abstraction.
@@ -88,10 +88,10 @@ void PromptForChoiceResult(
8888
/// Sends a progress update event to the user.
8989
/// </summary>
9090
/// <param name="sourceId">The source ID of the progress event.</param>
91-
/// <param name="progressRecord">The </param>
91+
/// <param name="progressDetails">The details of the activity's current progress.</param>
9292
void UpdateProgress(
9393
long sourceId,
94-
ProgressRecord progressRecord);
94+
ProgressDetails progressDetails);
9595

9696
/// <summary>
9797
/// Notifies the IConsoleHost implementation that the PowerShell

0 commit comments

Comments
 (0)