diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs index 43100069747706e99c167ba15dd3c7feeaa2adbf..2687b3b81cf07c2ad2abe1851b6cd0f6fae4e240 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs @@ -1661,6 +1661,12 @@ private bool CanConvertMetadataReferenceToProjectReference_NoLock(ProjectId proj } } + // If this is going to cause a circular reference, also disallow it + if (CurrentSolution.GetProjectDependencyGraph().GetProjectsThatThisProjectTransitivelyDependsOn(referencedProjectId).Contains(projectIdWithMetadataReference)) + { + return false; + } + return true; } diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/MetadataToProjectReferenceConversionTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/MetadataToProjectReferenceConversionTests.vb index 1be9c7d733cf595c9276364c871187d6c35e84c3..dd922ea8685269622fede18e424ee322aa066614 100644 --- a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/MetadataToProjectReferenceConversionTests.vb +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/MetadataToProjectReferenceConversionTests.vb @@ -262,5 +262,49 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Assert.Empty(getReferencingProject().MetadataReferences) End Using End Sub + + + + Public Sub MetadataReferenceCycleDoesNotCreateProjectReferenceCycleWhenAddingReferencesFirst() + Using environment = New TestEnvironment() + Dim project1 = environment.ProjectFactory.CreateAndAddToWorkspace("project1", LanguageNames.CSharp) + Dim project2 = environment.ProjectFactory.CreateAndAddToWorkspace("project2", LanguageNames.CSharp) + + Const ReferencePath1 = "C:\project1.dll" + Const ReferencePath2 = "C:\project2.dll" + + project1.AddMetadataReference(ReferencePath2, MetadataReferenceProperties.Assembly) + project2.AddMetadataReference(ReferencePath1, MetadataReferenceProperties.Assembly) + + project1.OutputFilePath = ReferencePath1 + project2.OutputFilePath = ReferencePath2 + + ' Remove both from the workspace to ensure we aren't in a corrupted state somehow where removal will break further + project1.RemoveFromWorkspace() + project2.RemoveFromWorkspace() + End Using + End Sub + + + + Public Sub MetadataReferenceCycleDoesNotCreateProjectReferenceCycleWhenSettingOutputPathsFirst() + Using environment = New TestEnvironment() + Dim project1 = environment.ProjectFactory.CreateAndAddToWorkspace("project1", LanguageNames.CSharp) + Dim project2 = environment.ProjectFactory.CreateAndAddToWorkspace("project2", LanguageNames.CSharp) + + Const ReferencePath1 = "C:\project1.dll" + Const ReferencePath2 = "C:\project2.dll" + + project1.OutputFilePath = ReferencePath1 + project2.OutputFilePath = ReferencePath2 + + project1.AddMetadataReference(ReferencePath2, MetadataReferenceProperties.Assembly) + project2.AddMetadataReference(ReferencePath1, MetadataReferenceProperties.Assembly) + + ' Remove both from the workspace to ensure we aren't in a corrupted state somehow where removal will break further + project1.RemoveFromWorkspace() + project2.RemoveFromWorkspace() + End Using + End Sub End Class End Namespace