From 549c2b5e0ce565f8b30072615e2e513eb5c22dd9 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Fri, 15 May 2020 17:18:54 -0700 Subject: [PATCH 1/3] Depend on DocumentUri for handing vscode Uri's --- .../CodeLens/PesterCodeLensProvider.cs | 16 +- .../CodeLens/ReferencesCodeLensProvider.cs | 7 +- .../Services/Symbols/SymbolReference.cs | 6 +- .../Symbols/Vistors/FindReferencesVisitor.cs | 3 +- .../Symbols/Vistors/FindSymbolVisitor.cs | 3 +- .../Symbols/Vistors/FindSymbolsVisitor.cs | 3 +- .../Handlers/DefinitionHandler.cs | 3 +- .../Handlers/DocumentSymbolHandler.cs | 3 +- .../Handlers/ReferencesHandler.cs | 3 +- .../Services/TextDocument/ScriptFile.cs | 3 +- .../Handlers/WorkspaceSymbolsHandler.cs | 4 +- .../Services/Workspace/WorkspaceService.cs | 147 ------------------ .../Utility/PathUtils.cs | 25 --- .../Session/WorkspaceTests.cs | 48 ------ 14 files changed, 34 insertions(+), 240 deletions(-) diff --git a/src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs index 421f11ead..557f43e9f 100644 --- a/src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs @@ -3,7 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; using System.Collections.Generic; using Microsoft.PowerShell.EditorServices.Services; using Microsoft.PowerShell.EditorServices.Services.Symbols; @@ -11,6 +10,7 @@ using Microsoft.PowerShell.EditorServices.Utility; using Newtonsoft.Json.Linq; using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using OmniSharp.Extensions.LanguageServer.Protocol.Serialization; namespace Microsoft.PowerShell.EditorServices.CodeLenses { @@ -60,11 +60,14 @@ private CodeLens[] GetPesterLens(PesterSymbolReference pesterSymbol, ScriptFile { Name = "PowerShell.RunPesterTests", Title = $"Run {word}", - Arguments = JArray.FromObject(new object[] { + Arguments = JArray.FromObject(new object[] + { scriptFile.DocumentUri, false /* No debug */, pesterSymbol.TestName, - pesterSymbol.ScriptRegion?.StartLineNumber }) + pesterSymbol.ScriptRegion?.StartLineNumber + }, + Serializer.Instance.JsonSerializer) } }, @@ -79,11 +82,14 @@ private CodeLens[] GetPesterLens(PesterSymbolReference pesterSymbol, ScriptFile { Name = "PowerShell.RunPesterTests", Title = $"Debug {word}", - Arguments = JArray.FromObject(new object[] { + Arguments = JArray.FromObject(new object[] + { scriptFile.DocumentUri, true /* No debug */, pesterSymbol.TestName, - pesterSymbol.ScriptRegion?.StartLineNumber }) + pesterSymbol.ScriptRegion?.StartLineNumber + }, + Serializer.Instance.JsonSerializer) } } }; diff --git a/src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs b/src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs index 50400ff55..edf5c7cff 100644 --- a/src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs +++ b/src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs @@ -11,7 +11,9 @@ using Microsoft.PowerShell.EditorServices.Services.TextDocument; using Microsoft.PowerShell.EditorServices.Utility; using Newtonsoft.Json.Linq; +using OmniSharp.Extensions.LanguageServer.Protocol; using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using OmniSharp.Extensions.LanguageServer.Protocol.Serialization; namespace Microsoft.PowerShell.EditorServices.CodeLenses { @@ -113,7 +115,7 @@ public CodeLens ResolveCodeLens(CodeLens codeLens, ScriptFile scriptFile) acc.Add(new Location { - Uri = PathUtils.ToUri(foundReference.FilePath), + Uri = DocumentUri.FromFileSystemPath(foundReference.FilePath), Range = foundReference.ScriptRegion.ToRange() }); } @@ -133,7 +135,8 @@ public CodeLens ResolveCodeLens(CodeLens codeLens, ScriptFile scriptFile) scriptFile.DocumentUri, codeLens.Range.Start, referenceLocations - }) + }, + Serializer.Instance.JsonSerializer) } }; } diff --git a/src/PowerShellEditorServices/Services/Symbols/SymbolReference.cs b/src/PowerShellEditorServices/Services/Symbols/SymbolReference.cs index f6af0fe3c..dce5df036 100644 --- a/src/PowerShellEditorServices/Services/Symbols/SymbolReference.cs +++ b/src/PowerShellEditorServices/Services/Symbols/SymbolReference.cs @@ -107,10 +107,8 @@ public SymbolReference( /// /// The higher level type of the symbol /// The script extent of the symbol - /// The file path of the symbol - /// The line contents of the given symbol (defaults to empty string) - public SymbolReference(SymbolType symbolType, IScriptExtent scriptExtent, string filePath = "", string sourceLine = "") - : this(symbolType, scriptExtent.Text, scriptExtent, filePath, sourceLine) + public SymbolReference(SymbolType symbolType, IScriptExtent scriptExtent) + : this(symbolType, scriptExtent.Text, scriptExtent, scriptExtent.File, "") { } } diff --git a/src/PowerShellEditorServices/Services/Symbols/Vistors/FindReferencesVisitor.cs b/src/PowerShellEditorServices/Services/Symbols/Vistors/FindReferencesVisitor.cs index a8ef9012b..256cfe559 100644 --- a/src/PowerShellEditorServices/Services/Symbols/Vistors/FindReferencesVisitor.cs +++ b/src/PowerShellEditorServices/Services/Symbols/Vistors/FindReferencesVisitor.cs @@ -133,7 +133,8 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun StartLineNumber = startLineNumber, EndLineNumber = startLineNumber, StartColumnNumber = startColumnNumber, - EndColumnNumber = startColumnNumber + functionDefinitionAst.Name.Length + EndColumnNumber = startColumnNumber + functionDefinitionAst.Name.Length, + File = functionDefinitionAst.Extent.File }; if (symbolRef.SymbolType.Equals(SymbolType.Function) && diff --git a/src/PowerShellEditorServices/Services/Symbols/Vistors/FindSymbolVisitor.cs b/src/PowerShellEditorServices/Services/Symbols/Vistors/FindSymbolVisitor.cs index 6d1629869..e80e70a3a 100644 --- a/src/PowerShellEditorServices/Services/Symbols/Vistors/FindSymbolVisitor.cs +++ b/src/PowerShellEditorServices/Services/Symbols/Vistors/FindSymbolVisitor.cs @@ -74,7 +74,8 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun StartLineNumber = functionDefinitionAst.Extent.StartLineNumber, EndLineNumber = functionDefinitionAst.Extent.EndLineNumber, StartColumnNumber = startColumnNumber, - EndColumnNumber = startColumnNumber + functionDefinitionAst.Name.Length + EndColumnNumber = startColumnNumber + functionDefinitionAst.Name.Length, + File = functionDefinitionAst.Extent.File }; if (this.IsPositionInExtent(nameExtent)) diff --git a/src/PowerShellEditorServices/Services/Symbols/Vistors/FindSymbolsVisitor.cs b/src/PowerShellEditorServices/Services/Symbols/Vistors/FindSymbolsVisitor.cs index c7f36544e..b8444fc64 100644 --- a/src/PowerShellEditorServices/Services/Symbols/Vistors/FindSymbolsVisitor.cs +++ b/src/PowerShellEditorServices/Services/Symbols/Vistors/FindSymbolsVisitor.cs @@ -36,7 +36,8 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun StartLineNumber = functionDefinitionAst.Extent.StartLineNumber, EndLineNumber = functionDefinitionAst.Extent.EndLineNumber, StartColumnNumber = functionDefinitionAst.Extent.StartColumnNumber, - EndColumnNumber = functionDefinitionAst.Extent.EndColumnNumber + EndColumnNumber = functionDefinitionAst.Extent.EndColumnNumber, + File = functionDefinitionAst.Extent.File }; SymbolType symbolType = diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs index 6cbeaa9eb..744b14128 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs @@ -11,6 +11,7 @@ using Microsoft.PowerShell.EditorServices.Services.Symbols; using Microsoft.PowerShell.EditorServices.Services.TextDocument; using Microsoft.PowerShell.EditorServices.Utility; +using OmniSharp.Extensions.LanguageServer.Protocol; using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; using OmniSharp.Extensions.LanguageServer.Protocol.Models; using OmniSharp.Extensions.LanguageServer.Protocol.Server; @@ -66,7 +67,7 @@ public async Task Handle(DefinitionParams request, Canc new LocationOrLocationLink( new Location { - Uri = PathUtils.ToUri(foundDefinition.FilePath), + Uri = DocumentUri.FromFileSystemPath(foundDefinition.FilePath), Range = GetRangeFromScriptRegion(foundDefinition.ScriptRegion) })); } diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentSymbolHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentSymbolHandler.cs index 22c1a99d6..743b721d3 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentSymbolHandler.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentSymbolHandler.cs @@ -16,6 +16,7 @@ using Microsoft.PowerShell.EditorServices.Services.Symbols; using Microsoft.PowerShell.EditorServices.Services.TextDocument; using Microsoft.PowerShell.EditorServices.Utility; +using OmniSharp.Extensions.LanguageServer.Protocol; using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; using OmniSharp.Extensions.LanguageServer.Protocol.Models; using OmniSharp.Extensions.LanguageServer.Protocol.Server; @@ -74,7 +75,7 @@ public Task Handle(DocumentSymbolPar Kind = GetSymbolKind(r.SymbolType), Location = new Location { - Uri = PathUtils.ToUri(r.FilePath), + Uri = DocumentUri.FromFileSystemPath(r.FilePath), Range = GetRangeFromScriptRegion(r.ScriptRegion) }, Name = GetDecoratedSymbolName(r) diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs index 41147f805..61ba070e0 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs @@ -11,6 +11,7 @@ using Microsoft.PowerShell.EditorServices.Services.Symbols; using Microsoft.PowerShell.EditorServices.Services.TextDocument; using Microsoft.PowerShell.EditorServices.Utility; +using OmniSharp.Extensions.LanguageServer.Protocol; using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; using OmniSharp.Extensions.LanguageServer.Protocol.Models; using OmniSharp.Extensions.LanguageServer.Protocol.Server; @@ -63,7 +64,7 @@ public Task Handle(ReferenceParams request, CancellationToken { locations.Add(new Location { - Uri = PathUtils.ToUri(foundReference.FilePath), + Uri = DocumentUri.FromFileSystemPath(foundReference.FilePath), Range = GetRangeFromScriptRegion(foundReference.ScriptRegion) }); } diff --git a/src/PowerShellEditorServices/Services/TextDocument/ScriptFile.cs b/src/PowerShellEditorServices/Services/TextDocument/ScriptFile.cs index 7b9858c3f..50775a579 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/ScriptFile.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/ScriptFile.cs @@ -60,9 +60,10 @@ public string DocumentUri { get { + // TODO: Have this be a DocumentUri type and stop having it be computed every time. return this.ClientFilePath == null ? string.Empty - : WorkspaceService.ConvertPathToDocumentUri(this.ClientFilePath); + : OmniSharp.Extensions.LanguageServer.Protocol.DocumentUri.FromFileSystemPath(ClientFilePath)?.ToString(); } } diff --git a/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs b/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs index 6bda1ed6e..c35989a24 100644 --- a/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs +++ b/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs @@ -12,7 +12,7 @@ using Microsoft.PowerShell.EditorServices.Services; using Microsoft.PowerShell.EditorServices.Services.Symbols; using Microsoft.PowerShell.EditorServices.Services.TextDocument; -using Microsoft.PowerShell.EditorServices.Utility; +using OmniSharp.Extensions.LanguageServer.Protocol; using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; using OmniSharp.Extensions.LanguageServer.Protocol.Models; using OmniSharp.Extensions.LanguageServer.Protocol.Server; @@ -59,7 +59,7 @@ public Task> Handle(WorkspaceSymbolParams request, var location = new Location { - Uri = PathUtils.ToUri(foundOccurrence.FilePath), + Uri = DocumentUri.FromFileSystemPath(foundOccurrence.FilePath), Range = GetRangeFromScriptRegion(foundOccurrence.ScriptRegion) }; diff --git a/src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs b/src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs index ba37f621c..d75766bb5 100644 --- a/src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs +++ b/src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs @@ -9,7 +9,6 @@ using System.IO; using System.Security; using System.Text; -using System.Runtime.InteropServices; using Microsoft.Extensions.FileSystemGlobbing; using Microsoft.Extensions.Logging; using Microsoft.PowerShell.EditorServices.Utility; @@ -462,17 +461,6 @@ private void RecursivelyFindReferences( } } - internal Uri ResolveFileUri(Uri fileUri) - { - if (fileUri.IsFile) - { - fileUri = WorkspaceService.UnescapeDriveColon(fileUri); - } - - this.logger.LogDebug("Resolved path: " + fileUri.OriginalString); - return fileUri; - } - internal static bool IsPathInMemory(string filePath) { bool isInMemory = false; @@ -562,141 +550,6 @@ internal string ResolveRelativeScriptPath(string baseFilePath, string relativePa return combinedPath; } - private static Uri UnescapeDriveColon(Uri fileUri) - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return fileUri; - } - - string driveSegment = fileUri.Segments[1]; - // Check here that we have something like "file:///C%3A/" as a prefix (caller must check the file:// part) - if (!(char.IsLetter(driveSegment[0]) && - driveSegment[1] == '%' && - driveSegment[2] == '3' && - driveSegment[3] == 'A' && - driveSegment[4] == '/')) - { - return fileUri; - } - - // We lost "%3A" and gained ":", so length - 2 - var sb = new StringBuilder(fileUri.OriginalString.Length - 2); - sb.Append("file:///"); - - // The drive letter. - sb.Append(driveSegment[0]); - sb.Append(":/"); - - // The rest of the URI after the colon. - // Skip the first two segments which are / and the drive. - for (int i = 2; i < fileUri.Segments.Length; i++) - { - sb.Append(fileUri.Segments[i]); - } - - return new Uri(sb.ToString()); - } - - /// - /// Converts a file system path into a DocumentUri required by Language Server Protocol. - /// - /// - /// When sending a document path to a LSP client, the path must be provided as a - /// DocumentUri in order to features like the Problems window or peek definition - /// to be able to open the specified file. - /// - /// - /// A file system path. Note: if the path is already a DocumentUri, it will be returned unmodified. - /// - /// The file system path encoded as a DocumentUri. - public static string ConvertPathToDocumentUri(string path) - { - const string fileUriPrefix = "file:"; - const string untitledUriPrefix = "untitled:"; - - // If path is already in document uri form, there is nothing to convert. - if (path.StartsWith(untitledUriPrefix, StringComparison.Ordinal) || - path.StartsWith(fileUriPrefix, StringComparison.Ordinal)) - { - return path; - } - - string escapedPath = Uri.EscapeDataString(path); - - // Max capacity of the StringBuilder will be the current escapedPath length - // plus extra chars for file:///. - var docUriStrBld = new StringBuilder(escapedPath.Length + fileUriPrefix.Length + 3); - docUriStrBld.Append(fileUriPrefix).Append("//"); - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // VSCode file URIs on Windows need the drive letter to be lowercase. Search the - // original path for colon since a char search (no string culture involved) is - // faster than a string search. If found, then lowercase the associated drive letter. - if (path.Contains(':')) - { - // A valid, drive-letter based path converted to URI form needs to be prefixed - // with a / to indicate the path is an absolute path. - docUriStrBld.Append("/"); - int prefixLen = docUriStrBld.Length; - - docUriStrBld.Append(escapedPath); - - // Uri.EscapeDataString goes a bit far, encoding \ chars. Also, VSCode wants / instead of \. - docUriStrBld.Replace("%5C", "/"); - - // Find the first colon after the "file:///" prefix, skipping the first char after - // the prefix since a Windows path cannot start with a colon. End the check at - // less than docUriStrBld.Length - 2 since we need to look-ahead two characters. - for (int i = prefixLen + 1; i < docUriStrBld.Length - 2; i++) - { - if ((docUriStrBld[i] == '%') && (docUriStrBld[i + 1] == '3') && (docUriStrBld[i + 2] == 'A')) - { - int driveLetterIndex = i - 1; - char driveLetter = char.ToLowerInvariant(docUriStrBld[driveLetterIndex]); - docUriStrBld.Replace(docUriStrBld[driveLetterIndex], driveLetter, driveLetterIndex, 1); - break; - } - } - } - else - { - // This is a Windows path without a drive specifier, must be either a relative or UNC path. - int prefixLen = docUriStrBld.Length; - - docUriStrBld.Append(escapedPath); - - // Uri.EscapeDataString goes a bit far, encoding \ chars. Also, VSCode wants / instead of \. - docUriStrBld.Replace("%5C", "/"); - - // The proper URI form for a UNC path is file://server/share. In the case of a UNC - // path, remove the path's leading // because the file:// prefix already provides it. - if ((docUriStrBld.Length > prefixLen + 1) && - (docUriStrBld[prefixLen] == '/') && - (docUriStrBld[prefixLen + 1] == '/')) - { - docUriStrBld.Remove(prefixLen, 2); - } - } - } - else - { - // On non-Windows systems, append the escapedPath and undo the over-aggressive - // escaping of / done by Uri.EscapeDataString. - docUriStrBld.Append(escapedPath).Replace("%2F", "/"); - } - - if (!VersionUtils.IsNetCore) - { - // ' is not encoded by Uri.EscapeDataString in Windows PowerShell 5.x. - // This is apparently a difference between .NET Framework and .NET Core. - docUriStrBld.Replace("'", "%27"); - } - - return docUriStrBld.ToString(); - } - #endregion } } diff --git a/src/PowerShellEditorServices/Utility/PathUtils.cs b/src/PowerShellEditorServices/Utility/PathUtils.cs index 26deebd72..b6ffe3762 100644 --- a/src/PowerShellEditorServices/Utility/PathUtils.cs +++ b/src/PowerShellEditorServices/Utility/PathUtils.cs @@ -3,7 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; using System.IO; using System.Runtime.InteropServices; @@ -18,7 +17,6 @@ internal class PathUtils /// it is '\', and on Linux, it is '/', as expected. /// internal static readonly char DefaultPathSeparator = Path.DirectorySeparatorChar; - internal static readonly string DefaultPathSeparatorString = DefaultPathSeparator.ToString(); /// /// The alternate path separator used by the base implementation of the providers. @@ -29,29 +27,6 @@ internal class PathUtils /// separator on Linux. /// internal static readonly char AlternatePathSeparator = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? '/' : '\\'; - internal static readonly string AlternatePathSeparatorString = AlternatePathSeparator.ToString(); - - public string WildcardUnescapePath(string path) - { - throw new NotImplementedException(); - } - - public static Uri ToUri(string filePath) - { - if (filePath.StartsWith("untitled", StringComparison.OrdinalIgnoreCase) || - filePath.StartsWith("inmemory", StringComparison.OrdinalIgnoreCase)) - { - return new Uri(filePath); - } - - filePath = filePath.Replace(":", "%3A").Replace("\\", "/"); - if (!filePath.StartsWith("/", StringComparison.OrdinalIgnoreCase)) - { - return new Uri($"file:///{filePath}"); - } - - return new Uri($"file://{filePath}"); - } /// /// Converts all alternate path separators to the current platform's main path separators. diff --git a/test/PowerShellEditorServices.Test/Session/WorkspaceTests.cs b/test/PowerShellEditorServices.Test/Session/WorkspaceTests.cs index 98f06a1aa..5b15539a8 100644 --- a/test/PowerShellEditorServices.Test/Session/WorkspaceTests.cs +++ b/test/PowerShellEditorServices.Test/Session/WorkspaceTests.cs @@ -191,53 +191,5 @@ public void CanDetermineIsPathInMemory() $"Testing path {testCase.Path}"); } } - - [Theory()] - [Trait("Category", "Workspace")] - [MemberData(nameof(PathsToResolve), parameters: 2)] - public void CorrectlyResolvesPaths(string givenPath, string expectedPath) - { - WorkspaceService workspace = new WorkspaceService(NullLoggerFactory.Instance); - - Uri resolvedPath = workspace.ResolveFileUri(new Uri(givenPath)); - - Assert.Equal(expectedPath, resolvedPath.LocalPath); - } - - public static IEnumerable PathsToResolve - { - get - { - return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) - ? s_winPathsToResolve - : s_unixPathsToResolve; - } - } - - private static object[][] s_winPathsToResolve = new object[][] - { - new object[] { "file:///C%3A/banana/", @"C:\banana\" }, - new object[] { "file:///C%3A/banana/ex.ps1", @"C:\banana\ex.ps1" }, - new object[] { "file:///E%3A/Path/to/awful%23path", @"E:\Path\to\awful#path" }, - new object[] { "file:///path/with/no/drive", "/path/with/no/drive" }, - new object[] { "file:///path/wi[th]/squ[are/brackets/", "/path/wi[th]/squ[are/brackets/" }, - new object[] { "file:///Carrots/A%5Ere/Good/", "/Carrots/A^re/Good/" }, - new object[] { "file:///Users/barnaby/%E8%84%9A%E6%9C%AC/Reduce-Directory", "/Users/barnaby/脚本/Reduce-Directory" }, - new object[] { "file:///C%3A/Program%20Files%20%28x86%29/PowerShell/6/pwsh.exe", @"C:\Program Files (x86)\PowerShell\6\pwsh.exe" }, - new object[] { "file:///home/maxim/test%20folder/%D0%9F%D0%B0%D0%BF%D0%BA%D0%B0/helloworld.ps1", "/home/maxim/test folder/Папка/helloworld.ps1" } - }; - - private static object[][] s_unixPathsToResolve = new object[][] - { - new object[] { "file:///banana/", @"/banana/" }, - new object[] { "file:///banana/ex.ps1", @"/banana/ex.ps1" }, - new object[] { "file:///Path/to/awful%23path", @"/Path/to/awful#path" }, - new object[] { "file:///path/with/no/drive", @"/path/with/no/drive" }, - new object[] { "file:///path/wi[th]/squ[are/brackets/", @"/path/wi[th]/squ[are/brackets/" }, - new object[] { "file:///Carrots/A%5Ere/Good/", @"/Carrots/A^re/Good/" }, - new object[] { "file:///Users/barnaby/%E8%84%9A%E6%9C%AC/Reduce-Directory", @"/Users/barnaby/脚本/Reduce-Directory" }, - new object[] { "file:///Program%20Files%20%28x86%29/PowerShell/6/pwsh.exe", @"/Program Files (x86)/PowerShell/6/pwsh.exe" }, - new object[] { "file:///home/maxim/test%20folder/%D0%9F%D0%B0%D0%BF%D0%BA%D0%B0/helloworld.ps1", @"/home/maxim/test folder/Папка/helloworld.ps1" } - }; } } From 9dd6e92e66875559b0d0262a7174d117827715e8 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Thu, 21 May 2020 16:11:03 -0700 Subject: [PATCH 2/3] unescape colon --- test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs b/test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs index dd6d35111..d0984dd9f 100644 --- a/test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs +++ b/test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs @@ -626,11 +626,11 @@ public void DocumentUriRetunsCorrectStringForAbsolutePath() { path = @"C:\Users\AmosBurton\projects\Rocinate\ProtoMolecule.ps1"; scriptFile = new ScriptFile(new Uri(path), emptyStringReader, PowerShellVersion); - Assert.Equal("file:///c%3A/Users/AmosBurton/projects/Rocinate/ProtoMolecule.ps1", scriptFile.DocumentUri); + Assert.Equal("file:///c:/Users/AmosBurton/projects/Rocinate/ProtoMolecule.ps1", scriptFile.DocumentUri); path = @"c:\Users\BobbieDraper\projects\Rocinate\foo's_~#-[@] +,;=%.ps1"; scriptFile = new ScriptFile(new Uri(path), emptyStringReader, PowerShellVersion); - Assert.Equal("file:///c%3A/Users/BobbieDraper/projects/Rocinate/foo%27s_~%23-%5B%40%5D%20%2B%2C%3B%3D%25.ps1", scriptFile.DocumentUri); + Assert.Equal("file:///c:/Users/BobbieDraper/projects/Rocinate/foo%27s_~%23-%5B%40%5D%20%2B%2C%3B%3D%25.ps1", scriptFile.DocumentUri); // Test UNC path path = @"\\ClarissaMao\projects\Rocinate\foo's_~#-[@] +,;=%.ps1"; From 1237baf269468aa73155cc71f8ab46db068201d2 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Thu, 21 May 2020 16:36:59 -0700 Subject: [PATCH 3/3] authorities are lowercase --- test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs b/test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs index d0984dd9f..6ab21d35f 100644 --- a/test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs +++ b/test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs @@ -635,7 +635,8 @@ public void DocumentUriRetunsCorrectStringForAbsolutePath() // Test UNC path path = @"\\ClarissaMao\projects\Rocinate\foo's_~#-[@] +,;=%.ps1"; scriptFile = new ScriptFile(new Uri(path), emptyStringReader, PowerShellVersion); - Assert.Equal("file://ClarissaMao/projects/Rocinate/foo%27s_~%23-%5B%40%5D%20%2B%2C%3B%3D%25.ps1", scriptFile.DocumentUri); + // UNC authorities are lowercased. This is what VS Code does as well. + Assert.Equal("file://clarissamao/projects/Rocinate/foo%27s_~%23-%5B%40%5D%20%2B%2C%3B%3D%25.ps1", scriptFile.DocumentUri); } else {