Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| index 5b54c63c095337507ff4cfdb7fbafa67bb3885a9..5ab78047645498b9750af33bfb5f2914ec682b79 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| @@ -509,8 +509,13 @@ class ResolverTask extends CompilerTask { |
| error, Diagnostic.ERROR); |
| } |
| - // Check that the mixed in class has Object as its superclass. |
| + // In case of cyclic mixin applications, the mixin chain will have |
| + // been cut. If so, we have already reported the error to the |
| + // user so we just return from here. |
| ClassElement mixin = mixinApplication.mixin; |
| + if (mixin == null) return; |
| + |
| + // Check that the mixed in class has Object as its superclass. |
| if (!mixin.superclass.isObject(compiler)) { |
| CompilationError error = MessageKind.ILLEGAL_MIXIN_SUPERCLASS.error(); |
| compiler.reportMessage(compiler.spanFromElement(mixin), |
| @@ -2901,6 +2906,25 @@ class ClassResolverVisitor extends TypeDefinitionVisitor { |
| mixinApplication.mixin.ensureResolved(compiler); |
| mixinApplication.addDefaultConstructorIfNeeded(compiler); |
| calculateAllSupertypes(mixinApplication); |
| + |
| + // Check for cycles in the mixin chain. |
| + ClassElement previous = mixinApplication; |
| + ClassElement current = mixinApplication.mixin; |
| + while (current != null && current.isMixinApplication) { |
| + MixinApplicationElement currentMixinApplication = current; |
| + if (currentMixinApplication == mixinApplication) { |
| + CompilationError error = MessageKind.ILLEGAL_MIXIN_CYCLE.error( |
| + [current.name, previous.name]); |
| + compiler.reportMessage(compiler.spanFromElement(mixinApplication), |
| + error, Diagnostic.ERROR); |
| + // Set the mixin to null to avoid running into issues where |
| + // traversing the members will result in infinite recursion. |
| + mixinApplication.mixin = null; |
| + break; |
| + } |
| + previous = current; |
| + current = currentMixinApplication.mixin; |
| + } |
|
Johnni Winther
2013/01/22 13:16:41
I don't think this handles the case when [mixinApp
|
| } |