Skip to content

Fix #99: 'using module' relative path resolution #183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
version: '$(core_version).{build}'
os: Unstable
os: WMF 5
configuration: Release
clone_depth: 10

Expand Down
13 changes: 10 additions & 3 deletions src/PowerShellEditorServices/PowerShellEditorServices.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,16 @@
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<RestorePackages>true</RestorePackages>
<DefineConstants Condition=" '$(PowerShellVersion)' == 'v3'">PowerShellv3</DefineConstants>
<DefineConstants Condition=" '$(PowerShellVersion)' == 'v4'">PowerShellv4</DefineConstants>
<DefineConstants Condition=" '$(PowerShellVersion)' == '' Or '$(PowerShellVersion)' == 'v5'">PowerShellv5</DefineConstants>
<DefineConstants Condition="'$(PowerShellVersion)' == 'v3'">$(DefineConstants);PowerShellv3</DefineConstants>
<DefineConstants Condition="'$(PowerShellVersion)' == 'v4'">$(DefineConstants);PowerShellv4</DefineConstants>
<!-- NOTE: -->
<!-- For PowerShell v5 there are some differences between the APIs released with -->
<!-- Windows 10 RTM and Windows 10 Update 1, thus we need to distinguish between -->
<!-- the two in our code. v5r1 indicates Win 10 RTM (10240) and v5r2 indicates -->
<!-- Win10 Update 1 (10586). The PowerShellv5 constant will be defined for both -->
<!-- of these versions for anything that should work against both APIs. -->
<DefineConstants Condition="'$(PowerShellVersion)' == 'v5r1'">$(DefineConstants);PowerShellv5r1;PowerShellv5</DefineConstants>
<DefineConstants Condition="'$(PowerShellVersion)' == 'v5r2' Or '$(PowerShellVersion)' == ''">$(DefineConstants);PowerShellv5r2;PowerShellv5</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand Down
6 changes: 3 additions & 3 deletions src/PowerShellEditorServices/Session/EditorSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ public class EditorSession
/// </summary>
public void StartSession()
{
// Create a workspace to contain open files
this.Workspace = new Workspace();

// Initialize all services
this.PowerShellContext = new PowerShellContext();
this.LanguageService = new LanguageService(this.PowerShellContext);
Expand All @@ -81,6 +78,9 @@ public void StartSession()
LogLevel.Warning,
"Script Analyzer binaries not found, AnalysisService will be disabled.");
}

// Create a workspace to contain open files
this.Workspace = new Workspace(this.PowerShellContext.PowerShellVersion);
}

#endregion
Expand Down
49 changes: 43 additions & 6 deletions src/PowerShellEditorServices/Workspace/ScriptFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class ScriptFile
#region Private Fields

private Token[] scriptTokens;
private Version powerShellVersion;

#endregion

Expand Down Expand Up @@ -126,12 +127,18 @@ public string[] ReferencedFiles
/// <param name="filePath">The path at which the script file resides.</param>
/// <param name="clientFilePath">The path which the client uses to identify the file.</param>
/// <param name="textReader">The TextReader to use for reading the file's contents.</param>
public ScriptFile(string filePath, string clientFilePath, TextReader textReader)
/// <param name="powerShellVersion">The version of PowerShell for which the script is being parsed.</param>
public ScriptFile(
string filePath,
string clientFilePath,
TextReader textReader,
Version powerShellVersion)
{
this.FilePath = filePath;
this.ClientFilePath = clientFilePath;
this.IsAnalysisEnabled = true;
this.IsInMemory = Workspace.IsPathInMemory(filePath);
this.powerShellVersion = powerShellVersion;

this.SetFileContents(textReader.ReadToEnd());
}
Expand All @@ -142,11 +149,17 @@ public ScriptFile(string filePath, string clientFilePath, TextReader textReader)
/// <param name="filePath">The path at which the script file resides.</param>
/// <param name="clientFilePath">The path which the client uses to identify the file.</param>
/// <param name="initialBuffer">The initial contents of the script file.</param>
public ScriptFile(string filePath, string clientFilePath, string initialBuffer)
/// <param name="powerShellVersion">The version of PowerShell for which the script is being parsed.</param>
public ScriptFile(
string filePath,
string clientFilePath,
string initialBuffer,
Version powerShellVersion)
{
this.FilePath = filePath;
this.ClientFilePath = clientFilePath;
this.IsAnalysisEnabled = true;
this.powerShellVersion = powerShellVersion;

this.SetFileContents(initialBuffer);
}
Expand Down Expand Up @@ -358,15 +371,39 @@ private void ParseFileContents()

try
{
#if PowerShellv5r2
// This overload appeared with Windows 10 Update 1
if (this.powerShellVersion.Major >= 5 &&
this.powerShellVersion.Build >= 10586)
{
// Include the file path so that module relative
// paths are evaluated correctly
this.ScriptAst =
Parser.ParseInput(
this.Contents,
this.FilePath,
out this.scriptTokens,
out parseErrors);
}
else
{
this.ScriptAst =
Parser.ParseInput(
this.Contents,
out this.scriptTokens,
out parseErrors);
}
#else
this.ScriptAst =
Parser.ParseInput(
this.Contents,
out this.scriptTokens,
this.Contents,
out this.scriptTokens,
out parseErrors);
#endif
}
catch (RuntimeException ex)
{
var parseError =
var parseError =
new ParseError(
null,
ex.ErrorRecord.FullyQualifiedErrorId,
Expand All @@ -388,6 +425,6 @@ private void ParseFileContents()
AstOperations.FindDotSourcedIncludes(this.ScriptAst);
}

#endregion
#endregion
}
}
30 changes: 28 additions & 2 deletions src/PowerShellEditorServices/Workspace/Workspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class Workspace
{
#region Private Fields

private Version powerShellVersion;
private Dictionary<string, ScriptFile> workspaceFiles = new Dictionary<string, ScriptFile>();

#endregion
Expand All @@ -33,6 +34,19 @@ public class Workspace

#endregion

#region Constructors

/// <summary>
/// Creates a new instance of the Workspace class.
/// </summary>
/// <param name="powerShellVersion">The version of PowerShell for which scripts will be parsed.</param>
public Workspace(Version powerShellVersion)
{
this.powerShellVersion = powerShellVersion;
}

#endregion

#region Public Methods

/// <summary>
Expand Down Expand Up @@ -63,7 +77,13 @@ public ScriptFile GetFile(string filePath)

using (StreamReader streamReader = new StreamReader(resolvedFilePath, Encoding.UTF8))
{
scriptFile = new ScriptFile(resolvedFilePath, filePath, streamReader);
scriptFile =
new ScriptFile(
resolvedFilePath,
filePath,
streamReader,
this.powerShellVersion);

this.workspaceFiles.Add(keyName, scriptFile);
}

Expand Down Expand Up @@ -92,7 +112,13 @@ public ScriptFile GetFileBuffer(string filePath, string initialBuffer)
ScriptFile scriptFile = null;
if (!this.workspaceFiles.TryGetValue(keyName, out scriptFile))
{
scriptFile = new ScriptFile(resolvedFilePath, filePath, initialBuffer);
scriptFile =
new ScriptFile(
resolvedFilePath,
filePath,
initialBuffer,
this.powerShellVersion);

this.workspaceFiles.Add(keyName, scriptFile);

Logger.Write(LogLevel.Verbose, "Opened file as in-memory buffer: " + resolvedFilePath);
Expand Down
15 changes: 15 additions & 0 deletions test/PowerShellEditorServices.Test.Host/LanguageServerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ await this.WaitForEvent(
Assert.Contains("unapproved", diagnostics.Diagnostics[0].Message);
}

[Fact]
public async Task ServiceReturnsNoErrorsForUsingRelativeModulePaths()
{
// Send the 'didOpen' event
await this.SendOpenFileEvent("TestFiles\\Module.psm1", false);

// Wait for the diagnostic event
PublishDiagnosticsNotification diagnostics =
await this.WaitForEvent(
PublishDiagnosticsNotification.Type);

// Was there a syntax error?
Assert.Equal(0, diagnostics.Diagnostics.Length);
}

[Fact]
public async Task ServiceCompletesFunctionName()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,18 @@
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
<None Include="TestFiles\ChildModule\ChildModule.psm1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="TestFiles\CompleteFunctionName.ps1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="TestFiles\FindReferences.ps1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="TestFiles\Module.psm1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="TestFiles\MultiLineReplace.ps1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
function Get-Stuff {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
using module ".\ChildModule"
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ public class DebugServiceTests : IDisposable

public DebugServiceTests()
{
this.workspace = new Workspace();
this.powerShellContext = new PowerShellContext();
this.powerShellContext.SessionStateChanged += powerShellContext_SessionStateChanged;

this.workspace = new Workspace(this.powerShellContext.PowerShellVersion);

// Load the test debug file
this.debugScriptFile =
Expand All @@ -41,13 +44,15 @@ public DebugServiceTests()
this.workspace.GetFile(
@"..\..\..\PowerShellEditorServices.Test.Shared\Debugging\VariableTest.ps1");

this.powerShellContext = new PowerShellContext();
this.powerShellContext.SessionStateChanged += powerShellContext_SessionStateChanged;

this.debugService = new DebugService(this.powerShellContext);
this.debugService.DebuggerStopped += debugService_DebuggerStopped;
this.debugService.BreakpointUpdated += debugService_BreakpointUpdated;
this.runnerContext = SynchronizationContext.Current;

// Load the test debug file
this.debugScriptFile =
this.workspace.GetFile(
@"..\..\..\PowerShellEditorServices.Test.Shared\Debugging\DebugTest.ps1");
}

async void powerShellContext_SessionStateChanged(object sender, SessionStateChangedEventArgs e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ public class LanguageServiceTests : IDisposable

public LanguageServiceTests()
{
this.workspace = new Workspace();

this.powerShellContext = new PowerShellContext();
this.workspace = new Workspace(this.powerShellContext.PowerShellVersion);
this.languageService = new LanguageService(this.powerShellContext);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ namespace Microsoft.PowerShell.EditorServices.Test.Language
public class PowerShellVersionTests
{
[Theory]
[InlineData("3")]
[InlineData("4")]
[InlineData("5")]
public void CompilesWithPowerShellVersion(string version)
[InlineData("3", "4")]
[InlineData("4", "4")]
[InlineData("5", "5r1")]
public void CompilesWithPowerShellVersion(string version, string versionSuffix)
{
var assemblyPath =
Path.GetFullPath(
Expand All @@ -40,15 +40,15 @@ public void CompilesWithPowerShellVersion(string version)

try
{
Compile(projectVersion, version);
Compile(projectVersion, version, versionSuffix);
}
finally
{
File.Delete(projectVersion);
}
}

private void Compile(string project, string version)
private void Compile(string project, string version, string versionSuffix)
{
string msbuild;
using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0"))
Expand Down
18 changes: 16 additions & 2 deletions test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
//

using Microsoft.PowerShell.EditorServices;
using System;
using System.IO;
using Xunit;

namespace PSLanguageService.Test
{
public class FileChangeTests
{
private static readonly Version PowerShellVersion = new Version("5.0");

[Fact]
public void CanApplySingleLineInsert()
{
Expand Down Expand Up @@ -135,7 +138,13 @@ public void FindsDotSourcedFiles()

using (StringReader stringReader = new StringReader(exampleScriptContents))
{
ScriptFile scriptFile = new ScriptFile("DotSourceTestFile.ps1", "DotSourceTestFile.ps1", stringReader);
ScriptFile scriptFile =
new ScriptFile(
"DotSourceTestFile.ps1",
"DotSourceTestFile.ps1",
stringReader,
PowerShellVersion);

Assert.Equal(3, scriptFile.ReferencedFiles.Length);
System.Console.Write("a" + scriptFile.ReferencedFiles[0]);
Assert.Equal(@".\athing.ps1", scriptFile.ReferencedFiles[0]);
Expand All @@ -150,7 +159,12 @@ private void AssertFileChange(
using (StringReader stringReader = new StringReader(initialString))
{
// Create an in-memory file from the StringReader
ScriptFile fileToChange = new ScriptFile("TestFile.ps1", "TestFile.ps1", stringReader);
ScriptFile fileToChange =
new ScriptFile(
"TestFile.ps1",
"TestFile.ps1",
stringReader,
PowerShellVersion);

// Apply the FileChange and assert the resulting contents
fileToChange.ApplyChange(fileChange);
Expand Down