From 72f2fd3b720613f1bb0a74770d0f2e1d4195721f Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 12:29:32 -0700 Subject: [PATCH 01/13] Switch SG mode to 'balanced' by default --- .../Rename/CSharp/SourceGeneratorTests.vb | 1 - .../Test2/Rename/RenameEngineResult.vb | 7 ++++--- .../WorkspaceConfigurationOptionsStorage.cs | 2 +- .../SourceGeneratorItemTests.vb | 18 ++++++++++++++++-- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/EditorFeatures/Test2/Rename/CSharp/SourceGeneratorTests.vb b/src/EditorFeatures/Test2/Rename/CSharp/SourceGeneratorTests.vb index 96808a907ff22..8ebc28eb5e830 100644 --- a/src/EditorFeatures/Test2/Rename/CSharp/SourceGeneratorTests.vb +++ b/src/EditorFeatures/Test2/Rename/CSharp/SourceGeneratorTests.vb @@ -72,7 +72,6 @@ public partial class GeneratedClass : IInterface { } , host:=host, renameTo:="A", sourceGenerator:=New GeneratorThatImplementsInterfaceMethod()) - End Using End Sub diff --git a/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb b/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb index 7cc7b5cb35379..3cfdffe90f3d5 100644 --- a/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb +++ b/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb @@ -6,10 +6,8 @@ Imports System.Collections.Immutable Imports System.Threading Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.CodeActions -Imports Microsoft.CodeAnalysis.CodeCleanup Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.Host -Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Remote.Testing Imports Microsoft.CodeAnalysis.Rename Imports Microsoft.CodeAnalysis.Rename.ConflictEngine @@ -62,7 +60,8 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename Dim composition = EditorTestCompositions.EditorFeatures.AddParts( GetType(NoCompilationContentTypeLanguageService), GetType(NoCompilationContentTypeDefinitions), - GetType(WorkspaceTestLogger)) + GetType(WorkspaceTestLogger), + GetType(TestWorkspaceConfigurationService)) If host = RenameTestHost.OutOfProcess_SingleCall OrElse host = RenameTestHost.OutOfProcess_SplitCall Then composition = composition.WithTestHostParts(TestHost.OutOfProcess) @@ -70,6 +69,8 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename Dim workspace = TestWorkspace.CreateWorkspace(workspaceXml, composition:=composition) workspace.Services.SolutionServices.SetWorkspaceTestOutput(helper) + workspace.GlobalOptions.SetGlobalOption( + WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic) If sourceGenerator IsNot Nothing Then workspace.OnAnalyzerReferenceAdded(workspace.CurrentSolution.ProjectIds.Single(), New TestGeneratorReference(sourceGenerator)) diff --git a/src/Features/LanguageServer/Protocol/Features/Options/WorkspaceConfigurationOptionsStorage.cs b/src/Features/LanguageServer/Protocol/Features/Options/WorkspaceConfigurationOptionsStorage.cs index 773b736d0cb20..514450460e7f3 100644 --- a/src/Features/LanguageServer/Protocol/Features/Options/WorkspaceConfigurationOptionsStorage.cs +++ b/src/Features/LanguageServer/Protocol/Features/Options/WorkspaceConfigurationOptionsStorage.cs @@ -50,5 +50,5 @@ public static WorkspaceConfigurationOptions GetWorkspaceConfigurationOptions(thi SourceGeneratorExecutionPreferenceUtilities.GetEditorConfigString)); public static readonly Option2 SourceGeneratorExecutionBalancedFeatureFlag = new( - "dotnet_source_generator_execution_balanced_feature_flag", false); + "dotnet_source_generator_execution_balanced_feature_flag", true); } diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb index 75edd90c0dd42..d475e6a87c8ef 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb @@ -5,7 +5,9 @@ Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Diagnostics Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities +Imports Microsoft.CodeAnalysis.Editor.UnitTests Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces +Imports Microsoft.CodeAnalysis.Host Imports Microsoft.CodeAnalysis.Shared.TestHooks Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text @@ -131,7 +133,13 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer - Using workspace = EditorTestWorkspace.Create(workspaceXml) + Using workspace = EditorTestWorkspace.Create( + workspaceXml, + composition:=EditorTestCompositions.EditorFeatures.AddParts(GetType(TestWorkspaceConfigurationService))) + + workspace.GlobalOptions.SetGlobalOption( + WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic) + Dim projectId = workspace.Projects.Single().Id Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId) Dim generatorItem = Assert.IsAssignableFrom(Of SourceGeneratorItem)(Assert.Single(source.Items)) @@ -159,7 +167,13 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer - Using workspace = EditorTestWorkspace.Create(workspaceXml) + Using workspace = EditorTestWorkspace.Create( + workspaceXml, + composition:=EditorTestCompositions.EditorFeatures.AddParts(GetType(TestWorkspaceConfigurationService))) + + workspace.GlobalOptions.SetGlobalOption( + WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic) + Dim projectId = workspace.Projects.Single().Id Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId) Dim generatorItem = Assert.IsAssignableFrom(Of SourceGeneratorItem)(Assert.Single(source.Items)) From ea95ad5ac2bef8c6a0090f62d9c29e5c7427dc1c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 13:34:20 -0700 Subject: [PATCH 02/13] Fix test --- src/EditorFeatures/Test2/Rename/RenameTestHelpers.vb | 6 ++---- src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/EditorFeatures/Test2/Rename/RenameTestHelpers.vb b/src/EditorFeatures/Test2/Rename/RenameTestHelpers.vb index e6b3540352073..19f53caf23725 100644 --- a/src/EditorFeatures/Test2/Rename/RenameTestHelpers.vb +++ b/src/EditorFeatures/Test2/Rename/RenameTestHelpers.vb @@ -10,10 +10,8 @@ Imports Microsoft.CodeAnalysis.Editor.Implementation.RenameTracking Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities Imports Microsoft.CodeAnalysis.Editor.UnitTests.RenameTracking Imports Microsoft.CodeAnalysis.Editor.UnitTests.Utilities.GoToHelpers -Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Shared.TestHooks -Imports Microsoft.CodeAnalysis.Rename Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.Text.Shared.Extensions Imports Microsoft.VisualStudio.Text @@ -22,10 +20,10 @@ Imports Microsoft.VisualStudio.Text.Tagging Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename Friend Module RenameTestHelpers - Private ReadOnly s_composition As TestComposition = EditorTestCompositions.EditorFeaturesWpf.AddParts( GetType(MockDocumentNavigationServiceFactory), - GetType(MockPreviewDialogService)) + GetType(MockPreviewDialogService), + GetType(TestWorkspaceConfigurationService)) Private Function GetSessionInfo(workspace As EditorTestWorkspace) As (document As Document, textSpan As TextSpan) Dim hostdoc = workspace.DocumentWithCursor diff --git a/src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb b/src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb index c86ff38b884bf..e406a633b70e6 100644 --- a/src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb +++ b/src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb @@ -6,6 +6,7 @@ Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.InlineRename Imports Microsoft.CodeAnalysis.Editor.InlineRename Imports Microsoft.CodeAnalysis.Editor.[Shared].Utilities +Imports Microsoft.CodeAnalysis.Host Imports Microsoft.CodeAnalysis.InlineRename Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.[Shared].TestHooks @@ -556,6 +557,7 @@ class D : B globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameInStrings, renameInStrings) globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameInComments, renameInComments) globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameFile, renameFile) + globalOptions.SetGlobalOption(WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic) Dim cursorDocument = workspace.Documents.Single(Function(d) d.CursorPosition.HasValue) Dim cursorPosition = cursorDocument.CursorPosition.Value From 90faf362efa7da7a168f38fc468f94a1cc7cd47a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 13:38:12 -0700 Subject: [PATCH 03/13] fix tests --- .../Workspaces/WorkspaceTests_EditorFeatures.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs index a04d587c91a78..a7db0c6c2340f 100644 --- a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs +++ b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs @@ -17,6 +17,7 @@ using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Indentation; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -471,7 +472,11 @@ End Class [Fact] public async Task TestGetCompilationOnCrossLanguageDependentProjectChanged() { - using var workspace = CreateWorkspace(); + using var workspace = CreateWorkspace(composition: EditorTestCompositions.EditorFeatures.AddParts(typeof(TestWorkspaceConfigurationService))); + + var options = workspace.ExportProvider.GetExportedValue(); + options.SetGlobalOption(WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic); + var solutionX = workspace.CurrentSolution; var document1 = new EditorTestHostDocument(@"public class C { }"); @@ -578,9 +583,15 @@ End Class [WpfFact] public async Task TestGetCompilationOnCrossLanguageDependentProjectChangedInProgress() { - var composition = EditorTestCompositions.EditorFeatures.AddParts(typeof(TestDocumentTrackingService)); + var composition = EditorTestCompositions.EditorFeatures.AddParts( + typeof(TestDocumentTrackingService), + typeof(TestWorkspaceConfigurationService)); using var workspace = CreateWorkspace(disablePartialSolutions: false, composition: composition); + + var options = workspace.ExportProvider.GetExportedValue(); + options.SetGlobalOption(WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic); + var trackingService = (TestDocumentTrackingService)workspace.Services.GetRequiredService(); var solutionX = workspace.CurrentSolution; From 70ec054a36217891d2d2795623189ae487e50a85 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 13:41:49 -0700 Subject: [PATCH 04/13] Make into theories --- .../Workspaces/WorkspaceTests_EditorFeatures.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs index a7db0c6c2340f..2c89636eedb85 100644 --- a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs +++ b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs @@ -469,13 +469,14 @@ End Class var classC = classD.BaseType; } - [Fact] - public async Task TestGetCompilationOnCrossLanguageDependentProjectChanged() + [Theory, CombinatorialData] + internal async Task TestGetCompilationOnCrossLanguageDependentProjectChanged( + SourceGeneratorExecutionPreference preference) { using var workspace = CreateWorkspace(composition: EditorTestCompositions.EditorFeatures.AddParts(typeof(TestWorkspaceConfigurationService))); var options = workspace.ExportProvider.GetExportedValue(); - options.SetGlobalOption(WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic); + options.SetGlobalOption(WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, preference); var solutionX = workspace.CurrentSolution; @@ -580,8 +581,9 @@ End Class } } - [WpfFact] - public async Task TestGetCompilationOnCrossLanguageDependentProjectChangedInProgress() + [WpfTheory, CombinatorialData] + internal async Task TestGetCompilationOnCrossLanguageDependentProjectChangedInProgress( + SourceGeneratorExecutionPreference preference) { var composition = EditorTestCompositions.EditorFeatures.AddParts( typeof(TestDocumentTrackingService), @@ -590,7 +592,7 @@ public async Task TestGetCompilationOnCrossLanguageDependentProjectChangedInProg using var workspace = CreateWorkspace(disablePartialSolutions: false, composition: composition); var options = workspace.ExportProvider.GetExportedValue(); - options.SetGlobalOption(WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic); + options.SetGlobalOption(WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, preference); var trackingService = (TestDocumentTrackingService)workspace.Services.GetRequiredService(); var solutionX = workspace.CurrentSolution; From 088f30b2081e7a5f96d2ac751e5e146903484ef7 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 13:50:36 -0700 Subject: [PATCH 05/13] Update tests --- .../SourceGeneratorItemTests.vb | 25 +++++++++++-------- .../TestWorkspaceConfigurationService.cs | 24 ++++++------------ 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb index d475e6a87c8ef..55919acdb7f73 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb @@ -6,7 +6,6 @@ Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Diagnostics Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities Imports Microsoft.CodeAnalysis.Editor.UnitTests -Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.Host Imports Microsoft.CodeAnalysis.Shared.TestHooks Imports Microsoft.CodeAnalysis.Test.Utilities @@ -124,8 +123,9 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer End Using End Function - - Public Async Function ChangeToRemoveAllGeneratedDocumentsUpdatesListCorrectly() As Task + + Friend Async Function ChangeToRemoveAllGeneratedDocumentsUpdatesListCorrectly( + preference As SourceGeneratorExecutionPreference) As Task Dim workspaceXml = @@ -137,8 +137,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer workspaceXml, composition:=EditorTestCompositions.EditorFeatures.AddParts(GetType(TestWorkspaceConfigurationService))) - workspace.GlobalOptions.SetGlobalOption( - WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic) + Dim configService = workspace.ExportProvider.GetExportedValue(Of TestWorkspaceConfigurationService) + configService.Options = New WorkspaceConfigurationOptions(SourceGeneratorExecution:=preference) Dim projectId = workspace.Projects.Single().Id Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId) @@ -155,12 +155,17 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer Await WaitForGeneratorsAndItemSourcesAsync(workspace) - Assert.IsType(Of NoSourceGeneratedFilesPlaceholderItem)(Assert.Single(generatorFilesItemSource.Items)) + If preference = SourceGeneratorExecutionPreference.Automatic Then + Assert.IsType(Of NoSourceGeneratedFilesPlaceholderItem)(Assert.Single(generatorFilesItemSource.Items)) + Else + Assert.IsType(Of SourceGeneratedFileItem)(Assert.Single(generatorFilesItemSource.Items)) + End If End Using End Function - - Public Async Function AddingAGeneratedDocumentUpdatesListCorrectly() As Task + + Friend Async Function AddingAGeneratedDocumentUpdatesListCorrectly( + preference As SourceGeneratorExecutionPreference) As Task Dim workspaceXml = @@ -171,8 +176,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer workspaceXml, composition:=EditorTestCompositions.EditorFeatures.AddParts(GetType(TestWorkspaceConfigurationService))) - workspace.GlobalOptions.SetGlobalOption( - WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic) + Dim configService = workspace.ExportProvider.GetExportedValue(Of TestWorkspaceConfigurationService) + configService.Options = New WorkspaceConfigurationOptions(SourceGeneratorExecution:=preference) Dim projectId = workspace.Projects.Single().Id Dim source = CreateItemSourceForAnalyzerReference(workspace, projectId) diff --git a/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspaceConfigurationService.cs b/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspaceConfigurationService.cs index 9915049dc04bb..c19eed238124a 100644 --- a/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspaceConfigurationService.cs +++ b/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspaceConfigurationService.cs @@ -4,24 +4,16 @@ using System; using System.Composition; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; -namespace Roslyn.Test.Utilities -{ - [Export] - [ExportWorkspaceService(typeof(IWorkspaceConfigurationService), ServiceLayer.Test)] - [Shared] - [PartNotDiscoverable] - internal sealed class TestWorkspaceConfigurationService : IWorkspaceConfigurationService - { - public WorkspaceConfigurationOptions Options { get; set; } +namespace Roslyn.Test.Utilities; - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public TestWorkspaceConfigurationService() - { - } - } +[Export, Shared, PartNotDiscoverable] +[ExportWorkspaceService(typeof(IWorkspaceConfigurationService), ServiceLayer.Test)] +[method: ImportingConstructor] +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed class TestWorkspaceConfigurationService() : IWorkspaceConfigurationService +{ + public WorkspaceConfigurationOptions Options { get; set; } } From 4148828842c3393fb4f2e3054d9175eef41298a6 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 13:53:33 -0700 Subject: [PATCH 06/13] Update tests --- .../SolutionExplorer/SourceGeneratorItemTests.vb | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb index 55919acdb7f73..74145221a2051 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/SourceGeneratorItemTests.vb @@ -155,6 +155,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer Await WaitForGeneratorsAndItemSourcesAsync(workspace) + ' In balanced-mode the SG file won't go away until a save/build happens. If preference = SourceGeneratorExecutionPreference.Automatic Then Assert.IsType(Of NoSourceGeneratedFilesPlaceholderItem)(Assert.Single(generatorFilesItemSource.Items)) Else @@ -198,7 +199,12 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer Await WaitForGeneratorsAndItemSourcesAsync(workspace) - Assert.IsType(Of SourceGeneratedFileItem)(Assert.Single(generatorFilesItemSource.Items)) + ' In balanced-mode the SG file won't be created until a save/build happens. + If preference = SourceGeneratorExecutionPreference.Automatic Then + Assert.IsType(Of SourceGeneratedFileItem)(Assert.Single(generatorFilesItemSource.Items)) + Else + Assert.IsType(Of NoSourceGeneratedFilesPlaceholderItem)(Assert.Single(generatorFilesItemSource.Items)) + End If ' Add a second item and see if it updates correctly again workspace.OnAdditionalDocumentAdded( @@ -207,7 +213,12 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer "Test2.txt")) Await WaitForGeneratorsAndItemSourcesAsync(workspace) - Assert.Equal(2, generatorFilesItemSource.Items.Cast(Of SourceGeneratedFileItem)().Count()) + + If preference = SourceGeneratorExecutionPreference.Automatic Then + Assert.Equal(2, generatorFilesItemSource.Items.Cast(Of SourceGeneratedFileItem)().Count()) + Else + Assert.Equal(1, generatorFilesItemSource.Items.Cast(Of NoSourceGeneratedFilesPlaceholderItem)().Count()) + End If End Using End Function From b4bac65adfb84b9eeafd1e9a0c0544cf93be356e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 13:58:22 -0700 Subject: [PATCH 07/13] Update tests --- .../WorkspaceTests_EditorFeatures.cs | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs index 2c89636eedb85..5539aca51eb18 100644 --- a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs +++ b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs @@ -475,8 +475,8 @@ internal async Task TestGetCompilationOnCrossLanguageDependentProjectChanged( { using var workspace = CreateWorkspace(composition: EditorTestCompositions.EditorFeatures.AddParts(typeof(TestWorkspaceConfigurationService))); - var options = workspace.ExportProvider.GetExportedValue(); - options.SetGlobalOption(WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, preference); + var configService = workspace.ExportProvider.GetExportedValue(); + configService.Options = new WorkspaceConfigurationOptions(SourceGeneratorExecution: preference); var solutionX = workspace.CurrentSolution; @@ -520,7 +520,12 @@ End Class var classDz = compilation2Z.SourceModule.GlobalNamespace.GetTypeMembers("D").Single(); var classCz = classDz.BaseType; - Assert.Equal(TypeKind.Error, classCz.TypeKind); + // In balanced mode the skeleton won't be regenerated. So the downstream project won't see the change to + // remove the class. + if (preference is SourceGeneratorExecutionPreference.Automatic) + Assert.Equal(TypeKind.Error, classCz.TypeKind); + else + Assert.Equal(TypeKind.Class, classCz.TypeKind); } [WpfFact] @@ -591,8 +596,8 @@ internal async Task TestGetCompilationOnCrossLanguageDependentProjectChangedInPr using var workspace = CreateWorkspace(disablePartialSolutions: false, composition: composition); - var options = workspace.ExportProvider.GetExportedValue(); - options.SetGlobalOption(WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, preference); + var configService = workspace.ExportProvider.GetExportedValue(); + configService.Options = new WorkspaceConfigurationOptions(SourceGeneratorExecution: preference); var trackingService = (TestDocumentTrackingService)workspace.Services.GetRequiredService(); var solutionX = workspace.CurrentSolution; @@ -675,8 +680,16 @@ End Class } } - // Should find now that we're going a normal compilation. - Assert.True(foundTheError, "Did not find error"); + // In balanced mode the skeleton won't be regenerated. So the downstream project won't see the change to + // remove the class. So it will not find the error symbol. + if (preference is SourceGeneratorExecutionPreference.Automatic) + { + Assert.True(foundTheError, "Did not find error"); + } + else + { + Assert.False(foundTheError); + } } [Fact] From c1a461d01fbef0790d94fecabf31fa58b733a051 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 13:58:55 -0700 Subject: [PATCH 08/13] Update tests --- .../CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs index 5539aca51eb18..dab3f3ac8d0cd 100644 --- a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs +++ b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests_EditorFeatures.cs @@ -683,13 +683,9 @@ End Class // In balanced mode the skeleton won't be regenerated. So the downstream project won't see the change to // remove the class. So it will not find the error symbol. if (preference is SourceGeneratorExecutionPreference.Automatic) - { - Assert.True(foundTheError, "Did not find error"); - } + Assert.True(foundTheError); else - { Assert.False(foundTheError); - } } [Fact] From 09864fb172d64f20738c33d00d2c22c824321bfe Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 14:02:19 -0700 Subject: [PATCH 09/13] Update rename --- src/EditorFeatures/Test2/Rename/RenameEngineResult.vb | 9 ++++++--- src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb | 8 +++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb b/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb index 3cfdffe90f3d5..510962f02c6f8 100644 --- a/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb +++ b/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb @@ -55,7 +55,8 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename host As RenameTestHost, Optional renameOptions As SymbolRenameOptions = Nothing, Optional expectFailure As Boolean = False, - Optional sourceGenerator As ISourceGenerator = Nothing) As RenameEngineResult + Optional sourceGenerator As ISourceGenerator = Nothing, + Optional executionPreference As SourceGeneratorExecutionPreference = SourceGeneratorExecutionPreference.Balanced) As RenameEngineResult Dim composition = EditorTestCompositions.EditorFeatures.AddParts( GetType(NoCompilationContentTypeLanguageService), @@ -68,9 +69,11 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename End If Dim workspace = TestWorkspace.CreateWorkspace(workspaceXml, composition:=composition) + + Dim configService = workspace.ExportProvider.GetExportedValue(Of TestWorkspaceConfigurationService) + configService.Options = New WorkspaceConfigurationOptions(SourceGeneratorExecution:=executionPreference) + workspace.Services.SolutionServices.SetWorkspaceTestOutput(helper) - workspace.GlobalOptions.SetGlobalOption( - WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic) If sourceGenerator IsNot Nothing Then workspace.OnAnalyzerReferenceAdded(workspace.CurrentSolution.ProjectIds.Single(), New TestGeneratorReference(sourceGenerator)) diff --git a/src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb b/src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb index e406a633b70e6..dad3866b291fc 100644 --- a/src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb +++ b/src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb @@ -548,8 +548,8 @@ class D : B Optional renameFile As Boolean = False, Optional resolvableConflictText As String = Nothing, Optional unresolvableConflictText As String = Nothing, - Optional severity As RenameDashboardSeverity = RenameDashboardSeverity.None - ) As Tasks.Task + Optional severity As RenameDashboardSeverity = RenameDashboardSeverity.None, + Optional executionPreference As SourceGeneratorExecutionPreference = SourceGeneratorExecutionPreference.Balanced) As Task Using workspace = CreateWorkspaceWithWaiter(test, host) Dim globalOptions = workspace.GetService(Of IGlobalOptionService)() @@ -557,7 +557,9 @@ class D : B globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameInStrings, renameInStrings) globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameInComments, renameInComments) globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameFile, renameFile) - globalOptions.SetGlobalOption(WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic) + + Dim configService = workspace.ExportProvider.GetExportedValue(Of TestWorkspaceConfigurationService) + configService.Options = New WorkspaceConfigurationOptions(SourceGeneratorExecution:=executionPreference) Dim cursorDocument = workspace.Documents.Single(Function(d) d.CursorPosition.HasValue) Dim cursorPosition = cursorDocument.CursorPosition.Value From d4acc8247405d26bdd100fd1a8d4cc6ed857991e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 14:06:30 -0700 Subject: [PATCH 10/13] Automatic by default --- src/EditorFeatures/Test2/Rename/RenameEngineResult.vb | 2 +- src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb b/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb index 510962f02c6f8..f0aa89b965adf 100644 --- a/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb +++ b/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb @@ -56,7 +56,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename Optional renameOptions As SymbolRenameOptions = Nothing, Optional expectFailure As Boolean = False, Optional sourceGenerator As ISourceGenerator = Nothing, - Optional executionPreference As SourceGeneratorExecutionPreference = SourceGeneratorExecutionPreference.Balanced) As RenameEngineResult + Optional executionPreference As SourceGeneratorExecutionPreference = SourceGeneratorExecutionPreference.Automatic) As RenameEngineResult Dim composition = EditorTestCompositions.EditorFeatures.AddParts( GetType(NoCompilationContentTypeLanguageService), diff --git a/src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb b/src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb index dad3866b291fc..19ecabcdd2cd3 100644 --- a/src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb +++ b/src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb @@ -549,7 +549,7 @@ class D : B Optional resolvableConflictText As String = Nothing, Optional unresolvableConflictText As String = Nothing, Optional severity As RenameDashboardSeverity = RenameDashboardSeverity.None, - Optional executionPreference As SourceGeneratorExecutionPreference = SourceGeneratorExecutionPreference.Balanced) As Task + Optional executionPreference As SourceGeneratorExecutionPreference = SourceGeneratorExecutionPreference.Automatic) As Task Using workspace = CreateWorkspaceWithWaiter(test, host) Dim globalOptions = workspace.GetService(Of IGlobalOptionService)() From bc793cf7d7dd6d84cd566dbc438bcd54ed36fa4b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 14:25:48 -0700 Subject: [PATCH 11/13] Automatic for LSP --- .../Microsoft.CodeAnalysis.LanguageServer/Program.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Features/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/Program.cs b/src/Features/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/Program.cs index cdd36c6cb0524..349adc7ecaeca 100644 --- a/src/Features/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/Program.cs +++ b/src/Features/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/Program.cs @@ -10,6 +10,7 @@ using System.Runtime.Loader; using System.Text.Json; using Microsoft.CodeAnalysis.Contracts.Telemetry; +using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.LanguageServer; using Microsoft.CodeAnalysis.LanguageServer.BrokeredServices; using Microsoft.CodeAnalysis.LanguageServer.HostWorkspace; @@ -17,6 +18,7 @@ using Microsoft.CodeAnalysis.LanguageServer.Logging; using Microsoft.CodeAnalysis.LanguageServer.Services; using Microsoft.CodeAnalysis.LanguageServer.StarredSuggestions; +using Microsoft.CodeAnalysis.Options; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Console; using Roslyn.Utilities; @@ -82,6 +84,11 @@ static async Task RunAsync(ServerConfiguration serverConfiguration, Cancellation using var exportProvider = await ExportProviderBuilder.CreateExportProviderAsync(extensionManager, serverConfiguration.DevKitDependencyPath, loggerFactory); + // LSP server doesn't have the pieces yet to support 'balanced' mode for source-generators. Hardcode us to + // 'automatic' for now. + var globalOptionService = exportProvider.GetExportedValue(); + globalOptionService.SetGlobalOption(WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution, SourceGeneratorExecutionPreference.Automatic); + // The log file directory passed to us by VSCode might not exist yet, though its parent directory is guaranteed to exist. Directory.CreateDirectory(serverConfiguration.ExtensionLogDirectory); From f3c2f0cdb741890b7aabba045b17fe3f27604f84 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 16:22:19 -0700 Subject: [PATCH 12/13] Rerun on analyzer added --- .../Workspace/ProjectSystem/ProjectSystemProject.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProject.cs b/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProject.cs index 4f387f594bed4..bffcc1de1673e 100644 --- a/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProject.cs +++ b/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProject.cs @@ -536,6 +536,8 @@ private async Task OnBatchScopeDisposedMaybeAsync(bool useAsync) var additionalDocumentsToOpen = new List<(DocumentId documentId, SourceTextContainer textContainer)>(); var analyzerConfigDocumentsToOpen = new List<(DocumentId documentId, SourceTextContainer textContainer)>(); + var hasAnalyzerChanges = _analyzersAddedInBatch.Count > 0 || _analyzersRemovedInBatch.Count > 0; + await _projectSystemProjectFactory.ApplyBatchChangeToWorkspaceMaybeAsync(useAsync, solutionChanges => { _sourceFiles.UpdateSolutionForBatch( @@ -686,6 +688,10 @@ await _projectSystemProjectFactory.ApplyBatchChangeToWorkspaceMaybeAsync(useAsyn { await _projectSystemProjectFactory.RaiseOnDocumentsAddedMaybeAsync(useAsync, documentFileNamesAdded.ToImmutable()).ConfigureAwait(false); } + + // If we added or removed analyzers, then re-run all generators to bring them up to date. + if (hasAnalyzerChanges) + _projectSystemProjectFactory.Workspace.EnqueueUpdateSourceGeneratorVersion(projectId: null, forceRegeneration: true); } } From 8f01700e86b38c45b0de7728497ccb9be8c4578f Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 16:26:06 -0700 Subject: [PATCH 13/13] formatting --- .../Workspace/ProjectSystem/ProjectSystemProject.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProject.cs b/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProject.cs index bffcc1de1673e..17d034fbf0951 100644 --- a/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProject.cs +++ b/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProject.cs @@ -669,25 +669,17 @@ await _projectSystemProjectFactory.ApplyBatchChangeToWorkspaceMaybeAsync(useAsyn }).ConfigureAwait(false); foreach (var (documentId, textContainer) in documentsToOpen) - { await _projectSystemProjectFactory.ApplyChangeToWorkspaceMaybeAsync(useAsync, w => w.OnDocumentOpened(documentId, textContainer)).ConfigureAwait(false); - } foreach (var (documentId, textContainer) in additionalDocumentsToOpen) - { await _projectSystemProjectFactory.ApplyChangeToWorkspaceMaybeAsync(useAsync, w => w.OnAdditionalDocumentOpened(documentId, textContainer)).ConfigureAwait(false); - } foreach (var (documentId, textContainer) in analyzerConfigDocumentsToOpen) - { await _projectSystemProjectFactory.ApplyChangeToWorkspaceMaybeAsync(useAsync, w => w.OnAnalyzerConfigDocumentOpened(documentId, textContainer)).ConfigureAwait(false); - } // Give the host the opportunity to check if those files are open if (documentFileNamesAdded.Count > 0) - { await _projectSystemProjectFactory.RaiseOnDocumentsAddedMaybeAsync(useAsync, documentFileNamesAdded.ToImmutable()).ConfigureAwait(false); - } // If we added or removed analyzers, then re-run all generators to bring them up to date. if (hasAnalyzerChanges)