How to avoid running Source Generator using CompilationProvider on every keystroke #74001
Unanswered
Dreamescaper
asked this question in
Q&A
Replies: 1 comment 1 reply
-
Don't combine with CompilationProvider 😄. I've done the same mistake... From https://github.com/dotnet/roslyn/blob/main/docs/features/incremental-generators.md: Consider the following (incorrect) combine where the basic inputs are combined, then used to generate some source: public void Initialize(IncrementalGeneratorInitializationContext context)
{
var compilation = context.CompilationProvider;
var texts = context.AdditionalTextsProvider;
// Don't do this!
var combined = texts.Combine(compilation);
context.RegisterSourceOutput(combined, static (spc, pair) =>
{
var assemblyName = pair.Right.AssemblyName;
// produce source ...
}); Any time the compilation changes, which it will frequently as the user is typing public void Initialize(IncrementalGeneratorInitializationContext context)
{
var assemblyName = context.CompilationProvider.Select(static (c, _) => c.AssemblyName);
var texts = context.AdditionalTextsProvider;
var combined = texts.Combine(assemblyName);
context.RegisterSourceOutput(combined, (spc, pair) =>
{
var assemblyName = pair.Right;
// produce source ...
});
} |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi all,
I have created a Source Generator to assist with DI services registration. The idea is that it scans assembly for types based on a criteria in an user-defined attribute.
So currently the pipeline is the following:
The problem is that while models returned from steps 1 and 3 are cacheable by themselves, combining it with a CompilationProvider makes all that assembly scanning to be performed on every keystroke.
Which is obviously not great.
As a workaround, I've added a custom EqualityComparer for the combined provider, which ignores the compilation and only compares the model.
It works exactly as I'd expect - the generated file might be stale, since it is regenerated only when the attribute is changed, but it won't detect when mathing types are changed. But it's perfectly fine for my use-case, since it will be regenerated on build anyway.
What are the downsides of such approach (apart from the stale generated files)? Is there any better suggestion here?
Beta Was this translation helpful? Give feedback.
All reactions