Description
A mixin class is a non-super-mixin that allows extension. This is already supported in Dart (you just use the class
keyword). The problem is that such mixins do not prevent unintentional breaking changes. For example:
- you can change it to extend another class
- you can add a constructor or a factory to the mixin
- you can instantiate the mixin directly (if it is concrete)
- you can add a
super
call to the class
These are all valid changes to normal Dart classes, but are breaking to a mixin. A dedicated class mixin declaration could prevent these issues by restricting what you can do with the class, similar to the restrictions placed on the plain mixin
(which is allowed to be a super-mixin).
Strawman proposal:
mixin class Foo extends Bar {
// ^
// ERROR: cannot extends other classes
Foo();
// ^
// ERROR: cannot have constructors
void foo() {
super.hashCode;
// ^
// ERROR: cannot call super
}
}
main() {
Foo(); // ERROR: cannot instantiate mixins
}
One example of such a mixin in Flutter is WidgetsBindingObserver.
prefer_mixin
lint
The current situation makes prefer_mixin
lint unusable because the lint shows up at the usage site (the with
clause), not at the mixin declaration site. IOW, the lint does not encourage the author of the mixin to change the declaration of the mixin, but asks the user of the mixin to use something else, which may not be possible.
Alternatively: remove this capability
If we don't like this idea in general, we should be clearer about the removal of this capability so we can start cleaning up our code now. Currently the spec only says that it may potentially be removed. However, that means our users will have to live with these quirks for a long time. Flutter will declare API stability soon and it will be hard to change this in the future.