macro_prototype icon indicating copy to clipboard operation
macro_prototype copied to clipboard

Ability to add mixins to classes

Open TimWhiting opened this issue 4 years ago • 8 comments

I think there should be a way to add mixins / implements / extends clauses to classes. Freezed requires a mixin for creating switch like functions for union classes. But currently you have to annotate it like this.

@freezed
class Person with _$Person {
  factory Person({ String? name, int? age }) = _Person;
}

Ideally the macro could add the mixin application itself, but currently the API only allows adding members to a class.

TimWhiting avatar Jul 29 '21 17:07 TimWhiting

There has been a lot of discussion around this. I have conflicted feelings about it - although I do think adding mixins specifically would be fine, and quite possibly implements as well.

Adding extends changes the class in a way that feels a lot more magic to me. But it is hard to actually make a solid argument around the difference :D.

jakemac53 avatar Jul 29 '21 17:07 jakemac53

Note that we would probably only allow this in the first phase - after that we start allowing you to ask questions about the subtype relationships of types, which this would affect the result of.

jakemac53 avatar Jul 29 '21 17:07 jakemac53

Yeah, I also wondered if extends was a good idea. mixins and implements seem fine to me.

TimWhiting avatar Jul 29 '21 17:07 TimWhiting

I do think we should support this. Otherwise, I think we will end up with macros where users are forced to write:

@awesomeThing SomeClass extends AwesomeThing { ... }

And that just seems needlessly redundant to me.

Further, I think there will likely be cases where a macro wants to add a hidden capability to the applied class. That might mean have the class implement an interface that only the macro library can see, so there would be no way for the user to hand-author the proper implements clause. The macro author wouldn't want them to either, because that would expose an implementation detail of the macro to users.

munificent avatar Jul 30 '21 22:07 munificent

Consider also https://github.com/jakemac53/macro_prototype/issues/31 which could possibly have some overlap in use cases.

I still feel uncomfortable about allowing adding extends so I think its worth discussing that more. As one concrete thing that gets weird with that, consider the constructors of these classes. They would now need super calls in some cases even though in the code itself there is no super class. That seems pretty weird to me. How should they even know what the super constructor looks like that they need to invoke?

jakemac53 avatar Aug 02 '21 16:08 jakemac53

As far as mixins/interfaces go, the ordering of these matters so we would need to consider how or if macros can determine the ordering of where they inject mixins/interfaces. Are they always at the end of the list, or can they inject them anywhere? It feels more natural to me if they can only layer them on top (at the end of the list).

jakemac53 avatar Aug 02 '21 16:08 jakemac53

If the macro is adding the extends class it likely also knows what super constructor to invoke and what the needed parameters are (since it probably knows something about the class it is making the superclass. A widget macro for example would know to extend StatelessWidget / StatefulWidget and call the super constructor forwarding any key parameter or else not passing in the optional key parameter if the subclass does not contain one.

TimWhiting avatar Aug 02 '21 20:08 TimWhiting

Ya, one way to approach the problem would be to say that a macro adding an extends clause must also add a super invocation to the intializer lists of all regular constructors in the class. I am not sure exactly what the api looks like for that though, and I am not sure if it really solves all the cases or not.

For instance what if one of those super constructor parameters should be configurable? Now the macro needs to be able to add parameters to the constructors as well, which we also currently don't allow.

jakemac53 avatar Aug 02 '21 20:08 jakemac53