diff --git a/src/PowerShellEditorServices/Services/TextDocument/ScriptFile.cs b/src/PowerShellEditorServices/Services/TextDocument/ScriptFile.cs
index 51ddd7f1a..edc0ac74b 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/ScriptFile.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/ScriptFile.cs
@@ -150,20 +150,24 @@ public string[] ReferencedFiles
/// Creates a new ScriptFile instance by reading file contents from
/// the given TextReader.
///
- /// The path at which the script file resides.
- /// The path which the client uses to identify the file.
+ /// The System.Uri of the file.
/// The TextReader to use for reading the file's contents.
/// The version of PowerShell for which the script is being parsed.
public ScriptFile(
- string filePath,
- string clientFilePath,
+ Uri fileUri,
TextReader textReader,
Version powerShellVersion)
{
- this.FilePath = filePath;
- this.ClientFilePath = clientFilePath;
+ // For non-files, use their URI representation instead
+ // so that other operations know it's untitled/in-memory
+ // and don't think that it's a relative path
+ // on the file system.
+ this.FilePath = fileUri.IsFile
+ ? fileUri.LocalPath
+ : fileUri.OriginalString;
+ this.ClientFilePath = fileUri.OriginalString;
this.IsAnalysisEnabled = true;
- this.IsInMemory = WorkspaceService.IsPathInMemory(filePath);
+ this.IsInMemory = !fileUri.IsFile;
this.powerShellVersion = powerShellVersion;
// SetFileContents() calls ParseFileContents() which initializes the rest of the properties.
@@ -173,41 +177,20 @@ public ScriptFile(
///
/// Creates a new ScriptFile instance with the specified file contents.
///
- /// The path at which the script file resides.
- /// The path which the client uses to identify the file.
+ /// The System.Uri of the file.
/// The initial contents of the script file.
/// The version of PowerShell for which the script is being parsed.
public ScriptFile(
- string filePath,
- string clientFilePath,
+ Uri fileUri,
string initialBuffer,
Version powerShellVersion)
: this(
- filePath,
- clientFilePath,
+ fileUri,
new StringReader(initialBuffer),
powerShellVersion)
{
}
- ///
- /// Creates a new ScriptFile instance with the specified filepath.
- ///
- /// 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(
- string filePath,
- string clientFilePath,
- Version powerShellVersion)
- : this(
- filePath,
- clientFilePath,
- File.ReadAllText(filePath),
- powerShellVersion)
- {
- }
-
#endregion
#region Public Methods
diff --git a/src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs b/src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs
index dba1362c3..5da819232 100644
--- a/src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs
+++ b/src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs
@@ -142,8 +142,7 @@ public ScriptFile GetFile(Uri fileUri)
{
scriptFile =
new ScriptFile(
- resolvedFileUri.LocalPath,
- resolvedFileUri.OriginalString,
+ resolvedFileUri,
streamReader,
this.powerShellVersion);
@@ -249,8 +248,7 @@ public ScriptFile GetFileBuffer(Uri fileUri, string initialBuffer)
{
scriptFile =
new ScriptFile(
- resolvedFileUri.LocalPath,
- resolvedFileUri.OriginalString,
+ resolvedFileUri,
initialBuffer,
this.powerShellVersion);
@@ -399,9 +397,9 @@ private void RecursivelyFindReferences(
Dictionary referencedScriptFiles)
{
// Get the base path of the current script for use in resolving relative paths
- string baseFilePath =
- GetBaseFilePath(
- scriptFile.FilePath);
+ string baseFilePath = scriptFile.IsInMemory
+ ? WorkspacePath
+ : Path.GetDirectoryName(scriptFile.FilePath);
foreach (string referencedFileName in scriptFile.ReferencedFiles)
{
@@ -437,31 +435,6 @@ private void RecursivelyFindReferences(
}
}
- internal string ResolveFilePath(string filePath)
- {
- if (!IsPathInMemory(filePath))
- {
- if (filePath.StartsWith(@"file://"))
- {
- filePath = WorkspaceService.UnescapeDriveColon(filePath);
- // Client sent the path in URI format, extract the local path
- filePath = new Uri(filePath).LocalPath;
- }
-
- // Clients could specify paths with escaped space, [ and ] characters which .NET APIs
- // will not handle. These paths will get appropriately escaped just before being passed
- // into the PowerShell engine.
- //filePath = PowerShellContext.UnescapeWildcardEscapedPath(filePath);
-
- // Get the absolute file path
- filePath = Path.GetFullPath(filePath);
- }
-
- this.logger.LogDebug("Resolved path: " + filePath);
-
- return filePath;
- }
-
internal Uri ResolveFileUri(Uri fileUri)
{
if (fileUri.IsFile)
@@ -509,27 +482,6 @@ internal static bool IsPathInMemory(string filePath)
return isInMemory;
}
- private string GetBaseFilePath(string filePath)
- {
- if (IsPathInMemory(filePath))
- {
- // If the file is in memory, use the workspace path
- return this.WorkspacePath;
- }
-
- if (!Path.IsPathRooted(filePath))
- {
- // TODO: Assert instead?
- throw new InvalidOperationException(
- string.Format(
- "Must provide a full path for originalScriptPath: {0}",
- filePath));
- }
-
- // Get the directory of the file path
- return Path.GetDirectoryName(filePath);
- }
-
internal string ResolveRelativeScriptPath(string baseFilePath, string relativePath)
{
string combinedPath = null;
@@ -578,39 +530,6 @@ internal string ResolveRelativeScriptPath(string baseFilePath, string relativePa
return combinedPath;
}
- ///
- /// Takes a file-scheme URI with an escaped colon after the drive letter and unescapes only the colon.
- /// VSCode sends escaped colons after drive letters, but System.Uri expects unescaped.
- ///
- /// The fully-escaped file-scheme URI string.
- /// A file-scheme URI string with the drive colon unescaped.
- private static string UnescapeDriveColon(string fileUri)
- {
- if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- return fileUri;
- }
-
- // Check here that we have something like "file:///C%3A/" as a prefix (caller must check the file:// part)
- if (!(fileUri[7] == '/' &&
- char.IsLetter(fileUri[8]) &&
- fileUri[9] == '%' &&
- fileUri[10] == '3' &&
- fileUri[11] == 'A' &&
- fileUri[12] == '/'))
- {
- return fileUri;
- }
-
- var sb = new StringBuilder(fileUri.Length - 2); // We lost "%3A" and gained ":", so length - 2
- sb.Append("file:///");
- sb.Append(fileUri[8]); // The drive letter
- sb.Append(':');
- sb.Append(fileUri.Substring(12)); // The rest of the URI after the colon
-
- return sb.ToString();
- }
-
private static Uri UnescapeDriveColon(Uri fileUri)
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))