Skip to content

Commit 00dcd81

Browse files
authored
Razor assembly redirector (#78852)
* 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 * Remove test that is no longer valid * Restore razorSourceGeneratorOption: - The VS Code C# extension is still passing the argument and we error if we get an unrecognized option. We can remove this once we update the C# side. * Fix redirect message
1 parent ccb0576 commit 00dcd81

File tree

14 files changed

+32
-230
lines changed

14 files changed

+32
-230
lines changed

src/Compilers/Core/Portable/CodeAnalysisEventSource.Common.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ internal unsafe void NodeTransform(int nodeHashCode, string name, string tableTy
125125
[Event(16, Message = "Analyzer reference '{0}' was removed from project '{1}'", Keywords = Keywords.AnalyzerLoading, Level = EventLevel.Informational)]
126126
internal void AnalyzerReferenceRemovedFromProject(string path, string projectName) => WriteEvent(16, path, projectName);
127127

128-
[Event(17, Message = "Analyzer reference was redirected by '{0}' from '{1}' to '{2}' for project '{3}'", Keywords = Keywords.AnalyzerLoading, Level = EventLevel.Verbose, Task = Tasks.BuildStateTable)]
128+
[Event(17, Message = "Analyzer reference was redirected by '{0}' from '{1}' to '{2}' for project '{3}'", Keywords = Keywords.AnalyzerLoading, Level = EventLevel.Informational)]
129129
internal unsafe void AnanlyzerReferenceRedirected(string redirectorType, string originalPath, string newPath, string project)
130130
{
131131
if (IsEnabled())

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 & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,6 @@ static CommandLineConfiguration CreateCommandLineParser()
273273
var sessionId = parseResult.GetValue(sessionIdOption);
274274
var extensionAssemblyPaths = parseResult.GetValue(extensionAssemblyPathsOption) ?? [];
275275
var devKitDependencyPath = parseResult.GetValue(devKitDependencyPathOption);
276-
var razorSourceGenerator = parseResult.GetValue(razorSourceGeneratorOption);
277276
var razorDesignTimePath = parseResult.GetValue(razorDesignTimePathOption);
278277
var extensionLogDirectory = parseResult.GetValue(extensionLogDirectoryOption)!;
279278
var serverPipeName = parseResult.GetValue(serverPipeNameOption);
@@ -287,7 +286,6 @@ static CommandLineConfiguration CreateCommandLineParser()
287286
SessionId: sessionId,
288287
ExtensionAssemblyPaths: extensionAssemblyPaths,
289288
DevKitDependencyPath: devKitDependencyPath,
290-
RazorSourceGenerator: razorSourceGenerator,
291289
RazorDesignTimePath: razorDesignTimePath,
292290
ServerPipeName: serverPipeName,
293291
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
@@ -18,7 +18,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Diagnostics;
1818
/// This service provides diagnostic analyzers from the analyzer assets specified in the manifest files of installed VSIX extensions.
1919
/// These analyzers are used across this workspace session.
2020
/// </summary>
21-
internal sealed partial class VisualStudioDiagnosticAnalyzerProvider : IHostDiagnosticAnalyzerProvider
21+
internal sealed partial class VisualStudioDiagnosticAnalyzerProvider
2222
{
2323
private const string AnalyzerContentTypeName = "Microsoft.VisualStudio.Analyzer";
2424

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

3535
private readonly Lazy<ImmutableArray<(AnalyzerFileReference reference, string extensionId)>> _lazyAnalyzerReferences;
36-
private readonly Lazy<ImmutableArray<(string path, string extensionId)>> _lazyRazorReferences;
3736

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

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

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

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,26 +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;
40+
private readonly JoinableTask _initializationTask;
4241

4342
[ImportingConstructor]
4443
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
4544
public VisualStudioProjectFactory(
4645
IThreadingContext threadingContext,
4746
VisualStudioWorkspaceImpl visualStudioWorkspaceImpl,
4847
[ImportMany] IEnumerable<Lazy<IDynamicFileInfoProvider, FileExtensionsMetadata>> fileInfoProviders,
49-
IVisualStudioDiagnosticAnalyzerProviderFactory vsixAnalyzerProviderFactory,
5048
[ImportMany] IEnumerable<IAnalyzerAssemblyRedirector> analyzerAssemblyRedirectors,
5149
IVsService<SVsBackgroundSolution, IVsBackgroundSolution> solution)
5250
{
5351
_threadingContext = threadingContext;
5452
_visualStudioWorkspaceImpl = visualStudioWorkspaceImpl;
5553
_dynamicFileInfoProviders = fileInfoProviders.AsImmutableOrEmpty();
56-
_vsixAnalyzerProviderFactory = vsixAnalyzerProviderFactory;
5754
_analyzerAssemblyRedirectors = analyzerAssemblyRedirectors.AsImmutableOrEmpty();
5855
_solution = solution;
5956

@@ -72,8 +69,6 @@ public VisualStudioProjectFactory(
7269

7370
_visualStudioWorkspaceImpl.SubscribeExternalErrorDiagnosticUpdateSourceToSolutionBuildEvents();
7471
_visualStudioWorkspaceImpl.SubscribeToSourceGeneratorImpactingEvents();
75-
76-
return await _vsixAnalyzerProviderFactory.GetOrCreateProviderAsync(cancellationToken).ConfigureAwait(true);
7772
});
7873
}
7974

@@ -83,7 +78,7 @@ public Task<ProjectSystemProject> CreateAndAddToWorkspaceAsync(string projectSys
8378
public async Task<ProjectSystemProject> CreateAndAddToWorkspaceAsync(
8479
string projectSystemName, string language, VisualStudioProjectCreationInfo creationInfo, CancellationToken cancellationToken)
8580
{
86-
var vsixAnalyzerProvider = await _initializationTask.JoinAsync(cancellationToken).ConfigureAwait(false);
81+
await _initializationTask.JoinAsync(cancellationToken).ConfigureAwait(false);
8782

8883
// 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
8984
// system creates project synchronously, and during solution load we've seen traces where the thread pool is sufficiently saturated that this
@@ -102,7 +97,7 @@ public async Task<ProjectSystemProject> CreateAndAddToWorkspaceAsync(
10297
_visualStudioWorkspaceImpl.ProjectSystemProjectFactory.SolutionPath = solution?.SolutionFileName;
10398
_visualStudioWorkspaceImpl.ProjectSystemProjectFactory.SolutionTelemetryId = GetSolutionSessionId();
10499

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

108103
_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
@@ -61,20 +61,5 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics
6161
End Using
6262
End Sub
6363

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

0 commit comments

Comments
 (0)