-
-
Notifications
You must be signed in to change notification settings - Fork 3
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
Remove usage of CompilationProvider #8
Conversation
Thanks for the suggestion, I'll take a deeper look later! Per my understanding, for the external assemblies case, assembly scanning will still happen for every keystroke, right? Only the cached data is potentially smaller? |
Unfortunately yeah, I think based on this comment that yes, any |
I can see that even dotnet maintainers ignore that recommendation quite often: Not to mention third parties... I'm going to wait for a while, maybe someone from Roslyn guys suggests anything useful: dotnet/roslyn#74001 I realized they've added an option to only run generators on saving or on builds in the latest VS Preview. Maybe they decided to "fix" this issue this way, not sure. |
Yeah I don't think my changes here are all that helpful, it just replaces one problem for another. The assembly scanning in particular is a tough one since there is no good Syntax or other provider to get easy access to them. I did have another thought overnight - not sure if it would be worth the effort but could be another option: Collect the type info from public types in external assemblies in a separate pre-build step. Some BeforeTarget=CoreCompile msbuild task that extracts type info into a json file in the obj folder or something, and include it as an AdditionalFile. This issue seems like it could maybe help in the future, but I am not sure which direction they might take it. I could picture something like having a Syntax provider that is focused on doing this external assembly scanning, but can use the assembly MVID or something like that to be able to short circuit if nothing has changed |
You might have already seen these, but here are some related issues that mention per-key updates and only needing to get info out of references, not syntax trees:
Edit: actually nvm - here is an example of Razor doing just that: https://github.com/dotnet/razor/blob/b4404959b514413320fa1f08ff418e1f600dc980/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/RazorSourceGenerator.cs#L206-L215 |
That's interresting. |
Closing this in favor of #9 |
Hey! A bit later than anticipated, but here is a draft PR showing some example code of how you could avoid using the CompilationProvider. I was moving things around between files and was not very organized and just dumped most everything into SymbolExtensions, so feel free to discard or refactor to your liking.
The main change: separate the path for when we are looking for types in external assemblies vs looking for types in the same C# project.
In the
ParseMethod
transform method, it now will optionally collect the matching types early on. The AttributeModel class now has a nullable array of ServiceRegistrationModelsRegistrationsFromAssembly
that can be set in cases where we collect these from external assemblies in this phase.Separately, there is a new SyntaxProvider that hooks into any TypeDeclarationSyntax node. This will scan the current C# project for any type, and extract a few relevant bits from each type (name, IsGeneric, etc). This will create a lookup of all types that are declared in the project that should be cache friendly. The cache will have potentially lots of these objects, but it will still be smaller than the entire Compilation object.
This provider is combined with the method provider, and for attributes that don't specify an external assembly (or specify a type from the current assembly), the RegistrationsFromAssembly array will be null, and indicate that we should instead look through the source-code defined types.
I did have to slightly tweak the StringBuilder AppendLine, since that uses Environment.NewlLine internally. I am on Windows so that was causing my unit tests to fail locally, but that might also be due to my local autocrlf settings and you could ignore.