diff --git a/src/Workspaces/Core/Desktop/PublicAPI.Unshipped.txt b/src/Workspaces/Core/Desktop/PublicAPI.Unshipped.txt index 11bc18bbd12f85686d39b9dc98df4b5f4e398aa1..3a954cb25e9cc4293c17dc2357164370379ea288 100644 --- a/src/Workspaces/Core/Desktop/PublicAPI.Unshipped.txt +++ b/src/Workspaces/Core/Desktop/PublicAPI.Unshipped.txt @@ -8,3 +8,4 @@ Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.MSBuildProjectLoader(Microso Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Properties.get -> System.Collections.Immutable.ImmutableDictionary Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.SkipUnrecognizedProjects.get -> bool Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.SkipUnrecognizedProjects.set -> void +static Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create(Microsoft.CodeAnalysis.Host.HostServices hostServices) -> Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace \ No newline at end of file diff --git a/src/Workspaces/Core/Desktop/Workspace/MSBuild/MSBuildProjectLoader.cs b/src/Workspaces/Core/Desktop/Workspace/MSBuild/MSBuildProjectLoader.cs index 1b5bc32544ac74580768e335c9bc8056cc977f4b..4a58d203baa8bcac867ab3ccef73fe07ca9527a0 100644 --- a/src/Workspaces/Core/Desktop/Workspace/MSBuild/MSBuildProjectLoader.cs +++ b/src/Workspaces/Core/Desktop/Workspace/MSBuild/MSBuildProjectLoader.cs @@ -716,6 +716,21 @@ private bool TryGetLoaderFromProjectPath(string projectFilePath, ReportMode mode } } + // since we have both C# and VB loaders in this same library, it no longer indicates whether we have full language support available. + if (loader != null) + { + language = loader.Language; + + // check for command line parser existing... if not then error. + var commandLineParser = _workspace.Services.GetLanguageServices(language).GetService(); + if (commandLineParser == null) + { + loader = null; + this.ReportFailure(mode, string.Format(WorkspacesResources.CannotOpenProjectUnsupportedLanguage, projectFilePath, language)); + return false; + } + } + return loader != null; } } diff --git a/src/Workspaces/Core/Desktop/Workspace/MSBuild/MSBuildWorkspace.cs b/src/Workspaces/Core/Desktop/Workspace/MSBuild/MSBuildWorkspace.cs index f0000ccc0a80ba2228d6394722206b9cd7b7554f..6d864ce7379440ab3242ba26fbb964283e2bfec0 100644 --- a/src/Workspaces/Core/Desktop/Workspace/MSBuild/MSBuildWorkspace.cs +++ b/src/Workspaces/Core/Desktop/Workspace/MSBuild/MSBuildWorkspace.cs @@ -60,6 +60,15 @@ public static MSBuildWorkspace Create(IDictionary properties) return Create(properties, DesktopMefHostServices.DefaultServices); } + /// + /// Create a new instance of a workspace that can be populated by opening solution and project files. + /// + /// The used to configure this workspace. + public static MSBuildWorkspace Create(HostServices hostServices) + { + return Create(ImmutableDictionary.Empty, hostServices); + } + /// /// Create a new instance of a workspace that can be populated by opening solution and project files. /// diff --git a/src/Workspaces/CoreTest/WorkspaceTests/MSBuildWorkspaceTests.cs b/src/Workspaces/CoreTest/WorkspaceTests/MSBuildWorkspaceTests.cs index dc03fc7a1a8e686a85b411235fd7ec59105b8ba9..a86b4a4536d4f3b4ea08d04d715a0efd52ccec05 100644 --- a/src/Workspaces/CoreTest/WorkspaceTests/MSBuildWorkspaceTests.cs +++ b/src/Workspaces/CoreTest/WorkspaceTests/MSBuildWorkspaceTests.cs @@ -11,6 +11,8 @@ using System.Xml.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.MSBuild; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; @@ -1031,6 +1033,67 @@ public void TestOpenSolution_WithUnrecognizedProjectTypeGuidAndUnrecognizedExten }); } + private HostServices hostServicesWithoutCSharp = MefHostServices.Create(MefHostServices.DefaultAssemblies.Where(a => !a.FullName.Contains("CSharp"))); + + [Fact, Trait(Traits.Feature, Traits.Features.Workspace)] + [WorkItem(3931, "https://github.com/dotnet/roslyn/issues/3931")] + public void TestOpenSolution_WithMissingLanguageLibraries_WithSkipFalse_Throws() + { + // proves that if the language libaries are missing then the appropriate error occurs + CreateFiles(GetSimpleCSharpSolutionFiles()); + + AssertThrows(() => + { + var ws = MSBuildWorkspace.Create(hostServicesWithoutCSharp); + ws.SkipUnrecognizedProjects = false; + var solution = ws.OpenSolutionAsync(GetSolutionFileName(@"TestSolution.sln")).Result; + }, + e => + { + Assert.Equal(true, e.Message.Contains("extension")); + }); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Workspace)] + [WorkItem(3931, "https://github.com/dotnet/roslyn/issues/3931")] + public void TestOpenSolution_WithMissingLanguageLibraries_WithSkipTrue_SucceedsWithDiagnostic() + { + // proves that if the language libaries are missing then the appropriate error occurs + CreateFiles(GetSimpleCSharpSolutionFiles()); + + var ws = MSBuildWorkspace.Create(hostServicesWithoutCSharp); + ws.SkipUnrecognizedProjects = true; + + var dx = new List(); + ws.WorkspaceFailed += delegate (object sender, WorkspaceDiagnosticEventArgs e) + { + dx.Add(e.Diagnostic); + }; + + var solution = ws.OpenSolutionAsync(GetSolutionFileName(@"TestSolution.sln")).Result; + + Assert.Equal(1, dx.Count); + Assert.True(dx[0].Message.Contains("extension")); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Workspace)] + [WorkItem(3931, "https://github.com/dotnet/roslyn/issues/3931")] + public void TestOpenProject_WithMissingLanguageLibraries_Throws() + { + // proves that if the language libaries are missing then the appropriate error occurs + CreateFiles(GetSimpleCSharpSolutionFiles()); + + AssertThrows(() => + { + var ws = MSBuildWorkspace.Create(hostServicesWithoutCSharp); + var project = ws.OpenProjectAsync(GetSolutionFileName(@"CSharpProject\CSharpProject.csproj")).Result; + }, + e => + { + Assert.Equal(true, e.Message.Contains("extension")); + }); + } + [Fact, Trait(Traits.Feature, Traits.Features.Workspace)] public void TestOpenProject_WithInvalidFilePath_Fails() {