Don't discount the developer experience too. With the codegen annotations, you either have to check in your .g.dart files to git which could be stale and break compilation in CI, or have them generate in CI, which is unnecessarily slow and eats up CI minutes. Added bonus is the macro API is less complex than the codegen API.
> or have them generate in CI, which is unnecessarily slow and eats up CI minutes.
Maybe I'm missing something since I'm not that familiar with Dart, but wouldn't Macros use the same amount of time to run and compile?
Either you're processing my_thing.dart and writing out my_thing.g.dart and then compiling the whole thing -or- you're processing my_thing.dart and writing out the new stuff to something in memory and then compiling the whole thing. Right? The amount of time it takes to generate the methods should be the same between the two and then the time to compile the same methods with the same code should be the same as well, right?
Again, I'm not that familiar with Dart and maybe the source generators have drawbacks that I'm unaware of, but it seems like the macro would be doing the same compile-time work (just without emitting the code to a file). I'd love to know what it's doing differently if that isn't how it's working.
Yeah, it is. It inspired the reflection in Dart, which inspired the macros. You can only use Dart's reflection when running in VM mode though. Flutter apps use AOT compilation, due to tree-shaking, so you lose the reflection and fall back to having to run codegen - kind of like TypeScript -> JS. This is a nice improvement that is run in memory before compilation and allows better access to the AST.
Dart has runtime reflection and annotations that predate this. The benefit of making this compile time are mainly performance.