diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CSharpHelpers.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CSharpHelpers.cs index 0b964001315fb488a4118e61eadfdb022ca67628..2935f0f76e18d8988eadccc3b28359df79c1c8b1 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CSharpHelpers.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CSharpHelpers.cs @@ -7,6 +7,7 @@ using System.IO; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Host; using Microsoft.VisualStudio; using Microsoft.VisualStudio.LanguageServices.CSharp.ProjectSystemShim; @@ -76,6 +77,22 @@ public static CPSProject CreateCSharpCPSProject(TestEnvironment environment, str return cpsProject; } + public static CPSProject CreateNonCompilableProject(TestEnvironment environment, string projectName, string projectFilePath) + { + var hierarchy = environment.CreateHierarchy(projectName, projectFilePath, ""); + + return CPSProjectFactory.CreateCPSProject( + environment.ProjectTracker, + environment.ServiceProvider, + hierarchy, + projectName, + projectFilePath, + Guid.NewGuid(), + NoCompilationConstants.LanguageName, + commandLineParserService: null, + binOutputPath: null); + } + private static string GetOutputPathFromArguments(string[] commandLineArguments) { const string outPrefix = "/out:"; diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/CSharpReferencesTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/CSharpReferencesTests.cs index 6ffcf7b6352aae05923a7323f9429a4d330e81c0..cc43b8a469a5f26bd89618291ce16c92347471fd 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/CSharpReferencesTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/CSharpReferencesTests.cs @@ -135,5 +135,29 @@ public void AddingProjectReferenceAndUpdateReferenceBinPath() project1.Disconnect(); } } + + + [WorkItem(461967, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/461967")] + [WpfFact()] + [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] + public void AddingMetadataReferenceToProjectThatCannotCompileInTheIdeKeepsMetadataReference() + { + using (var environment = new TestEnvironment()) + { + var project1 = CreateCSharpProject(environment, "project1"); + environment.ProjectTracker.UpdateProjectBinPath(project1, null, @"c:\project1.dll"); + + var project2 = CreateNonCompilableProject(environment, "project2", @"C:\project2.fsproj"); + environment.ProjectTracker.UpdateProjectBinPath(project2, null, @"c:\project2.dll"); + + project1.OnImportAdded(@"c:\project2.dll", "project2"); + + // We shoudl not have converted that to a project reference, because we would have no way to produce the compilation + Assert.Empty(project1.GetCurrentProjectReferences()); + + project2.Disconnect(); + project1.Disconnect(); + } + } } } \ No newline at end of file diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/AbstractProject.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/AbstractProject.cs index f279a9a93bf3147e7e104753b2d57b3582dd80bf..9787f7c1f2b840315af8a0aea17d107bed319c48 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/AbstractProject.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/AbstractProject.cs @@ -794,6 +794,17 @@ protected bool CanAddProjectReference(ProjectReference projectReference) var project = this.ProjectTracker.GetProject(projectReference.ProjectId); if (project != null) { + // We won't allow project-to-project references if this one supports compilation and the other one doesn't. + // This causes problems because if we then try to create a compilation, we'll fail even though it would have worked with + // a metadata reference. If neither supports compilation, we'll let the reference go through on the assumption the + // language (TypeScript/F#, etc.) is doing that intentionally. + if (this.Language != project.Language && + this.ProjectTracker.WorkspaceServices.GetLanguageServices(this.Language).GetService() != null && + this.ProjectTracker.WorkspaceServices.GetLanguageServices(project.Language).GetService() == null) + { + return false; + } + // cannot add a reference to a project that references us (it would make a cycle) return !project.TransitivelyReferences(this.Id); }