Skip to content

Commit a1576d6

Browse files
Merge pull request #73618 from CyrusNajmabadi/sourceGenBalanced
Switch SG mode to 'balanced' by default
2 parents 45cb0c8 + 8f01700 commit a1576d6

File tree

10 files changed

+109
-55
lines changed

10 files changed

+109
-55
lines changed

src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using Microsoft.CodeAnalysis.Editor.UnitTests;
1818
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
1919
using Microsoft.CodeAnalysis.Formatting;
20+
using Microsoft.CodeAnalysis.Host;
2021
using Microsoft.CodeAnalysis.Indentation;
2122
using Microsoft.CodeAnalysis.Options;
2223
using Microsoft.CodeAnalysis.Shared.Extensions;
@@ -468,10 +469,15 @@ End Class
468469
var classC = classD.BaseType;
469470
}
470471

471-
[Fact]
472-
public async Task TestGetCompilationOnCrossLanguageDependentProjectChanged()
472+
[Theory, CombinatorialData]
473+
internal async Task TestGetCompilationOnCrossLanguageDependentProjectChanged(
474+
SourceGeneratorExecutionPreference preference)
473475
{
474-
using var workspace = CreateWorkspace();
476+
using var workspace = CreateWorkspace(composition: EditorTestCompositions.EditorFeatures.AddParts(typeof(TestWorkspaceConfigurationService)));
477+
478+
var configService = workspace.ExportProvider.GetExportedValue<TestWorkspaceConfigurationService>();
479+
configService.Options = new WorkspaceConfigurationOptions(SourceGeneratorExecution: preference);
480+
475481
var solutionX = workspace.CurrentSolution;
476482

477483
var document1 = new EditorTestHostDocument(@"public class C { }");
@@ -514,7 +520,12 @@ End Class
514520
var classDz = compilation2Z.SourceModule.GlobalNamespace.GetTypeMembers("D").Single();
515521
var classCz = classDz.BaseType;
516522

517-
Assert.Equal(TypeKind.Error, classCz.TypeKind);
523+
// In balanced mode the skeleton won't be regenerated. So the downstream project won't see the change to
524+
// remove the class.
525+
if (preference is SourceGeneratorExecutionPreference.Automatic)
526+
Assert.Equal(TypeKind.Error, classCz.TypeKind);
527+
else
528+
Assert.Equal(TypeKind.Class, classCz.TypeKind);
518529
}
519530

520531
[WpfFact]
@@ -575,12 +586,19 @@ End Class
575586
}
576587
}
577588

578-
[WpfFact]
579-
public async Task TestGetCompilationOnCrossLanguageDependentProjectChangedInProgress()
589+
[WpfTheory, CombinatorialData]
590+
internal async Task TestGetCompilationOnCrossLanguageDependentProjectChangedInProgress(
591+
SourceGeneratorExecutionPreference preference)
580592
{
581-
var composition = EditorTestCompositions.EditorFeatures.AddParts(typeof(TestDocumentTrackingService));
593+
var composition = EditorTestCompositions.EditorFeatures.AddParts(
594+
typeof(TestDocumentTrackingService),
595+
typeof(TestWorkspaceConfigurationService));
582596

583597
using var workspace = CreateWorkspace(disablePartialSolutions: false, composition: composition);
598+
599+
var configService = workspace.ExportProvider.GetExportedValue<TestWorkspaceConfigurationService>();
600+
configService.Options = new WorkspaceConfigurationOptions(SourceGeneratorExecution: preference);
601+
584602
var trackingService = (TestDocumentTrackingService)workspace.Services.GetRequiredService<IDocumentTrackingService>();
585603
var solutionX = workspace.CurrentSolution;
586604

@@ -662,8 +680,12 @@ End Class
662680
}
663681
}
664682

665-
// Should find now that we're going a normal compilation.
666-
Assert.True(foundTheError, "Did not find error");
683+
// In balanced mode the skeleton won't be regenerated. So the downstream project won't see the change to
684+
// remove the class. So it will not find the error symbol.
685+
if (preference is SourceGeneratorExecutionPreference.Automatic)
686+
Assert.True(foundTheError);
687+
else
688+
Assert.False(foundTheError);
667689
}
668690

669691
[Fact]

src/EditorFeatures/Test2/Rename/CSharp/SourceGeneratorTests.vb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ public partial class GeneratedClass : IInterface { }
7272
</Document>
7373
</Project>
7474
</Workspace>, host:=host, renameTo:="A", sourceGenerator:=New GeneratorThatImplementsInterfaceMethod())
75-
7675
End Using
7776
End Sub
7877

src/EditorFeatures/Test2/Rename/RenameEngineResult.vb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@ Imports System.Collections.Immutable
66
Imports System.Threading
77
Imports Microsoft.CodeAnalysis
88
Imports Microsoft.CodeAnalysis.CodeActions
9-
Imports Microsoft.CodeAnalysis.CodeCleanup
109
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
1110
Imports Microsoft.CodeAnalysis.Host
12-
Imports Microsoft.CodeAnalysis.Options
1311
Imports Microsoft.CodeAnalysis.Remote.Testing
1412
Imports Microsoft.CodeAnalysis.Rename
1513
Imports Microsoft.CodeAnalysis.Rename.ConflictEngine
@@ -57,18 +55,24 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename
5755
host As RenameTestHost,
5856
Optional renameOptions As SymbolRenameOptions = Nothing,
5957
Optional expectFailure As Boolean = False,
60-
Optional sourceGenerator As ISourceGenerator = Nothing) As RenameEngineResult
58+
Optional sourceGenerator As ISourceGenerator = Nothing,
59+
Optional executionPreference As SourceGeneratorExecutionPreference = SourceGeneratorExecutionPreference.Automatic) As RenameEngineResult
6160

6261
Dim composition = EditorTestCompositions.EditorFeatures.AddParts(
6362
GetType(NoCompilationContentTypeLanguageService),
6463
GetType(NoCompilationContentTypeDefinitions),
65-
GetType(WorkspaceTestLogger))
64+
GetType(WorkspaceTestLogger),
65+
GetType(TestWorkspaceConfigurationService))
6666

6767
If host = RenameTestHost.OutOfProcess_SingleCall OrElse host = RenameTestHost.OutOfProcess_SplitCall Then
6868
composition = composition.WithTestHostParts(TestHost.OutOfProcess)
6969
End If
7070

7171
Dim workspace = TestWorkspace.CreateWorkspace(workspaceXml, composition:=composition)
72+
73+
Dim configService = workspace.ExportProvider.GetExportedValue(Of TestWorkspaceConfigurationService)
74+
configService.Options = New WorkspaceConfigurationOptions(SourceGeneratorExecution:=executionPreference)
75+
7276
workspace.Services.SolutionServices.SetWorkspaceTestOutput(helper)
7377

7478
If sourceGenerator IsNot Nothing Then

src/EditorFeatures/Test2/Rename/RenameTestHelpers.vb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ Imports Microsoft.CodeAnalysis.Editor.Implementation.RenameTracking
1010
Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities
1111
Imports Microsoft.CodeAnalysis.Editor.UnitTests.RenameTracking
1212
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Utilities.GoToHelpers
13-
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
1413
Imports Microsoft.CodeAnalysis.Options
1514
Imports Microsoft.CodeAnalysis.Shared.TestHooks
16-
Imports Microsoft.CodeAnalysis.Rename
1715
Imports Microsoft.CodeAnalysis.Text
1816
Imports Microsoft.CodeAnalysis.Text.Shared.Extensions
1917
Imports Microsoft.VisualStudio.Text
@@ -22,10 +20,10 @@ Imports Microsoft.VisualStudio.Text.Tagging
2220

2321
Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename
2422
Friend Module RenameTestHelpers
25-
2623
Private ReadOnly s_composition As TestComposition = EditorTestCompositions.EditorFeaturesWpf.AddParts(
2724
GetType(MockDocumentNavigationServiceFactory),
28-
GetType(MockPreviewDialogService))
25+
GetType(MockPreviewDialogService),
26+
GetType(TestWorkspaceConfigurationService))
2927

3028
Private Function GetSessionInfo(workspace As EditorTestWorkspace) As (document As Document, textSpan As TextSpan)
3129
Dim hostdoc = workspace.DocumentWithCursor

src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Imports System.Threading
66
Imports Microsoft.CodeAnalysis.Editor.Implementation.InlineRename
77
Imports Microsoft.CodeAnalysis.Editor.InlineRename
88
Imports Microsoft.CodeAnalysis.Editor.[Shared].Utilities
9+
Imports Microsoft.CodeAnalysis.Host
910
Imports Microsoft.CodeAnalysis.InlineRename
1011
Imports Microsoft.CodeAnalysis.Options
1112
Imports Microsoft.CodeAnalysis.[Shared].TestHooks
@@ -547,8 +548,8 @@ class D : B
547548
Optional renameFile As Boolean = False,
548549
Optional resolvableConflictText As String = Nothing,
549550
Optional unresolvableConflictText As String = Nothing,
550-
Optional severity As RenameDashboardSeverity = RenameDashboardSeverity.None
551-
) As Tasks.Task
551+
Optional severity As RenameDashboardSeverity = RenameDashboardSeverity.None,
552+
Optional executionPreference As SourceGeneratorExecutionPreference = SourceGeneratorExecutionPreference.Automatic) As Task
552553

553554
Using workspace = CreateWorkspaceWithWaiter(test, host)
554555
Dim globalOptions = workspace.GetService(Of IGlobalOptionService)()
@@ -557,6 +558,9 @@ class D : B
557558
globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameInComments, renameInComments)
558559
globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameFile, renameFile)
559560

561+
Dim configService = workspace.ExportProvider.GetExportedValue(Of TestWorkspaceConfigurationService)
562+
configService.Options = New WorkspaceConfigurationOptions(SourceGeneratorExecution:=executionPreference)
563+
560564
Dim cursorDocument = workspace.Documents.Single(Function(d) d.CursorPosition.HasValue)
561565
Dim cursorPosition = cursorDocument.CursorPosition.Value
562566

src/Features/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/Program.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
using System.Runtime.Loader;
1111
using System.Text.Json;
1212
using Microsoft.CodeAnalysis.Contracts.Telemetry;
13+
using Microsoft.CodeAnalysis.Host;
1314
using Microsoft.CodeAnalysis.LanguageServer;
1415
using Microsoft.CodeAnalysis.LanguageServer.BrokeredServices;
1516
using Microsoft.CodeAnalysis.LanguageServer.HostWorkspace;
1617
using Microsoft.CodeAnalysis.LanguageServer.LanguageServer;
1718
using Microsoft.CodeAnalysis.LanguageServer.Logging;
1819
using Microsoft.CodeAnalysis.LanguageServer.Services;
1920
using Microsoft.CodeAnalysis.LanguageServer.StarredSuggestions;
21+
using Microsoft.CodeAnalysis.Options;
2022
using Microsoft.Extensions.Logging;
2123
using Microsoft.Extensions.Logging.Console;
2224
using Roslyn.Utilities;
@@ -82,6 +84,11 @@ static async Task RunAsync(ServerConfiguration serverConfiguration, Cancellation
8284

8385
using var exportProvider = await ExportProviderBuilder.CreateExportProviderAsync(extensionManager, serverConfiguration.DevKitDependencyPath, loggerFactory);
8486

87+
// LSP server doesn't have the pieces yet to support 'balanced' mode for source-generators. Hardcode us to
88+
// 'automatic' for now.
89+
var globalOptionService = exportProvider.GetExportedValue<IGlobalOptionService>();
90+
globalOptionService.SetGlobalOption(WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic);
91+
8592
// The log file directory passed to us by VSCode might not exist yet, though its parent directory is guaranteed to exist.
8693
Directory.CreateDirectory(serverConfiguration.ExtensionLogDirectory);
8794

src/Features/LanguageServer/Protocol/Features/Options/WorkspaceConfigurationOptionsStorage.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,5 @@ public static WorkspaceConfigurationOptions GetWorkspaceConfigurationOptions(thi
5050
SourceGeneratorExecutionPreferenceUtilities.GetEditorConfigString));
5151

5252
public static readonly Option2<bool> SourceGeneratorExecutionBalancedFeatureFlag = new(
53-
"dotnet_source_generator_execution_balanced_feature_flag", false);
53+
"dotnet_source_generator_execution_balanced_feature_flag", true);
5454
}

src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
Imports Microsoft.CodeAnalysis
66
Imports Microsoft.CodeAnalysis.Diagnostics
77
Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities
8-
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
8+
Imports Microsoft.CodeAnalysis.Editor.UnitTests
9+
Imports Microsoft.CodeAnalysis.Host
910
Imports Microsoft.CodeAnalysis.Shared.TestHooks
1011
Imports Microsoft.CodeAnalysis.Test.Utilities
1112
Imports Microsoft.CodeAnalysis.Text
@@ -122,16 +123,23 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer
122123
End Using
123124
End Function
124125

125-
<WpfFact>
126-
Public Async Function ChangeToRemoveAllGeneratedDocumentsUpdatesListCorrectly() As Task
126+
<WpfTheory, CombinatorialData>
127+
Friend Async Function ChangeToRemoveAllGeneratedDocumentsUpdatesListCorrectly(
128+
preference As SourceGeneratorExecutionPreference) As Task
127129
Dim workspaceXml =
128130
<Workspace>
129131
<Project Language="C#" CommonReferences="true" LanguageVersion="Preview">
130132
<AdditionalDocument FilePath="Test1.txt"></AdditionalDocument>
131133
</Project>
132134
</Workspace>
133135

134-
Using workspace = EditorTestWorkspace.Create(workspaceXml)
136+
Using workspace = EditorTestWorkspace.Create(
137+
workspaceXml,
138+
composition:=EditorTestCompositions.EditorFeatures.AddParts(GetType(TestWorkspaceConfigurationService)))
139+
140+
Dim configService = workspace.ExportProvider.GetExportedValue(Of TestWorkspaceConfigurationService)
141+
configService.Options = New WorkspaceConfigurationOptions(SourceGeneratorExecution:=preference)
142+
135143
Dim projectId = workspace.Projects.Single().Id
136144
Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId)
137145
Dim generatorItem = Assert.IsAssignableFrom(Of SourceGeneratorItem)(Assert.Single(source.Items))
@@ -147,19 +155,31 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer
147155

148156
Await WaitForGeneratorsAndItemSourcesAsync(workspace)
149157

150-
Assert.IsType(Of NoSourceGeneratedFilesPlaceholderItem)(Assert.Single(generatorFilesItemSource.Items))
158+
' In balanced-mode the SG file won't go away until a save/build happens.
159+
If preference = SourceGeneratorExecutionPreference.Automatic Then
160+
Assert.IsType(Of NoSourceGeneratedFilesPlaceholderItem)(Assert.Single(generatorFilesItemSource.Items))
161+
Else
162+
Assert.IsType(Of SourceGeneratedFileItem)(Assert.Single(generatorFilesItemSource.Items))
163+
End If
151164
End Using
152165
End Function
153166

154-
<WpfFact>
155-
Public Async Function AddingAGeneratedDocumentUpdatesListCorrectly() As Task
167+
<WpfTheory, CombinatorialData>
168+
Friend Async Function AddingAGeneratedDocumentUpdatesListCorrectly(
169+
preference As SourceGeneratorExecutionPreference) As Task
156170
Dim workspaceXml =
157171
<Workspace>
158172
<Project Language="C#" CommonReferences="true" LanguageVersion="Preview">
159173
</Project>
160174
</Workspace>
161175

162-
Using workspace = EditorTestWorkspace.Create(workspaceXml)
176+
Using workspace = EditorTestWorkspace.Create(
177+
workspaceXml,
178+
composition:=EditorTestCompositions.EditorFeatures.AddParts(GetType(TestWorkspaceConfigurationService)))
179+
180+
Dim configService = workspace.ExportProvider.GetExportedValue(Of TestWorkspaceConfigurationService)
181+
configService.Options = New WorkspaceConfigurationOptions(SourceGeneratorExecution:=preference)
182+
163183
Dim projectId = workspace.Projects.Single().Id
164184
Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId)
165185
Dim generatorItem = Assert.IsAssignableFrom(Of SourceGeneratorItem)(Assert.Single(source.Items))
@@ -179,7 +199,12 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer
179199

180200
Await WaitForGeneratorsAndItemSourcesAsync(workspace)
181201

182-
Assert.IsType(Of SourceGeneratedFileItem)(Assert.Single(generatorFilesItemSource.Items))
202+
' In balanced-mode the SG file won't be created until a save/build happens.
203+
If preference = SourceGeneratorExecutionPreference.Automatic Then
204+
Assert.IsType(Of SourceGeneratedFileItem)(Assert.Single(generatorFilesItemSource.Items))
205+
Else
206+
Assert.IsType(Of NoSourceGeneratedFilesPlaceholderItem)(Assert.Single(generatorFilesItemSource.Items))
207+
End If
183208

184209
' Add a second item and see if it updates correctly again
185210
workspace.OnAdditionalDocumentAdded(
@@ -188,7 +213,12 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer
188213
"Test2.txt"))
189214

190215
Await WaitForGeneratorsAndItemSourcesAsync(workspace)
191-
Assert.Equal(2, generatorFilesItemSource.Items.Cast(Of SourceGeneratedFileItem)().Count())
216+
217+
If preference = SourceGeneratorExecutionPreference.Automatic Then
218+
Assert.Equal(2, generatorFilesItemSource.Items.Cast(Of SourceGeneratedFileItem)().Count())
219+
Else
220+
Assert.Equal(1, generatorFilesItemSource.Items.Cast(Of NoSourceGeneratedFilesPlaceholderItem)().Count())
221+
End If
192222
End Using
193223
End Function
194224

src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProject.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,8 @@ private async Task OnBatchScopeDisposedMaybeAsync(bool useAsync)
536536
var additionalDocumentsToOpen = new List<(DocumentId documentId, SourceTextContainer textContainer)>();
537537
var analyzerConfigDocumentsToOpen = new List<(DocumentId documentId, SourceTextContainer textContainer)>();
538538

539+
var hasAnalyzerChanges = _analyzersAddedInBatch.Count > 0 || _analyzersRemovedInBatch.Count > 0;
540+
539541
await _projectSystemProjectFactory.ApplyBatchChangeToWorkspaceMaybeAsync(useAsync, solutionChanges =>
540542
{
541543
_sourceFiles.UpdateSolutionForBatch(
@@ -667,25 +669,21 @@ await _projectSystemProjectFactory.ApplyBatchChangeToWorkspaceMaybeAsync(useAsyn
667669
}).ConfigureAwait(false);
668670

669671
foreach (var (documentId, textContainer) in documentsToOpen)
670-
{
671672
await _projectSystemProjectFactory.ApplyChangeToWorkspaceMaybeAsync(useAsync, w => w.OnDocumentOpened(documentId, textContainer)).ConfigureAwait(false);
672-
}
673673

674674
foreach (var (documentId, textContainer) in additionalDocumentsToOpen)
675-
{
676675
await _projectSystemProjectFactory.ApplyChangeToWorkspaceMaybeAsync(useAsync, w => w.OnAdditionalDocumentOpened(documentId, textContainer)).ConfigureAwait(false);
677-
}
678676

679677
foreach (var (documentId, textContainer) in analyzerConfigDocumentsToOpen)
680-
{
681678
await _projectSystemProjectFactory.ApplyChangeToWorkspaceMaybeAsync(useAsync, w => w.OnAnalyzerConfigDocumentOpened(documentId, textContainer)).ConfigureAwait(false);
682-
}
683679

684680
// Give the host the opportunity to check if those files are open
685681
if (documentFileNamesAdded.Count > 0)
686-
{
687682
await _projectSystemProjectFactory.RaiseOnDocumentsAddedMaybeAsync(useAsync, documentFileNamesAdded.ToImmutable()).ConfigureAwait(false);
688-
}
683+
684+
// If we added or removed analyzers, then re-run all generators to bring them up to date.
685+
if (hasAnalyzerChanges)
686+
_projectSystemProjectFactory.Workspace.EnqueueUpdateSourceGeneratorVersion(projectId: null, forceRegeneration: true);
689687
}
690688
}
691689

src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspaceConfigurationService.cs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,16 @@
44

55
using System;
66
using System.Composition;
7-
using Microsoft.CodeAnalysis;
87
using Microsoft.CodeAnalysis.Host;
98
using Microsoft.CodeAnalysis.Host.Mef;
109

11-
namespace Roslyn.Test.Utilities
12-
{
13-
[Export]
14-
[ExportWorkspaceService(typeof(IWorkspaceConfigurationService), ServiceLayer.Test)]
15-
[Shared]
16-
[PartNotDiscoverable]
17-
internal sealed class TestWorkspaceConfigurationService : IWorkspaceConfigurationService
18-
{
19-
public WorkspaceConfigurationOptions Options { get; set; }
10+
namespace Roslyn.Test.Utilities;
2011

21-
[ImportingConstructor]
22-
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
23-
public TestWorkspaceConfigurationService()
24-
{
25-
}
26-
}
12+
[Export, Shared, PartNotDiscoverable]
13+
[ExportWorkspaceService(typeof(IWorkspaceConfigurationService), ServiceLayer.Test)]
14+
[method: ImportingConstructor]
15+
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
16+
internal sealed class TestWorkspaceConfigurationService() : IWorkspaceConfigurationService
17+
{
18+
public WorkspaceConfigurationOptions Options { get; set; }
2719
}

0 commit comments

Comments
 (0)