Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 12041018: Disallow cyclic mixins. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add extra test - simplify code. Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of resolution; 5 part of resolution;
6 6
7 abstract class TreeElements { 7 abstract class TreeElements {
8 Element operator[](Node node); 8 Element operator[](Node node);
9 Selector getSelector(Send send); 9 Selector getSelector(Send send);
10 DartType getType(Node node); 10 DartType getType(Node node);
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT; 502 int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT;
503 if (illegalFlags != 0) { 503 if (illegalFlags != 0) {
504 Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags); 504 Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags);
505 CompilationError error = 505 CompilationError error =
506 MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS.error( 506 MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS.error(
507 [illegalModifiers]); 507 [illegalModifiers]);
508 compiler.reportMessage(compiler.spanFromSpannable(modifiers), 508 compiler.reportMessage(compiler.spanFromSpannable(modifiers),
509 error, Diagnostic.ERROR); 509 error, Diagnostic.ERROR);
510 } 510 }
511 511
512 // In case of cyclic mixin applications, the mixin chain will have
513 // been cut. If so, we have already reported the error to the
514 // user so we just return from here.
515 ClassElement mixin = mixinApplication.mixin;
516 if (mixin == null) return;
517
512 // Check that the mixed in class has Object as its superclass. 518 // Check that the mixed in class has Object as its superclass.
513 ClassElement mixin = mixinApplication.mixin;
514 if (!mixin.superclass.isObject(compiler)) { 519 if (!mixin.superclass.isObject(compiler)) {
515 CompilationError error = MessageKind.ILLEGAL_MIXIN_SUPERCLASS.error(); 520 CompilationError error = MessageKind.ILLEGAL_MIXIN_SUPERCLASS.error();
516 compiler.reportMessage(compiler.spanFromElement(mixin), 521 compiler.reportMessage(compiler.spanFromElement(mixin),
517 error, Diagnostic.ERROR); 522 error, Diagnostic.ERROR);
518 } 523 }
519 524
520 // Check that the mixed in class doesn't have any constructors. 525 // Check that the mixed in class doesn't have any constructors.
521 mixin.forEachLocalMember((Element member) { 526 mixin.forEachLocalMember((Element member) {
522 if (member.isGenerativeConstructor() && !member.isSynthesized) { 527 if (member.isGenerativeConstructor() && !member.isSynthesized) {
523 CompilationError error = MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR.error(); 528 CompilationError error = MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR.error();
(...skipping 2366 matching lines...) Expand 10 before | Expand all | Expand 10 after
2890 mixinApplication.supertype = supertype; 2895 mixinApplication.supertype = supertype;
2891 2896
2892 // The class that is the result of a mixin application implements 2897 // The class that is the result of a mixin application implements
2893 // the interface of the class that was mixed in. 2898 // the interface of the class that was mixed in.
2894 Link<DartType> interfaces = const Link<DartType>(); 2899 Link<DartType> interfaces = const Link<DartType>();
2895 interfaces = interfaces.prepend(mixinType); 2900 interfaces = interfaces.prepend(mixinType);
2896 assert(mixinApplication.interfaces == null); 2901 assert(mixinApplication.interfaces == null);
2897 mixinApplication.interfaces = interfaces; 2902 mixinApplication.interfaces = interfaces;
2898 2903
2899 assert(mixinApplication.mixin == null); 2904 assert(mixinApplication.mixin == null);
2900 mixinApplication.mixin = mixinType.element; 2905 mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType);
2901 mixinApplication.mixin.ensureResolved(compiler);
2902 mixinApplication.addDefaultConstructorIfNeeded(compiler); 2906 mixinApplication.addDefaultConstructorIfNeeded(compiler);
2903 calculateAllSupertypes(mixinApplication); 2907 calculateAllSupertypes(mixinApplication);
2904 } 2908 }
2905 2909
2910 ClassElement resolveMixinFor(MixinApplicationElement mixinApplication,
2911 DartType mixinType) {
2912 ClassElement mixin = mixinType.element;
2913 mixin.ensureResolved(compiler);
2914
2915 // Check for cycles in the mixin chain.
2916 ClassElement previous = mixinApplication; // For better error messages.
2917 ClassElement current = mixin;
2918 while (current != null && current.isMixinApplication) {
2919 MixinApplicationElement currentMixinApplication = current;
2920 if (currentMixinApplication == mixinApplication) {
2921 CompilationError error = MessageKind.ILLEGAL_MIXIN_CYCLE.error(
2922 [current.name, previous.name]);
2923 compiler.reportMessage(compiler.spanFromElement(mixinApplication),
2924 error, Diagnostic.ERROR);
2925 // We have found a cycle in the mixin chain. Return null as
2926 // the mixin for this application to avoid getting into
2927 // infinite recursion when traversing members.
2928 return null;
2929 }
2930 previous = current;
2931 current = currentMixinApplication.mixin;
2932 }
2933 return mixin;
2934 }
2906 2935
2907 // TODO(johnniwinther): Remove when default class is no longer supported. 2936 // TODO(johnniwinther): Remove when default class is no longer supported.
2908 DartType visitTypeAnnotation(TypeAnnotation node) { 2937 DartType visitTypeAnnotation(TypeAnnotation node) {
2909 return visit(node.typeName); 2938 return visit(node.typeName);
2910 } 2939 }
2911 2940
2912 // TODO(johnniwinther): Remove when default class is no longer supported. 2941 // TODO(johnniwinther): Remove when default class is no longer supported.
2913 DartType visitIdentifier(Identifier node) { 2942 DartType visitIdentifier(Identifier node) {
2914 Element element = scope.lookup(node.source); 2943 Element element = scope.lookup(node.source);
2915 if (element == null) { 2944 if (element == null) {
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
3509 return e; 3538 return e;
3510 } 3539 }
3511 3540
3512 /// Assumed to be called by [resolveRedirectingFactory]. 3541 /// Assumed to be called by [resolveRedirectingFactory].
3513 Element visitReturn(Return node) { 3542 Element visitReturn(Return node) {
3514 Node expression = node.expression; 3543 Node expression = node.expression;
3515 return finishConstructorReference(visit(expression), 3544 return finishConstructorReference(visit(expression),
3516 expression, expression); 3545 expression, expression);
3517 } 3546 }
3518 } 3547 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/warnings.dart » ('j') | tests/language/mixin_illegal_cycles_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698