Skip to content

Conversation

chsienki
Copy link
Member

This is the Razor half of dotnet/roslyn#78852

It provides a redirector that will redirect the razor generator and its dependencies.

@chsienki
Copy link
Member Author

@dotnet/razor-compiler for reviews please.

@chsienki
Copy link
Member Author

/cc @davidwengier @ToddGrun

Copy link
Member

@davidwengier davidwengier left a comment

Choose a reason for hiding this comment

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

LGTM in general, very happy to see this progressing. Just not sure how strict we need to be about the version of Roslyn we use.

<Dependencies>
<Source Uri="https://github.com/dotnet/dotnet" Mapping="razor" Sha="f5705c8f4c5079bba77bae8698ba1583bde0388c" BarId="269610" />
<ProductDependencies>
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="5.0.0-1.25316.1">
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="5.0.0-1.25321.1">
Copy link
Member

Choose a reason for hiding this comment

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

It doesn't look like this version has been inserted into VS main yet, so merging this PR could possibly break people, or our integration tests. It looks like if we downgrade this to 5.0.0-1.25319.11 then we get a version that has the Razor redirector and is in VS main.

The alternative is to wait a few days, or roll the dice that this will be fine. Or I guess we could kick off an integration test run for this branch?

Copy link
Member

Choose a reason for hiding this comment

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

Scratch that, looks like 5.0.0-1.25323.2 has been inserted now, so this version should be fine.

[Export(typeof(IRazorAnalyzerAssemblyRedirector))]
[method: ImportingConstructor]
#pragma warning restore RS0030 // Do not use banned APIs
internal class RazorAnalyzerAssemblyRedirector() : IRazorAnalyzerAssemblyRedirector
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
internal class RazorAnalyzerAssemblyRedirector() : IRazorAnalyzerAssemblyRedirector
internal sealed class RazorAnalyzerAssemblyRedirector() : IRazorAnalyzerAssemblyRedirector


namespace Microsoft.VisualStudio.Razor;

#pragma warning disable RS0030 // Do not use banned APIs
Copy link
Member

Choose a reason for hiding this comment

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

What's the banned API? And why is it banned?

Copy link
Member

Choose a reason for hiding this comment

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

The export attributes and its friends are MEF v2, which is banned in the LanguageServices.Razor project, which uses this shared library. I'm not sure I can remember why, but whats a little cargo culting between friends.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure I can remember why, but whats a little cargo culting between friends.

MS.VS.LanguageServers.Razor enforces MEFv1 because Visual Studio's MEF attributes are MEFv1. VS MEF supports importing both MEFv1 and MEFv2 attributes, but things can get in certain scenarios if their attributes are mixed on the same types.

Copy link
Member Author

Choose a reason for hiding this comment

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

but whats a little cargo culting between friends

This precisely. It wasn't getting imported into VSCode when using one version, so I looked at the other exported parts and they had the other version and the suppression, so I copied it and it worked.

Copy link
Member

Choose a reason for hiding this comment

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

Should we consider leaving a comment about this for future readers?

Copy link
Member

Choose a reason for hiding this comment

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

It's replicated across most of the files in this shared project.


namespace Microsoft.VisualStudio.Razor;

#pragma warning disable RS0030 // Do not use banned APIs
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure I can remember why, but whats a little cargo culting between friends.

MS.VS.LanguageServers.Razor enforces MEFv1 because Visual Studio's MEF attributes are MEFv1. VS MEF supports importing both MEFv1 and MEFv2 attributes, but things can get in certain scenarios if their attributes are mixed on the same types.

Copy link
Member

@DustinCampbell DustinCampbell left a comment

Choose a reason for hiding this comment

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

oops. Accidentally blocked the PR. 😄

@DustinCampbell DustinCampbell self-requested a review June 24, 2025 15:55
@davidwengier
Copy link
Member

FYI, I merged the cleanup PR so the file header on your new file will be incorrect in CI. You probably want to merge in main :)

@chsienki
Copy link
Member Author

This is waiting on dotnet/roslyn#79154 to prevent the extra assembly load in non-razor cases.


namespace Microsoft.VisualStudio.Razor;

#pragma warning disable RS0030 // Do not use banned APIs
Copy link
Member

Choose a reason for hiding this comment

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

Should we consider leaving a comment about this for future readers?

{
private static readonly ImmutableArray<Type> s_compilerAssemblyTypes = [

typeof(CodeAnalysis.Razor.CompilerFeatures), // Microsoft.CodeAnalysis.Razor.Compiler.dll
Copy link
Member

Choose a reason for hiding this comment

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

Can we assert these comments somehow? Or at least assert that they are different assemblies? Maybe there's some reflection-based asserts we can do to ensure that there's no unexpected assemblies being referenced that would need to be redirected in the face of a future refactoring?

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 ended up adding a unit test that 'pins' the expected assemblies, so if they change or get moved etc it will fail and we can't accidentally break things. I added a comment explaining the purpose.

@chsienki chsienki force-pushed the analyzer_redirector branch from 2378993 to a606e79 Compare June 27, 2025 19:51
davidwengier added a commit that referenced this pull request Jul 1, 2025
Mostly fixes #11942

We still currently get "Couldn't get code document" errors when the
source generator is hooked up, but didn't run, but I'm leaving that
because it should be fixed by
#11972, and if it isn't then we
either want to know, or can add handling of it in then.

Commit-at-a-time is probably easiest, mostly because the 2nd commit
changes every cohost endpoint to inherit from a new base class, so it's
pretty noisy.
@chsienki
Copy link
Member Author

chsienki commented Jul 2, 2025

Merging as internal insertion now shows clean metrics: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/648244

@chsienki chsienki merged commit 3e772db into dotnet:main Jul 2, 2025
11 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Jul 2, 2025
@RikkiGibson RikkiGibson removed this from the Next milestone Aug 20, 2025
@RikkiGibson RikkiGibson added this to the 18.0 P1 milestone Aug 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants