Skip to content
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

Update Razor EA #77194

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open

Update Razor EA #77194

wants to merge 16 commits into from

Conversation

ryzngard
Copy link
Contributor

@ryzngard ryzngard commented Feb 13, 2025

Commit by commit tells a story

The story started strong but is in shambles now.

The goal of this is to start separating the Razor EA from things requiring EditorFeatures and things that do not. Some things are left clunky due to not wanting to break/dual insert into VS.

For VS Code a dual insertion will be needed. Razor will now be loaded into the Roslyn LSP server through a new binary "Microsoft.VisualStudioCode.RazorExtension" which will ship in the .razor folder in vs code. This will provide all of the hooks necessary to provide dynamic file info as well as any LSP endpoints needed in MS.CA.LanguageServer for razor to function.

/Shared : will eventually be the area for all source items shared between
the current EA and the new EA.Razor.Features
/Features : will have an EA that is restricted to depending only on the
features layer. This will help provide a way to ship a more sane EA
structure for VS Code as well as reduce the likelyhood and work required
for a dual insertion
/EditorFeatures : contains the current EA. The project name is kept the
same for now but the folder is moved. This denotes that the binary does
depend on the EditorFeatures layer in Roslyn

Code changes limited to updating references and pathing only. No
new/edited/removed code.
… razor in LSP that is based on reflection. Initialize and Dynamic file will use this to handle razor logic.
Shared contains mostly contracts and a few data classes/wrappers that
are common between VS/VS Code. The layering itself is not strictly for
those clients but instead is meant to be a split to remove the
dependency upon EditorFeatures.

Prepare for Features layer to load an IRazorServiceProvider to be used
in Microsoft.CodeAnalysis.LanguageServer

Remove a lot of the implementation logic from
Microsoft.CodeAnalysis.LanguageServer. This should now be provided from
the razor assembly that is loaded in the LanguageServer via
RazorLSPServiceProvider

Remove shared code from the existing EA.
Publish MSCA.EA.Razor.Features

Remove IsExternalInit
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Feb 13, 2025
@dotnet-policy-service dotnet-policy-service bot added VSCode Needs API Review Needs to be reviewed by the API review council labels Feb 13, 2025
@ryzngard ryzngard changed the title Update Razor EA [DRAFT] Update Razor EA Feb 13, 2025
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.

The layout makes sense, had a couple of questions, but probably just be not seeing the bigger picture

<!--
This is used to load in the language server so it gets special treatment. Otherwise only razor assemblies should be added.
-->
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.LanguageServer" />
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this going to cause a problem later, when we need the language server to have IVT to this project, so we can put LSP endpoints in it? Or is that going to go through the IRazorServiceProvider?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Might need to chat with you. My understanding of how the lsp endpoints got hooked up is just a normal export with a razor class in the middle. That's what I thought co-hosting was doing.

Can we hook up endpoints through the service provider? Might make things easier and cleaner

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 an export, yeah, but the type being exported has to inherit from something like ILspServiceRequestHandler which we expose via our EA.

BUT I just looked it up to be sure, and actually I'm wrong, and I think this will be fine, because that type is in MS.CA.LS.Protocol, so maybe we can get away with never needing to expose anything from the language server itself through our EA.

using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.LanguageServer;

namespace Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost;

[Shared]
[ExportCohostLspServiceFactory(typeof(IRazorCohostClientLanguageServerManager))]
[ExportCohostLspServiceFactory(typeof(IRazorClientLanguageServerManager))]
Copy link
Member

Choose a reason for hiding this comment

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

FYI, this makes this PR binary breaking so we need a dual insertion. Not necessarily the end of the world since this would be the 3rd in line, but wanted to note it at least. If this is the only break, it could be pretty trivially avoided if that was preferred.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah yea. I can do without this change for now to avoid a binary break

Copy link
Member

Choose a reason for hiding this comment

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

To be clear though, the new name makes sense, so perhaps export this twice, once with the old and once with the new name, so we can move over to it in time.

@ryzngard
Copy link
Contributor Author

This is at least in a state where VS shouldn't break or require a dual insertion. Marking ready for review.

VS Code will need a dual insertion. Hopefully one of the last ones....

@ryzngard ryzngard marked this pull request as ready for review February 19, 2025 20:37
@ryzngard ryzngard requested review from a team as code owners February 19, 2025 20:37
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.

Nit: Should remove "[DRAFT]" from the PR title 😛

Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.CodeAnalysis.ExtnernalAccess.Razor.Shared", "src\Tools\ExternalAccess\Razor\Shared\Microsoft.CodeAnalysis.ExtnernalAccess.Razor.Shared.shproj", "{4853A78A-4EC4-4D86-9F02-D0DDEAE85520}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CodeAnalysis.ExternalAccess.Razor.Features", "src\Tools\ExternalAccess\Razor\Features\Microsoft.CodeAnalysis.ExternalAccess.Razor.Features.csproj", "{D5A8E20C-E8D2-4A57-906A-263994D8731D}"
EndProject
Global
Copy link
Member

Choose a reason for hiding this comment

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

The external access projects will continue until morale improves!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I asked co-pilot when that would be and...

Magic8ballSimpsonsGIF

await dynamicFileInfoProvider.EnsureInitializedAsync(
static ct =>
{
return RazorLSPServiceProvider.GetRequiredServiceAsync<IRazorClientLanguageServerManager>(ct);
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a comment explaining this indirection? Seems odd to initialize a razor service with a delegate to get a different razor service from a razor service provider. Can the initialize method not take the IRazorClientLanguageServerManager directly? Or even better, the IRazorServiceProvider in case its dependencies change?


namespace Microsoft.CodeAnalysis.ExternalAccess.Razor.Features;

internal interface IRazorLSPDynamicFileInfoProvider
Copy link
Member

Choose a reason for hiding this comment

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

"LSP" in the name here seems odd. Isn't this just an IRazorDynamicFileInfoProvider, and the implementation happens to use LSP in VS Code, and not in VS?

The only thing that is "LSP-y" about this seems to be the IRazorClientLanguageServerManager bit on the initialize method, so maybe my above comment about passing in a IRazorServiceProvider would resolve that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea, let me rethink this. The main thing is that the LSP portion = needs a way to communicate using IRazorClientLanguageServerManager. Let me see if I can get rid of the initialize method and change the name

@ryzngard ryzngard changed the title [DRAFT] Update Razor EA Update Razor EA Feb 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE Needs API Review Needs to be reviewed by the API review council untriaged Issues and PRs which have not yet been triaged by a lead VSCode
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants