diff --git a/CHANGELOG.md b/CHANGELOG.md index 437fb13f1a..83092a2bba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All changes to the project will be documented in this file. ## [1.33.0] - Not yet released * Added support for files without a project. (PR: [#1252](https://github.com/OmniSharp/omnisharp-roslyn/pull/1252)) +* Fixed a bug where `*.rsp`-based scripting references where not exposed in the Workspace information endpoint (PR: [#1272](https://github.com/OmniSharp/omnisharp-roslyn/pull/1272)) ## [1.32.2] - 2018-08-07 * OmniSharp now targets **net461**, instead of **net46** (PR: [#1237](https://github.com/OmniSharp/omnisharp-roslyn/pull/1237)) diff --git a/src/OmniSharp.Script/ScriptContext.cs b/src/OmniSharp.Script/ScriptContext.cs index 0a2f3e56e7..20515bd17a 100644 --- a/src/OmniSharp.Script/ScriptContext.cs +++ b/src/OmniSharp.Script/ScriptContext.cs @@ -7,11 +7,10 @@ namespace OmniSharp.Script { public class ScriptContext { - public ScriptContext(ScriptProjectProvider scriptProjectProvider, HashSet metadataReferences, HashSet assemblyReferences, CompilationDependency[] compilationDependencies, Type globalsType) + public ScriptContext(ScriptProjectProvider scriptProjectProvider, HashSet metadataReferences, CompilationDependency[] compilationDependencies, Type globalsType) { ScriptProjectProvider = scriptProjectProvider; MetadataReferences = metadataReferences; - AssemblyReferences = assemblyReferences; CompilationDependencies = compilationDependencies; GlobalsType = globalsType; } @@ -20,8 +19,6 @@ public ScriptContext(ScriptProjectProvider scriptProjectProvider, HashSet MetadataReferences { get; } - public HashSet AssemblyReferences { get; } - public CompilationDependency[] CompilationDependencies { get; } public Type GlobalsType { get; } diff --git a/src/OmniSharp.Script/ScriptContextModel.cs b/src/OmniSharp.Script/ScriptContextModel.cs index 0bd1a891da..3cdccb009c 100644 --- a/src/OmniSharp.Script/ScriptContextModel.cs +++ b/src/OmniSharp.Script/ScriptContextModel.cs @@ -1,22 +1,32 @@ using System; using System.Collections.Generic; +using System.Linq; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; namespace OmniSharp.Script { public class ScriptContextModel { - public ScriptContextModel(string csxPath, ProjectInfo project, HashSet implicitAssemblyReferences) + public ScriptContextModel(string csxPath, ProjectInfo project) { Path = csxPath; - ImplicitAssemblyReferences = implicitAssemblyReferences; - CommonUsings = ScriptProjectProvider.DefaultNamespaces; + AssemblyReferences = project.MetadataReferences.Select(a => + { + if (a is PortableExecutableReference portableExecutableReference) + { + return portableExecutableReference.FilePath ?? portableExecutableReference.Display; + } + + return a.Display; + }); + CommonUsings = ((CSharpCompilationOptions)(project.CompilationOptions)).Usings; GlobalsType = project.HostObjectType; } public string Path { get; } - public HashSet ImplicitAssemblyReferences { get; } + public IEnumerable AssemblyReferences { get; } public Type GlobalsType { get; } diff --git a/src/OmniSharp.Script/ScriptContextProvider.cs b/src/OmniSharp.Script/ScriptContextProvider.cs index 95b5967f9d..245a0ae3b1 100644 --- a/src/OmniSharp.Script/ScriptContextProvider.cs +++ b/src/OmniSharp.Script/ScriptContextProvider.cs @@ -76,7 +76,6 @@ public ScriptContext CreateScriptContext(ScriptOptions scriptOptions) } var metadataReferences = new HashSet(MetadataReferenceEqualityComparer.Instance); - var assemblyReferences = new HashSet(); var isDesktopClr = true; // if we have no compilation dependencies @@ -86,7 +85,7 @@ public ScriptContext CreateScriptContext(ScriptOptions scriptOptions) if (!compilationDependencies.Any()) { _logger.LogInformation("Unable to find dependency context for CSX files. Will default to non-context usage (Desktop CLR scripts)."); - AddDefaultClrMetadataReferences(metadataReferences, assemblyReferences); + AddDefaultClrMetadataReferences(metadataReferences); } else { @@ -98,7 +97,7 @@ public ScriptContext CreateScriptContext(ScriptOptions scriptOptions) if (loadedFiles.Add(Path.GetFileName(compilationAssembly))) { _logger.LogDebug("Discovered script compilation assembly reference: " + compilationAssembly); - AddMetadataReference(metadataReferences, assemblyReferences, compilationAssembly); + AddMetadataReference(metadataReferences, compilationAssembly); } } } @@ -107,22 +106,18 @@ public ScriptContext CreateScriptContext(ScriptOptions scriptOptions) foreach (var inheritedCompileLib in inheritedCompileLibraries) { _logger.LogDebug("Adding implicit reference: " + inheritedCompileLib); - AddMetadataReference(metadataReferences, assemblyReferences, inheritedCompileLib.Location); + AddMetadataReference(metadataReferences, inheritedCompileLib.Location); } var scriptProjectProvider = new ScriptProjectProvider(scriptOptions, _env, _loggerFactory, isDesktopClr); - return new ScriptContext(scriptProjectProvider, metadataReferences, assemblyReferences, compilationDependencies, _defaultGlobalsType); + return new ScriptContext(scriptProjectProvider, metadataReferences, compilationDependencies, _defaultGlobalsType); } - private void AddDefaultClrMetadataReferences(HashSet commonReferences, HashSet assemblyReferences) + private void AddDefaultClrMetadataReferences(HashSet commonReferences) { var references = DefaultMetadataReferenceHelper.GetDefaultMetadataReferenceLocations() - .Select(l => - { - assemblyReferences.Add(l); - return _metadataFileReferenceCache.GetMetadataReference(l); - }); + .Select(l => _metadataFileReferenceCache.GetMetadataReference(l)); foreach (var reference in references) { @@ -130,7 +125,7 @@ private void AddDefaultClrMetadataReferences(HashSet commonRe } } - private void AddMetadataReference(ISet referenceCollection, HashSet assemblyReferences, string fileReference) + private void AddMetadataReference(ISet referenceCollection, string fileReference) { if (!File.Exists(fileReference)) { @@ -146,7 +141,6 @@ private void AddMetadataReference(ISet referenceCollection, H } referenceCollection.Add(metadataReference); - assemblyReferences.Add(fileReference); _logger.LogDebug($"Added reference to '{fileReference}'"); } } diff --git a/src/OmniSharp.Script/ScriptProjectSystem.cs b/src/OmniSharp.Script/ScriptProjectSystem.cs index d4b7dd9633..3f9737985d 100644 --- a/src/OmniSharp.Script/ScriptProjectSystem.cs +++ b/src/OmniSharp.Script/ScriptProjectSystem.cs @@ -168,7 +168,7 @@ Task IProjectSystem.GetProjectModelAsync(string filePath) return Task.FromResult(null); } - return Task.FromResult(new ScriptContextModel(filePath, projectInfo, _scriptContext.Value.AssemblyReferences)); + return Task.FromResult(new ScriptContextModel(filePath, projectInfo)); } Task IProjectSystem.GetWorkspaceModelAsync(WorkspaceInformationRequest request) @@ -176,7 +176,7 @@ Task IProjectSystem.GetWorkspaceModelAsync(WorkspaceInformationRequest r var scriptContextModels = new List(); foreach (var project in _projects) { - scriptContextModels.Add(new ScriptContextModel(project.Key, project.Value, _scriptContext.Value.AssemblyReferences)); + scriptContextModels.Add(new ScriptContextModel(project.Key, project.Value)); } return Task.FromResult(new ScriptContextModelCollection(scriptContextModels)); } diff --git a/test-assets/test-scripts/EmptyScript/.gitignore b/test-assets/test-scripts/EmptyScript/.gitignore new file mode 100644 index 0000000000..ec08eea34d --- /dev/null +++ b/test-assets/test-scripts/EmptyScript/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything +* +# Except gitignore file +!.gitignore \ No newline at end of file diff --git a/test-assets/test-scripts/SingleCsiScriptWithCustomRsp/main.csx b/test-assets/test-scripts/SingleCsiScriptWithCustomRsp/main.csx new file mode 100644 index 0000000000..308e6ef040 --- /dev/null +++ b/test-assets/test-scripts/SingleCsiScriptWithCustomRsp/main.csx @@ -0,0 +1,5 @@ +#r "System.Net.Http" + +using System.Net.Http; +var client = new HttpClient(); +Console.WriteLine(client.GetAsync("https://google.com")); \ No newline at end of file diff --git a/test-assets/test-scripts/SingleCsiScriptWithCustomRsp/test.rsp b/test-assets/test-scripts/SingleCsiScriptWithCustomRsp/test.rsp new file mode 100644 index 0000000000..3ebca01b80 --- /dev/null +++ b/test-assets/test-scripts/SingleCsiScriptWithCustomRsp/test.rsp @@ -0,0 +1,2 @@ +/u:System.Web +/r:System.Web \ No newline at end of file diff --git a/tests/OmniSharp.Script.Tests/WorkspaceInformationTests.cs b/tests/OmniSharp.Script.Tests/WorkspaceInformationTests.cs index e6626f8561..208e282e9a 100644 --- a/tests/OmniSharp.Script.Tests/WorkspaceInformationTests.cs +++ b/tests/OmniSharp.Script.Tests/WorkspaceInformationTests.cs @@ -46,6 +46,33 @@ public async Task SingleCsiScript() } } + [Fact] + public async Task SingleCsiScriptWithCustomRspNamespacesAndReferences() + { + using (var testProject = TestAssets.Instance.GetTestScript("SingleCsiScriptWithCustomRsp")) + using (var host = CreateOmniSharpHost(testProject.Directory, new Dictionary + { + ["script:rspFilePath"] = Path.Combine(testProject.Directory, "test.rsp") + })) + { + var workspaceInfo = await GetWorkspaceInfoAsync(host); + var project = Assert.Single(workspaceInfo.Projects); + + Assert.Equal("main.csx", Path.GetFileName(project.Path)); + + // should have reference to mscorlib + VerifyCorLib(project); + + // default globals object + Assert.Equal(typeof(CommandLineScriptGlobals), project.GlobalsType); + + // should have RSP inherited settings + VerifyAssemblyReference(project, "system.web"); + var commonUsingStatement = Assert.Single(project.CommonUsings); + Assert.Equal("System.Web", commonUsingStatement); + } + } + [Fact] public async Task CsiScriptWithFileCreatedAfterStartingServer() { @@ -163,12 +190,12 @@ public async Task DotnetCoreScriptWithNuget() private void VerifyCorLib(ScriptContextModel project, bool expected = true) { - var corLibFound = project.ImplicitAssemblyReferences.Any(r => r == GetMsCorlibPath()); + var corLibFound = project.AssemblyReferences.Any(r => r == GetMsCorlibPath()); Assert.True(corLibFound == expected, $"{(expected ? "Missing" : "Unnecessary")} reference to mscorlib"); } private void VerifyAssemblyReference(ScriptContextModel project, string partialName) => - Assert.True(project.ImplicitAssemblyReferences.Any(r => r.IndexOf(partialName, StringComparison.OrdinalIgnoreCase) > 0), $"Missing reference to {partialName}"); + Assert.True(project.AssemblyReferences.Any(r => r.IndexOf(partialName, StringComparison.OrdinalIgnoreCase) > 0), $"Missing reference to {partialName}"); private static async Task GetWorkspaceInfoAsync(OmniSharpTestHost host) { diff --git a/tests/TestUtility/TestAssets.TestProject.cs b/tests/TestUtility/TestAssets.TestProject.cs index e5e3cf420b..46c45cbda3 100644 --- a/tests/TestUtility/TestAssets.TestProject.cs +++ b/tests/TestUtility/TestAssets.TestProject.cs @@ -32,7 +32,7 @@ public TestProject(string name, string baseDirectory, string directory, bool sha public string AddDisposableFile(string fileName, string contents = null) { - var filePath = Path.Combine(BaseDirectory, fileName); + var filePath = Path.Combine(Directory, fileName); File.WriteAllText(filePath, contents ?? string.Empty); _disposableFiles.Add(filePath); @@ -59,7 +59,7 @@ public virtual void Dispose() foreach (var filePath in _disposableFiles) { RunWithRetry(() => File.Delete(filePath)); - if (System.IO.Directory.Exists(this.BaseDirectory)) + if (System.IO.File.Exists(filePath)) { throw new InvalidOperationException($"{nameof(ITestProject)} file still exists: '{filePath}'"); }