-
-
Notifications
You must be signed in to change notification settings - Fork 851
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
Replace ImageExtensions.Save.tt with Source Generator #2237
base: main
Are you sure you want to change the base?
Conversation
I see the build is failing due to the fact that the |
Urgh...... So we explicitly tell dotnet build which target framework we want to build against during CI. This lets us identify JIT issues which we have an uncanny ability to uncover. I wonder why the compiler doesn't multi target? |
I see! I will try to multi target the SG later and see what happens. Should work fine. |
I actually don't think it will because our build process isolates each target within any multi target declarations. Not quite sure what to do. 🤔 |
That's fine, the generator will build and work correctly under .NET 6 as well. It just won't show up in IntelliSense, which doesn't matter for a CI build. This is why it is discouraged to use a higher version than |
I don't understand the point of this PR. T4 templates are better suited for this purpose. Source generators are not a replacement for T4 generators and they're not inherently better, they're just meant for different use cases, and this doesn't look like one. |
@Sergio0694 This PR was meant as a demonstration for the ImageSharp maintainers so they could evaluate the maintenance costs of abandoning T4 templates. |
Right, but I'm saying there's just no reason to do so at all. T4 templates are the right tool for this. Not to mention, using source generators with a local project reference is unsupported, and has broken tooling. If you clean the repository (eg. |
We should only merge this if we are absolutely sure this is the way forward and we are ready to migrate our entire T4 logic to source generators, especially the massive usage around PixelFormats:
TBH I was always assuming that we should switch to source generators at some point, since it's "the modern tool" for generating more source code based on existing sources, which is how our use case looks like (or should actually look like): generate chore code for all the pixel types in the repo automatically, generate
@Sergio0694 can you elaborate what do you mean by this considering our use-cases?
I guess ... it's a show stopper for the adaption then? Though I really believed source generators are in better shape already. How do other projects deal with these problems? Or they don't have them? |
Very curious to hear more expert opinion here. This is all very new to me! |
The advantage of source generators is that they can dynamically generate code based on what code you're using in your own project, but that really only makes sense when there's some kind of introspection being done on said code from the generator end. Say, you're using The point is: source generators are not meant to replace T4 templates, they're just meant for different scenarios. If you need to generate some fixed templated code, then a T4 template is a perfectly reasonable, and much simpler, choice. Eg. I'm heavily using T4 templates in ComputeSharp too to generate all the HLSL primitive projection types for C#, not generators. In your case, eg. in those pixel operations files that Anton linked, that setup looks perfectly reasonable. If you wanted to make it more compact, you could just use an array of all pixel format types, and generate all the partial types in a single file 🙂 |
This is how we implemented stuff with T4, but in theory it would be more robust if we could enumerate & inspect the existing pixel types, and existing If I get the whole picture right, you basically say: use Source Generator if you really need a reusable tool to generate more code based on existing code in a flexible manner. Use T4 if you want to generate code for a single project you control, otherwise you'll just end up adding even more complexity and maintenance burden. I think we should stick with T4 then? Or are any counter-opinions in the community which are based on experience with bigger projects? |
Yeah, I definitely agree that SGs are meant for scenarios where more of the code is actually analyzed/introspected to generate the result. I was just under the impression that the tooling around T4 templates (across all operating systems and IDEs) is also not great and that this would cancel out the Source Generators' shortcomings. |
I would say that in some cases it might make sense to still use a source generator for internal use, as long as the benefit is worth the extra work, eg. if you have lots of different uses on random types where the introspection makes sense due to the high variety of scenarios that are supported, but even then it's something you should think about on a case by case basis. One rule of thumb I can definitely give you though is: if your generator is only using |
|
||
// <auto-generated />"; | ||
|
||
private static readonly string[] ImageFormats = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be better to have some sort of attribute on the encoder type that can be used to generate the methods instead?
That would make it more generator worthy would it not @Sergio0694 ?
It would be amazing if we could add that to a base class (ImageEncoder See #2269) and have these methods generated automatically without us ever having to touch this file again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, this would be possible and probably a better suited scenario for a Source Generator. You'd still have the issues around local projects with SGs which @Sergio0694 mentioned in #2237 (comment) and would need to decide if this is okay for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not to mention, using source generators with a local project reference is unsupported, and has broken tooling
This one? I'm still blown away by that. How does someone test such a thing if locally referencing the project is unsupported? It seems incredibly short sighted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, to be honest I haven't noticed this as much. I rarely clean my repository like that.
I have multiple SGs in a local project at work and only get red squiggly lines when modifying the SG code, which rarely happens. Even then closing and reopening the solution fixes it. Other than that, all is good.
Prerequisites
Description
This PR removes the ImageExtensions.Save T4 template and replaces it with a Source Generator.
The generator (and all future generators) is placed in the
ImageSharp.Generators
project, since generators need to be in a separate project than the code they generate for.I have also added
<LangVersion>10</LangVersion>
to the generator, in order to use features like file-scoped namespaces and such. It is completely safe to use a language version as high as the project which consumes the generator.Everything still builds and it is still possible to navigate to source for the extension methods the generator replaces. Let me know what you think!