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

[cherry-pick] Use separate async tracker for SG work instad of reusing workspace async tracker #73895

Merged
merged 1 commit into from
Jun 8, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace Roslyn.VisualStudio.Next.UnitTests.Remote
{
[UseExportProvider]
[Trait(Traits.Feature, Traits.Features.RemoteHost)]
public class ServiceHubServicesTests
public sealed class ServiceHubServicesTests
{
private static TestWorkspace CreateWorkspace(Type[] additionalParts = null)
=> new(composition: FeaturesTestCompositions.Features.WithTestHostParts(TestHost.OutOfProcess).AddParts(additionalParts));
Expand Down Expand Up @@ -765,10 +765,10 @@ private static DocumentId AddSimpleDocument(TestWorkspace workspace, CallbackGen
return tempDoc.Id;
}

private static IAsynchronousOperationWaiter GetWorkspaceWaiter(TestWorkspace workspace)
private static async Task WaitForSourceGeneratorsAsync(TestWorkspace workspace)
{
var operations = workspace.ExportProvider.GetExportedValue<AsynchronousOperationListenerProvider>();
return operations.GetWaiter(FeatureAttribute.Workspace);
await operations.WaitAllAsync(workspace, [FeatureAttribute.Workspace, FeatureAttribute.SourceGenerators]);
}

[Theory, CombinatorialData]
Expand Down Expand Up @@ -810,7 +810,7 @@ internal async Task TestSourceGenerationExecution_MinorVersionChange_NoActualCha
Assert.Equal(1, callCount);

workspace.EnqueueUpdateSourceGeneratorVersion(projectId: null, forceRegeneration: false);
await GetWorkspaceWaiter(workspace).ExpeditedWaitAsync();
await WaitForSourceGeneratorsAsync(workspace);

solution = workspace.CurrentSolution;
project = solution.Projects.Single();
Expand Down Expand Up @@ -866,7 +866,7 @@ internal async Task TestSourceGenerationExecution_MajorVersionChange_NoActualCha

// Because we're forcing regeneration, in both mode we should now see two calls to the generator.
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: null, forceRegeneration: true);
await GetWorkspaceWaiter(workspace).ExpeditedWaitAsync();
await WaitForSourceGeneratorsAsync(workspace);

solution = workspace.CurrentSolution;
project = solution.Projects.Single();
Expand Down Expand Up @@ -913,7 +913,7 @@ internal async Task TestSourceGenerationExecution_FullSolutionChange_Minor(Sourc
var initialSolution = workspace.CurrentSolution;

workspace.EnqueueUpdateSourceGeneratorVersion(projectId: null, forceRegeneration: false);
await GetWorkspaceWaiter(workspace).ExpeditedWaitAsync();
await WaitForSourceGeneratorsAsync(workspace);

var currentSolution = workspace.CurrentSolution;

Expand Down Expand Up @@ -964,7 +964,7 @@ internal async Task TestSourceGenerationExecution_FullSolutionChange_Major(Sourc
var initialSolution = workspace.CurrentSolution;

workspace.EnqueueUpdateSourceGeneratorVersion(projectId: null, forceRegeneration: true);
await GetWorkspaceWaiter(workspace).ExpeditedWaitAsync();
await WaitForSourceGeneratorsAsync(workspace);

var currentSolution = workspace.CurrentSolution;

Expand Down Expand Up @@ -1007,7 +1007,7 @@ internal async Task TestSourceGenerationExecution_FullSolutionChange_MajorAndMin
// forceRegeneration=true should take precedence.
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: null, forceRegeneration: false);
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: null, forceRegeneration: true);
await GetWorkspaceWaiter(workspace).ExpeditedWaitAsync();
await WaitForSourceGeneratorsAsync(workspace);

var currentSolution = workspace.CurrentSolution;

Expand Down Expand Up @@ -1049,7 +1049,7 @@ internal async Task TestSourceGenerationExecution_ProjectChange_Minor_1(SourceGe

// Updating project1 should only impact it.
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: projectId1, forceRegeneration: false);
await GetWorkspaceWaiter(workspace).ExpeditedWaitAsync();
await WaitForSourceGeneratorsAsync(workspace);

var currentSolution = workspace.CurrentSolution;

Expand Down Expand Up @@ -1102,7 +1102,7 @@ internal async Task TestSourceGenerationExecution_ProjectChange_Minor_2(SourceGe

// Updating project1 should regen both projects due to p2p reference.
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: projectId1, forceRegeneration: false);
await GetWorkspaceWaiter(workspace).ExpeditedWaitAsync();
await WaitForSourceGeneratorsAsync(workspace);

var currentSolution = workspace.CurrentSolution;

Expand Down Expand Up @@ -1155,7 +1155,7 @@ internal async Task TestSourceGenerationExecution_ProjectChange_Minor_3(SourceGe

// Updating project2 should regen only it due to project1 having no reference to it.
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: projectId2, forceRegeneration: false);
await GetWorkspaceWaiter(workspace).ExpeditedWaitAsync();
await WaitForSourceGeneratorsAsync(workspace);

var currentSolution = workspace.CurrentSolution;

Expand Down Expand Up @@ -1210,7 +1210,7 @@ internal async Task TestSourceGenerationExecution_ProjectChange_MinorAndMajor1(S
// for both as project2 has a ref on project1.
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: projectId1, forceRegeneration: true);
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: projectId2, forceRegeneration: false);
await GetWorkspaceWaiter(workspace).ExpeditedWaitAsync();
await WaitForSourceGeneratorsAsync(workspace);

var currentSolution = workspace.CurrentSolution;

Expand Down Expand Up @@ -1255,7 +1255,7 @@ internal async Task TestSourceGenerationExecution_ProjectChange_MinorAndMajor2(S
// only for project2 as project1 doesn't have a ref on it.
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: projectId1, forceRegeneration: false);
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: projectId2, forceRegeneration: true);
await GetWorkspaceWaiter(workspace).ExpeditedWaitAsync();
await WaitForSourceGeneratorsAsync(workspace);

var currentSolution = workspace.CurrentSolution;

Expand Down Expand Up @@ -1298,7 +1298,7 @@ internal async Task TestSourceGenerationExecution_SolutionAndProjectChange_1(Sou
// Project2 should have a minor update since we only have a solution-minor change.
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: null, forceRegeneration: false);
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: projectId1, forceRegeneration: true);
await GetWorkspaceWaiter(workspace).ExpeditedWaitAsync();
await WaitForSourceGeneratorsAsync(workspace);

var currentSolution = workspace.CurrentSolution;

Expand Down Expand Up @@ -1341,7 +1341,7 @@ internal async Task TestSourceGenerationExecution_SolutionAndProjectChange_2(Sou
// Project1 and 2 should have a major update since we have a solution-majorchange.
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: null, forceRegeneration: true);
workspace.EnqueueUpdateSourceGeneratorVersion(projectId: projectId1, forceRegeneration: false);
await GetWorkspaceWaiter(workspace).ExpeditedWaitAsync();
await WaitForSourceGeneratorsAsync(workspace);

var currentSolution = workspace.CurrentSolution;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
Expand Down Expand Up @@ -117,8 +118,8 @@ public async Task WaitForAsyncOperationsAsync(string featuresToWaitFor, bool wai

if (waitForWorkspaceFirst)
{
var workspaceWaiter = listenerProvider.GetWaiter(FeatureAttribute.Workspace);
await workspaceWaiter.ExpeditedWaitAsync().WithCancellation(cancellationToken);
await listenerProvider.WaitAllAsync(
workspace: null, [FeatureAttribute.Workspace, FeatureAttribute.SourceGenerators]).WithCancellation(cancellationToken);
}

var featureWaiter = listenerProvider.GetWaiter(featuresToWaitFor);
Expand All @@ -129,6 +130,9 @@ public async Task WaitForAllAsyncOperationsAsync(string[] featureNames, Cancella
{
if (featureNames.Contains(FeatureAttribute.Workspace))
{
if (!featureNames.Contains(FeatureAttribute.SourceGenerators))
featureNames = [.. featureNames, FeatureAttribute.SourceGenerators];

await WaitForProjectSystemAsync(cancellationToken);
await TestServices.Shell.WaitForFileChangeNotificationsAsync(cancellationToken);
await TestServices.Editor.WaitForEditorOperationsAsync(cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ namespace Microsoft.CodeAnalysis.Host;
internal interface IWorkspaceAsynchronousOperationListenerProvider : IWorkspaceService
{
IAsynchronousOperationListener GetListener();
IAsynchronousOperationListener GetListener(string featureName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ internal sealed class WorkspaceAsynchronousOperationListenerProvider(IAsynchrono

public IAsynchronousOperationListener GetListener()
=> _listener;

public IAsynchronousOperationListener GetListener(string featureName)
=> listenerProvider.GetListener(featureName);
}
3 changes: 2 additions & 1 deletion src/Workspaces/Core/Portable/Workspace/Workspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Remote;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;

Expand Down Expand Up @@ -92,7 +93,7 @@ protected Workspace(HostServices host, string? workspaceKind)
TimeSpan.FromMilliseconds(1500),
ProcessUpdateSourceGeneratorRequestAsync,
EqualityComparer<(ProjectId? projectId, bool forceRegeneration)>.Default,
listenerProvider.GetListener(),
listenerProvider.GetListener(FeatureAttribute.SourceGenerators),
_updateSourceGeneratorsQueueTokenSource.Token);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ private async ValueTask ProcessUpdateSourceGeneratorRequestAsync(
return;
}

// Ensure we're fully loaded before rerunning generators.
var workspaceStatusService = this.Services.GetRequiredService<IWorkspaceStatusService>();
await workspaceStatusService.WaitUntilFullyLoadedAsync(cancellationToken).ConfigureAwait(false);

await this.SetCurrentSolutionAsync(
useAsync: true,
oldSolution =>
Expand Down
Loading