From 318dbb7590168716e383374f275a7099ec9a4c5a Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Tue, 27 Feb 2018 16:58:22 +0800 Subject: [PATCH 01/10] EditorServiceHost: allow Tcp/NamedPipe/Stdio listeners --- .../EditorServicesHost.cs | 77 ++++++++++++++----- .../Channel/ServerListenerBase.cs | 13 +++- 2 files changed, 67 insertions(+), 23 deletions(-) diff --git a/src/PowerShellEditorServices.Host/EditorServicesHost.cs b/src/PowerShellEditorServices.Host/EditorServicesHost.cs index c0275efce..cb7a0162b 100644 --- a/src/PowerShellEditorServices.Host/EditorServicesHost.cs +++ b/src/PowerShellEditorServices.Host/EditorServicesHost.cs @@ -29,6 +29,25 @@ public enum EditorServicesHostStatus Ended } + public enum EditorServiceTransportType + { + Tcp, + NamedPipe, + Stdio + } + + public class EditorServiceTransportConfig + { + public EditorServiceTransportType TransportType { get; set; } + /// + /// Configures the endpoint of the transport. + /// For Tcp it's an integer specifying the port. + /// For Stdio it's ignored. + /// For NamedPipe it's the pipe name. + /// + public string Endpoint { get; set; } + } + /// /// Provides a simplified interface for hosting the language and debug services /// over the named pipe server protocol. @@ -48,8 +67,8 @@ public class EditorServicesHost private HashSet featureFlags; private LanguageServer languageServer; - private TcpSocketServerListener languageServiceListener; - private TcpSocketServerListener debugServiceListener; + private IServerListener languageServiceListener; + private IServerListener debugServiceListener; private TaskCompletionSource serverCompletedTask; @@ -164,15 +183,11 @@ public void StartLogging(string logFilePath, LogLevel logLevel) /// /// The port number for the language service. /// The object containing the profile paths to load for this session. - public void StartLanguageService(int languageServicePort, ProfilePaths profilePaths) + public void StartLanguageService(EditorServiceTransportConfig config, ProfilePaths profilePaths) { this.profilePaths = profilePaths; - this.languageServiceListener = - new TcpSocketServerListener( - MessageProtocolType.LanguageServer, - languageServicePort, - this.logger); + this.languageServiceListener = CreateServiceListener(MessageProtocolType.LanguageServer, config); this.languageServiceListener.ClientConnect += this.OnLanguageServiceClientConnect; this.languageServiceListener.Start(); @@ -180,13 +195,13 @@ public void StartLanguageService(int languageServicePort, ProfilePaths profilePa this.logger.Write( LogLevel.Normal, string.Format( - "Language service started, listening on port {0}", - languageServicePort)); + "Language service started, type = {0}, endpoint = {1}", + config.TransportType, config.Endpoint)); } private async void OnLanguageServiceClientConnect( object sender, - TcpSocketServerChannel serverChannel) + ChannelBase serverChannel) { MessageDispatcher messageDispatcher = new MessageDispatcher(this.logger); @@ -238,27 +253,22 @@ await this.editorSession.PowerShellContext.ImportCommandsModule( /// /// The port number for the debug service. public void StartDebugService( - int debugServicePort, + EditorServiceTransportConfig config, ProfilePaths profilePaths, bool useExistingSession) { - this.debugServiceListener = - new TcpSocketServerListener( - MessageProtocolType.DebugAdapter, - debugServicePort, - this.logger); - + this.debugServiceListener = CreateServiceListener(MessageProtocolType.DebugAdapter, config); this.debugServiceListener.ClientConnect += OnDebugServiceClientConnect; this.debugServiceListener.Start(); this.logger.Write( LogLevel.Normal, string.Format( - "Debug service started, listening on port {0}", - debugServicePort)); + "Debug service started, type = {0}, endpoint = {1}", + config.TransportType, config.Endpoint)); } - private void OnDebugServiceClientConnect(object sender, TcpSocketServerChannel serverChannel) + private void OnDebugServiceClientConnect(object sender, ChannelBase serverChannel) { MessageDispatcher messageDispatcher = new MessageDispatcher(this.logger); @@ -441,6 +451,31 @@ private void CurrentDomain_UnhandledException( e.ExceptionObject.ToString())); } #endif + private IServerListener CreateServiceListener(MessageProtocolType protocol, EditorServiceTransportConfig config) + { + switch (config.TransportType) + { + case EditorServiceTransportType.Tcp: + { + return new TcpSocketServerListener(protocol, int.Parse(config.Endpoint), this.logger); + } + + case EditorServiceTransportType.Stdio: + { + return new StdioServerListener(protocol, this.logger); + } + + case EditorServiceTransportType.NamedPipe: + { + return new NamedPipeServerListener(protocol, config.Endpoint, this.logger); + } + + default: + { + throw new NotSupportedException(); + } + } + } #endregion } diff --git a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/ServerListenerBase.cs b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/ServerListenerBase.cs index de2b034f0..433f6aabb 100644 --- a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/ServerListenerBase.cs +++ b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/ServerListenerBase.cs @@ -8,7 +8,7 @@ namespace Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol.Channel { - public abstract class ServerListenerBase + public abstract class ServerListenerBase : IServerListener where TChannel : ChannelBase { private MessageProtocolType messageProtocolType; @@ -22,7 +22,7 @@ public ServerListenerBase(MessageProtocolType messageProtocolType) public abstract void Stop(); - public event EventHandler ClientConnect; + public event EventHandler ClientConnect; protected void OnClientConnect(TChannel channel) { @@ -30,4 +30,13 @@ protected void OnClientConnect(TChannel channel) this.ClientConnect?.Invoke(this, channel); } } + + public interface IServerListener + { + void Start(); + + void Stop(); + + event EventHandler ClientConnect; + } } \ No newline at end of file From ae39b16744c06e091dca2cd3cd004d3b95fc8a11 Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Tue, 27 Feb 2018 19:11:08 +0800 Subject: [PATCH 02/10] update ps scripts --- .../PowerShellEditorServices.psm1 | 50 +++++++++++++++---- module/Start-EditorServices.ps1 | 23 +++++++-- 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 index b19caa8bd..9d06a897c 100644 --- a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 +++ b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 @@ -31,16 +31,21 @@ function Start-EditorServicesHost { [string] $HostVersion, - [Parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] [int] $LanguageServicePort, - [Parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] [int] $DebugServicePort, + [bool] + $Stdio, + + [string] + $LanguageServiceNamedPipe, + + [string] + $DebugServiceNamedPipe, + [ValidateNotNullOrEmpty()] [string] $BundledModulesPath, @@ -89,12 +94,39 @@ function Start-EditorServicesHost { $editorServicesHost.StartLogging($LogPath, $LogLevel); - if ($DebugServiceOnly.IsPresent) { - $editorServicesHost.StartDebugService($DebugServicePort, $profilePaths, $false); + $languageServiceConfig = New-Object Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportConfig + $debugServiceConfig = New-Object Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportConfig + + if ($Stdio) { + $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::Stdio + $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::Stdio } - else { - $editorServicesHost.StartLanguageService($LanguageServicePort, $profilePaths); - $editorServicesHost.StartDebugService($DebugServicePort, $profilePaths, $true); + + if ($LanguageServicePort) { + $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::Tcp + $languageServiceConfig.Endpoint = "$LanguageServicePort" + } + + if ($DebugServicePort) { + $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::Tcp + $debugServiceConfig.Endpoint = "$DebugServicePort" + } + + if ($LanguageServiceNamedPipe) { + $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe + $languageServiceConfig.Endpoint = "$LanguageServiceNamedPipe" + } + + if ($DebugServicePort) { + $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe + $debugServiceConfig.Endpoint = "$DebugServiceNamedPipe" + } + + if ($DebugServiceOnly.IsPresent) { + $editorServicesHost.StartDebugService($debugServiceConfig, $profilePaths, $false); + } else { + $editorServicesHost.StartLanguageService($languageServiceConfig, $profilePaths); + $editorServicesHost.StartDebugService($debugServiceConfig, $profilePaths, $true); } return $editorServicesHost diff --git a/module/Start-EditorServices.ps1 b/module/Start-EditorServices.ps1 index 332016352..52d9267e5 100644 --- a/module/Start-EditorServices.ps1 +++ b/module/Start-EditorServices.ps1 @@ -51,7 +51,16 @@ param( $WaitForDebugger, [switch] - $ConfirmInstall + $ConfirmInstall, + + [switch] + $Stdio, + + [string] + $LanguageServicePipeName = $null, + + [string] + $DebugServicePipeName = $null ) # This variable will be assigned later to contain information about @@ -149,8 +158,9 @@ if ((Test-ModuleAvailable "PowerShellEditorServices" -RequiredVersion $parsedVer Import-Module PowerShellEditorServices -RequiredVersion $parsedVersion -ErrorAction Stop # Locate available port numbers for services -$languageServicePort = Get-AvailablePort -$debugServicePort = Get-AvailablePort + +if (-not ($Stdio.IsPresent -or $LanguageServicePipeName)) { $languageServicePort = Get-AvailablePort } +if (-not ($Stdio.IsPresent -or $DebugServicePipeName)) { $debugServicePort = Get-AvailablePort } $editorServicesHost = Start-EditorServicesHost ` @@ -162,6 +172,9 @@ $editorServicesHost = -AdditionalModules @() ` -LanguageServicePort $languageServicePort ` -DebugServicePort $debugServicePort ` + -Stdio $Stdio.IsPresent` + -LanguageServiceNamedPipe $LanguageServicePipeName ` + -DebugServiceNamedPipe $DebugServicePipeName ` -BundledModulesPath $BundledModulesPath ` -WaitForDebugger:$WaitForDebugger.IsPresent @@ -169,9 +182,11 @@ $editorServicesHost = $resultDetails = @{ "status" = "started"; - "channel" = "tcp"; "languageServicePort" = $languageServicePort; "debugServicePort" = $debugServicePort; + "languageServiceNamedPipe" = $LanguageServicePipeName; + "debugServiceNamedPipe" = $DebugServicePipeName; + "Stdio" = $Stdio.IsPresent; }; # Notify the client that the services have started From 941ab40d4653b610dc7ec525f62fd4d1f8162e32 Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Tue, 27 Feb 2018 23:07:06 +0800 Subject: [PATCH 03/10] fix script and test errors; --- module/PowerShellEditorServices/PowerShellEditorServices.psm1 | 2 +- test/PowerShellEditorServices.Test.Host/ServerTestsBase.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 index 9d06a897c..c792c2cf0 100644 --- a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 +++ b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 @@ -117,7 +117,7 @@ function Start-EditorServicesHost { $languageServiceConfig.Endpoint = "$LanguageServiceNamedPipe" } - if ($DebugServicePort) { + if ($DebugServiceNamedPipe) { $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe $debugServiceConfig.Endpoint = "$DebugServiceNamedPipe" } diff --git a/test/PowerShellEditorServices.Test.Host/ServerTestsBase.cs b/test/PowerShellEditorServices.Test.Host/ServerTestsBase.cs index 6cfb1f6dc..30eb156a9 100644 --- a/test/PowerShellEditorServices.Test.Host/ServerTestsBase.cs +++ b/test/PowerShellEditorServices.Test.Host/ServerTestsBase.cs @@ -12,6 +12,9 @@ using System.IO; using System.Text; using System.Threading.Tasks; +#if CoreCLR +using System.Reflection; +#endif namespace Microsoft.PowerShell.EditorServices.Test.Host { From ed6b7221de04f053c7008c5aa687c8a2092b4287 Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Wed, 28 Feb 2018 13:07:28 +0800 Subject: [PATCH 04/10] update startup script: there can be only one service on the stdio channel --- module/Start-EditorServices.ps1 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/module/Start-EditorServices.ps1 b/module/Start-EditorServices.ps1 index 52d9267e5..dbbacf29e 100644 --- a/module/Start-EditorServices.ps1 +++ b/module/Start-EditorServices.ps1 @@ -56,6 +56,9 @@ param( [switch] $Stdio, + [switch] + $DebugServiceOnly, + [string] $LanguageServicePipeName = $null, @@ -158,9 +161,9 @@ if ((Test-ModuleAvailable "PowerShellEditorServices" -RequiredVersion $parsedVer Import-Module PowerShellEditorServices -RequiredVersion $parsedVersion -ErrorAction Stop # Locate available port numbers for services - -if (-not ($Stdio.IsPresent -or $LanguageServicePipeName)) { $languageServicePort = Get-AvailablePort } -if (-not ($Stdio.IsPresent -or $DebugServicePipeName)) { $debugServicePort = Get-AvailablePort } +# There could be only one service on Stdio channel +if (-not (($Stdio.IsPresent -and -not $DebugServiceOnly.IsPresent) -or $LanguageServicePipeName)) { $languageServicePort = Get-AvailablePort } +if (-not (($Stdio.IsPresent -and $DebugServiceOnly.IsPresent) -or $DebugServicePipeName)) { $debugServicePort = Get-AvailablePort } $editorServicesHost = Start-EditorServicesHost ` @@ -176,6 +179,7 @@ $editorServicesHost = -LanguageServiceNamedPipe $LanguageServicePipeName ` -DebugServiceNamedPipe $DebugServicePipeName ` -BundledModulesPath $BundledModulesPath ` + -DebugServiceOnly:$DebugServiceOnly.IsPresent` -WaitForDebugger:$WaitForDebugger.IsPresent # TODO: Verify that the service is started From efdf05a4a3703e27dc11c91cb4042f5981bbb11c Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Thu, 1 Mar 2018 14:06:34 +0800 Subject: [PATCH 05/10] 1. handle file refresh where range info is absent; 2. listen to the named pipe on start. --- .../Channel/NamedPipeServerListener.cs | 1 + .../Server/LanguageServer.cs | 5 +- .../Workspace/FileChange.cs | 7 ++ .../Workspace/ScriptFile.cs | 96 +++++++++++-------- 4 files changed, 66 insertions(+), 43 deletions(-) diff --git a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs index cf1cb3e4c..1f17b749c 100644 --- a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs +++ b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs @@ -38,6 +38,7 @@ public override void Start() 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); + ListenForConnection(); } catch (IOException e) { diff --git a/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs b/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs index 854812717..d1fa8afa4 100644 --- a/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs +++ b/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs @@ -1348,13 +1348,16 @@ private static FileChange GetFileChangeDetails(Range changeRange, string insertS { // The protocol's positions are zero-based so add 1 to all offsets + if (changeRange == null) return new FileChange { InsertString = insertString, Reloaded = true }; + return new FileChange { InsertString = insertString, Line = changeRange.Start.Line + 1, Offset = changeRange.Start.Character + 1, EndLine = changeRange.End.Line + 1, - EndOffset = changeRange.End.Character + 1 + EndOffset = changeRange.End.Character + 1, + Reloaded = false }; } diff --git a/src/PowerShellEditorServices/Workspace/FileChange.cs b/src/PowerShellEditorServices/Workspace/FileChange.cs index 3bec7982e..a98428770 100644 --- a/src/PowerShellEditorServices/Workspace/FileChange.cs +++ b/src/PowerShellEditorServices/Workspace/FileChange.cs @@ -34,5 +34,12 @@ public class FileChange /// The 1-based column offset where the change ends. /// public int EndOffset { get; set; } + + /// + /// Indicates that the InsertString is an overwrite + /// of the content, and all stale content and metadata + /// should be discarded. + /// + public bool Reloaded { get; set; } } } diff --git a/src/PowerShellEditorServices/Workspace/ScriptFile.cs b/src/PowerShellEditorServices/Workspace/ScriptFile.cs index 19060fb01..1f118275b 100644 --- a/src/PowerShellEditorServices/Workspace/ScriptFile.cs +++ b/src/PowerShellEditorServices/Workspace/ScriptFile.cs @@ -63,7 +63,7 @@ public string Id /// /// Gets a string containing the full contents of the file. /// - public string Contents + public string Contents { get { @@ -175,7 +175,7 @@ public ScriptFile( /// The path at which the script file resides. /// The path which the client uses to identify the file. /// The version of PowerShell for which the script is being parsed. - public ScriptFile ( + public ScriptFile( string filePath, string clientFilePath, Version powerShellVersion) @@ -184,9 +184,9 @@ public ScriptFile ( clientFilePath, File.ReadAllText(filePath), powerShellVersion) - { + { - } + } #endregion @@ -315,52 +315,64 @@ public void ValidatePosition(int line, int column) /// The FileChange to apply to the file's contents. public void ApplyChange(FileChange fileChange) { - this.ValidatePosition(fileChange.Line, fileChange.Offset); - this.ValidatePosition(fileChange.EndLine, fileChange.EndOffset); - // Break up the change lines string[] changeLines = fileChange.InsertString.Split('\n'); - // Get the first fragment of the first line - string firstLineFragment = + if (fileChange.Reloaded) + { + this.FileLines.Clear(); + foreach (var changeLine in changeLines) + { + this.FileLines.Add(changeLine); + } + } + else + { + this.ValidatePosition(fileChange.Line, fileChange.Offset); + this.ValidatePosition(fileChange.EndLine, fileChange.EndOffset); + + // Get the first fragment of the first line + string firstLineFragment = this.FileLines[fileChange.Line - 1] .Substring(0, fileChange.Offset - 1); - // Get the last fragment of the last line - string endLine = this.FileLines[fileChange.EndLine - 1]; - string lastLineFragment = + // Get the last fragment of the last line + string endLine = this.FileLines[fileChange.EndLine - 1]; + string lastLineFragment = endLine.Substring( - fileChange.EndOffset - 1, + fileChange.EndOffset - 1, (this.FileLines[fileChange.EndLine - 1].Length - fileChange.EndOffset) + 1); - // Remove the old lines - for (int i = 0; i <= fileChange.EndLine - fileChange.Line; i++) - { - this.FileLines.RemoveAt(fileChange.Line - 1); - } - - // Build and insert the new lines - int currentLineNumber = fileChange.Line; - for (int changeIndex = 0; changeIndex < changeLines.Length; changeIndex++) - { - // Since we split the lines above using \n, make sure to - // trim the ending \r's off as well. - string finalLine = changeLines[changeIndex].TrimEnd('\r'); - - // Should we add first or last line fragments? - if (changeIndex == 0) + // Remove the old lines + for (int i = 0; i <= fileChange.EndLine - fileChange.Line; i++) { - // Append the first line fragment - finalLine = firstLineFragment + finalLine; + this.FileLines.RemoveAt(fileChange.Line - 1); } - if (changeIndex == changeLines.Length - 1) + + // Build and insert the new lines + int currentLineNumber = fileChange.Line; + for (int changeIndex = 0; changeIndex < changeLines.Length; changeIndex++) { - // Append the last line fragment - finalLine = finalLine + lastLineFragment; + // Since we split the lines above using \n, make sure to + // trim the ending \r's off as well. + string finalLine = changeLines[changeIndex].TrimEnd('\r'); + + // Should we add first or last line fragments? + if (changeIndex == 0) + { + // Append the first line fragment + finalLine = firstLineFragment + finalLine; + } + if (changeIndex == changeLines.Length - 1) + { + // Append the last line fragment + finalLine = finalLine + lastLineFragment; + } + + this.FileLines.Insert(currentLineNumber - 1, finalLine); + currentLineNumber++; } - this.FileLines.Insert(currentLineNumber - 1, finalLine); - currentLineNumber++; } // Parse the script again to be up-to-date @@ -381,12 +393,12 @@ public int GetOffsetAtPosition(int lineNumber, int columnNumber) int offset = 0; - for(int i = 0; i < lineNumber; i++) + for (int i = 0; i < lineNumber; i++) { if (i == lineNumber - 1) { // Subtract 1 to account for 1-based column numbering - offset += columnNumber - 1; + offset += columnNumber - 1; } else { @@ -430,7 +442,7 @@ public FilePosition CalculatePosition( /// A new BufferPosition containing the position of the offset. public BufferPosition GetPositionAtOffset(int bufferOffset) { - BufferRange bufferRange = + BufferRange bufferRange = GetRangeBetweenOffsets( bufferOffset, bufferOffset); @@ -572,7 +584,7 @@ private void ParseFileContents() var parseError = new ParseError( null, - ex.ErrorRecord.FullyQualifiedErrorId, + ex.ErrorRecord.FullyQualifiedErrorId, ex.Message); parseErrors = new[] { parseError }; @@ -585,12 +597,12 @@ private void ParseFileContents() parseErrors .Select(ScriptFileMarker.FromParseError) .ToArray(); - + //Get all dot sourced referenced files and store them this.ReferencedFiles = AstOperations.FindDotSourcedIncludes(this.ScriptAst); } -#endregion + #endregion } } From 8de969db5fe9310527b18efa62c4611dbe67aa9a Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Tue, 20 Mar 2018 09:57:12 +0800 Subject: [PATCH 06/10] FileChange: Reloaded->IsReload --- .../Server/LanguageServer.cs | 4 ++-- src/PowerShellEditorServices/Workspace/FileChange.cs | 2 +- src/PowerShellEditorServices/Workspace/ScriptFile.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs b/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs index d1fa8afa4..3bd97b5df 100644 --- a/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs +++ b/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs @@ -1348,7 +1348,7 @@ private static FileChange GetFileChangeDetails(Range changeRange, string insertS { // The protocol's positions are zero-based so add 1 to all offsets - if (changeRange == null) return new FileChange { InsertString = insertString, Reloaded = true }; + if (changeRange == null) return new FileChange { InsertString = insertString, IsReload = true }; return new FileChange { @@ -1357,7 +1357,7 @@ private static FileChange GetFileChangeDetails(Range changeRange, string insertS Offset = changeRange.Start.Character + 1, EndLine = changeRange.End.Line + 1, EndOffset = changeRange.End.Character + 1, - Reloaded = false + IsReload = false }; } diff --git a/src/PowerShellEditorServices/Workspace/FileChange.cs b/src/PowerShellEditorServices/Workspace/FileChange.cs index a98428770..79f6925ea 100644 --- a/src/PowerShellEditorServices/Workspace/FileChange.cs +++ b/src/PowerShellEditorServices/Workspace/FileChange.cs @@ -40,6 +40,6 @@ public class FileChange /// of the content, and all stale content and metadata /// should be discarded. /// - public bool Reloaded { get; set; } + public bool IsReload { get; set; } } } diff --git a/src/PowerShellEditorServices/Workspace/ScriptFile.cs b/src/PowerShellEditorServices/Workspace/ScriptFile.cs index 1f118275b..fc290cff0 100644 --- a/src/PowerShellEditorServices/Workspace/ScriptFile.cs +++ b/src/PowerShellEditorServices/Workspace/ScriptFile.cs @@ -318,7 +318,7 @@ public void ApplyChange(FileChange fileChange) // Break up the change lines string[] changeLines = fileChange.InsertString.Split('\n'); - if (fileChange.Reloaded) + if (fileChange.IsReload) { this.FileLines.Clear(); foreach (var changeLine in changeLines) From 17ce8b7832c7d290a0b8224987a92e4f14af870a Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Tue, 20 Mar 2018 10:16:41 +0800 Subject: [PATCH 07/10] Start-EditorServices.ps1: $env:PSMODULEPATH -> $env:PsModulePath --- module/Start-EditorServices.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/Start-EditorServices.ps1 b/module/Start-EditorServices.ps1 index dbbacf29e..4efa09803 100644 --- a/module/Start-EditorServices.ps1 +++ b/module/Start-EditorServices.ps1 @@ -135,7 +135,7 @@ function Get-AvailablePort { # Add BundledModulesPath to $env:PSModulePath if ($BundledModulesPath) { - $env:PSMODULEPATH = $BundledModulesPath + [System.IO.Path]::PathSeparator + $env:PSMODULEPATH + $env:PsModulePath = $BundledModulesPath + [System.IO.Path]::PathSeparator + $env:PsModulePath } # Check if PowerShellGet module is available From 66da3fe185962af2d52872df01737ac5d5c58a8c Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Tue, 20 Mar 2018 17:13:38 +0800 Subject: [PATCH 08/10] Update Start-EditorServices.ps1 --- module/Start-EditorServices.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/Start-EditorServices.ps1 b/module/Start-EditorServices.ps1 index 4efa09803..315d94e31 100644 --- a/module/Start-EditorServices.ps1 +++ b/module/Start-EditorServices.ps1 @@ -135,7 +135,7 @@ function Get-AvailablePort { # Add BundledModulesPath to $env:PSModulePath if ($BundledModulesPath) { - $env:PsModulePath = $BundledModulesPath + [System.IO.Path]::PathSeparator + $env:PsModulePath + $env:PSModulePath = $BundledModulesPath + [System.IO.Path]::PathSeparator + $env:PSModulePath } # Check if PowerShellGet module is available From f73d784a393706056f4baf9e9f17e36209d356e0 Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Tue, 27 Mar 2018 16:11:37 +0800 Subject: [PATCH 09/10] update startup script. --- module/Start-EditorServices.ps1 | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/module/Start-EditorServices.ps1 b/module/Start-EditorServices.ps1 index d074a7373..83364f091 100644 --- a/module/Start-EditorServices.ps1 +++ b/module/Start-EditorServices.ps1 @@ -282,12 +282,19 @@ try { # Locate available port numbers for services # There could be only one service on Stdio channel - if (-not (($Stdio.IsPresent -and -not $DebugServiceOnly.IsPresent) -or $LanguageServicePipeName)) { $languageServicePort = Get-AvailablePort } - if (-not (($Stdio.IsPresent -and $DebugServiceOnly.IsPresent) -or $DebugServicePipeName)) { $debugServicePort = Get-AvailablePort } - if (!$languageServicePort -or !$debugServicePort) { - ExitWithError "Failed to find an open socket port for either the language or debug service." - } + $languageServiceTransport = $null + $debugServiceTransport = $null + + if ($Stdio.IsPresent -and -not $DebugServiceOnly.IsPresent) { $languageServiceTransport = "Stdio" } + elseif ($LanguageServicePipeName) { $languageServiceTransport = "Named pipe $LanguageServicePipeName" } + elseif ($languageServicePort = Get-AvailablePort) { $languageServiceTransport = "Tcp port $languageServicePort"} + else { ExitWithError "Failed to find an open socket port for language service." } + + if ($Stdio.IsPresent -and $DebugServiceOnly.IsPresent) { $debugServiceTransport = "Stdio" } + elseif ($DebugServicePipeName) { $debugServiceTransport = "Named pipe $DebugServicePipeName" } + elseif ($debugServicePort = Get-AvailablePort) { $debugServiceTransport = "Tcp port $debugServicePort"} + else { ExitWithError "Failed to find an open socket port for debug service." } if ($EnableConsoleRepl) { Write-Host "PowerShell Integrated Console`n" @@ -318,11 +325,8 @@ try { $resultDetails = @{ "status" = "started"; - "languageServicePort" = $languageServicePort; - "debugServicePort" = $debugServicePort; - "languageServiceNamedPipe" = $LanguageServicePipeName; - "debugServiceNamedPipe" = $DebugServicePipeName; - "Stdio" = $Stdio.IsPresent; + "languageServiceTransport" = $languageServiceTransport; + "debugServiceTransport" = $debugServiceTransport; }; # Notify the client that the services have started From 592d29da92bf186e96c24f7d5dffe357de3eefdb Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Thu, 19 Apr 2018 16:31:43 +0800 Subject: [PATCH 10/10] update startup script, fix tests --- module/Start-EditorServices.ps1 | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/module/Start-EditorServices.ps1 b/module/Start-EditorServices.ps1 index 83364f091..c81d92920 100644 --- a/module/Start-EditorServices.ps1 +++ b/module/Start-EditorServices.ps1 @@ -287,13 +287,13 @@ try { $debugServiceTransport = $null if ($Stdio.IsPresent -and -not $DebugServiceOnly.IsPresent) { $languageServiceTransport = "Stdio" } - elseif ($LanguageServicePipeName) { $languageServiceTransport = "Named pipe $LanguageServicePipeName" } - elseif ($languageServicePort = Get-AvailablePort) { $languageServiceTransport = "Tcp port $languageServicePort"} + elseif ($LanguageServicePipeName) { $languageServiceTransport = "NamedPipe"; $languageServicePipeName = "$LanguageServicePipeName" } + elseif ($languageServicePort = Get-AvailablePort) { $languageServiceTransport = "Tcp" } else { ExitWithError "Failed to find an open socket port for language service." } if ($Stdio.IsPresent -and $DebugServiceOnly.IsPresent) { $debugServiceTransport = "Stdio" } - elseif ($DebugServicePipeName) { $debugServiceTransport = "Named pipe $DebugServicePipeName" } - elseif ($debugServicePort = Get-AvailablePort) { $debugServiceTransport = "Tcp port $debugServicePort"} + elseif ($DebugServicePipeName) { $debugServiceTransport = "NamedPipe"; $debugServicePipeName = "$DebugServicePipeName" } + elseif ($debugServicePort = Get-AvailablePort) { $debugServiceTransport = "Tcp" } else { ExitWithError "Failed to find an open socket port for debug service." } if ($EnableConsoleRepl) { @@ -329,6 +329,12 @@ try { "debugServiceTransport" = $debugServiceTransport; }; + if ($languageServicePipeName) { $resultDetails["languageServicePipeName"] = "$languageServicePipeName" } + if ($debugServicePipeName) { $resultDetails["debugServicePipeName"] = "$debugServicePipeName" } + + if ($languageServicePort) { $resultDetails["languageServicePort"] = $languageServicePort } + if ($debugServicePort) { $resultDetails["debugServicePort"] = $debugServicePort } + # Notify the client that the services have started WriteSessionFile $resultDetails