Skip to content

Commit ad2e8df

Browse files
committed
Implement razor redirection as an assembly redirector
- Remove the special casing for razor in projectsystemproject - Remove HostDiagnosticAnalyzerProvider as it is no longer needed - Add an EA redirector that razor can implement - MEF import the redirectors where needed - Remove RazorSourceGenerator option from language server
1 parent cac213f commit ad2e8df

File tree

12 files changed

+28
-171
lines changed

12 files changed

+28
-171
lines changed

src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer.UnitTests/Utilities/LanguageServerTestComposition.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ internal sealed class LanguageServerTestComposition
2424
SessionId: null,
2525
ExtensionAssemblyPaths: extensionPaths ?? [],
2626
DevKitDependencyPath: devKitDependencyPath,
27-
RazorSourceGenerator: null,
2827
RazorDesignTimePath: null,
2928
ExtensionLogDirectory: string.Empty,
3029
ServerPipeName: null,

src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/HostDiagnosticAnalyzerProvider.cs

Lines changed: 0 additions & 45 deletions
This file was deleted.

src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/LanguageServerWorkspaceFactory.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Microsoft.CodeAnalysis.LanguageServer.Handler.DebugConfiguration;
1111
using Microsoft.CodeAnalysis.LanguageServer.Services;
1212
using Microsoft.CodeAnalysis.ProjectSystem;
13+
using Microsoft.CodeAnalysis.Workspaces.AnalyzerRedirecting;
1314
using Microsoft.CodeAnalysis.Workspaces.ProjectSystem;
1415
using Microsoft.Extensions.Logging;
1516
using Microsoft.VisualStudio.Composition;
@@ -30,8 +31,8 @@ public LanguageServerWorkspaceFactory(
3031
IFileChangeWatcher fileChangeWatcher,
3132
[ImportMany] IEnumerable<Lazy<IDynamicFileInfoProvider, FileExtensionsMetadata>> dynamicFileInfoProviders,
3233
ProjectTargetFrameworkManager projectTargetFrameworkManager,
33-
ServerConfigurationFactory serverConfigurationFactory,
3434
ExtensionAssemblyManager extensionManager,
35+
[ImportMany] IEnumerable<IAnalyzerAssemblyRedirector> assemblyRedirectors,
3536
ILoggerFactory loggerFactory)
3637
{
3738
_logger = loggerFactory.CreateLogger(nameof(LanguageServerWorkspaceFactory));
@@ -62,11 +63,9 @@ public LanguageServerWorkspaceFactory(
6263
fileBasedProgramsWorkspace, fileChangeWatcher, static (_, _) => Task.CompletedTask, _ => { }, CancellationToken.None);
6364
fileBasedProgramsWorkspace.ProjectSystemProjectFactory = FileBasedProgramsProjectFactory;
6465

65-
var razorSourceGenerator = serverConfigurationFactory?.ServerConfiguration?.RazorSourceGenerator;
6666
ProjectSystemHostInfo = new ProjectSystemHostInfo(
6767
DynamicFileInfoProviders: [.. dynamicFileInfoProviders],
68-
new HostDiagnosticAnalyzerProvider(razorSourceGenerator),
69-
AnalyzerAssemblyRedirectors: []);
68+
AnalyzerAssemblyRedirectors: [.. assemblyRedirectors]);
7069

7170
TargetFrameworkManager = projectTargetFrameworkManager;
7271
}

src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/Program.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,6 @@ static CommandLineConfiguration CreateCommandLineParser()
221221
Required = false
222222
};
223223

224-
var razorSourceGeneratorOption = new Option<string?>("--razorSourceGenerator")
225-
{
226-
Description = "Full path to the Razor source generator (optional).",
227-
Required = false
228-
};
229-
230224
var razorDesignTimePathOption = new Option<string?>("--razorDesignTimePath")
231225
{
232226
Description = "Full path to the Razor design time target path (optional).",
@@ -257,7 +251,6 @@ static CommandLineConfiguration CreateCommandLineParser()
257251
sessionIdOption,
258252
extensionAssemblyPathsOption,
259253
devKitDependencyPathOption,
260-
razorSourceGeneratorOption,
261254
razorDesignTimePathOption,
262255
extensionLogDirectoryOption,
263256
serverPipeNameOption,
@@ -273,7 +266,6 @@ static CommandLineConfiguration CreateCommandLineParser()
273266
var sessionId = parseResult.GetValue(sessionIdOption);
274267
var extensionAssemblyPaths = parseResult.GetValue(extensionAssemblyPathsOption) ?? [];
275268
var devKitDependencyPath = parseResult.GetValue(devKitDependencyPathOption);
276-
var razorSourceGenerator = parseResult.GetValue(razorSourceGeneratorOption);
277269
var razorDesignTimePath = parseResult.GetValue(razorDesignTimePathOption);
278270
var extensionLogDirectory = parseResult.GetValue(extensionLogDirectoryOption)!;
279271
var serverPipeName = parseResult.GetValue(serverPipeNameOption);
@@ -287,7 +279,6 @@ static CommandLineConfiguration CreateCommandLineParser()
287279
SessionId: sessionId,
288280
ExtensionAssemblyPaths: extensionAssemblyPaths,
289281
DevKitDependencyPath: devKitDependencyPath,
290-
RazorSourceGenerator: razorSourceGenerator,
291282
RazorDesignTimePath: razorDesignTimePath,
292283
ServerPipeName: serverPipeName,
293284
UseStdIo: useStdIo,

src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/ServerConfigurationFactory.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ internal sealed record class ServerConfiguration(
4848
string? SessionId,
4949
IEnumerable<string> ExtensionAssemblyPaths,
5050
string? DevKitDependencyPath,
51-
string? RazorSourceGenerator,
5251
string? RazorDesignTimePath,
5352
string? ServerPipeName,
5453
bool UseStdIo,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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;
6+
using System.Composition;
7+
using Microsoft.CodeAnalysis.Host.Mef;
8+
using Microsoft.CodeAnalysis.Workspaces.AnalyzerRedirecting;
9+
10+
namespace Microsoft.CodeAnalysis.ExternalAccess.Razor;
11+
12+
[Export(typeof(IAnalyzerAssemblyRedirector)), Shared]
13+
[method: ImportingConstructor]
14+
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
15+
internal sealed class RazorAnalyzerAssemblyRedirector([Import(AllowDefault = true)] RazorAnalyzerAssemblyRedirector.IRazorAnalyzerAssemblyRedirector? razorRedirector = null) : IAnalyzerAssemblyRedirector
16+
{
17+
public string? RedirectPath(string fullPath) => razorRedirector?.RedirectPath(fullPath);
18+
19+
internal interface IRazorAnalyzerAssemblyRedirector
20+
{
21+
string? RedirectPath(string fullPath);
22+
}
23+
}

src/VisualStudio/Core/Def/Diagnostics/VisualStudioDiagnosticAnalyzerProvider.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Diagnostics;
1919
/// This service provides diagnostic analyzers from the analyzer assets specified in the manifest files of installed VSIX extensions.
2020
/// These analyzers are used across this workspace session.
2121
/// </summary>
22-
internal sealed partial class VisualStudioDiagnosticAnalyzerProvider : IHostDiagnosticAnalyzerProvider
22+
internal sealed partial class VisualStudioDiagnosticAnalyzerProvider
2323
{
2424
private const string AnalyzerContentTypeName = "Microsoft.VisualStudio.Analyzer";
2525

@@ -34,7 +34,6 @@ internal sealed partial class VisualStudioDiagnosticAnalyzerProvider : IHostDiag
3434
private readonly Type _typeIExtensionContent;
3535

3636
private readonly Lazy<ImmutableArray<(AnalyzerFileReference reference, string extensionId)>> _lazyAnalyzerReferences;
37-
private readonly Lazy<ImmutableArray<(string path, string extensionId)>> _lazyRazorReferences;
3837

3938
// internal for testing
4039
internal VisualStudioDiagnosticAnalyzerProvider(object extensionManager, Type typeIExtensionContent)
@@ -45,15 +44,11 @@ internal VisualStudioDiagnosticAnalyzerProvider(object extensionManager, Type ty
4544
_extensionManager = extensionManager;
4645
_typeIExtensionContent = typeIExtensionContent;
4746
_lazyAnalyzerReferences = new Lazy<ImmutableArray<(AnalyzerFileReference, string)>>(() => GetExtensionContent(AnalyzerContentTypeName).SelectAsArray(c => (new AnalyzerFileReference(c.path, AnalyzerAssemblyLoader), c.extensionId)));
48-
_lazyRazorReferences = new Lazy<ImmutableArray<(string, string)>>(() => GetExtensionContent(RazorContentTypeName));
4947
}
5048

5149
public ImmutableArray<(AnalyzerFileReference reference, string extensionId)> GetAnalyzerReferencesInExtensions()
5250
=> _lazyAnalyzerReferences.Value;
5351

54-
public ImmutableArray<(string path, string extensionId)> GetRazorAssembliesInExtensions()
55-
=> _lazyRazorReferences.Value;
56-
5752
private ImmutableArray<(string path, string extensionId)> GetExtensionContent(string contentTypeName)
5853
{
5954
try

src/VisualStudio/Core/Def/ProjectSystem/VisualStudioProjectFactory.cs

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,47 +34,23 @@ internal sealed class VisualStudioProjectFactory : IVsTypeScriptVisualStudioProj
3434
private readonly IThreadingContext _threadingContext;
3535
private readonly VisualStudioWorkspaceImpl _visualStudioWorkspaceImpl;
3636
private readonly ImmutableArray<Lazy<IDynamicFileInfoProvider, FileExtensionsMetadata>> _dynamicFileInfoProviders;
37-
private readonly IVisualStudioDiagnosticAnalyzerProviderFactory _vsixAnalyzerProviderFactory;
3837
private readonly ImmutableArray<IAnalyzerAssemblyRedirector> _analyzerAssemblyRedirectors;
3938
private readonly IVsService<SVsBackgroundSolution, IVsBackgroundSolution> _solution;
4039

41-
private readonly JoinableTask<VisualStudioDiagnosticAnalyzerProvider> _initializationTask;
42-
4340
[ImportingConstructor]
4441
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
4542
public VisualStudioProjectFactory(
4643
IThreadingContext threadingContext,
4744
VisualStudioWorkspaceImpl visualStudioWorkspaceImpl,
4845
[ImportMany] IEnumerable<Lazy<IDynamicFileInfoProvider, FileExtensionsMetadata>> fileInfoProviders,
49-
IVisualStudioDiagnosticAnalyzerProviderFactory vsixAnalyzerProviderFactory,
5046
[ImportMany] IEnumerable<IAnalyzerAssemblyRedirector> analyzerAssemblyRedirectors,
5147
IVsService<SVsBackgroundSolution, IVsBackgroundSolution> solution)
5248
{
5349
_threadingContext = threadingContext;
5450
_visualStudioWorkspaceImpl = visualStudioWorkspaceImpl;
5551
_dynamicFileInfoProviders = fileInfoProviders.AsImmutableOrEmpty();
56-
_vsixAnalyzerProviderFactory = vsixAnalyzerProviderFactory;
5752
_analyzerAssemblyRedirectors = analyzerAssemblyRedirectors.AsImmutableOrEmpty();
5853
_solution = solution;
59-
60-
_initializationTask = _threadingContext.JoinableTaskFactory.RunAsync(
61-
async () =>
62-
{
63-
var cancellationToken = _threadingContext.DisposalToken;
64-
65-
// HACK: Fetch this service to ensure it's still created on the UI thread; once this is
66-
// moved off we'll need to fix up it's constructor to be free-threaded.
67-
68-
// yield if on the main thread, as the VisualStudioMetadataReferenceManager construction can be fairly expensive
69-
// and we don't want the case where VisualStudioProjectFactory is constructed on the main thread to block on that.
70-
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(alwaysYield: true, cancellationToken);
71-
_visualStudioWorkspaceImpl.Services.GetRequiredService<VisualStudioMetadataReferenceManager>();
72-
73-
_visualStudioWorkspaceImpl.SubscribeExternalErrorDiagnosticUpdateSourceToSolutionBuildEvents();
74-
_visualStudioWorkspaceImpl.SubscribeToSourceGeneratorImpactingEvents();
75-
76-
return await _vsixAnalyzerProviderFactory.GetOrCreateProviderAsync(cancellationToken).ConfigureAwait(true);
77-
});
7854
}
7955

8056
public Task<ProjectSystemProject> CreateAndAddToWorkspaceAsync(string projectSystemName, string language, CancellationToken cancellationToken)
@@ -83,8 +59,6 @@ public Task<ProjectSystemProject> CreateAndAddToWorkspaceAsync(string projectSys
8359
public async Task<ProjectSystemProject> CreateAndAddToWorkspaceAsync(
8460
string projectSystemName, string language, VisualStudioProjectCreationInfo creationInfo, CancellationToken cancellationToken)
8561
{
86-
var vsixAnalyzerProvider = await _initializationTask.JoinAsync(cancellationToken).ConfigureAwait(false);
87-
8862
// The rest of this method can be ran off the UI thread. We'll only switch though if the UI thread isn't already blocked -- the legacy project
8963
// system creates project synchronously, and during solution load we've seen traces where the thread pool is sufficiently saturated that this
9064
// switch can't be completed quickly. For the rest of this method, we won't use ConfigureAwait(false) since we're expecting VS threading
@@ -102,7 +76,7 @@ public async Task<ProjectSystemProject> CreateAndAddToWorkspaceAsync(
10276
_visualStudioWorkspaceImpl.ProjectSystemProjectFactory.SolutionPath = solution?.SolutionFileName;
10377
_visualStudioWorkspaceImpl.ProjectSystemProjectFactory.SolutionTelemetryId = GetSolutionSessionId();
10478

105-
var hostInfo = new ProjectSystemHostInfo(_dynamicFileInfoProviders, vsixAnalyzerProvider, _analyzerAssemblyRedirectors);
79+
var hostInfo = new ProjectSystemHostInfo(_dynamicFileInfoProviders, _analyzerAssemblyRedirectors);
10680
var project = await _visualStudioWorkspaceImpl.ProjectSystemProjectFactory.CreateAndAddToWorkspaceAsync(projectSystemName, language, creationInfo, hostInfo).ConfigureAwait(true);
10781

10882
_visualStudioWorkspaceImpl.AddProjectToInternalMaps(project, creationInfo.Hierarchy, creationInfo.ProjectGuid, projectSystemName);

src/VisualStudio/Core/Test/Diagnostics/VisualStudioDiagnosticAnalyzerProviderTests.vb

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,5 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics
6262
End Using
6363
End Sub
6464

65-
<Fact>
66-
Public Sub GetRazorReferencesInExtensions()
67-
Dim extensionManager = New VisualStudioDiagnosticAnalyzerProvider(
68-
New MockExtensionManager({({"razorPath1", "razorPath2"}, "RazorVsix")}, contentType:="Microsoft.VisualStudio.RazorAssembly"),
69-
GetType(MockExtensionManager.MockContent))
70-
71-
Dim references = extensionManager.GetRazorAssembliesInExtensions()
72-
73-
AssertEx.SetEqual(
74-
{
75-
Path.Combine(TempRoot.Root, "InstallPath\razorPath1"),
76-
Path.Combine(TempRoot.Root, "InstallPath\razorPath2")
77-
},
78-
references.Select(Function(pathAndId) pathAndId.path))
79-
End Sub
8065
End Class
8166
End Namespace

src/Workspaces/Core/Portable/Workspace/ProjectSystem/IHostDiagnosticAnalyzerProvider.cs

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)