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

Load razor assembly directly: #76808

Merged
merged 3 commits into from
Jan 21, 2025

Conversation

chsienki
Copy link
Contributor

  • Pass the root directory to assembly resolvers
  • When looking for razor or its deps load them into the same ALC as the compiler

- Pass the root directory to assembly resolvers
- When looking for razor or its deps load them into the same ALC as the compiler
@chsienki chsienki requested review from a team as code owners January 18, 2025 02:59
@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged Issues and PRs which have not yet been triaged by a lead label Jan 18, 2025
{
return loadedAssembly;
}
return compilerContext.LoadFromAssemblyPath(assembly);
Copy link
Contributor Author

@chsienki chsienki Jan 18, 2025

Choose a reason for hiding this comment

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

Note that here we're loading razor into the 'main' compiler ALC. We could create our own ALC to load into, but it will need to be custom code that defers to the main ALC for things like MS.CA.dll. That seemed overkill, so I just used the main one (which is already conceptually the 'shared' one anyway).

s_assemblyResolver = resolver;
return true;
var compilerContext = AssemblyLoadContext.GetLoadContext(typeof(Compilation).Assembly)!;
if (compilerContext.Assemblies.SingleOrDefault(a => a.GetName().Name == assemblyName.Name) is Assembly loadedAssembly)
Copy link
Member

Choose a reason for hiding this comment

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

Consider marking the lambda static if possible (by passing assemblyName.Name as an additional argument).

@@ -26,7 +26,7 @@ internal class RemoteWorkspaceManager
MefHostServices.DefaultAssemblies
.Add(typeof(AspNetCoreEmbeddedLanguageClassifier).Assembly)
.Add(typeof(BrokeredServiceBase).Assembly)
.Add(typeof(RazorAnalyzerAssemblyResolver).Assembly)
.Add(typeof(IRazorLanguageServerTarget).Assembly)
Copy link
Member

Choose a reason for hiding this comment

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

Why has this changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because it targets both .NET and netstandard. In the netstandard version RazorAnalyzerAssemblyResolver no longer exists. It just seemed neater to change the type we're referencing instead of #if-defing the assembly add.

@chsienki chsienki merged commit 5970c1a into dotnet:main Jan 21, 2025
28 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Jan 21, 2025
{
if (s_assemblyResolver is null && !s_assembliesRequested.Contains(canaryAssembly))
lock (s_loaderLock)
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need a lock here?

return loadedAssembly;
}

var assembly = Path.Combine(rootDirectory, $"{assemblyName.Name}.dll");
Copy link
Member

Choose a reason for hiding this comment

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

Think that this code only works when the IDE has normalized the path to the razor assemblies. Essentially this logic only works if every path to the razor compiler passed via /analyzer: is the same path once we get to this layer. If there is a different path then we will be in a "first one wins" situation (the first winner will be cached in the compiler ALC).

If that is correct think we should add some explanation here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jaredpar I filed #76868 to track addressing this feedback.

private static Func<AssemblyName, Assembly?>? s_assemblyResolver;
private const string RazorCompilerAssemblyName = "Microsoft.CodeAnalysis.Razor.Compiler";
private const string RazorUtilsAssemblyName = "Microsoft.AspNetCore.Razor.Utilities.Shared";
private const string ObjectPoolAssemblyName = "Microsoft.Extensions.ObjectPool";
Copy link
Member

Choose a reason for hiding this comment

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

Where in the code do we keep the list of generators that the IDE remaps from SDK to the VS copy? Wanted to make sure there is agreement on all the assemblies in that map and what we redirect here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers 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.

5 participants