Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "When we're removing the last project, fire SolutionRemoved" #63161

Merged
merged 1 commit into from
Aug 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 1 addition & 11 deletions src/VisualStudio/Core/Def/ProjectSystem/VisualStudioProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1231,17 +1231,7 @@ public void RemoveFromWorkspace()
// references being converted to metadata references (or vice versa) and we might either
// miss stopping a file watcher or might end up double-stopping a file watcher.
remainingMetadataReferences = w.CurrentSolution.GetRequiredProject(Id).MetadataReferences;
_workspace.RemoveProjectFromTrackingMaps_NoLock(Id);

// If this is our last project, clear the entire solution.
if (w.CurrentSolution.ProjectIds.Count == 1)
{
_workspace.RemoveSolution_NoLock();
}
else
{
_workspace.OnProjectRemoved(Id);
}
w.OnProjectRemoved(Id);
});

Contract.ThrowIfNull(remainingMetadataReferences);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.ExternalAccess.VSTypeScript.Api;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.VisualStudio.LanguageServices.ExternalAccess.VSTypeScript.Api;
Expand Down Expand Up @@ -116,7 +115,6 @@ await _visualStudioWorkspaceImpl.ApplyChangeToWorkspaceAsync(w =>
.WithTelemetryId(creationInfo.ProjectGuid);

// If we don't have any projects and this is our first project being added, then we'll create a new SolutionId
// and count this as the solution being added so that event is raised.
if (w.CurrentSolution.ProjectIds.Count == 0)
{
var solutionSessionId = GetSolutionSessionId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1660,11 +1660,7 @@ private ProjectReferenceInformation GetReferenceInfo_NoLock(ProjectId projectId)
return _projectReferenceInfoMap.GetOrAdd(projectId, _ => new ProjectReferenceInformation());
}

/// <summary>
/// Removes the project from the various maps this type maintains; it's still up to the caller to actually remove
/// the project in one way or another.
/// </summary>
internal void RemoveProjectFromTrackingMaps_NoLock(ProjectId projectId)
protected internal override void OnProjectRemoved(ProjectId projectId)
{
string? languageName;

Expand Down Expand Up @@ -1708,6 +1704,8 @@ internal void RemoveProjectFromTrackingMaps_NoLock(ProjectId projectId)
}
}

base.OnProjectRemoved(projectId);

// Try to update the UI context info. But cancel that work if we're shutting down.
_threadingContext.RunWithShutdownBlockAsync(async cancellationToken =>
{
Expand All @@ -1716,31 +1714,6 @@ internal void RemoveProjectFromTrackingMaps_NoLock(ProjectId projectId)
});
}

internal void RemoveSolution_NoLock()
{
Contract.ThrowIfFalse(_gate.CurrentCount == 0);

// At this point, we should have had RemoveProjectFromTrackingMaps_NoLock called for everything else, so it's just the solution itself
// to clean up
Contract.ThrowIfFalse(_projectReferenceInfoMap.Count == 0);
Contract.ThrowIfFalse(_projectToHierarchyMap.Count == 0);
Contract.ThrowIfFalse(_projectToGuidMap.Count == 0);
Contract.ThrowIfFalse(_projectToMaxSupportedLangVersionMap.Count == 0);
Contract.ThrowIfFalse(_projectToDependencyNodeTargetIdentifier.Count == 0);
Contract.ThrowIfFalse(_projectToRuleSetFilePath.Count == 0);
Contract.ThrowIfFalse(_projectSystemNameToProjectsMap.Count == 0);

// Create a new empty solution and set this; we will reuse the same SolutionId and path since components still may have persistence information they still need
// to look up by that location; we also keep the existing analyzer references around since those are host-level analyzers that were loaded asynchronously.
SetCurrentSolution(
solution => CreateSolution(
SolutionInfo.Create(
SolutionId.CreateNewId(),
VersionStamp.Create(),
analyzerReferences: solution.AnalyzerReferences)),
WorkspaceChangeKind.SolutionRemoved);
}

private sealed class ProjectReferenceInformation
{
public readonly List<string> OutputPaths = new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,21 +106,5 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim
Assert.Same(startingSolution, environment.Workspace.CurrentSolution)
End Using
End Function

<WpfFact>
<CombinatorialData>
Public Async Function AddingAndRemovingOnlyProjectTriggersSolutionAddedAndSolutionRemoved() As Task
Using environment = New TestEnvironment()
Dim workspaceChangeEvents = New WorkspaceChangeWatcher(environment)
Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync(
"Project", LanguageNames.CSharp, CancellationToken.None)

Assert.Equal(WorkspaceChangeKind.SolutionAdded, Assert.Single(Await workspaceChangeEvents.GetNewChangeEventsAsync()).Kind)

project.RemoveFromWorkspace()

Assert.Equal(WorkspaceChangeKind.SolutionRemoved, Assert.Single(Await workspaceChangeEvents.GetNewChangeEventsAsync()).Kind)
End Using
End Function
End Class
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@ public async Task VerifyWorkingFolder()

await TestServices.SolutionExplorer.CloseSolutionAsync(HangMitigatingCancellationToken);

// Since we no longer have an open solution, we don't have a storage location for it, since that
// depends on the open solution.
Assert.Null(persistentStorageConfiguration.TryGetStorageLocation(SolutionKey.ToSolutionKey(visualStudioWorkspace.CurrentSolution)));
// because the solution cache directory is stored in the user temp folder,
// closing the solution has no effect on what is returned.
Assert.NotNull(persistentStorageConfiguration.TryGetStorageLocation(SolutionKey.ToSolutionKey(visualStudioWorkspace.CurrentSolution)));
}

private async Task WaitForNavigateAsync(CancellationToken cancellationToken)
Expand Down