Skip to content

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

Merged
merged 191 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
191 commits
Select commit Hold shift + click to select a range
4a74960
In progress
CyrusNajmabadi Aug 15, 2024
9b15720
in progress
CyrusNajmabadi Aug 15, 2024
fcd2791
in progress
CyrusNajmabadi Aug 15, 2024
476346f
in progress
CyrusNajmabadi Aug 15, 2024
eb9e531
Finish up
CyrusNajmabadi Aug 15, 2024
4f33bb9
in progress
CyrusNajmabadi Aug 15, 2024
1fcd8fa
in progress
CyrusNajmabadi Aug 15, 2024
6598832
Add back
CyrusNajmabadi Aug 15, 2024
eda27b0
dedicated file
CyrusNajmabadi Aug 15, 2024
6276106
in progress
CyrusNajmabadi Aug 15, 2024
ee79e75
in progress
CyrusNajmabadi Aug 15, 2024
ef8c9b3
simplify
CyrusNajmabadi Aug 15, 2024
bb30403
Revert
CyrusNajmabadi Aug 15, 2024
40d111f
Share more
CyrusNajmabadi Aug 15, 2024
72527b7
docs
CyrusNajmabadi Aug 15, 2024
9c5ce93
Docs
CyrusNajmabadi Aug 15, 2024
df1fa06
Docs
CyrusNajmabadi Aug 15, 2024
e1c8108
Docs
CyrusNajmabadi Aug 15, 2024
abf7d7d
Unique path
CyrusNajmabadi Aug 15, 2024
e5508fd
Doc
CyrusNajmabadi Aug 15, 2024
d82d2a9
Simplify
CyrusNajmabadi Aug 15, 2024
0000865
Change ifdefs
CyrusNajmabadi Aug 15, 2024
46931b1
Change ifdefs
CyrusNajmabadi Aug 15, 2024
b943bf8
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 19, 2024
cf71ad8
in progress
CyrusNajmabadi Aug 19, 2024
e0b00d5
move
CyrusNajmabadi Aug 19, 2024
cdf0aed
fix
CyrusNajmabadi Aug 19, 2024
e650f96
Simplify
CyrusNajmabadi Aug 19, 2024
682c455
Simplify
CyrusNajmabadi Aug 19, 2024
6bbd6aa
move to common location
CyrusNajmabadi Aug 19, 2024
a729ef1
Move to shared location
CyrusNajmabadi Aug 20, 2024
3cf946d
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 20, 2024
9fd7fc8
Docs
CyrusNajmabadi Aug 20, 2024
3dcf644
Docs
CyrusNajmabadi Aug 20, 2024
a83ebc5
Docs
CyrusNajmabadi Aug 20, 2024
4925999
Docs
CyrusNajmabadi Aug 20, 2024
84a60b6
Similar logic
CyrusNajmabadi Aug 20, 2024
34db05b
Sharing
CyrusNajmabadi Aug 20, 2024
6ba258a
Docs
CyrusNajmabadi Aug 20, 2024
8e70d06
restore
CyrusNajmabadi Aug 20, 2024
b771f97
Docs
CyrusNajmabadi Aug 20, 2024
df5764f
Docs
CyrusNajmabadi Aug 20, 2024
514c0b4
Docs
CyrusNajmabadi Aug 20, 2024
306e783
not abstract
CyrusNajmabadi Aug 20, 2024
658abfa
renames
CyrusNajmabadi Aug 20, 2024
8eda644
Docs
CyrusNajmabadi Aug 20, 2024
4cf1330
Merge remote-tracking branch 'dibarbet/fix_design_time_build' into is…
CyrusNajmabadi Aug 20, 2024
730c883
in progress
CyrusNajmabadi Aug 20, 2024
e6a3883
Make protected
CyrusNajmabadi Aug 20, 2024
91d97dc
simplify
CyrusNajmabadi Aug 20, 2024
78c734e
Fix
CyrusNajmabadi Aug 20, 2024
217a496
Fix
CyrusNajmabadi Aug 20, 2024
a7959ce
primary constructor
CyrusNajmabadi Aug 20, 2024
a6c5e97
Merge branch 'checksummedObject' into isolatedALC
CyrusNajmabadi Aug 20, 2024
abc6af5
Fix
CyrusNajmabadi Aug 20, 2024
8661560
Fix
CyrusNajmabadi Aug 20, 2024
bd8f926
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 21, 2024
5b481d6
Fix
CyrusNajmabadi Aug 21, 2024
a07bb12
Jared pattern
CyrusNajmabadi Aug 21, 2024
8d2d21a
Revert
CyrusNajmabadi Aug 21, 2024
694080c
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 21, 2024
fe82439
revert
CyrusNajmabadi Aug 21, 2024
3fff183
revert
CyrusNajmabadi Aug 21, 2024
14a7ff4
no default
CyrusNajmabadi Aug 21, 2024
01d109e
Update src/Workspaces/CoreTestUtilities/Remote/TestSerializerService.cs
CyrusNajmabadi Aug 21, 2024
7c001e5
Simplify
CyrusNajmabadi Aug 21, 2024
d4450d9
Wrapping
CyrusNajmabadi Aug 21, 2024
3f3e15c
contract messages
CyrusNajmabadi Aug 21, 2024
ae16400
Rename
CyrusNajmabadi Aug 21, 2024
39bcc6e
Add gc
CyrusNajmabadi Aug 21, 2024
dfc26e0
move code
CyrusNajmabadi Aug 21, 2024
f534e72
Collection expression
CyrusNajmabadi Aug 21, 2024
32518fb
asserts
CyrusNajmabadi Aug 21, 2024
ea7f576
blank lines
CyrusNajmabadi Aug 21, 2024
6f5a76f
Sort usings
CyrusNajmabadi Aug 21, 2024
063d9a2
Make a counter instead
CyrusNajmabadi Aug 21, 2024
d105e2f
Merge branch 'main' into isolatedALC
CyrusNajmabadi Aug 21, 2024
7b7392a
Different approach
CyrusNajmabadi Aug 21, 2024
fd6fb98
in progress
CyrusNajmabadi Aug 21, 2024
65620d2
in progress
CyrusNajmabadi Aug 21, 2024
b597d4a
Cleanup
CyrusNajmabadi Aug 21, 2024
a478c33
Trivially bail out
CyrusNajmabadi Aug 21, 2024
07b0497
File change notifications working
CyrusNajmabadi Aug 21, 2024
f554f3e
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 22, 2024
e9d636d
Merge branch 'moveType' into isolatedALC
CyrusNajmabadi Aug 22, 2024
362cf63
Merge branch 'moveType' into isolatedALC
CyrusNajmabadi Aug 22, 2024
10af3cf
Merge branch 'analyzerWatching' into isolatedALC
CyrusNajmabadi Aug 22, 2024
ae1c683
Make static
CyrusNajmabadi Aug 22, 2024
23307e0
Merge branch 'analyzerWatching' into isolatedALC
CyrusNajmabadi Aug 22, 2024
e5711f8
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 22, 2024
f224ba0
Merge branch 'unloadAll' into isolatedALC
CyrusNajmabadi Aug 22, 2024
a960412
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 22, 2024
fa01f64
Merge branch 'batching' into isolatedALC
CyrusNajmabadi Aug 22, 2024
5a69e9c
in progresS
CyrusNajmabadi Aug 22, 2024
3c7e326
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 22, 2024
18b5893
in progress
CyrusNajmabadi Aug 22, 2024
f6cd0bd
Rename
CyrusNajmabadi Aug 22, 2024
efda682
Remove
CyrusNajmabadi Aug 22, 2024
a3ebfc9
Working test
CyrusNajmabadi Aug 22, 2024
f01eaf8
Renames
CyrusNajmabadi Aug 22, 2024
e801da2
Merge branch 'main' into isolatedALC
CyrusNajmabadi Aug 23, 2024
01e8e65
Update src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssembl…
CyrusNajmabadi Aug 23, 2024
c53f25a
Cleanup api
CyrusNajmabadi Aug 23, 2024
24b7698
keealive
CyrusNajmabadi Aug 23, 2024
2aaa1bc
Merge branch 'main' into isolatedALC
CyrusNajmabadi Aug 23, 2024
ef90315
in progress
CyrusNajmabadi Aug 23, 2024
1352fff
Merge branch 'stringFileWatching' into isolatedALC
CyrusNajmabadi Aug 23, 2024
b31dca4
in progress
CyrusNajmabadi Aug 23, 2024
b030aa4
in progress
CyrusNajmabadi Aug 23, 2024
f836f16
in progress
CyrusNajmabadi Aug 23, 2024
ae5aa2e
in progress
CyrusNajmabadi Aug 23, 2024
5c9d7b4
in progress
CyrusNajmabadi Aug 23, 2024
188e44d
Simplify
CyrusNajmabadi Aug 23, 2024
f44e95f
more work
CyrusNajmabadi Aug 23, 2024
e637c25
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 23, 2024
57152d8
in progress
CyrusNajmabadi Aug 23, 2024
da0e43e
Move and rename
CyrusNajmabadi Aug 23, 2024
d3d3866
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 23, 2024
587b6c3
Downsream fallout
CyrusNajmabadi Aug 23, 2024
bcb33a8
Tests
CyrusNajmabadi Aug 23, 2024
9470752
Use new context
CyrusNajmabadi Aug 23, 2024
f851590
move back
CyrusNajmabadi Aug 23, 2024
a5244a6
Docs
CyrusNajmabadi Aug 23, 2024
df51cbd
revert
CyrusNajmabadi Aug 23, 2024
1bd7e08
REvert
CyrusNajmabadi Aug 23, 2024
1fa9eec
Simplify
CyrusNajmabadi Aug 23, 2024
c551d72
move
CyrusNajmabadi Aug 23, 2024
d688f8e
REvert
CyrusNajmabadi Aug 23, 2024
73fc9ff
REvert
CyrusNajmabadi Aug 23, 2024
523035e
in progress
CyrusNajmabadi Aug 23, 2024
a5964bd
partials
CyrusNajmabadi Aug 23, 2024
857f0e0
cleanup
CyrusNajmabadi Aug 23, 2024
5ed0d68
cleanup
CyrusNajmabadi Aug 23, 2024
c363a01
REvert
CyrusNajmabadi Aug 23, 2024
6854ae1
Sort
CyrusNajmabadi Aug 23, 2024
438db6f
REvert
CyrusNajmabadi Aug 23, 2024
55d9748
Sort
CyrusNajmabadi Aug 23, 2024
3124d1e
Remove
CyrusNajmabadi Aug 23, 2024
520508b
Merge branch 'passAlongServices' into isolatedALC
CyrusNajmabadi Aug 23, 2024
81d0fd3
Merge branch 'passAlongServices' into isolatedALC
CyrusNajmabadi Aug 23, 2024
2e2393e
REmove
CyrusNajmabadi Aug 23, 2024
28b0ca4
Use helper
CyrusNajmabadi Aug 23, 2024
d1a3c0d
in progress
CyrusNajmabadi Aug 23, 2024
7e871f6
in progress
CyrusNajmabadi Aug 23, 2024
abb4df4
In progress
CyrusNajmabadi Aug 23, 2024
393b5a2
in progress
CyrusNajmabadi Aug 23, 2024
20a88fa
In progress
CyrusNajmabadi Aug 23, 2024
79f701c
move to strings
CyrusNajmabadi Aug 23, 2024
390ada5
Don't go through the workspace
CyrusNajmabadi Aug 23, 2024
642ac91
Merge branch 'fileChangeWorkQueue' into isolatedALC
CyrusNajmabadi Aug 23, 2024
24bfad2
REvert
CyrusNajmabadi Aug 23, 2024
a1e46b6
Merge branch 'fileChangeWorkQueue' into isolatedALC
CyrusNajmabadi Aug 23, 2024
b99b396
Merge branch 'fileChangeWorkQueue' into isolatedALC
CyrusNajmabadi Aug 23, 2024
c4162c0
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 23, 2024
9dc6b7e
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 24, 2024
cc270ee
Update src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostW…
CyrusNajmabadi Aug 24, 2024
82f7120
only in net
CyrusNajmabadi Aug 24, 2024
f86a8aa
docs
CyrusNajmabadi Aug 24, 2024
a6b6d9e
Merge branch 'isolatedALC' of https://github.com/CyrusNajmabadi/rosly…
CyrusNajmabadi Aug 24, 2024
9ad33f7
move
CyrusNajmabadi Aug 24, 2024
4f961ff
rename
CyrusNajmabadi Aug 24, 2024
d0bfc65
docs
CyrusNajmabadi Aug 24, 2024
1975a1a
docs
CyrusNajmabadi Aug 24, 2024
7462d05
docs
CyrusNajmabadi Aug 24, 2024
266e439
Simplify logic
CyrusNajmabadi Aug 24, 2024
b823683
update test
CyrusNajmabadi Aug 24, 2024
ab4ba87
Fix comment
CyrusNajmabadi Aug 24, 2024
176b8a8
pass id
CyrusNajmabadi Aug 24, 2024
57aee0e
simplify
CyrusNajmabadi Aug 24, 2024
4758f3b
stop watching references
CyrusNajmabadi Aug 24, 2024
75a4955
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 25, 2024
a613d6a
Fix
CyrusNajmabadi Aug 25, 2024
a90f7ec
Share code
CyrusNajmabadi Aug 25, 2024
1ef5673
name our directory
CyrusNajmabadi Aug 25, 2024
cbf85eb
Merge branch 'loaderProvider' into isolatedALC
CyrusNajmabadi Aug 25, 2024
81afa79
Simplify
CyrusNajmabadi Aug 25, 2024
9e011e7
Merge branch 'loaderProvider' into isolatedALC
CyrusNajmabadi Aug 25, 2024
49435a4
Merge branch 'loaderProvider' into isolatedALC
CyrusNajmabadi Aug 25, 2024
14139ef
inline
CyrusNajmabadi Aug 25, 2024
c793b18
remove
CyrusNajmabadi Aug 25, 2024
9eba2a5
Merge branch 'loaderProvider' into isolatedALC
CyrusNajmabadi Aug 25, 2024
c03b6da
Docs
CyrusNajmabadi Aug 25, 2024
c622459
Merge branch 'loaderProvider' into isolatedALC
CyrusNajmabadi Aug 25, 2024
ae387e5
Merge branch 'loaderProvider' into isolatedALC
CyrusNajmabadi Aug 26, 2024
82ddb42
move into pp region
CyrusNajmabadi Aug 26, 2024
059e3ff
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 26, 2024
bd46648
remove
CyrusNajmabadi Aug 26, 2024
4b77dc5
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 26, 2024
9be2700
Update src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSy…
CyrusNajmabadi Aug 27, 2024
ca06773
Update src/Workspaces/CoreTest/SolutionTests/SolutionWithSourceGenera…
CyrusNajmabadi Aug 27, 2024
70c973c
Merge remote-tracking branch 'upstream/main' into isolatedALC
CyrusNajmabadi Aug 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
using System.Runtime.InteropServices;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

view with whitespace off.

using Roslyn.Utilities;

#if NET
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Inconsistent usage of NET or NETCOREAPP within the same file

Copy link
Member Author

Choose a reason for hiding this comment

The 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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code base largely uses NETCOREAPP for historical reasons. The more idiomatic approach is #if NET.

using System.Runtime.Loader;
#endif

namespace Microsoft.CodeAnalysis
{
internal sealed class DefaultAnalyzerAssemblyLoader : AnalyzerAssemblyLoader
Expand Down Expand Up @@ -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
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

Expand All @@ -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);
}
}
}
6 changes: 5 additions & 1 deletion src/Compilers/Server/VBCSCompiler/CompilerRequestHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,11 @@ internal CompilerServerHost(string clientDirectory, string? sdkDirectory, ICompi
ClientDirectory = clientDirectory;
SdkDirectory = sdkDirectory;
Logger = logger;
AnalyzerAssemblyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(Path.Combine(Path.GetTempPath(), "VBCSCompiler", "AnalyzerAssemblyLoader"));
AnalyzerAssemblyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(
#if NET
loadContext: null,
#endif
Path.Combine(Path.GetTempPath(), "VBCSCompiler", "AnalyzerAssemblyLoader"));
}

public bool TryCreateCompiler(in RunRequest request, BuildPaths buildPaths, [NotNullWhen(true)] out CommonCompiler? compiler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,11 @@ public void LoadLibraryWithMissingReference()
{
var directory = Temp.CreateDirectory();
_ = directory.CopyFile(TestFixture.Alpha);
var assemblyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(directory.CreateDirectory("shadow").Path);
var assemblyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(
#if NET
loadContext: null,
#endif
directory.CreateDirectory("shadow").Path);

var analyzerReferences = ImmutableArray.Create(new CommandLineAnalyzerReference("Alpha.dll"));
var result = AnalyzerConsistencyChecker.Check(directory.Path, analyzerReferences, assemblyLoader, Logger);
Expand All @@ -95,7 +99,11 @@ public void LoadLibraryWithMissingReference()
public void LoadLibraryAll()
{
var directory = Temp.CreateDirectory();
var assemblyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(directory.CreateDirectory("shadow").Path);
var assemblyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(
#if NET
loadContext: null,
#endif
directory.CreateDirectory("shadow").Path);
var analyzerReferences = ImmutableArray.Create(
new CommandLineAnalyzerReference("Alpha.dll"),
new CommandLineAnalyzerReference("Beta.dll"),
Expand All @@ -110,7 +118,11 @@ public void LoadLibraryAll()
public void DifferingMvidsDifferentDirectory()
{
var directory = Temp.CreateDirectory();
var assemblyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(directory.CreateDirectory("shadow").Path);
var assemblyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(
#if NET
loadContext: null,
#endif
directory.CreateDirectory("shadow").Path);

var key = NetStandard20.References.netstandard.GetAssemblyIdentity().PublicKey;
var mvidAlpha1 = CreateNetStandardDll(directory.CreateDirectory("mvid1"), "MvidAlpha", "1.0.0.0", key, "class C { }");
Expand All @@ -135,7 +147,11 @@ public void DifferingMvidsDifferentDirectory()
public void DifferingMvidsSameDirectory()
{
var directory = Temp.CreateDirectory();
var assemblyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(directory.CreateDirectory("shadow").Path);
var assemblyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(
#if NET
loadContext: null,
#endif
directory.CreateDirectory("shadow").Path);

var key = NetStandard20.References.netstandard.GetAssemblyIdentity().PublicKey;
var mvidAlpha1 = CreateNetStandardDll(directory, "MvidAlpha", "1.0.0.0", key, "class C { }");
Expand Down
12 changes: 10 additions & 2 deletions src/Compilers/Server/VBCSCompilerTests/TouchedFileLoggingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ End Class
[ConditionalFact(typeof(DesktopOnly))]
public void CSharpTrivialMetadataCaching()
{
var loader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(Temp.CreateDirectory().Path);
var loader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(
#if NET
loadContext: null,
#endif
Temp.CreateDirectory().Path);
var filelist = new List<string>();

// Do the following compilation twice.
Expand Down Expand Up @@ -97,7 +101,11 @@ public void CSharpTrivialMetadataCaching()
[ConditionalFact(typeof(DesktopOnly))]
public void VisualBasicTrivialMetadataCaching()
{
var loader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(Temp.CreateDirectory().Path);
var loader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(
#if NET
loadContext: null,
#endif
Temp.CreateDirectory().Path);
var filelist = new List<string>();

// Do the following compilation twice.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Immutable;
using System.Composition;
using System.Reflection;
using System.Runtime.Loader;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.LanguageServer.Services;
Expand All @@ -24,9 +25,10 @@ internal sealed class VSCodeAnalyzerLoaderProvider(
private readonly ExtensionAssemblyManager _extensionAssemblyManager = extensionAssemblyManager;
private readonly ILoggerFactory _loggerFactory = loggerFactory;

protected override IAnalyzerAssemblyLoader CreateShadowCopyLoader(ImmutableArray<IAnalyzerAssemblyResolver> externalResolvers)
protected override IAnalyzerAssemblyLoader CreateShadowCopyLoader(
AssemblyLoadContext? loadContext, string isolatedRoot)
{
var baseLoader = base.CreateShadowCopyLoader(externalResolvers);
var baseLoader = base.CreateShadowCopyLoader(loadContext, isolatedRoot);
return new VSCodeExtensionAssemblyAnalyzerLoader(baseLoader, _extensionAssemblyManager, _loggerFactory.CreateLogger<VSCodeExtensionAssemblyAnalyzerLoader>());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
using System.Collections.Immutable;
using System.IO;

#if NET
using System.Runtime.Loader;
#endif

namespace Microsoft.CodeAnalysis.Host;

/// <summary>
Expand All @@ -15,20 +19,47 @@ namespace Microsoft.CodeAnalysis.Host;
internal abstract class AbstractAnalyzerAssemblyLoaderProvider : IAnalyzerAssemblyLoaderProvider
Copy link
Member Author

Choose a reason for hiding this comment

The 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
loadContext: null,
#endif
Copy link
Member Author

Choose a reason for hiding this comment

The 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
Expand Up @@ -9,6 +9,10 @@
using System.Collections.Immutable;
using System.Collections.Generic;

#if NET
using System.Runtime.Loader;
#endif

namespace Microsoft.CodeAnalysis.Host;

[ExportWorkspaceServiceFactory(typeof(IAnalyzerAssemblyLoaderProvider)), Shared]
Expand All @@ -31,10 +35,27 @@ private sealed class DefaultAnalyzerAssemblyLoaderProvider(string workspaceKind,
/// correctness. But it is annoying and does cause noise in our perf test harness.
/// </summary>
private readonly IAnalyzerAssemblyLoader _shadowCopyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(
Path.Combine(Path.GetTempPath(), "CodeAnalysis", "WorkspacesAnalyzerShadowCopies", workspaceKind),
externalResolvers: externalResolvers);
#if NET
loadContext: null,
#endif
GetPath(workspaceKind, isolatedRoot: ""),
externalResolvers);

private static string GetPath(string workspaceKind, string isolatedRoot)
=> Path.Combine(Path.GetTempPath(), "CodeAnalysis", "WorkspacesAnalyzerShadowCopies", workspaceKind, isolatedRoot);

#if NET

public IAnalyzerAssemblyLoader GetShadowCopyLoader(AssemblyLoadContext? loadContext, string isolatedRoot)
=> loadContext is null && isolatedRoot == ""
? _shadowCopyLoader
: DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(loadContext, GetPath(workspaceKind, isolatedRoot));

#else

public IAnalyzerAssemblyLoader GetShadowCopyLoader()
=> _shadowCopyLoader;

#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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,10 @@ public virtual AnalyzerReference ReadAnalyzerReferenceFrom(ObjectReader reader,
switch (reader.ReadString())
{
case nameof(AnalyzerFileReference):
var fullPath = reader.ReadRequiredString();
return new AnalyzerFileReference(fullPath, _analyzerLoaderProvider.GetShadowCopyLoader());
// Don't rehydrate an AnalyzerFileReference. That will happen in
// RemoteWorkspace.CreateAnalyzerReferencesInIsolatedAssemblyLoadContextAsync when it sees the entire
// set of assembly references it wants to populate its solution with.
return new SerializedAnalyzerReference(reader.ReadRequiredString());

case nameof(AnalyzerImageReference):
var guid = reader.ReadGuid();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,27 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.CodeAnalysis.Diagnostics;

#if NET
using System.Runtime.Loader;
#endif

namespace Microsoft.CodeAnalysis.Host;

internal interface IAnalyzerAssemblyLoaderProvider : IWorkspaceService
{
#if NET
/// <summary>
/// In .Net core, gives back a shadow copying loader that will load all <see cref="AnalyzerReference"/> in the
/// requested <paramref name="loadContext"/> (or a default one if unspecified). <paramref name="isolatedRoot"/> can
/// be used to ensure a dedicated directory for the shadow copying to happen in, to prevent any collisions
/// whatsoever. For example, given two <see cref="AnalyzerReference"/>s with the same MVID, but loaded into
/// different <see cref="AssemblyLoadContext"/>s; different paths would be desired to prevent collisions.
/// </summary>
IAnalyzerAssemblyLoader GetShadowCopyLoader(AssemblyLoadContext? loadContext = null, string isolatedRoot = "");
#else

IAnalyzerAssemblyLoader GetShadowCopyLoader();
#endif
}
Loading