Skip to content

Commit 5f6ffda

Browse files
authored
Merge pull request #1120 from sharwell/export-provider
Create export provider asynchronously
2 parents 6535e67 + c5d471a commit 5f6ffda

File tree

4 files changed

+60
-22
lines changed

4 files changed

+60
-22
lines changed

src/Microsoft.CodeAnalysis.Testing/Directory.Build.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
<When Condition="'$(Language)' == 'C#'">
3636
<PropertyGroup>
37-
<LangVersion>9</LangVersion>
37+
<LangVersion>10</LangVersion>
3838
</PropertyGroup>
3939
</When>
4040
</Choose>

src/Microsoft.CodeAnalysis.Testing/Microsoft.CodeAnalysis.Analyzer.Testing/AnalyzerTest`1.cs

+16-21
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Collections.Concurrent;
77
using System.Collections.Generic;
88
using System.Collections.Immutable;
9+
using System.ComponentModel;
910
using System.IO;
1011
using System.Linq;
1112
using System.Reflection;
@@ -32,25 +33,8 @@ namespace Microsoft.CodeAnalysis.Testing
3233
public abstract class AnalyzerTest<TVerifier>
3334
where TVerifier : IVerifier, new()
3435
{
35-
private static readonly Lazy<IExportProviderFactory> ExportProviderFactory;
3636
private static readonly ConditionalWeakTable<Diagnostic, object> NonLocalDiagnostics = new ConditionalWeakTable<Diagnostic, object>();
3737

38-
static AnalyzerTest()
39-
{
40-
ExportProviderFactory = new Lazy<IExportProviderFactory>(
41-
() =>
42-
{
43-
var discovery = new AttributedPartDiscovery(Resolver.DefaultInstance, isNonPublicSupported: true);
44-
var parts = Task.Run(() => discovery.CreatePartsAsync(MefHostServices.DefaultAssemblies)).GetAwaiter().GetResult();
45-
var catalog = ComposableCatalog.Create(Resolver.DefaultInstance).AddParts(parts).WithDocumentTextDifferencingService();
46-
47-
var configuration = CompositionConfiguration.Create(catalog);
48-
var runtimeComposition = RuntimeComposition.CreateRuntimeComposition(configuration);
49-
return runtimeComposition.CreateExportProviderFactory();
50-
},
51-
LazyThreadSafetyMode.ExecutionAndPublication);
52-
}
53-
5438
/// <summary>
5539
/// Gets the default verifier for the test.
5640
/// </summary>
@@ -1587,7 +1571,7 @@ protected virtual async Task<Solution> CreateSolutionAsync(ProjectId projectId,
15871571
var parseOptions = CreateParseOptions()
15881572
.WithDocumentationMode(projectState.DocumentationMode);
15891573

1590-
var workspace = CreateWorkspace();
1574+
var workspace = await CreateWorkspaceAsync().ConfigureAwait(false);
15911575
foreach (var transform in OptionsTransforms)
15921576
{
15931577
workspace.Options = transform(workspace.Options);
@@ -1660,16 +1644,27 @@ protected virtual Project ApplyCompilationOptions(Project project)
16601644
return solution.GetProject(project.Id);
16611645
}
16621646

1647+
[EditorBrowsable(EditorBrowsableState.Never)]
1648+
[Obsolete($"Use {nameof(CreateWorkspaceAsync)} instead. https://github.com/dotnet/roslyn-sdk/pull/1120", error: true)]
16631649
public Workspace CreateWorkspace()
1650+
=> throw new NotSupportedException();
1651+
1652+
[EditorBrowsable(EditorBrowsableState.Never)]
1653+
[Obsolete($"Use {nameof(CreateWorkspaceImplAsync)} instead. https://github.com/dotnet/roslyn-sdk/pull/1120", error: true)]
1654+
protected virtual Workspace CreateWorkspaceImpl()
1655+
=> throw new NotSupportedException();
1656+
1657+
public async Task<Workspace> CreateWorkspaceAsync()
16641658
{
1665-
var workspace = CreateWorkspaceImpl();
1659+
var workspace = await CreateWorkspaceImplAsync().ConfigureAwait(false);
16661660
_workspaces.Add(workspace);
16671661
return workspace;
16681662
}
16691663

1670-
protected virtual Workspace CreateWorkspaceImpl()
1664+
protected virtual async Task<Workspace> CreateWorkspaceImplAsync()
16711665
{
1672-
var exportProvider = ExportProviderFactory.Value.CreateExportProvider();
1666+
var exportProviderFactory = await ExportProviderFactory.GetOrCreateExportProviderFactoryAsync().ConfigureAwait(false);
1667+
var exportProvider = exportProviderFactory.CreateExportProvider();
16731668
var host = MefHostServices.Create(exportProvider.AsCompositionContext());
16741669
return new AdhocWorkspace(host);
16751670
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Threading.Tasks;
6+
using Microsoft.CodeAnalysis.Host.Mef;
7+
using Microsoft.VisualStudio.Composition;
8+
9+
namespace Microsoft.CodeAnalysis.Testing
10+
{
11+
internal static class ExportProviderFactory
12+
{
13+
private static readonly object s_lock = new();
14+
private static Task<IExportProviderFactory>? s_exportProviderFactory;
15+
16+
public static Task<IExportProviderFactory> GetOrCreateExportProviderFactoryAsync()
17+
{
18+
if (s_exportProviderFactory is { } exportProviderFactory)
19+
{
20+
return exportProviderFactory;
21+
}
22+
23+
lock (s_lock)
24+
{
25+
s_exportProviderFactory ??= Task.Run(CreateExportProviderFactorySlowAsync);
26+
return s_exportProviderFactory;
27+
}
28+
29+
static async Task<IExportProviderFactory> CreateExportProviderFactorySlowAsync()
30+
{
31+
var discovery = new AttributedPartDiscovery(Resolver.DefaultInstance, isNonPublicSupported: true);
32+
var parts = await discovery.CreatePartsAsync(MefHostServices.DefaultAssemblies).ConfigureAwait(false);
33+
var catalog = ComposableCatalog.Create(Resolver.DefaultInstance).AddParts(parts).WithDocumentTextDifferencingService();
34+
35+
var configuration = CompositionConfiguration.Create(catalog);
36+
var runtimeComposition = RuntimeComposition.CreateRuntimeComposition(configuration);
37+
return runtimeComposition.CreateExportProviderFactory();
38+
}
39+
}
40+
}
41+
}

src/Microsoft.CodeAnalysis.Testing/Microsoft.CodeAnalysis.Analyzer.Testing/PublicAPI.Unshipped.txt

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.CompilerDiagnostics.get -
44
Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.CompilerDiagnostics.set -> void
55
Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.CreateProjectAsync(Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState primaryProject, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState> additionalProjects, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Project>
66
Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.CreateWorkspace() -> Microsoft.CodeAnalysis.Workspace
7+
Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.CreateWorkspaceAsync() -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Workspace>
78
Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.DiagnosticVerifier.get -> System.Action<Microsoft.CodeAnalysis.Diagnostic, Microsoft.CodeAnalysis.Testing.DiagnosticResult, Microsoft.CodeAnalysis.Testing.IVerifier>
89
Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.DiagnosticVerifier.set -> void
910
Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.DisabledDiagnostics.get -> System.Collections.Generic.List<string>
@@ -350,6 +351,7 @@ virtual Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.CreateCompilation
350351
virtual Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.CreateProjectImplAsync(Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState primaryProject, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState> additionalProjects, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Project>
351352
virtual Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.CreateSolutionAsync(Microsoft.CodeAnalysis.ProjectId projectId, Microsoft.CodeAnalysis.Testing.Model.EvaluatedProjectState projectState, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Solution>
352353
virtual Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.CreateWorkspaceImpl() -> Microsoft.CodeAnalysis.Workspace
354+
virtual Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.CreateWorkspaceImplAsync() -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Workspace>
353355
virtual Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.DefaultFilePath.get -> string
354356
virtual Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.DefaultFilePathPrefix.get -> string
355357
virtual Microsoft.CodeAnalysis.Testing.AnalyzerTest<TVerifier>.DefaultTestProjectName.get -> string

0 commit comments

Comments
 (0)