Chromium Code Reviews| Index: pkg/dev_compiler/lib/src/compiler/code_generator.dart |
| diff --git a/pkg/dev_compiler/lib/src/compiler/code_generator.dart b/pkg/dev_compiler/lib/src/compiler/code_generator.dart |
| index 50d6c19e5535a112484041abfd2cd437bdcaf34b..f00fd619c7160d7b5d31c05d57cc6873156aa5a4 100644 |
| --- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart |
| +++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart |
| @@ -1274,6 +1274,31 @@ class CodeGenerator extends GeneralizingAstVisitor |
| typeParams: typeParams, fields: jsFields); |
| } |
| + /// In some corner cases, a mixin may have its own mixins. |
| + /// E.g., M2 is a valid mixin: |
| + /// |
| + /// class M1 { int foo() => 42; } |
| + /// class M2 = Object with M1; |
| + /// class M3 = Object with M2; |
| + /// |
| + /// We expand out the list of mixins to treat M1 and M2 as separate |
| + /// applications. |
| + List<InterfaceType> _flattenMixins(List<InterfaceType> mixins) { |
|
Jennifer Messerly
2017/03/27 22:15:15
I don't think this is correct in general?
it will
|
| + if (mixins.any((m) => m.mixins.isNotEmpty)) { |
| + // Clone, so we do not overwrite. |
| + mixins = new List<InterfaceType>.from(mixins); |
| + for (int i = 0; i < mixins.length; ++i) { |
| + var mixin = mixins[i]; |
| + if (mixin.mixins.isNotEmpty) { |
| + var indirectMixins = _flattenMixins(mixin.mixins); |
| + mixins.insertAll(i, indirectMixins); |
| + i += indirectMixins.length; |
| + } |
| + } |
| + } |
| + return mixins; |
| + } |
| + |
| JS.Expression _emitClassHeritage(ClassElement element) { |
| var type = element.type; |
| if (type.isObject) return null; |
| @@ -1281,7 +1306,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
| _loader.startTopLevel(element); |
| // List of "direct" supertypes (supertype + mixins) |
| - var basetypes = [type.superclass]..addAll(type.mixins); |
| + var basetypes = [type.superclass]..addAll(_flattenMixins(type.mixins)); |
| // If any of these are recursive (via type parameter), defer setting |
| // the real superclass. |
| @@ -1721,7 +1746,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
| var newBaseClass = _emitType(classElem.type.superclass, |
| nameType: false, subClass: classElem, className: className); |
| if (classElem.type.mixins.isNotEmpty) { |
| - var mixins = classElem.type.mixins |
| + var mixins = _flattenMixins(classElem.type.mixins) |
| .map((t) => _emitType(t, nameType: false)) |
| .toList(); |
| mixins.insert(0, newBaseClass); |