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

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

Issue 12288041: It's not allowed to have an initializer for a final field that is initialized where it's declared. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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 | tests/co19/co19-dart2js.status » ('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 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 918 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 } 929 }
930 } 930 }
931 931
932 class InitializerResolver { 932 class InitializerResolver {
933 final ResolverVisitor visitor; 933 final ResolverVisitor visitor;
934 final Map<SourceString, Node> initialized; 934 final Map<SourceString, Node> initialized;
935 Link<Node> initializers; 935 Link<Node> initializers;
936 bool hasSuper; 936 bool hasSuper;
937 937
938 InitializerResolver(this.visitor) 938 InitializerResolver(this.visitor)
939 : initialized = new Map<SourceString, Node>(), hasSuper = false; 939 : initialized = new Map<Element, Node>(), hasSuper = false;
940 940
941 error(Node node, MessageKind kind, [arguments = const {}]) { 941 error(Node node, MessageKind kind, [arguments = const {}]) {
942 visitor.error(node, kind, arguments); 942 visitor.error(node, kind, arguments);
943 } 943 }
944 944
945 warning(Node node, MessageKind kind, [arguments = const {}]) { 945 warning(Node node, MessageKind kind, [arguments = const {}]) {
946 visitor.warning(node, kind, arguments); 946 visitor.warning(node, kind, arguments);
947 } 947 }
948 948
949 bool isFieldInitializer(SendSet node) { 949 bool isFieldInitializer(SendSet node) {
950 if (node.selector.asIdentifier() == null) return false; 950 if (node.selector.asIdentifier() == null) return false;
951 if (node.receiver == null) return true; 951 if (node.receiver == null) return true;
952 if (node.receiver.asIdentifier() == null) return false; 952 if (node.receiver.asIdentifier() == null) return false;
953 return node.receiver.asIdentifier().isThis(); 953 return node.receiver.asIdentifier().isThis();
954 } 954 }
955 955
956 void checkForDuplicateInitializers(SourceString name, Node init) { 956 void checkForDuplicateInitializers(Element field, Node init) {
957 if (initialized.containsKey(name)) { 957 SourceString name = field.name;
958 if (initialized.containsKey(field)) {
959 warning(initialized[field], MessageKind.ALREADY_INITIALIZED,
ahe 2013/02/19 10:58:10 This is not optimal. See if you can use something
ngeoffray 2013/02/19 11:18:10 Done.
960 {'fieldName': name});
958 error(init, MessageKind.DUPLICATE_INITIALIZER, {'fieldName': name}); 961 error(init, MessageKind.DUPLICATE_INITIALIZER, {'fieldName': name});
959 warning(initialized[name], MessageKind.ALREADY_INITIALIZED, 962 } else if (field.modifiers.isFinal()) {
960 {'fieldName': name}); 963 Node fieldNode = field.parseNode(visitor.compiler).asSendSet();
ahe 2013/02/19 10:58:10 Why asSendSet?
ngeoffray 2013/02/19 11:18:10 Because that's how we know the field is initialize
ahe 2013/02/19 11:46:07 Sorry, I misread the code.
964 if (fieldNode != null) {
965 warning(fieldNode, MessageKind.ALREADY_INITIALIZED,
966 {'fieldName': name});
967 error(init, MessageKind.DUPLICATE_INITIALIZER, {'fieldName': name});
968 }
961 } 969 }
962 initialized[name] = init; 970 initialized[field] = init;
963 } 971 }
964 972
965 void resolveFieldInitializer(FunctionElement constructor, SendSet init) { 973 void resolveFieldInitializer(FunctionElement constructor, SendSet init) {
966 // init is of the form [this.]field = value. 974 // init is of the form [this.]field = value.
967 final Node selector = init.selector; 975 final Node selector = init.selector;
968 final SourceString name = selector.asIdentifier().source; 976 final SourceString name = selector.asIdentifier().source;
969 // Lookup target field. 977 // Lookup target field.
970 Element target; 978 Element target;
971 if (isFieldInitializer(init)) { 979 if (isFieldInitializer(init)) {
972 target = constructor.getEnclosingClass().lookupLocalMember(name); 980 target = constructor.getEnclosingClass().lookupLocalMember(name);
973 if (target == null) { 981 if (target == null) {
974 error(selector, MessageKind.CANNOT_RESOLVE, {'name': name}); 982 error(selector, MessageKind.CANNOT_RESOLVE, {'name': name});
975 } else if (target.kind != ElementKind.FIELD) { 983 } else if (target.kind != ElementKind.FIELD) {
976 error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name}); 984 error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name});
977 } else if (!target.isInstanceMember()) { 985 } else if (!target.isInstanceMember()) {
978 error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name}); 986 error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name});
979 } 987 }
980 } else { 988 } else {
981 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); 989 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
982 } 990 }
983 visitor.useElement(init, target); 991 visitor.useElement(init, target);
984 visitor.world.registerStaticUse(target); 992 visitor.world.registerStaticUse(target);
985 checkForDuplicateInitializers(name, init); 993 checkForDuplicateInitializers(target, init);
986 // Resolve initializing value. 994 // Resolve initializing value.
987 visitor.visitInStaticContext(init.arguments.head); 995 visitor.visitInStaticContext(init.arguments.head);
988 } 996 }
989 997
990 ClassElement getSuperOrThisLookupTarget(FunctionElement constructor, 998 ClassElement getSuperOrThisLookupTarget(FunctionElement constructor,
991 bool isSuperCall, 999 bool isSuperCall,
992 Node diagnosticNode) { 1000 Node diagnosticNode) {
993 ClassElement lookupTarget = constructor.getEnclosingClass(); 1001 ClassElement lookupTarget = constructor.getEnclosingClass();
994 if (isSuperCall) { 1002 if (isSuperCall) {
995 // Calculate correct lookup target and constructor name. 1003 // Calculate correct lookup target and constructor name.
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 * constructor, the resolved constructor's function element is returned. 1122 * constructor, the resolved constructor's function element is returned.
1115 */ 1123 */
1116 FunctionElement resolveInitializers(FunctionElement constructor, 1124 FunctionElement resolveInitializers(FunctionElement constructor,
1117 FunctionExpression functionNode) { 1125 FunctionExpression functionNode) {
1118 // Keep track of all "this.param" parameters specified for constructor so 1126 // Keep track of all "this.param" parameters specified for constructor so
1119 // that we can ensure that fields are initialized only once. 1127 // that we can ensure that fields are initialized only once.
1120 FunctionSignature functionParameters = 1128 FunctionSignature functionParameters =
1121 constructor.computeSignature(visitor.compiler); 1129 constructor.computeSignature(visitor.compiler);
1122 functionParameters.forEachParameter((Element element) { 1130 functionParameters.forEachParameter((Element element) {
1123 if (identical(element.kind, ElementKind.FIELD_PARAMETER)) { 1131 if (identical(element.kind, ElementKind.FIELD_PARAMETER)) {
1124 checkForDuplicateInitializers(element.name, 1132 FieldParameterElement fieldParameter = element;
1133 checkForDuplicateInitializers(fieldParameter.fieldElement,
1125 element.parseNode(visitor.compiler)); 1134 element.parseNode(visitor.compiler));
1126 } 1135 }
1127 }); 1136 });
1128 1137
1129 if (functionNode.initializers == null) { 1138 if (functionNode.initializers == null) {
1130 initializers = const Link<Node>(); 1139 initializers = const Link<Node>();
1131 } else { 1140 } else {
1132 initializers = functionNode.initializers.nodes; 1141 initializers = functionNode.initializers.nodes;
1133 } 1142 }
1134 FunctionElement result; 1143 FunctionElement result;
(...skipping 2565 matching lines...) Expand 10 before | Expand all | Expand 10 after
3700 return e; 3709 return e;
3701 } 3710 }
3702 3711
3703 /// Assumed to be called by [resolveRedirectingFactory]. 3712 /// Assumed to be called by [resolveRedirectingFactory].
3704 Element visitReturn(Return node) { 3713 Element visitReturn(Return node) {
3705 Node expression = node.expression; 3714 Node expression = node.expression;
3706 return finishConstructorReference(visit(expression), 3715 return finishConstructorReference(visit(expression),
3707 expression, expression); 3716 expression, expression);
3708 } 3717 }
3709 } 3718 }
OLDNEW
« no previous file with comments | « no previous file | tests/co19/co19-dart2js.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698