From 9fc882c5b5fdd12fc4a241445e66f5f9f9848b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Thu, 11 Jan 2024 15:04:09 -0800 Subject: [PATCH] Correct change detection when projects not supporting EnC are added/removed (#71586) --- .../EditAndContinueWorkspaceServiceTests.cs | 17 ++++++++--- .../Portable/EditAndContinue/EditSession.cs | 28 ++++++++++++++----- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/EditorFeatures/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs b/src/EditorFeatures/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs index e8aa8bb0a2494..c056d717ea787 100644 --- a/src/EditorFeatures/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs +++ b/src/EditorFeatures/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs @@ -1852,7 +1852,7 @@ public async Task SemanticError() [Fact] public async Task HasChanges() { - using var _ = CreateWorkspace(out var solution, out var service); + using var _ = CreateWorkspace(out var solution, out var service, [typeof(NoCompilationLanguageService)]); var pathA = Path.Combine(TempRoot.Root, "A.cs"); var pathB = Path.Combine(TempRoot.Root, "B.cs"); @@ -1903,6 +1903,17 @@ public async Task HasChanges() // remove a project: Assert.True(await EditSession.HasChangesAsync(solution, solution.RemoveProject(projectD.Id), CancellationToken.None)); + // add a project that doesn't support EnC: + + oldSolution = solution; + var projectE = solution.AddProject("E", "E", NoCompilationConstants.LanguageName); + solution = projectE.Solution; + + Assert.False(await EditSession.HasChangesAsync(oldSolution, solution, CancellationToken.None)); + + // remove a project that doesn't support EnC: + Assert.False(await EditSession.HasChangesAsync(solution, oldSolution, CancellationToken.None)); + EndDebuggingSession(debuggingSession); } @@ -3677,9 +3688,7 @@ public async Task ActiveStatements_SyntaxErrorOrOutOfSyncDocument(bool isOutOfSy [CombinatorialData] public async Task ActiveStatements_ForeignDocument(bool withPath, bool designTimeOnly) { - var composition = FeaturesTestCompositions.Features.AddParts(typeof(NoCompilationLanguageService)); - - using var _ = CreateWorkspace(out var solution, out var service, new[] { typeof(NoCompilationLanguageService) }); + using var _ = CreateWorkspace(out var solution, out var service, [typeof(NoCompilationLanguageService)]); var project = solution.AddProject("dummy_proj", "dummy_proj", designTimeOnly ? LanguageNames.CSharp : NoCompilationConstants.LanguageName); var filePath = withPath ? Path.Combine(TempRoot.Root, "test.cs") : null; diff --git a/src/Features/Core/Portable/EditAndContinue/EditSession.cs b/src/Features/Core/Portable/EditAndContinue/EditSession.cs index 03083aa251704..5a268bc95d193 100644 --- a/src/Features/Core/Portable/EditAndContinue/EditSession.cs +++ b/src/Features/Core/Portable/EditAndContinue/EditSession.cs @@ -290,22 +290,36 @@ public static async ValueTask HasChangesAsync(Solution oldSolution, Soluti return false; } - if (oldSolution.ProjectIds.Count != newSolution.ProjectIds.Count) - { - return true; - } - foreach (var newProject in newSolution.Projects) { + if (!newProject.SupportsEditAndContinue()) + { + continue; + } + var oldProject = oldSolution.GetProject(newProject.Id); if (oldProject == null || await HasChangedOrAddedDocumentsAsync(oldProject, newProject, changedOrAddedDocuments: null, cancellationToken).ConfigureAwait(false)) { + // project added or has changes + return true; + } + } + + foreach (var oldProject in oldSolution.Projects) + { + if (!oldProject.SupportsEditAndContinue()) + { + continue; + } + + var newProject = newSolution.GetProject(oldProject.Id); + if (newProject == null) + { + // project removed return true; } } - // The number of projects in both solution is the same and there are no new projects and no changes in existing projects. - // Therefore there are no changes. return false; }