diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/AdditionalPropertiesTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/AdditionalPropertiesTests.cs index fe587be47db36..972bad5c7d916 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/AdditionalPropertiesTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/AdditionalPropertiesTests.cs @@ -5,6 +5,7 @@ #nullable disable using System.Linq; +using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio; @@ -22,10 +23,10 @@ public class AdditionalPropertiesTests { [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void SetProperty_RootNamespace_CPS() + public async Task SetProperty_RootNamespace_CPS() { using (var environment = new TestEnvironment()) - using (var project = CSharpHelpers.CreateCSharpCPSProject(environment, "Test")) + using (var project = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test")) { Assert.Null(DefaultNamespaceOfSingleProject(environment)); @@ -47,12 +48,12 @@ static string DefaultNamespaceOfSingleProject(TestEnvironment environment) [InlineData(LanguageVersion.LatestMajor)] [InlineData(LanguageVersion.Preview)] [InlineData(null)] - public void SetProperty_MaxSupportedLangVersion_CPS(LanguageVersion? maxSupportedLangVersion) + public async Task SetProperty_MaxSupportedLangVersion_CPS(LanguageVersion? maxSupportedLangVersion) { const LanguageVersion attemptedVersion = LanguageVersion.CSharp8; using (var environment = new TestEnvironment(typeof(CSharpParseOptionsChangingService))) - using (var cpsProject = CSharpHelpers.CreateCSharpCPSProject(environment, "Test")) + using (var cpsProject = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test")) { var project = environment.Workspace.CurrentSolution.Projects.Single(); var oldParseOptions = (CSharpParseOptions)project.ParseOptions; @@ -76,12 +77,12 @@ public void SetProperty_MaxSupportedLangVersion_CPS(LanguageVersion? maxSupporte } [WpfFact] - public void SetProperty_MaxSupportedLangVersion_CPS_NotSet() + public async Task SetProperty_MaxSupportedLangVersion_CPS_NotSet() { const LanguageVersion attemptedVersion = LanguageVersion.CSharp8; using (var environment = new TestEnvironment(typeof(CSharpParseOptionsChangingService))) - using (var cpsProject = CSharpHelpers.CreateCSharpCPSProject(environment, "Test")) + using (var cpsProject = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test")) { var project = environment.Workspace.CurrentSolution.Projects.Single(); var oldParseOptions = (CSharpParseOptions)project.ParseOptions; @@ -119,16 +120,16 @@ public void SetProperty_MaxSupportedLangVersion_CPS_NotSet() [InlineData("FALSE", "", false)] // Invalid values ignored [InlineData("Invalid", "INVALID", true)] - public void SetProperty_RunAnalyzersAndRunAnalyzersDuringLiveAnalysis(string runAnalyzers, string runAnalyzersDuringLiveAnalysis, bool expectedRunAnalyzers) + public async Task SetProperty_RunAnalyzersAndRunAnalyzersDuringLiveAnalysis(string runAnalyzers, string runAnalyzersDuringLiveAnalysis, bool expectedRunAnalyzers) { - TestCPSProject(); + await TestCPSProject(); TestLegacyProject(); return; - void TestCPSProject() + async Task TestCPSProject() { using var environment = new TestEnvironment(); - using var cpsProject = CSharpHelpers.CreateCSharpCPSProject(environment, "Test"); + using var cpsProject = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test"); cpsProject.SetProperty(AdditionalPropertyNames.RunAnalyzers, runAnalyzers); cpsProject.SetProperty(AdditionalPropertyNames.RunAnalyzersDuringLiveAnalysis, runAnalyzersDuringLiveAnalysis); diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/AnalyzersTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/AnalyzersTests.cs index 76b73d7b32722..3f7ff49c67ffa 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/AnalyzersTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/AnalyzersTests.cs @@ -6,6 +6,7 @@ using System.Collections.Immutable; using System.Linq; +using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Test.Utilities; @@ -20,7 +21,7 @@ public class AnalyzersTests : TestBase { [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void RuleSet_GeneralOption_CPS() + public async Task RuleSet_GeneralOption_CPS() { var ruleSetFile = Temp.CreateFile().WriteAllText( @" @@ -29,7 +30,7 @@ public void RuleSet_GeneralOption_CPS() "); using var environment = new TestEnvironment(); - using var project = CSharpHelpers.CreateCSharpCPSProject(environment, "Test"); + using var project = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test"); var workspaceProject = environment.Workspace.CurrentSolution.Projects.Single(); var options = (CSharpCompilationOptions)workspaceProject.CompilationOptions; @@ -45,7 +46,7 @@ public void RuleSet_GeneralOption_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void RuleSet_SpecificOptions_CPS() + public async Task RuleSet_SpecificOptions_CPS() { var ruleSetFile = Temp.CreateFile().WriteAllText( @" @@ -58,7 +59,7 @@ public void RuleSet_SpecificOptions_CPS() "); using var environment = new TestEnvironment(); - using var project = CSharpHelpers.CreateCSharpCPSProject(environment, "Test"); + using var project = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test"); // Verify SetRuleSetFile updates the ruleset. project.SetOptions(ImmutableArray.Create($"/ruleset:{ruleSetFile.Path}")); @@ -70,13 +71,13 @@ public void RuleSet_SpecificOptions_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void RuleSet_PathCanBeFound() + public async Task RuleSet_PathCanBeFound() { var ruleSetFile = Temp.CreateFile(); using var environment = new TestEnvironment(); ProjectId projectId; - using (var project = CSharpHelpers.CreateCSharpCPSProject(environment, "Test")) + using (var project = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test")) { project.SetOptions(ImmutableArray.Create($"/ruleset:{ruleSetFile.Path}")); diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpCompilerOptionsTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpCompilerOptionsTests.cs index 546ae7fcac829..5343f23a54cd9 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpCompilerOptionsTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpCompilerOptionsTests.cs @@ -8,6 +8,7 @@ using System.Collections.Immutable; using System.IO; using System.Linq; +using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.LanguageServices.ProjectSystem; @@ -23,30 +24,30 @@ public class CSharpCompilerOptionsTests : TestBase { [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void DocumentationModeSetToDiagnoseIfProducingDocFile_CPS() + public async Task DocumentationModeSetToDiagnoseIfProducingDocFile_CPS() { using var environment = new TestEnvironment(); - using var project = CSharpHelpers.CreateCSharpCPSProject(environment, "Test", commandLineArguments: @"/doc:DocFile.xml"); + using var project = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test", commandLineArguments: @"/doc:DocFile.xml"); var parseOptions = environment.Workspace.CurrentSolution.Projects.Single().ParseOptions; Assert.Equal(DocumentationMode.Diagnose, parseOptions.DocumentationMode); } [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void DocumentationModeSetToParseIfNotProducingDocFile_CPS() + public async Task DocumentationModeSetToParseIfNotProducingDocFile_CPS() { using var environment = new TestEnvironment(); - using var project = CSharpHelpers.CreateCSharpCPSProject(environment, "Test", commandLineArguments: @"/doc:"); + using var project = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test", commandLineArguments: @"/doc:"); var parseOptions = environment.Workspace.CurrentSolution.Projects.Single().ParseOptions; Assert.Equal(DocumentationMode.Parse, parseOptions.DocumentationMode); } [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ProjectSettingsOptionAddAndRemove_CPS() + public async Task ProjectSettingsOptionAddAndRemove_CPS() { using var environment = new TestEnvironment(); - using var project = CSharpHelpers.CreateCSharpCPSProject(environment, "Test", commandLineArguments: @"/warnaserror:CS1111"); + using var project = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test", commandLineArguments: @"/warnaserror:CS1111"); var options = environment.GetUpdatedCompilationOptionOfSingleProject(); Assert.Equal(expected: ReportDiagnostic.Error, actual: options.SpecificDiagnosticOptions["CS1111"]); @@ -57,13 +58,13 @@ public void ProjectSettingsOptionAddAndRemove_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ProjectOutputBinPathChange_CPS() + public async Task ProjectOutputBinPathChange_CPS() { var initialObjPath = @"C:\test.dll"; var initialBinPath = initialObjPath; using var environment = new TestEnvironment(); - using var project = CSharpHelpers.CreateCSharpCPSProject(environment, "Test", commandLineArguments: $"/out:{initialObjPath}"); + using var project = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test", commandLineArguments: $"/out:{initialObjPath}"); Assert.Equal(initialObjPath, project.CompilationOutputAssemblyFilePath); Assert.Equal(initialBinPath, project.BinOutputPath); @@ -101,42 +102,42 @@ public void ProjectOutputBinPathChange_CPS() [WpfFact, WorkItem(14520, "https://github.com/dotnet/roslyn/issues/14520")] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void InvalidProjectOutputBinPaths_CPS1() + public async Task InvalidProjectOutputBinPaths_CPS1() { using var environment = new TestEnvironment(); - using var project1 = CSharpHelpers.CreateCSharpCPSProject(environment, "Test", binOutputPath: null); + using var project1 = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test", binOutputPath: null); // Null output path is allowed. Assert.Null(project1.BinOutputPath); } [WpfFact, WorkItem(14520, "https://github.com/dotnet/roslyn/issues/14520")] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void InvalidProjectOutputBinPaths_CPS2() + public async Task InvalidProjectOutputBinPaths_CPS2() { using var environment = new TestEnvironment(); - using var project2 = CSharpHelpers.CreateCSharpCPSProject(environment, "Test2", binOutputPath: String.Empty); + using var project2 = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test2", binOutputPath: String.Empty); // Empty output path is not allowed, it gets reset to null. Assert.Null(project2.BinOutputPath); } [WpfFact, WorkItem(14520, "https://github.com/dotnet/roslyn/issues/14520")] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void InvalidProjectOutputBinPaths_CPS3() + public async Task InvalidProjectOutputBinPaths_CPS3() { using var environment = new TestEnvironment(); - using var project3 = CSharpHelpers.CreateCSharpCPSProject(environment, "Test3", binOutputPath: "Test.dll"); + using var project3 = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test3", binOutputPath: "Test.dll"); // Non-rooted output path is not allowed, it gets reset to a temp rooted path. Assert.Equal(Path.Combine(Path.GetTempPath(), "Test.dll"), project3.BinOutputPath); } [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ProjectGuidSetter_CPS() + public async Task ProjectGuidSetter_CPS() { var initialGuid = Guid.NewGuid(); using var environment = new TestEnvironment(); - using IWorkspaceProjectContext projectContext = CSharpHelpers.CreateCSharpCPSProject(environment, "Test", initialGuid); + using IWorkspaceProjectContext projectContext = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test", initialGuid); Assert.Equal(initialGuid, projectContext.Guid); var newGuid = Guid.NewGuid(); @@ -146,10 +147,10 @@ public void ProjectGuidSetter_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ProjectLastDesignTimeBuildSucceededSetter_CPS() + public async Task ProjectLastDesignTimeBuildSucceededSetter_CPS() { using var environment = new TestEnvironment(); - using IWorkspaceProjectContext projectContext = CSharpHelpers.CreateCSharpCPSProject(environment, "Test"); + using IWorkspaceProjectContext projectContext = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test"); Assert.True(projectContext.LastDesignTimeBuildSucceeded); projectContext.LastDesignTimeBuildSucceeded = false; @@ -158,10 +159,10 @@ public void ProjectLastDesignTimeBuildSucceededSetter_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ProjectDisplayNameSetter_CPS() + public async Task ProjectDisplayNameSetter_CPS() { using var environment = new TestEnvironment(); - using IWorkspaceProjectContext project = CSharpHelpers.CreateCSharpCPSProject(environment, "Test"); + using IWorkspaceProjectContext project = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test"); Assert.Equal("Test", project.DisplayName); var initialProjectFilePath = project.ProjectFilePath; @@ -174,10 +175,10 @@ public void ProjectDisplayNameSetter_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ProjectFilePathSetter_CPS() + public async Task ProjectFilePathSetter_CPS() { using var environment = new TestEnvironment(); - using IWorkspaceProjectContext project = CSharpHelpers.CreateCSharpCPSProject(environment, "Test"); + using IWorkspaceProjectContext project = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test"); var initialProjectDisplayName = project.DisplayName; var initialProjectFilePath = project.ProjectFilePath; var newFilePath = Temp.CreateFile().Path; diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpReferencesTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpReferencesTests.cs index 0b285610b2421..adf7124932402 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpReferencesTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpReferencesTests.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Test.Utilities; @@ -24,13 +25,13 @@ public class CSharpReferenceTests { [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void AddRemoveProjectAndMetadataReference_CPS() + public async Task AddRemoveProjectAndMetadataReference_CPS() { using var environment = new TestEnvironment(); - var project1 = CreateCSharpCPSProject(environment, "project1", commandLineArguments: @"/out:c:\project1.dll"); - var project2 = CreateCSharpCPSProject(environment, "project2", commandLineArguments: @"/out:c:\project2.dll"); - var project3 = CreateCSharpCPSProject(environment, "project3", commandLineArguments: @"/out:c:\project3.dll"); - var project4 = CreateCSharpCPSProject(environment, "project4"); + var project1 = await CreateCSharpCPSProjectAsync(environment, "project1", commandLineArguments: @"/out:c:\project1.dll"); + var project2 = await CreateCSharpCPSProjectAsync(environment, "project2", commandLineArguments: @"/out:c:\project2.dll"); + var project3 = await CreateCSharpCPSProjectAsync(environment, "project3", commandLineArguments: @"/out:c:\project3.dll"); + var project4 = await CreateCSharpCPSProjectAsync(environment, "project4"); // Add project reference project3.AddProjectReference(project1, new MetadataReferenceProperties()); @@ -90,11 +91,11 @@ IEnumerable GetProject3MetadataReferences() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void RemoveProjectConvertsProjectReferencesBack() + public async Task RemoveProjectConvertsProjectReferencesBack() { using var environment = new TestEnvironment(); - var project1 = CreateCSharpCPSProject(environment, "project1", commandLineArguments: @"/out:c:\project1.dll"); - var project2 = CreateCSharpCPSProject(environment, "project2"); + var project1 = await CreateCSharpCPSProjectAsync(environment, "project1", commandLineArguments: @"/out:c:\project1.dll"); + var project2 = await CreateCSharpCPSProjectAsync(environment, "project2"); // Add project reference as metadata reference: since this is known to be the output path of project1, the metadata reference is converted to a project reference project2.AddMetadataReference(@"c:\project1.dll", new MetadataReferenceProperties()); @@ -112,11 +113,11 @@ public void RemoveProjectConvertsProjectReferencesBack() [WorkItem(461967, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/461967")] [WorkItem(727173, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/727173")] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void AddingMetadataReferenceToProjectThatCannotCompileInTheIdeKeepsMetadataReference() + public async Task AddingMetadataReferenceToProjectThatCannotCompileInTheIdeKeepsMetadataReference() { using var environment = new TestEnvironment(typeof(NoCompilationLanguageServiceFactory)); - var project1 = CreateCSharpCPSProject(environment, "project1", commandLineArguments: @"/out:c:\project1.dll"); - var project2 = CreateNonCompilableProject(environment, "project2", @"C:\project2.fsproj"); + var project1 = await CreateCSharpCPSProjectAsync(environment, "project1", commandLineArguments: @"/out:c:\project1.dll"); + var project2 = await CreateNonCompilableProjectAsync(environment, "project2", @"C:\project2.fsproj"); project2.BinOutputPath = "c:\\project2.dll"; project1.AddMetadataReference(project2.BinOutputPath, MetadataReferenceProperties.Assembly); @@ -130,10 +131,10 @@ public void AddingMetadataReferenceToProjectThatCannotCompileInTheIdeKeepsMetada [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void AddRemoveAnalyzerReference_CPS() + public async Task AddRemoveAnalyzerReference_CPS() { using var environment = new TestEnvironment(); - using var project = CreateCSharpCPSProject(environment, "project1"); + using var project = await CreateCSharpCPSProjectAsync(environment, "project1"); // Add analyzer reference var analyzerAssemblyFullPath = @"c:\someAssembly.dll"; diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/EditAndContinueTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/EditAndContinueTests.cs index aed15aae56e7f..a10e5576e66f2 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/EditAndContinueTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/EditAndContinueTests.cs @@ -4,6 +4,7 @@ #nullable disable +using System.Threading.Tasks; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.LanguageServices.Implementation.EditAndContinue.Interop; using Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Framework; @@ -17,10 +18,10 @@ public class EditAndContinueTests { [WpfFact, WorkItem(31034, "https://github.com/dotnet/roslyn/issues/31034")] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void EditAndContinueInterfacesAreImplemented() + public async Task EditAndContinueInterfacesAreImplemented() { using var environment = new TestEnvironment(); - using var project = CSharpHelpers.CreateCSharpCPSProject(environment, "Test", binOutputPath: null); + using var project = await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test", binOutputPath: null); Assert.IsAssignableFrom(project); Assert.IsAssignableFrom(project); } diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/SourceFileHandlingTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/SourceFileHandlingTests.cs index 7177786d69c8d..7e76edaafcdf3 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/SourceFileHandlingTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/SourceFileHandlingTests.cs @@ -15,6 +15,7 @@ namespace Roslyn.VisualStudio.CSharp.UnitTests.ProjectSystemShim.CPS { using System.Collections.Generic; + using System.Threading.Tasks; using static CSharpHelpers; [UseExportProvider] @@ -22,10 +23,10 @@ public class SourceFileHandlingTests { [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void AddRemoveSourceFile_CPS() + public async Task AddRemoveSourceFile_CPS() { using var environment = new TestEnvironment(); - using var project = CreateCSharpCPSProject(environment, "project1"); + using var project = await CreateCSharpCPSProjectAsync(environment, "project1"); IEnumerable GetCurrentDocuments() => environment.Workspace.CurrentSolution.Projects.Single().Documents; Assert.Empty(GetCurrentDocuments()); @@ -42,10 +43,10 @@ public void AddRemoveSourceFile_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void AddRemoveAdditionalFile_CPS() + public async Task AddRemoveAdditionalFile_CPS() { using var environment = new TestEnvironment(); - using var project = CreateCSharpCPSProject(environment, "project1"); + using var project = await CreateCSharpCPSProjectAsync(environment, "project1"); IEnumerable GetCurrentAdditionalDocuments() => environment.Workspace.CurrentSolution.Projects.Single().AdditionalDocuments; Assert.Empty(GetCurrentAdditionalDocuments()); @@ -61,10 +62,10 @@ public void AddRemoveAdditionalFile_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ReorderSourceFiles_CPS() + public async Task ReorderSourceFiles_CPS() { using var environment = new TestEnvironment(); - using var project = CreateCSharpCPSProject(environment, "project1"); + using var project = await CreateCSharpCPSProjectAsync(environment, "project1"); IEnumerable GetCurrentDocuments() => environment.Workspace.CurrentSolution.Projects.Single().Documents; VersionStamp GetVersion() => environment.Workspace.CurrentSolution.Projects.Single().Version; @@ -112,10 +113,10 @@ public void ReorderSourceFiles_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ReorderSourceFilesBatch_CPS() + public async Task ReorderSourceFilesBatch_CPS() { using var environment = new TestEnvironment(); - using var project = CreateCSharpCPSProject(environment, "project1"); + using var project = await CreateCSharpCPSProjectAsync(environment, "project1"); IEnumerable GetCurrentDocuments() => environment.Workspace.CurrentSolution.Projects.Single().Documents; Assert.Empty(GetCurrentDocuments()); @@ -154,10 +155,10 @@ public void ReorderSourceFilesBatch_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ReorderSourceFilesBatchWithReAdding_CPS() + public async Task ReorderSourceFilesBatchWithReAdding_CPS() { using var environment = new TestEnvironment(); - using var project = CreateCSharpCPSProject(environment, "project1"); + using var project = await CreateCSharpCPSProjectAsync(environment, "project1"); IEnumerable GetCurrentDocuments() => environment.Workspace.CurrentSolution.Projects.Single().Documents; Assert.Empty(GetCurrentDocuments()); @@ -208,10 +209,10 @@ public void ReorderSourceFilesBatchWithReAdding_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ReorderSourceFilesBatchAddAfterReorder_CPS() + public async Task ReorderSourceFilesBatchAddAfterReorder_CPS() { using var environment = new TestEnvironment(); - using var project = CreateCSharpCPSProject(environment, "project1"); + using var project = await CreateCSharpCPSProjectAsync(environment, "project1"); IEnumerable GetCurrentDocuments() => environment.Workspace.CurrentSolution.Projects.Single().Documents; Assert.Empty(GetCurrentDocuments()); @@ -248,10 +249,10 @@ public void ReorderSourceFilesBatchAddAfterReorder_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ReorderSourceFilesBatchRemoveAfterReorder_CPS() + public async Task ReorderSourceFilesBatchRemoveAfterReorder_CPS() { using var environment = new TestEnvironment(); - using var project = CreateCSharpCPSProject(environment, "project1"); + using var project = await CreateCSharpCPSProjectAsync(environment, "project1"); IEnumerable GetCurrentDocuments() => environment.Workspace.CurrentSolution.Projects.Single().Documents; Assert.Empty(GetCurrentDocuments()); @@ -288,10 +289,10 @@ public void ReorderSourceFilesBatchRemoveAfterReorder_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ReorderSourceFilesExceptions_CPS() + public async Task ReorderSourceFilesExceptions_CPS() { using var environment = new TestEnvironment(); - using var project = CreateCSharpCPSProject(environment, "project1"); + using var project = await CreateCSharpCPSProjectAsync(environment, "project1"); IEnumerable GetCurrentDocuments() => environment.Workspace.CurrentSolution.Projects.Single().Documents; Assert.Empty(GetCurrentDocuments()); @@ -325,10 +326,10 @@ public void ReorderSourceFilesExceptions_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ReorderSourceFilesBatchExceptions_CPS() + public async Task ReorderSourceFilesBatchExceptions_CPS() { using var environment = new TestEnvironment(); - using var project = CreateCSharpCPSProject(environment, "project1"); + using var project = await CreateCSharpCPSProjectAsync(environment, "project1"); IEnumerable GetCurrentDocuments() => environment.Workspace.CurrentSolution.Projects.Single().Documents; Assert.Empty(GetCurrentDocuments()); @@ -375,10 +376,10 @@ public void ReorderSourceFilesBatchExceptions_CPS() [WpfFact] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] - public void ReorderSourceFilesBatchExceptionRemoveFile_CPS() + public async Task ReorderSourceFilesBatchExceptionRemoveFile_CPS() { using var environment = new TestEnvironment(); - using var project = CreateCSharpCPSProject(environment, "project1"); + using var project = await CreateCSharpCPSProjectAsync(environment, "project1"); IEnumerable GetCurrentDocuments() => environment.Workspace.CurrentSolution.Projects.Single().Documents; Assert.Empty(GetCurrentDocuments()); diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CSharpHelpers.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CSharpHelpers.cs index c6957d764465d..41bc80f793c64 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CSharpHelpers.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CSharpHelpers.cs @@ -9,6 +9,8 @@ using System.Collections.Immutable; using System.IO; using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Host; @@ -44,23 +46,23 @@ public static CSharpProjectShim CreateCSharpProject(TestEnvironment environment, threadingContext: environment.ThreadingContext); } - public static CPSProject CreateCSharpCPSProject(TestEnvironment environment, string projectName, params string[] commandLineArguments) + public static Task CreateCSharpCPSProjectAsync(TestEnvironment environment, string projectName, params string[] commandLineArguments) { - return CreateCSharpCPSProject(environment, projectName, projectGuid: Guid.NewGuid(), commandLineArguments: commandLineArguments); + return CreateCSharpCPSProjectAsync(environment, projectName, projectGuid: Guid.NewGuid(), commandLineArguments: commandLineArguments); } - public static CPSProject CreateCSharpCPSProject(TestEnvironment environment, string projectName, Guid projectGuid, params string[] commandLineArguments) + public static Task CreateCSharpCPSProjectAsync(TestEnvironment environment, string projectName, Guid projectGuid, params string[] commandLineArguments) { var projectFilePath = Path.GetTempPath(); var binOutputPath = GetOutputPathFromArguments(commandLineArguments) ?? Path.Combine(projectFilePath, projectName + ".dll"); - return CreateCSharpCPSProject(environment, projectName, projectFilePath, binOutputPath, projectGuid, commandLineArguments); + return CreateCSharpCPSProjectAsync(environment, projectName, projectFilePath, binOutputPath, projectGuid, commandLineArguments); } - public static CPSProject CreateCSharpCPSProject(TestEnvironment environment, string projectName, string binOutputPath, params string[] commandLineArguments) + public static Task CreateCSharpCPSProjectAsync(TestEnvironment environment, string projectName, string binOutputPath, params string[] commandLineArguments) { var projectFilePath = Path.GetTempPath(); - return CreateCSharpCPSProject(environment, projectName, projectFilePath, binOutputPath, projectGuid: Guid.NewGuid(), commandLineArguments: commandLineArguments); + return CreateCSharpCPSProjectAsync(environment, projectName, projectFilePath, binOutputPath, projectGuid: Guid.NewGuid(), commandLineArguments: commandLineArguments); } public static unsafe void SetOption(this CSharpProjectShim csharpProject, CompilerOptions optionID, object value) @@ -73,35 +75,37 @@ public static unsafe void SetOption(this CSharpProjectShim csharpProject, Compil csharpProject.SetOption(optionID, variant); } - public static CPSProject CreateCSharpCPSProject(TestEnvironment environment, string projectName, string projectFilePath, string binOutputPath, Guid projectGuid, params string[] commandLineArguments) + public static async Task CreateCSharpCPSProjectAsync(TestEnvironment environment, string projectName, string projectFilePath, string binOutputPath, Guid projectGuid, params string[] commandLineArguments) { var hierarchy = environment.CreateHierarchy(projectName, binOutputPath, projectRefPath: null, "CSharp"); var cpsProjectFactory = environment.ExportProvider.GetExportedValue(); - var cpsProject = (CPSProject)cpsProjectFactory.CreateProjectContext( + var cpsProject = (CPSProject)await cpsProjectFactory.CreateProjectContextAsync( LanguageNames.CSharp, projectName, projectFilePath, projectGuid, hierarchy, - binOutputPath); + binOutputPath, + CancellationToken.None); cpsProject.SetOptions(ImmutableArray.Create(commandLineArguments)); return cpsProject; } - public static CPSProject CreateNonCompilableProject(TestEnvironment environment, string projectName, string projectFilePath) + public static async Task CreateNonCompilableProjectAsync(TestEnvironment environment, string projectName, string projectFilePath) { var hierarchy = environment.CreateHierarchy(projectName, projectBinPath: null, projectRefPath: null, ""); var cpsProjectFactory = environment.ExportProvider.GetExportedValue(); - return (CPSProject)cpsProjectFactory.CreateProjectContext( + return (CPSProject)await cpsProjectFactory.CreateProjectContextAsync( NoCompilationConstants.LanguageName, projectName, projectFilePath, Guid.NewGuid(), hierarchy, - binOutputPath: null); + binOutputPath: null, + CancellationToken.None); } private static string GetOutputPathFromArguments(string[] commandLineArguments) diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/AnalyzersTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/AnalyzersTests.cs index c43167cb985c5..5baa5ff3218d9 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/AnalyzersTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/AnalyzersTests.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Shared.TestHooks; @@ -230,7 +231,7 @@ public void RuleSet_ProjectNoWarnOverridesOtherSettings() [CombinatorialData] [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)] [WorkItem(33505, "https://github.com/dotnet/roslyn/pull/33505")] - public void RuleSet_FileChangingOnDiskRefreshes(bool useCpsProject) + public async Task RuleSet_FileChangingOnDiskRefreshes(bool useCpsProject) { var ruleSetSource = @" @@ -243,7 +244,7 @@ public void RuleSet_FileChangingOnDiskRefreshes(bool useCpsProject) using var environment = new TestEnvironment(); if (useCpsProject) { - CSharpHelpers.CreateCSharpCPSProject(environment, "Test", binOutputPath: null, $"/ruleset:\"{ruleSetFile.Path}\""); + await CSharpHelpers.CreateCSharpCPSProjectAsync(environment, "Test", binOutputPath: null, $"/ruleset:\"{ruleSetFile.Path}\""); } else { diff --git a/src/VisualStudio/Core/Def/ExternalAccess/VSTypeScript/Api/IVsTypeScriptVisualStudioProjectFactory.cs b/src/VisualStudio/Core/Def/ExternalAccess/VSTypeScript/Api/IVsTypeScriptVisualStudioProjectFactory.cs index 333e0bfd49889..9d46bafa11ea6 100644 --- a/src/VisualStudio/Core/Def/ExternalAccess/VSTypeScript/Api/IVsTypeScriptVisualStudioProjectFactory.cs +++ b/src/VisualStudio/Core/Def/ExternalAccess/VSTypeScript/Api/IVsTypeScriptVisualStudioProjectFactory.cs @@ -3,12 +3,17 @@ // See the LICENSE file in the project root for more information. using System; +using System.Threading; +using System.Threading.Tasks; using Microsoft.VisualStudio.Shell.Interop; namespace Microsoft.VisualStudio.LanguageServices.ExternalAccess.VSTypeScript.Api { internal interface IVsTypeScriptVisualStudioProjectFactory { + [Obsolete("Use CreateAndAddToWorkspaceAsync instead")] VSTypeScriptVisualStudioProjectWrapper CreateAndAddToWorkspace(string projectSystemName, string language, string projectFilePath, IVsHierarchy hierarchy, Guid projectGuid); + + ValueTask CreateAndAddToWorkspaceAsync(string projectSystemName, string language, string projectFilePath, IVsHierarchy hierarchy, Guid projectGuid, CancellationToken cancellationToken); } } diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/CPS/IWorkspaceProjectContext.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/CPS/IWorkspaceProjectContext.cs index 98d4fdf4c1f60..7ad681fccd36c 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/CPS/IWorkspaceProjectContext.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/CPS/IWorkspaceProjectContext.cs @@ -12,8 +12,12 @@ namespace Microsoft.VisualStudio.LanguageServices.ProjectSystem { /// - /// Project context to initialize properties and items of a Workspace project created with . + /// Project context to initialize properties and items of a Workspace project created with . /// + /// + /// is safe to call on instances of this type on any thread. + /// internal interface IWorkspaceProjectContext : IDisposable { // Project properties. diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/CPS/IWorkspaceProjectContextFactory.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/CPS/IWorkspaceProjectContextFactory.cs index a0620feb73b59..240a399223658 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/CPS/IWorkspaceProjectContextFactory.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/CPS/IWorkspaceProjectContextFactory.cs @@ -5,7 +5,8 @@ #nullable disable using System; -using Microsoft.VisualStudio.LanguageServices.Implementation.TaskList; +using System.Threading; +using System.Threading.Tasks; namespace Microsoft.VisualStudio.LanguageServices.ProjectSystem { @@ -14,8 +15,15 @@ namespace Microsoft.VisualStudio.LanguageServices.ProjectSystem /// internal interface IWorkspaceProjectContextFactory { + /// + [Obsolete("Use CreateProjectContextAsync instead")] + IWorkspaceProjectContext CreateProjectContext(string languageName, string projectUniqueName, string projectFilePath, Guid projectGuid, object hierarchy, string binOutputPath); + /// - /// Creates and initializes a new Workspace project and returns a to lazily initialize the properties and items for the project. + /// Creates and initializes a new Workspace project and returns a to lazily initialize the properties and items for the + /// project. This method guarantees that either the project is added (and the returned task + /// completes) or cancellation is observed and no project is added. /// /// Project language. /// Unique name for the project. @@ -23,6 +31,6 @@ internal interface IWorkspaceProjectContextFactory /// Project guid. /// Obsolete. The argument is ignored. /// Initial project binary output path. - IWorkspaceProjectContext CreateProjectContext(string languageName, string projectUniqueName, string projectFilePath, Guid projectGuid, object hierarchy, string binOutputPath); + Task CreateProjectContextAsync(string languageName, string projectUniqueName, string projectFilePath, Guid projectGuid, object hierarchy, string binOutputPath, CancellationToken cancellationToken); } } diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/Legacy/AbstractLegacyProject.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/Legacy/AbstractLegacyProject.cs index 1bf839efd0d89..1f1a2d0c107e7 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/Legacy/AbstractLegacyProject.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/Legacy/AbstractLegacyProject.cs @@ -9,6 +9,7 @@ using System.Collections.Immutable; using System.IO; using System.Linq; +using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.VisualStudio.ComponentModelHost; @@ -101,7 +102,7 @@ public AbstractLegacyProject( } var projectFactory = componentModel.GetService(); - VisualStudioProject = projectFactory.CreateAndAddToWorkspace( + VisualStudioProject = threadingContext.JoinableTaskFactory.Run(() => projectFactory.CreateAndAddToWorkspaceAsync( projectSystemName, language, new VisualStudioProjectCreationInfo @@ -112,7 +113,8 @@ public AbstractLegacyProject( FilePath = projectFilePath, Hierarchy = hierarchy, ProjectGuid = GetProjectIDGuid(hierarchy), - }); + }, + CancellationToken.None)); workspaceImpl.AddProjectRuleSetFileToInternalMaps( VisualStudioProject, diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProjectFactory.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProjectFactory.cs index 777dcb5a8ba57..e1f2038048348 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProjectFactory.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProjectFactory.cs @@ -7,13 +7,18 @@ using System.Collections.Immutable; using System.ComponentModel.Composition; using System.IO; +using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.VisualStudio.LanguageServices.ExternalAccess.VSTypeScript.Api; using Microsoft.VisualStudio.LanguageServices.Implementation.TaskList; +using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Telemetry; +using Microsoft.VisualStudio.Threading; namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem { @@ -24,32 +29,53 @@ internal sealed class VisualStudioProjectFactory : IVsTypeScriptVisualStudioProj private const string SolutionContextName = "Solution"; private const string SolutionSessionIdPropertyName = "SolutionSessionID"; + private readonly IThreadingContext _threadingContext; private readonly VisualStudioWorkspaceImpl _visualStudioWorkspaceImpl; - private readonly HostDiagnosticUpdateSource _hostDiagnosticUpdateSource; private readonly ImmutableArray> _dynamicFileInfoProviders; + private readonly HostDiagnosticUpdateSource _hostDiagnosticUpdateSource; + private readonly Shell.IAsyncServiceProvider _serviceProvider; [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public VisualStudioProjectFactory( + IThreadingContext threadingContext, VisualStudioWorkspaceImpl visualStudioWorkspaceImpl, [ImportMany] IEnumerable> fileInfoProviders, - HostDiagnosticUpdateSource hostDiagnosticUpdateSource) + HostDiagnosticUpdateSource hostDiagnosticUpdateSource, + SVsServiceProvider serviceProvider) { + _threadingContext = threadingContext; _visualStudioWorkspaceImpl = visualStudioWorkspaceImpl; _dynamicFileInfoProviders = fileInfoProviders.AsImmutableOrEmpty(); _hostDiagnosticUpdateSource = hostDiagnosticUpdateSource; + _serviceProvider = (Shell.IAsyncServiceProvider)serviceProvider; } - public VisualStudioProject CreateAndAddToWorkspace(string projectSystemName, string language) - => CreateAndAddToWorkspace(projectSystemName, language, new VisualStudioProjectCreationInfo()); + public Task CreateAndAddToWorkspaceAsync(string projectSystemName, string language, CancellationToken cancellationToken) + => CreateAndAddToWorkspaceAsync(projectSystemName, language, new VisualStudioProjectCreationInfo(), cancellationToken); - public VisualStudioProject CreateAndAddToWorkspace(string projectSystemName, string language, VisualStudioProjectCreationInfo creationInfo) + public async Task CreateAndAddToWorkspaceAsync( + string projectSystemName, string language, VisualStudioProjectCreationInfo creationInfo, CancellationToken cancellationToken) { - // HACK: Fetch this service to ensure it's still created on the UI thread; once this is moved off we'll need to fix up it's constructor to be free-threaded. + // HACK: Fetch this service to ensure it's still created on the UI thread; once this is + // moved off we'll need to fix up it's constructor to be free-threaded. + + await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); _visualStudioWorkspaceImpl.Services.GetRequiredService(); - // HACK: since we're on the UI thread, ensure we initialize our options provider which depends on a UI-affinitized experimentation service - _visualStudioWorkspaceImpl.EnsureDocumentOptionProvidersInitialized(); + // Since we're on the UI thread here anyways, use that as an opportunity to grab the + // IVsSolution object and solution file path. + // + // ConfigureAwait(true) as we have to come back to the UI thread to do the cast to IVsSolution2. + var solution = (IVsSolution2?)await _serviceProvider.GetServiceAsync(typeof(SVsSolution)).ConfigureAwait(true); + var solutionFilePath = solution != null && ErrorHandler.Succeeded(solution.GetSolutionInfo(out _, out var filePath, out _)) + ? filePath + : null; + + await _visualStudioWorkspaceImpl.EnsureDocumentOptionProvidersInitializedAsync(cancellationToken).ConfigureAwait(true); + + // From this point on, we start mutating the solution. So make us non cancellable. + cancellationToken = CancellationToken.None; var id = ProjectId.CreateNewId(projectSystemName); var assemblyName = creationInfo.AssemblyName ?? projectSystemName; @@ -88,18 +114,6 @@ public VisualStudioProject CreateAndAddToWorkspace(string projectSystemName, str // If we don't have any projects and this is our first project being added, then we'll create a new SolutionId if (w.CurrentSolution.ProjectIds.Count == 0) { - // Fetch the current solution path. Since we're on the UI thread right now, we can do that. - string? solutionFilePath = null; - var solution = (IVsSolution)Shell.ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution)); - if (solution != null) - { - if (ErrorHandler.Failed(solution.GetSolutionInfo(out _, out solutionFilePath, out _))) - { - // Paranoia: if the call failed, we definitely don't want to use any stuff that was set - solutionFilePath = null; - } - } - var solutionSessionId = GetSolutionSessionId(); w.OnSolutionAdded( @@ -134,6 +148,13 @@ static Guid GetSolutionSessionId() } VSTypeScriptVisualStudioProjectWrapper IVsTypeScriptVisualStudioProjectFactory.CreateAndAddToWorkspace(string projectSystemName, string language, string projectFilePath, IVsHierarchy hierarchy, Guid projectGuid) + { + return _threadingContext.JoinableTaskFactory.Run(async () => + await ((IVsTypeScriptVisualStudioProjectFactory)this).CreateAndAddToWorkspaceAsync(projectSystemName, language, projectFilePath, hierarchy, projectGuid, CancellationToken.None).ConfigureAwait(false)); + } + + async ValueTask IVsTypeScriptVisualStudioProjectFactory.CreateAndAddToWorkspaceAsync( + string projectSystemName, string language, string projectFilePath, IVsHierarchy hierarchy, Guid projectGuid, CancellationToken cancellationToken) { var projectInfo = new VisualStudioProjectCreationInfo { @@ -141,7 +162,7 @@ VSTypeScriptVisualStudioProjectWrapper IVsTypeScriptVisualStudioProjectFactory.C Hierarchy = hierarchy, ProjectGuid = projectGuid, }; - var visualStudioProject = this.CreateAndAddToWorkspace(projectSystemName, language, projectInfo); + var visualStudioProject = await this.CreateAndAddToWorkspaceAsync(projectSystemName, language, projectInfo, cancellationToken).ConfigureAwait(false); return new VSTypeScriptVisualStudioProjectWrapper(visualStudioProject); } } diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProjectTracker.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProjectTracker.cs index 825db6828eae9..eaeaa45573cbb 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProjectTracker.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProjectTracker.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host; @@ -133,7 +134,8 @@ public void AddProject(AbstractProject project) Hierarchy = project.Hierarchy, ProjectGuid = project.Guid, }; - project.VisualStudioProject = _projectFactory.CreateAndAddToWorkspace(project.ProjectSystemName, project.Language, creationInfo); + project.VisualStudioProject = this.ThreadingContext.JoinableTaskFactory.Run(() => _projectFactory.CreateAndAddToWorkspaceAsync( + project.ProjectSystemName, project.Language, creationInfo, CancellationToken.None)); project.UpdateVisualStudioProjectProperties(); } else diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs index 5e8ceeea3af5d..d3b5d3085a399 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs @@ -1615,6 +1615,7 @@ protected internal override void OnProjectRemoved(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 => { await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); @@ -1968,8 +1969,12 @@ private void RefreshMetadataReferencesForFile(object sender, string fullFilePath } } - internal void EnsureDocumentOptionProvidersInitialized() + internal async Task EnsureDocumentOptionProvidersInitializedAsync(CancellationToken cancellationToken) { + // HACK: switch to the UI thread, ensure we initialize our options provider which depends on a + // UI-affinitized experimentation service + await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + _foregroundObject.AssertIsForeground(); if (_documentOptionsProvidersInitialized) diff --git a/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProjectFactory.cs b/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProjectFactory.cs index a532508ad2299..5857e66907340 100644 --- a/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProjectFactory.cs +++ b/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProjectFactory.cs @@ -5,14 +5,13 @@ #nullable disable using System; -using System.Collections.Generic; -using System.Collections.Immutable; using System.ComponentModel.Composition; -using System.IO; +using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel; -using Microsoft.VisualStudio.LanguageServices.Implementation.TaskList; using Microsoft.VisualStudio.LanguageServices.ProjectSystem; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; @@ -22,56 +21,71 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.C [Export(typeof(IWorkspaceProjectContextFactory))] internal partial class CPSProjectFactory : IWorkspaceProjectContextFactory { + private readonly IThreadingContext _threadingContext; private readonly VisualStudioProjectFactory _projectFactory; private readonly VisualStudioWorkspaceImpl _workspace; private readonly IProjectCodeModelFactory _projectCodeModelFactory; + private readonly Shell.IAsyncServiceProvider _serviceProvider; [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public CPSProjectFactory( + IThreadingContext threadingContext, VisualStudioProjectFactory projectFactory, VisualStudioWorkspaceImpl workspace, - IProjectCodeModelFactory projectCodeModelFactory) + IProjectCodeModelFactory projectCodeModelFactory, + SVsServiceProvider serviceProvider) { + _threadingContext = threadingContext; _projectFactory = projectFactory; _workspace = workspace; _projectCodeModelFactory = projectCodeModelFactory; + _serviceProvider = (Shell.IAsyncServiceProvider)serviceProvider; } - IWorkspaceProjectContext IWorkspaceProjectContextFactory.CreateProjectContext( + IWorkspaceProjectContext IWorkspaceProjectContextFactory.CreateProjectContext(string languageName, string projectUniqueName, string projectFilePath, Guid projectGuid, object hierarchy, string binOutputPath) + { + return _threadingContext.JoinableTaskFactory.Run(() => + this.CreateProjectContextAsync(languageName, projectUniqueName, projectFilePath, projectGuid, hierarchy, binOutputPath, CancellationToken.None)); + } + + public async Task CreateProjectContextAsync( string languageName, string projectUniqueName, string projectFilePath, Guid projectGuid, object hierarchy, - string binOutputPath) + string binOutputPath, + CancellationToken cancellationToken) { - var visualStudioProject = CreateVisualStudioProject(languageName, projectUniqueName, projectFilePath, hierarchy as IVsHierarchy, projectGuid); - return new CPSProject(visualStudioProject, _workspace, _projectCodeModelFactory, projectGuid, binOutputPath); - } + await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(); - private VisualStudioProject CreateVisualStudioProject(string languageName, string projectUniqueName, string projectFilePath, IVsHierarchy hierarchy, Guid projectGuid) - { var creationInfo = new VisualStudioProjectCreationInfo { FilePath = projectFilePath, - Hierarchy = hierarchy, + Hierarchy = hierarchy as IVsHierarchy, ProjectGuid = projectGuid, }; - var visualStudioProject = _projectFactory.CreateAndAddToWorkspace(projectUniqueName, languageName, creationInfo); + var visualStudioProject = await _projectFactory.CreateAndAddToWorkspaceAsync( + projectUniqueName, languageName, creationInfo, cancellationToken).ConfigureAwait(true); + + // At this point we've mutated the workspace. So we're no longer cancellable. + cancellationToken = CancellationToken.None; if (languageName == LanguageNames.FSharp) { - var shell = (IVsShell)ServiceProvider.GlobalProvider.GetService(typeof(SVsShell)); + var shell = await _serviceProvider.GetServiceAsync().ConfigureAwait(true); // Force the F# package to load; this is necessary because the F# package listens to WorkspaceChanged to // set up some items, and the F# project system doesn't guarantee that the F# package has been loaded itself // so we're caught in the middle doing this. - shell.LoadPackage(Guids.FSharpPackageId, out _); + var packageId = Guids.FSharpPackageId; + await shell.LoadPackageAsync(ref packageId); } - return visualStudioProject; + // CPSProject constructor has a UI thread dependencies currently, so switch back to the UI thread before proceeding. + return new CPSProject(visualStudioProject, _workspace, _projectCodeModelFactory, projectGuid, binOutputPath); } } } diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/DynamicFileTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/DynamicFileTests.vb index 446f6f3169d40..cf7b9d1a935db 100644 --- a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/DynamicFileTests.vb +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/DynamicFileTests.vb @@ -6,7 +6,6 @@ Imports System.Collections.Immutable Imports System.Threading Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.CodeAnalysis.UnitTests Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Framework Imports Roslyn.Test.Utilities @@ -14,11 +13,10 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim <[UseExportProvider]> Public Class DynamicFileTests - Public Sub AddAndRemoveFileWhenDynamicFileInfoProviderProducesNothing() + Public Async Function AddAndRemoveFileWhenDynamicFileInfoProviderProducesNothing() As Task Using environment = New TestEnvironment(GetType(TestDynamicFileInfoProviderThatProducesNoFiles)) - Dim project = environment.ProjectFactory.CreateAndAddToWorkspace( - "project", - LanguageNames.CSharp) + Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project", LanguageNames.CSharp, CancellationToken.None) Const DynamicFileName As String = "DynamicFile.cshtml" @@ -26,14 +24,13 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim project.RemoveDynamicSourceFile(DynamicFileName) End Using - End Sub + End Function - Public Sub AddAndRemoveFileWhenDynamicFileInfoProviderProducesSomething() + Public Async Function AddAndRemoveFileWhenDynamicFileInfoProviderProducesSomething() As Task Using environment = New TestEnvironment(GetType(TestDynamicFileInfoProviderThatProducesFiles)) - Dim project = environment.ProjectFactory.CreateAndAddToWorkspace( - "project", - LanguageNames.CSharp) + Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project", LanguageNames.CSharp, CancellationToken.None) Const DynamicFileName As String = "DynamicFile.cshtml" @@ -49,14 +46,13 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Assert.Empty(environment.Workspace.CurrentSolution.Projects.Single().Documents) End Using - End Sub + End Function - Public Sub AddAndRemoveFileAndAddAgain() + Public Async Function AddAndRemoveFileAndAddAgain() As Task Using environment = New TestEnvironment(GetType(TestDynamicFileInfoProviderThatProducesFiles)) - Dim project = environment.ProjectFactory.CreateAndAddToWorkspace( - "project", - LanguageNames.CSharp) + Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project", LanguageNames.CSharp, CancellationToken.None) Const DynamicFileName As String = "DynamicFile.cshtml" @@ -66,14 +62,13 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim project.AddDynamicSourceFile(DynamicFileName, ImmutableArray(Of String).Empty) End Using - End Sub + End Function - Public Sub AddAndRemoveExtensionlessFile() + Public Async Function AddAndRemoveExtensionlessFile() As Task Using environment = New TestEnvironment(GetType(TestDynamicFileInfoProviderThatProducesFiles)) - Dim project = environment.ProjectFactory.CreateAndAddToWorkspace( - "project", - LanguageNames.CSharp) + Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project", LanguageNames.CSharp, CancellationToken.None) Const DynamicFileName As String = "DynamicFile" @@ -85,7 +80,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Assert.Empty(environment.Workspace.CurrentSolution.Projects.Single().Documents) End Using - End Sub + End Function End Class End Namespace diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/MetadataToProjectReferenceConversionTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/MetadataToProjectReferenceConversionTests.vb index 762b633f31592..ab86519a9eb61 100644 --- a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/MetadataToProjectReferenceConversionTests.vb +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/MetadataToProjectReferenceConversionTests.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports System.Collections.Immutable +Imports System.Threading Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Framework @@ -13,15 +14,13 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Public Class MetadataToProjectReferenceConversionTests - Public Sub ProjectReferenceConvertedToMetadataReferenceCanBeRemoved() + Public Async Function ProjectReferenceConvertedToMetadataReferenceCanBeRemoved() As Task Using environment = New TestEnvironment() - Dim project1 = environment.ProjectFactory.CreateAndAddToWorkspace( - "project1", - LanguageNames.CSharp) + Dim project1 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project1", LanguageNames.CSharp, CancellationToken.None) - Dim project2 = environment.ProjectFactory.CreateAndAddToWorkspace( - "project2", - LanguageNames.CSharp) + Dim project2 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project2", LanguageNames.CSharp, CancellationToken.None) Const ReferencePath = "C:\project1.dll" project1.OutputFilePath = ReferencePath @@ -39,15 +38,17 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim project2.RemoveMetadataReference(ReferencePath, MetadataReferenceProperties.Assembly) End Using - End Sub + End Function - Public Sub TwoProjectsProducingSameOutputPathBehavesCorrectly() + Public Async Function TwoProjectsProducingSameOutputPathBehavesCorrectly() As Task Using environment = New TestEnvironment() - Dim referencingProject = environment.ProjectFactory.CreateAndAddToWorkspace("referencingProject", LanguageNames.CSharp) + Dim referencingProject = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "referencingProject", LanguageNames.CSharp, CancellationToken.None) - Dim project1 = environment.ProjectFactory.CreateAndAddToWorkspace("project1", LanguageNames.CSharp) + Dim project1 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project1", LanguageNames.CSharp, CancellationToken.None) ' First: have a single project producing this DLL, and ensure we wired up correctly Const ReferencePath = "C:\project1.dll" @@ -61,7 +62,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim ' Create a second project referencing this same DLL. By rule, we now don't know which project to reference, so we just convert back to ' a file reference because something is screwed up. - Dim project2 = environment.ProjectFactory.CreateAndAddToWorkspace("project2", LanguageNames.CSharp) + Dim project2 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project2", LanguageNames.CSharp, CancellationToken.None) project2.OutputFilePath = ReferencePath Assert.Empty(getReferencingProject().ProjectReferences) @@ -73,14 +75,16 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Assert.Equal(project2.Id, Assert.Single(getReferencingProject().ProjectReferences).ProjectId) Assert.Empty(getReferencingProject().MetadataReferences) End Using - End Sub + End Function - Public Sub TwoProjectsProducingSameOutputPathAndIntermediateOutputBehavesCorrectly() + Public Async Function TwoProjectsProducingSameOutputPathAndIntermediateOutputBehavesCorrectly() As Task Using environment = New TestEnvironment() - Dim referencingProject = environment.ProjectFactory.CreateAndAddToWorkspace("referencingProject", LanguageNames.CSharp) + Dim referencingProject = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "referencingProject", LanguageNames.CSharp, CancellationToken.None) - Dim project1 = environment.ProjectFactory.CreateAndAddToWorkspace("project1", LanguageNames.CSharp) + Dim project1 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project1", LanguageNames.CSharp, CancellationToken.None) ' First: have a single project producing this DLL, and ensure we wired up correctly Const ReferencePath = "C:\project1.dll" @@ -94,7 +98,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim ' Create a second project referencing this same DLL. We'll make this one even more complicated by using the same path for both the ' regular OutputFilePath and the IntermediateOutputFilePath - Dim project2 = environment.ProjectFactory.CreateAndAddToWorkspace("project2", LanguageNames.CSharp) + Dim project2 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project2", LanguageNames.CSharp, CancellationToken.None) project2.CompilationOutputAssemblyFilePath = ReferencePath project2.OutputFilePath = ReferencePath @@ -107,18 +112,18 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Assert.Equal(project2.Id, Assert.Single(getReferencingProject().ProjectReferences).ProjectId) Assert.Empty(getReferencingProject().MetadataReferences) End Using - End Sub + End Function ' This is a test for a potential race between two operations; with 20 iterations on my machine either all would fail ' or one might pass, it seems the race is easy enough to hit without the fix. #Disable Warning IDE0060 ' Remove unused parameter - used for test iterations. - Public Sub ProjectBeingAddedWhileOutputPathBeingUpdatedDoesNotRace( iteration As Integer) + Public Async Function ProjectBeingAddedWhileOutputPathBeingUpdatedDoesNotRace( iteration As Integer) As Task #Enable Warning IDE0060 ' Remove unused parameter Using environment = New TestEnvironment() - Dim referencingProject = environment.ProjectFactory.CreateAndAddToWorkspace("referencingProject", LanguageNames.CSharp) - Dim referencedProject = environment.ProjectFactory.CreateAndAddToWorkspace("referencedProject", LanguageNames.CSharp) + Dim referencingProject = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("referencingProject", LanguageNames.CSharp, CancellationToken.None) + Dim referencedProject = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("referencedProject", LanguageNames.CSharp, CancellationToken.None) ' First: have a single project producing this DLL, and ensure we wired up correctly Const ReferencePath = "C:\project.dll" @@ -139,13 +144,13 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Task.WaitAll(task1, task2) End Using - End Sub + End Function - Public Sub AddingAndRemovingTwoReferencesWithDifferentPropertiesConvertsCorrectly() + Public Async Function AddingAndRemovingTwoReferencesWithDifferentPropertiesConvertsCorrectly() As Task Using environment = New TestEnvironment() - Dim referencingProject = environment.ProjectFactory.CreateAndAddToWorkspace("referencingProject", LanguageNames.CSharp) - Dim referencedProject = environment.ProjectFactory.CreateAndAddToWorkspace("referencedProject", LanguageNames.CSharp) + Dim referencingProject = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("referencingProject", LanguageNames.CSharp, CancellationToken.None) + Dim referencedProject = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("referencedProject", LanguageNames.CSharp, CancellationToken.None) Const ReferencePath = "C:\project.dll" referencingProject.AddMetadataReference(ReferencePath, New MetadataReferenceProperties(aliases:=ImmutableArray.Create("alias1"))) @@ -169,14 +174,14 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Assert.Empty(getReferencingProject().ProjectReferences) End Using - End Sub + End Function - Public Sub MetadataReferenceBeingAddedWhileOutputPathUpdateInInterleavedBatches(closeReferencedProjectBatchFirst As Boolean) + Public Async Function MetadataReferenceBeingAddedWhileOutputPathUpdateInInterleavedBatches(closeReferencedProjectBatchFirst As Boolean) As Task Using environment = New TestEnvironment() - Dim referencingProject = environment.ProjectFactory.CreateAndAddToWorkspace("referencingProject", LanguageNames.CSharp) - Dim referencedProject = environment.ProjectFactory.CreateAndAddToWorkspace("referencedProject", LanguageNames.CSharp) + Dim referencingProject = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("referencingProject", LanguageNames.CSharp, CancellationToken.None) + Dim referencedProject = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("referencedProject", LanguageNames.CSharp, CancellationToken.None) Dim referencingProjectBatch = referencingProject.CreateBatchScope() Dim referencedProjectBatch = referencedProject.CreateBatchScope() @@ -201,14 +206,14 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Assert.Single(getReferencingProject().ProjectReferences) Assert.Empty(getReferencingProject().MetadataReferences) End Using - End Sub + End Function - Public Sub MetadataReferenceBeingRemovedAndReAddedWhileOutputPathUpdateInInterleavedBatches(closeReferencedProjectBatchFirst As Boolean) + Public Async Function MetadataReferenceBeingRemovedAndReAddedWhileOutputPathUpdateInInterleavedBatches(closeReferencedProjectBatchFirst As Boolean) As Task Using environment = New TestEnvironment() - Dim referencingProject = environment.ProjectFactory.CreateAndAddToWorkspace("referencingProject", LanguageNames.CSharp) - Dim referencedProject = environment.ProjectFactory.CreateAndAddToWorkspace("referencedProject", LanguageNames.CSharp) + Dim referencingProject = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("referencingProject", LanguageNames.CSharp, CancellationToken.None) + Dim referencedProject = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("referencedProject", LanguageNames.CSharp, CancellationToken.None) Const ReferencePath = "C:\project.dll" referencingProject.AddMetadataReference(ReferencePath, MetadataReferenceProperties.Assembly.WithAliases(ImmutableArray.Create("temporary"))) @@ -235,15 +240,15 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Assert.Single(getReferencingProject().ProjectReferences) Assert.Empty(getReferencingProject().MetadataReferences) End Using - End Sub + End Function - Public Sub RemoveAndReAddReferenceInSingleBatchWhileChangingCase() + Public Async Function RemoveAndReAddReferenceInSingleBatchWhileChangingCase() As Task Using environment = New TestEnvironment() - Dim referencingProject = environment.ProjectFactory.CreateAndAddToWorkspace("referencingProject", LanguageNames.CSharp) - Dim referencedProject = environment.ProjectFactory.CreateAndAddToWorkspace("referencedProject", LanguageNames.CSharp) + Dim referencingProject = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("referencingProject", LanguageNames.CSharp, CancellationToken.None) + Dim referencedProject = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("referencedProject", LanguageNames.CSharp, CancellationToken.None) Const ReferencePath = "C:\project.dll" referencingProject.AddMetadataReference(ReferencePath, MetadataReferenceProperties.Assembly) @@ -263,14 +268,14 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Assert.Single(getReferencingProject().ProjectReferences) Assert.Empty(getReferencingProject().MetadataReferences) End Using - End Sub + End Function - Public Sub MetadataReferenceCycleDoesNotCreateProjectReferenceCycleWhenAddingReferencesFirst() + Public Async Function MetadataReferenceCycleDoesNotCreateProjectReferenceCycleWhenAddingReferencesFirst() As Task Using environment = New TestEnvironment() - Dim project1 = environment.ProjectFactory.CreateAndAddToWorkspace("project1", LanguageNames.CSharp) - Dim project2 = environment.ProjectFactory.CreateAndAddToWorkspace("project2", LanguageNames.CSharp) + Dim project1 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("project1", LanguageNames.CSharp, CancellationToken.None) + Dim project2 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("project2", LanguageNames.CSharp, CancellationToken.None) Const ReferencePath1 = "C:\project1.dll" Const ReferencePath2 = "C:\project2.dll" @@ -285,14 +290,14 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim project1.RemoveFromWorkspace() project2.RemoveFromWorkspace() End Using - End Sub + End Function - Public Sub MetadataReferenceCycleDoesNotCreateProjectReferenceCycleWhenSettingOutputPathsFirst() + Public Async Function MetadataReferenceCycleDoesNotCreateProjectReferenceCycleWhenSettingOutputPathsFirst() As Task Using environment = New TestEnvironment() - Dim project1 = environment.ProjectFactory.CreateAndAddToWorkspace("project1", LanguageNames.CSharp) - Dim project2 = environment.ProjectFactory.CreateAndAddToWorkspace("project2", LanguageNames.CSharp) + Dim project1 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("project1", LanguageNames.CSharp, CancellationToken.None) + Dim project2 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync("project2", LanguageNames.CSharp, CancellationToken.None) Const ReferencePath1 = "C:\project1.dll" Const ReferencePath2 = "C:\project2.dll" @@ -307,6 +312,6 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim project1.RemoveFromWorkspace() project2.RemoveFromWorkspace() End Using - End Sub + End Function End Class End Namespace diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/PrimaryProjectTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/PrimaryProjectTests.vb index ef37eeb52212d..a249e6eed2fce 100644 --- a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/PrimaryProjectTests.vb +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/PrimaryProjectTests.vb @@ -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. +Imports System.Threading Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Framework @@ -11,40 +12,37 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim <[UseExportProvider]> Public Class PrimaryProjectTests - Public Sub ProjectIsPrimaryByDefault() + Public Async Function ProjectIsPrimaryByDefault() As Task Using environment = New TestEnvironment(GetType(TestDynamicFileInfoProviderThatProducesNoFiles)) - Dim project = environment.ProjectFactory.CreateAndAddToWorkspace( - "project", - LanguageNames.CSharp) + Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project", LanguageNames.CSharp, CancellationToken.None) Assert.True(project.IsPrimary) End Using - End Sub + End Function - Public Sub ChangeProjectIsPrimary() + Public Async Function ChangeProjectIsPrimary() As Task Using environment = New TestEnvironment(GetType(TestDynamicFileInfoProviderThatProducesNoFiles)) - Dim project = environment.ProjectFactory.CreateAndAddToWorkspace( - "project", - LanguageNames.CSharp) + Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project", LanguageNames.CSharp, CancellationToken.None) project.IsPrimary = False Assert.False(project.IsPrimary) End Using - End Sub + End Function - Public Sub ChangeProjectIsPrimaryBack() + Public Async Function ChangeProjectIsPrimaryBack() As Task Using environment = New TestEnvironment(GetType(TestDynamicFileInfoProviderThatProducesNoFiles)) - Dim project = environment.ProjectFactory.CreateAndAddToWorkspace( - "project", - LanguageNames.CSharp) + Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project", LanguageNames.CSharp, CancellationToken.None) project.IsPrimary = False project.IsPrimary = True Assert.True(project.IsPrimary) End Using - End Sub + End Function End Class End Namespace diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/SolutionIdTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/SolutionIdTests.vb index d3b86f28fb254..a532bae29277a 100644 --- a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/SolutionIdTests.vb +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/SolutionIdTests.vb @@ -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. +Imports System.Threading Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Framework @@ -12,29 +13,33 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Public Class SolutionIdTests - Public Sub RemovingAndAddingProjectCreatesNewSolutionId() + Public Async Function RemovingAndAddingProjectCreatesNewSolutionId() As Task Using environment = New TestEnvironment() - Dim project1 = environment.ProjectFactory.CreateAndAddToWorkspace("Project1", LanguageNames.CSharp) + Dim project1 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "Project1", LanguageNames.CSharp, CancellationToken.None) Dim solutionId = environment.Workspace.CurrentSolution.Id project1.RemoveFromWorkspace() - Dim project2 = environment.ProjectFactory.CreateAndAddToWorkspace("Project2", LanguageNames.CSharp) + Dim project2 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "Project2", LanguageNames.CSharp, CancellationToken.None) ' A new ID should have been generated for the new solution Assert.NotEqual(solutionId, environment.Workspace.CurrentSolution.Id) End Using - End Sub + End Function - Public Sub AddingASecondProjectLeavesSolutionIdUntouched() + Public Async Function AddingASecondProjectLeavesSolutionIdUntouched() As Task Using environment = New TestEnvironment() - Dim project1 = environment.ProjectFactory.CreateAndAddToWorkspace("Project1", LanguageNames.CSharp) + Dim project1 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "Project1", LanguageNames.CSharp, CancellationToken.None) Dim solutionId = environment.Workspace.CurrentSolution.Id - Dim project2 = environment.ProjectFactory.CreateAndAddToWorkspace("Project2", LanguageNames.CSharp) + Dim project2 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "Project2", LanguageNames.CSharp, CancellationToken.None) Assert.Equal(solutionId, environment.Workspace.CurrentSolution.Id) End Using - End Sub + End Function End Class End Namespace diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/WorkspaceChangedEventTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/WorkspaceChangedEventTests.vb index 9c907c981ec8a..2da9431ccc652 100644 --- a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/WorkspaceChangedEventTests.vb +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/WorkspaceChangedEventTests.vb @@ -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. +Imports System.Threading Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Framework @@ -14,7 +15,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Public Async Function AddingASingleSourceFileRaisesDocumentAdded(addInBatch As Boolean) As Task Using environment = New TestEnvironment() - Dim project = environment.ProjectFactory.CreateAndAddToWorkspace("Project", LanguageNames.CSharp) + Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "Project", LanguageNames.CSharp, CancellationToken.None) Dim workspaceChangeEvents = New WorkspaceChangeWatcher(environment) Using If(addInBatch, project.CreateBatchScope(), Nothing) @@ -32,7 +34,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Public Async Function AddingTwoDocumentsInBatchRaisesProjectChanged() As Task Using environment = New TestEnvironment() - Dim project = environment.ProjectFactory.CreateAndAddToWorkspace("Project", LanguageNames.CSharp) + Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "Project", LanguageNames.CSharp, CancellationToken.None) Dim workspaceChangeEvents = New WorkspaceChangeWatcher(environment) Using project.CreateBatchScope() @@ -52,7 +55,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Public Async Function AddingASingleAdditionalFileInABatchRaisesDocumentAdded(addInBatch As Boolean) As Task Using environment = New TestEnvironment() - Dim project = environment.ProjectFactory.CreateAndAddToWorkspace("Project", LanguageNames.CSharp) + Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "Project", LanguageNames.CSharp, CancellationToken.None) Dim workspaceChangeEvents = New WorkspaceChangeWatcher(environment) Using If(addInBatch, project.CreateBatchScope(), Nothing) @@ -71,7 +75,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Public Async Function AddingASingleMetadataReferenceRaisesProjectChanged(addInBatch As Boolean) As Task Using environment = New TestEnvironment() - Dim project = environment.ProjectFactory.CreateAndAddToWorkspace("Project", LanguageNames.CSharp) + Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "Project", LanguageNames.CSharp, CancellationToken.None) Dim workspaceChangeEvents = New WorkspaceChangeWatcher(environment) Using If(addInBatch, project.CreateBatchScope(), Nothing) @@ -90,7 +95,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Public Async Function StartingAndEndingBatchWithNoChangesDoesNothing() As Task Using environment = New TestEnvironment() - Dim project = environment.ProjectFactory.CreateAndAddToWorkspace("Project", LanguageNames.CSharp) + Dim project = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "Project", LanguageNames.CSharp, CancellationToken.None) Dim workspaceChangeEvents = New WorkspaceChangeWatcher(environment) Dim startingSolution = environment.Workspace.CurrentSolution diff --git a/src/VisualStudio/TestUtilities2/ProjectSystemShim/Framework/TestEnvironment.vb b/src/VisualStudio/TestUtilities2/ProjectSystemShim/Framework/TestEnvironment.vb index 19fb9095362f1..e5be5fae42aa0 100644 --- a/src/VisualStudio/TestUtilities2/ProjectSystemShim/Framework/TestEnvironment.vb +++ b/src/VisualStudio/TestUtilities2/ProjectSystemShim/Framework/TestEnvironment.vb @@ -185,7 +185,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Fr Select Case serviceType Case GetType(SVsSolution) ' Return a loose mock that just is a big no-op - Dim solutionMock As New Mock(Of IVsSolution)(MockBehavior.Loose) + Dim solutionMock As New Mock(Of IVsSolution2)(MockBehavior.Loose) Return solutionMock.Object Case GetType(SComponentModel) diff --git a/src/VisualStudio/Xaml/Impl/Implementation/XamlProjectService.cs b/src/VisualStudio/Xaml/Impl/Implementation/XamlProjectService.cs index c3ebbc05cac00..5f42eacd9e5c7 100644 --- a/src/VisualStudio/Xaml/Impl/Implementation/XamlProjectService.cs +++ b/src/VisualStudio/Xaml/Impl/Implementation/XamlProjectService.cs @@ -2,12 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable enable - using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.Linq; +using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; @@ -16,10 +15,8 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Xaml.Diagnostics.Analyzers; -using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Editor; using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem; -using Microsoft.VisualStudio.LanguageServices.Xaml.Telemetry; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Text; @@ -136,7 +133,8 @@ public XamlProjectService( ProjectGuid = projectGuid }; - project = _visualStudioProjectFactory.CreateAndAddToWorkspace(name, StringConstants.XamlLanguageName, projectInfo); + project = _threadingContext.JoinableTaskFactory.Run(() => _visualStudioProjectFactory.CreateAndAddToWorkspaceAsync( + name, StringConstants.XamlLanguageName, projectInfo, CancellationToken.None)); _xamlProjects.Add(hierarchy, project); }