-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Load analyzers and generators in isolated ALCs in our OOP process #74780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
4a74960
9b15720
fcd2791
476346f
eb9e531
4f33bb9
1fcd8fa
6598832
eda27b0
6276106
ee79e75
ef8c9b3
bb30403
40d111f
72527b7
9c5ce93
df1fa06
e1c8108
abf7d7d
e5508fd
d82d2a9
0000865
46931b1
b943bf8
cf71ad8
e0b00d5
cdf0aed
e650f96
682c455
6bbd6aa
a729ef1
3cf946d
9fd7fc8
3dcf644
a83ebc5
4925999
84a60b6
34db05b
6ba258a
8e70d06
b771f97
df5764f
514c0b4
306e783
658abfa
8eda644
4cf1330
730c883
e6a3883
91d97dc
78c734e
217a496
a7959ce
a6c5e97
abc6af5
8661560
bd8f926
5b481d6
a07bb12
8d2d21a
694080c
fe82439
3fff183
14a7ff4
01d109e
7c001e5
d4450d9
3f3e15c
ae16400
39bcc6e
dfc26e0
f534e72
32518fb
ea7f576
6f5a76f
063d9a2
d105e2f
7b7392a
fd6fb98
65620d2
b597d4a
a478c33
07b0497
f554f3e
e9d636d
362cf63
10af3cf
ae1c683
23307e0
e5711f8
f224ba0
a960412
fa01f64
5a69e9c
3c7e326
18b5893
f6cd0bd
efda682
a3ebfc9
f01eaf8
e801da2
01e8e65
c53f25a
24b7698
2aaa1bc
ef90315
1352fff
b31dca4
b030aa4
f836f16
ae5aa2e
5c9d7b4
188e44d
f44e95f
e637c25
57152d8
da0e43e
d3d3866
587b6c3
bcb33a8
9470752
f851590
a5244a6
df51cbd
1bd7e08
1fa9eec
c551d72
d688f8e
73fc9ff
523035e
a5964bd
857f0e0
5ed0d68
c363a01
6854ae1
438db6f
55d9748
3124d1e
520508b
81d0fd3
2e2393e
28b0ca4
d1a3c0d
7e871f6
abb4df4
393b5a2
20a88fa
79f701c
390ada5
642ac91
24bfad2
a1e46b6
b99b396
c4162c0
9dc6b7e
cc270ee
82f7120
f86a8aa
a6b6d9e
9ad33f7
4f961ff
d0bfc65
1975a1a
7462d05
266e439
b823683
ab4ba87
176b8a8
57aee0e
4758f3b
75a4955
a613d6a
a90f7ec
1ef5673
cbf85eb
81afa79
9e011e7
49435a4
14139ef
c793b18
9eba2a5
c03b6da
c622459
ae387e5
82ddb42
059e3ff
bd46648
4b77dc5
9be2700
ca06773
70c973c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,10 @@ | |
using System.Runtime.InteropServices; | ||
using Roslyn.Utilities; | ||
|
||
#if NET | ||
CyrusNajmabadi marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Inconsistent usage of NET or NETCOREAPP within the same file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jaredpar what's your preference here. IDE uses NET for this. not sure how it differs from NETCOREAPP. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code base largely uses |
||
using System.Runtime.Loader; | ||
#endif | ||
|
||
namespace Microsoft.CodeAnalysis | ||
{ | ||
internal sealed class DefaultAnalyzerAssemblyLoader : AnalyzerAssemblyLoader | ||
|
@@ -57,12 +61,17 @@ protected override string PrepareSatelliteAssemblyToLoad(string assemblyFilePath | |
/// </summary> | ||
/// <param name="windowsShadowPath">A shadow copy path will be created on Windows and this value | ||
/// will be the base directory where shadow copy assemblies are stored. </param> | ||
internal static IAnalyzerAssemblyLoaderInternal CreateNonLockingLoader(string windowsShadowPath, ImmutableArray<IAnalyzerAssemblyResolver>? externalResolvers = null) | ||
internal static IAnalyzerAssemblyLoaderInternal CreateNonLockingLoader( | ||
#if NET | ||
AssemblyLoadContext? loadContext, | ||
#endif | ||
CyrusNajmabadi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
string windowsShadowPath, | ||
ImmutableArray<IAnalyzerAssemblyResolver>? externalResolvers = null) | ||
{ | ||
#if NETCOREAPP | ||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||
{ | ||
return new DefaultAnalyzerAssemblyLoader(loadOption: AnalyzerLoadOption.LoadFromStream, externalResolvers: externalResolvers); | ||
return new DefaultAnalyzerAssemblyLoader(loadContext, loadOption: AnalyzerLoadOption.LoadFromStream, externalResolvers: externalResolvers); | ||
} | ||
#endif | ||
|
||
|
@@ -74,7 +83,12 @@ internal static IAnalyzerAssemblyLoaderInternal CreateNonLockingLoader(string wi | |
throw new ArgumentException("Must be a full path.", nameof(windowsShadowPath)); | ||
} | ||
|
||
return new ShadowCopyAnalyzerAssemblyLoader(windowsShadowPath, externalResolvers); | ||
return new ShadowCopyAnalyzerAssemblyLoader( | ||
#if NET | ||
loadContext, | ||
#endif | ||
windowsShadowPath, | ||
externalResolvers); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,10 @@ | |
using System.Collections.Immutable; | ||
using System.IO; | ||
|
||
#if NET | ||
using System.Runtime.Loader; | ||
#endif | ||
|
||
namespace Microsoft.CodeAnalysis.Host; | ||
|
||
/// <summary> | ||
|
@@ -15,20 +19,47 @@ namespace Microsoft.CodeAnalysis.Host; | |
internal abstract class AbstractAnalyzerAssemblyLoaderProvider : IAnalyzerAssemblyLoaderProvider | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. view with whitespace off. |
||
{ | ||
private readonly Lazy<IAnalyzerAssemblyLoader> _shadowCopyLoader; | ||
private readonly ImmutableArray<IAnalyzerAssemblyResolver> _externalResolvers; | ||
|
||
public AbstractAnalyzerAssemblyLoaderProvider(ImmutableArray<IAnalyzerAssemblyResolver> externalResolvers) | ||
{ | ||
// We use a lazy here in case creating the loader requires MEF imports in the derived constructor. | ||
_shadowCopyLoader = new Lazy<IAnalyzerAssemblyLoader>(() => CreateShadowCopyLoader(externalResolvers)); | ||
_shadowCopyLoader = new Lazy<IAnalyzerAssemblyLoader>(() => CreateShadowCopyLoader( | ||
#if NET | ||
CyrusNajmabadi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
loadContext: null, | ||
#endif | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i prefer writing things this way on the IDE side vs duplicating the full call, and passing in this parameter on one side. it keeps the amount of duplication to an absolute minimum. |
||
isolatedRoot: "")); | ||
_externalResolvers = externalResolvers; | ||
} | ||
|
||
public IAnalyzerAssemblyLoader GetShadowCopyLoader() | ||
=> _shadowCopyLoader.Value; | ||
private static string GetPath(string isolatedRoot) | ||
=> Path.Combine(Path.GetTempPath(), "VS", "AnalyzerAssemblyLoader", isolatedRoot); | ||
|
||
protected virtual IAnalyzerAssemblyLoader CreateShadowCopyLoader(ImmutableArray<IAnalyzerAssemblyResolver> externalResolvers) | ||
protected virtual IAnalyzerAssemblyLoader CreateShadowCopyLoader( | ||
#if NET | ||
AssemblyLoadContext? loadContext, | ||
#endif | ||
string isolatedRoot) | ||
{ | ||
return DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader( | ||
Path.Combine(Path.GetTempPath(), "VS", "AnalyzerAssemblyLoader"), | ||
externalResolvers: externalResolvers); | ||
#if NET | ||
loadContext, | ||
#endif | ||
GetPath(isolatedRoot), | ||
_externalResolvers); | ||
} | ||
|
||
#if NET | ||
|
||
public IAnalyzerAssemblyLoader GetShadowCopyLoader(AssemblyLoadContext? loadContext, string isolatedRoot) | ||
=> loadContext is null && isolatedRoot == "" | ||
? _shadowCopyLoader.Value | ||
: CreateShadowCopyLoader(loadContext, isolatedRoot); | ||
|
||
#else | ||
|
||
public IAnalyzerAssemblyLoader GetShadowCopyLoader() | ||
=> _shadowCopyLoader.Value; | ||
|
||
#endif | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System; | ||
using System.Collections.Immutable; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
using Microsoft.CodeAnalysis.Host; | ||
|
||
namespace Microsoft.CodeAnalysis.Serialization; | ||
|
||
internal partial class SerializerService | ||
{ | ||
/// <summary> | ||
/// No methods on this serialized type should be called. It exists as a placeholder to allow the data to be | ||
/// transmitted from the host to the remote side. On the remote side we will first collect *all* of these | ||
/// serialized analyzer references, then create the actual <see cref="AnalyzerFileReference"/>s in their own safe | ||
/// AssemblyLoadContext distinct from everything else. | ||
/// </summary> | ||
public sealed class SerializedAnalyzerReference(string fullPath) : AnalyzerReference | ||
{ | ||
public override string FullPath { get; } = fullPath; | ||
|
||
public override object Id | ||
=> throw new InvalidOperationException(); | ||
|
||
public override ImmutableArray<DiagnosticAnalyzer> GetAnalyzers(string language) | ||
=> throw new InvalidOperationException(); | ||
|
||
public override ImmutableArray<DiagnosticAnalyzer> GetAnalyzersForAllLanguages() | ||
=> throw new InvalidOperationException(); | ||
|
||
[Obsolete] | ||
public override ImmutableArray<ISourceGenerator> GetGenerators() | ||
=> throw new InvalidOperationException(); | ||
|
||
public override ImmutableArray<ISourceGenerator> GetGenerators(string language) | ||
=> throw new InvalidOperationException(); | ||
|
||
public override ImmutableArray<ISourceGenerator> GetGeneratorsForAllLanguages() | ||
=> throw new InvalidOperationException(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
view with whitespace off.