kernel
kernel copied to clipboard
Mixin application canonicalization
Do we think the front end should canonicalize mixin applications?
i.e. Should this
class Base {}
class Mixin {}
class C1 extends Base with Mixin {}
class C2 extends Base with Mixin {}
be converted to
class Base {}
class Mixin {}
mixin Base&Mixin = Base with Mixin;
class C1 extends Base&Mixin {}
class C2 extends Base&Mixin {}
?
/cc @peter-ahe-google @asgerf
FWIW, this is what rastak generates:
library;
import self as self;
import "dart:core" as core;
class Base extends core::Object {
constructor •() → self::Base
: super core::Object::•();
}
class Mixin extends core::Object {
constructor •() → self::Mixin
: super core::Object::•();
}
class C1 extends self::#class1 {
constructor •() → self::C1
: super self::Base::•();
}
class C2 extends self::#class2 {
constructor •() → self::C2
: super self::Base::•();
}
abstract mixin #class2 = self::Base with self::Mixin implements self::Mixin;
abstract mixin #class1 = self::Base with self::Mixin implements self::Mixin;
As far as I can tell, what Martin asks is if #class1 and #class2 should be the same class.
I'm not sure how mixin application canonicalization would interact with modular compilation. One option is that mixin application canonicalization takes place in a link phase.
I think we should do mixin canonicalization per library. That way it won't interfere with modular compilation and we can name the mixin classes without creating two similarly named classes.
We could canonicalize them globally as part of the mixin resolution step.
They are currently canonicalized per library, but this has turned out to cause issues with strong mode, and the current implementation in kernel creates too way many duplicated type parameters.