Index: runtime/vm/class_finalizer.cc |
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc |
index 61660f04a88c8dbbc8ee141e6c6f46f4b5d07380..f13d562061ef4a27dbfcfa430baea9bc8c33593c 100644 |
--- a/runtime/vm/class_finalizer.cc |
+++ b/runtime/vm/class_finalizer.cc |
@@ -2774,12 +2774,17 @@ RawType* ClassFinalizer::ResolveMixinAppType( |
// a BoundedType itself. |
CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); |
AbstractType& mixin_type = AbstractType::Handle(zone); |
- Class& mixin_type_class = Class::Handle(zone); |
Class& mixin_app_class = Class::Handle(zone); |
+ Class& mixin_super_type_class = Class::Handle(zone); |
+ Class& mixin_type_class = Class::Handle(zone); |
+ Library& mixin_super_type_library = Library::Handle(zone); |
+ Library& mixin_type_library = Library::Handle(zone); |
String& mixin_app_class_name = String::Handle(zone); |
String& mixin_type_class_name = String::Handle(zone); |
AbstractType& super_type_arg = AbstractType::Handle(zone); |
AbstractType& mixin_type_arg = AbstractType::Handle(zone); |
+ Type& generic_mixin_type = Type::Handle(zone); |
+ Array& interfaces = Array::Handle(zone); |
const intptr_t depth = mixin_app_type.Depth(); |
for (intptr_t i = 0; i < depth; i++) { |
mixin_type = mixin_app_type.MixinTypeAt(i); |
@@ -2787,6 +2792,13 @@ RawType* ClassFinalizer::ResolveMixinAppType( |
ResolveType(cls, mixin_type); |
ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. |
ASSERT(mixin_type.IsType()); |
+ if (mixin_type.IsMalformedOrMalbounded()) { |
+ ReportError(Error::Handle(zone, mixin_type.error())); |
+ } |
+ if (mixin_type.IsDynamicType()) { |
+ ReportError(cls, cls.token_pos(), "class '%s' may not mixin 'dynamic'", |
+ String::Handle(zone, cls.Name()).ToCString()); |
+ } |
const intptr_t num_super_type_args = type_args.Length(); |
CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); |
@@ -2812,8 +2824,19 @@ RawType* ClassFinalizer::ResolveMixinAppType( |
} |
// The name of the mixin application class is a combination of |
- // the super class name and mixin class name. |
+ // the super class name and mixin class name, as well as their respective |
+ // library private keys if their library is different than the library of |
+ // the mixin application class. |
+ // Note that appending the library url would break naming conventions (e.g. |
+ // no period in the class name). |
mixin_app_class_name = mixin_super_type.ClassName(); |
+ mixin_super_type_class = mixin_super_type.type_class(); |
+ mixin_super_type_library = mixin_super_type_class.library(); |
+ if (mixin_super_type_library.raw() != library.raw()) { |
+ mixin_app_class_name = String::Concat( |
+ mixin_app_class_name, |
+ String::Handle(zone, mixin_super_type_library.private_key())); |
+ } |
mixin_app_class_name = |
String::Concat(mixin_app_class_name, Symbols::Ampersand()); |
// If the type parameters are shared between the super type and the mixin |
@@ -2824,6 +2847,13 @@ RawType* ClassFinalizer::ResolveMixinAppType( |
String::Concat(mixin_app_class_name, Symbols::Ampersand()); |
} |
mixin_type_class_name = mixin_type.ClassName(); |
+ mixin_type_class = mixin_type.type_class(); |
+ mixin_type_library = mixin_type_class.library(); |
+ if (mixin_type_library.raw() != library.raw()) { |
+ mixin_type_class_name = String::Concat( |
+ mixin_type_class_name, |
+ String::Handle(zone, mixin_type_library.private_key())); |
+ } |
mixin_app_class_name = |
String::Concat(mixin_app_class_name, mixin_type_class_name); |
mixin_app_class = library.LookupLocalClass(mixin_app_class_name); |
@@ -2832,15 +2862,14 @@ RawType* ClassFinalizer::ResolveMixinAppType( |
mixin_app_class = Class::New(library, mixin_app_class_name, script, |
mixin_type.token_pos()); |
mixin_app_class.set_super_type(mixin_super_type); |
- mixin_type_class = mixin_type.type_class(); |
- const Type& generic_mixin_type = Type::Handle( |
- zone, Type::New(mixin_type_class, Object::null_type_arguments(), |
- mixin_type.token_pos())); |
+ generic_mixin_type = |
+ Type::New(mixin_type_class, Object::null_type_arguments(), |
+ mixin_type.token_pos()); |
mixin_app_class.set_mixin(generic_mixin_type); |
// Add the mixin type to the list of interfaces that the mixin application |
// class implements. This is necessary so that cycle check work at |
// compile time (type arguments are ignored by that check). |
- const Array& interfaces = Array::Handle(zone, Array::New(1)); |
+ interfaces = Array::New(1); |
interfaces.SetAt(0, generic_mixin_type); |
ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); |
mixin_app_class.set_interfaces(interfaces); |