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

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

Issue 23533040: Check for non-final field in the face of const constructors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 7 years, 3 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
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/warnings.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 get currentElement; 8 Element get currentElement;
9 Set<Node> get superUses; 9 Set<Node> get superUses;
10 10
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 use, 661 use,
662 MessageKind.ILLEGAL_MIXIN_SUPER_USE); 662 MessageKind.ILLEGAL_MIXIN_SUPER_USE);
663 } 663 }
664 } 664 }
665 665
666 void checkClassMembers(ClassElement cls) { 666 void checkClassMembers(ClassElement cls) {
667 assert(invariant(cls, cls.isDeclaration)); 667 assert(invariant(cls, cls.isDeclaration));
668 if (cls.isObject(compiler)) return; 668 if (cls.isObject(compiler)) return;
669 // TODO(johnniwinther): Should this be done on the implementation element as 669 // TODO(johnniwinther): Should this be done on the implementation element as
670 // well? 670 // well?
671 List<Element> constConstructors = <Element>[];
672 List<Element> nonFinalInstanceFields = <Element>[];
671 cls.forEachMember((holder, member) { 673 cls.forEachMember((holder, member) {
672 compiler.withCurrentElement(member, () { 674 compiler.withCurrentElement(member, () {
673 // Perform various checks as side effect of "computing" the type. 675 // Perform various checks as side effect of "computing" the type.
674 member.computeType(compiler); 676 member.computeType(compiler);
675 677
676 // Check modifiers. 678 // Check modifiers.
677 if (member.isFunction() && member.modifiers.isFinal()) { 679 if (member.isFunction() && member.modifiers.isFinal()) {
678 compiler.reportError( 680 compiler.reportError(
679 member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER); 681 member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER);
680 } 682 }
681 if (member.isConstructor()) { 683 if (member.isConstructor()) {
682 final mismatchedFlagsBits = 684 final mismatchedFlagsBits =
683 member.modifiers.flags & 685 member.modifiers.flags &
684 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT); 686 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT);
685 if (mismatchedFlagsBits != 0) { 687 if (mismatchedFlagsBits != 0) {
686 final mismatchedFlags = 688 final mismatchedFlags =
687 new Modifiers.withFlags(null, mismatchedFlagsBits); 689 new Modifiers.withFlags(null, mismatchedFlagsBits);
688 compiler.reportError( 690 compiler.reportError(
689 member, 691 member,
690 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS, 692 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
691 {'modifiers': mismatchedFlags}); 693 {'modifiers': mismatchedFlags});
692 } 694 }
695 if (member.modifiers.isConst()) {
696 constConstructors.add(member);
697 }
698 }
699 if (member.isField()) {
700 if (!member.modifiers.isStatic() &&
701 !member.modifiers.isFinal()) {
702 nonFinalInstanceFields.add(member);
703 }
693 } 704 }
694 checkAbstractField(member); 705 checkAbstractField(member);
695 checkValidOverride(member, cls.lookupSuperMember(member.name)); 706 checkValidOverride(member, cls.lookupSuperMember(member.name));
696 checkUserDefinableOperator(member); 707 checkUserDefinableOperator(member);
697 }); 708 });
698 }); 709 });
710 if (!constConstructors.isEmpty && !nonFinalInstanceFields.isEmpty) {
711 Spannable span = constConstructors.length > 1
712 ? cls : constConstructors[0];
713 compiler.reportError(span,
714 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
715 {'className': cls.name});
716 if (constConstructors.length > 1) {
717 for (Element constructor in constConstructors) {
718 compiler.reportInfo(constructor,
719 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR);
720 }
721 }
722 for (Element field in nonFinalInstanceFields) {
723 compiler.reportInfo(field,
724 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD);
725 }
726 }
699 } 727 }
700 728
701 void checkAbstractField(Element member) { 729 void checkAbstractField(Element member) {
702 // Only check for getters. The test can only fail if there is both a setter 730 // Only check for getters. The test can only fail if there is both a setter
703 // and a getter with the same name, and we only need to check each abstract 731 // and a getter with the same name, and we only need to check each abstract
704 // field once, so we just ignore setters. 732 // field once, so we just ignore setters.
705 if (!member.isGetter()) return; 733 if (!member.isGetter()) return;
706 734
707 // Find the associated abstract field. 735 // Find the associated abstract field.
708 ClassElement classElement = member.getEnclosingClass(); 736 ClassElement classElement = member.getEnclosingClass();
(...skipping 2007 matching lines...) Expand 10 before | Expand all | Expand 10 after
2716 if (!symbolValidationPattern.hasMatch(name)) { 2744 if (!symbolValidationPattern.hasMatch(name)) {
2717 if (reportError) { 2745 if (reportError) {
2718 compiler.reportError(node, MessageKind.INVALID_SYMBOL, 2746 compiler.reportError(node, MessageKind.INVALID_SYMBOL,
2719 {'value': name}); 2747 {'value': name});
2720 } 2748 }
2721 return false; 2749 return false;
2722 } 2750 }
2723 return true; 2751 return true;
2724 } 2752 }
2725 2753
2726
2727 /** 2754 /**
2728 * Try to resolve the constructor that is referred to by [node]. 2755 * Try to resolve the constructor that is referred to by [node].
2729 * Note: this function may return an ErroneousFunctionElement instead of 2756 * Note: this function may return an ErroneousFunctionElement instead of
2730 * [null], if there is no corresponding constructor, class or library. 2757 * [null], if there is no corresponding constructor, class or library.
2731 */ 2758 */
2732 FunctionElement resolveConstructor(NewExpression node) { 2759 FunctionElement resolveConstructor(NewExpression node) {
2733 return node.accept(new ConstructorResolver(compiler, this)); 2760 return node.accept(new ConstructorResolver(compiler, this));
2734 } 2761 }
2735 2762
2736 FunctionElement resolveRedirectingFactory(Return node) { 2763 FunctionElement resolveRedirectingFactory(Return node) {
(...skipping 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after
4122 return e; 4149 return e;
4123 } 4150 }
4124 4151
4125 /// Assumed to be called by [resolveRedirectingFactory]. 4152 /// Assumed to be called by [resolveRedirectingFactory].
4126 Element visitReturn(Return node) { 4153 Element visitReturn(Return node) {
4127 Node expression = node.expression; 4154 Node expression = node.expression;
4128 return finishConstructorReference(visit(expression), 4155 return finishConstructorReference(visit(expression),
4129 expression, expression); 4156 expression, expression);
4130 } 4157 }
4131 } 4158 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/warnings.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698