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

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 913 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 } 924 }
925 925
926 error(Node node, MessageKind kind, [arguments = const {}]) { 926 error(Node node, MessageKind kind, [arguments = const {}]) {
927 ResolutionError message = new ResolutionError(kind, arguments); 927 ResolutionError message = new ResolutionError(kind, arguments);
928 compiler.reportError(node, message); 928 compiler.reportError(node, message);
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<Element, 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 reportDuplicateInitializerError(Element field, Node init, Node existing) {
957 if (initialized.containsKey(name)) { 957 visitor.compiler.reportError(
958 error(init, MessageKind.DUPLICATE_INITIALIZER, {'fieldName': name}); 958 init,
959 warning(initialized[name], MessageKind.ALREADY_INITIALIZED, 959 new ResolutionError(MessageKind.DUPLICATE_INITIALIZER,
960 {'fieldName': name}); 960 {'fieldName': field.name}));
961 visitor.compiler.reportMessage(
962 visitor.compiler.spanFromNode(existing),
963 new ResolutionError(MessageKind.ALREADY_INITIALIZED,
964 {'fieldName': field.name}),
965 Diagnostic.INFO);
966 }
967
968 void checkForDuplicateInitializers(Element field, Node init) {
969 SourceString name = field.name;
970 if (initialized.containsKey(field)) {
971 reportDuplicateInitializerError(field, init, initialized[field]);
972 } else if (field.modifiers.isFinal()) {
973 Node fieldNode = field.parseNode(visitor.compiler).asSendSet();
974 if (fieldNode != null) {
975 reportDuplicateInitializerError(field, init, fieldNode);
976 }
961 } 977 }
962 initialized[name] = init; 978 initialized[field] = init;
963 } 979 }
964 980
965 void resolveFieldInitializer(FunctionElement constructor, SendSet init) { 981 void resolveFieldInitializer(FunctionElement constructor, SendSet init) {
966 // init is of the form [this.]field = value. 982 // init is of the form [this.]field = value.
967 final Node selector = init.selector; 983 final Node selector = init.selector;
968 final SourceString name = selector.asIdentifier().source; 984 final SourceString name = selector.asIdentifier().source;
969 // Lookup target field. 985 // Lookup target field.
970 Element target; 986 Element target;
971 if (isFieldInitializer(init)) { 987 if (isFieldInitializer(init)) {
972 target = constructor.getEnclosingClass().lookupLocalMember(name); 988 target = constructor.getEnclosingClass().lookupLocalMember(name);
973 if (target == null) { 989 if (target == null) {
974 error(selector, MessageKind.CANNOT_RESOLVE, {'name': name}); 990 error(selector, MessageKind.CANNOT_RESOLVE, {'name': name});
975 } else if (target.kind != ElementKind.FIELD) { 991 } else if (target.kind != ElementKind.FIELD) {
976 error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name}); 992 error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name});
977 } else if (!target.isInstanceMember()) { 993 } else if (!target.isInstanceMember()) {
978 error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name}); 994 error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name});
979 } 995 }
980 } else { 996 } else {
981 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); 997 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
982 } 998 }
983 visitor.useElement(init, target); 999 visitor.useElement(init, target);
984 visitor.world.registerStaticUse(target); 1000 visitor.world.registerStaticUse(target);
985 checkForDuplicateInitializers(name, init); 1001 checkForDuplicateInitializers(target, init);
986 // Resolve initializing value. 1002 // Resolve initializing value.
987 visitor.visitInStaticContext(init.arguments.head); 1003 visitor.visitInStaticContext(init.arguments.head);
988 } 1004 }
989 1005
990 ClassElement getSuperOrThisLookupTarget(FunctionElement constructor, 1006 ClassElement getSuperOrThisLookupTarget(FunctionElement constructor,
991 bool isSuperCall, 1007 bool isSuperCall,
992 Node diagnosticNode) { 1008 Node diagnosticNode) {
993 ClassElement lookupTarget = constructor.getEnclosingClass(); 1009 ClassElement lookupTarget = constructor.getEnclosingClass();
994 if (isSuperCall) { 1010 if (isSuperCall) {
995 // Calculate correct lookup target and constructor name. 1011 // 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. 1130 * constructor, the resolved constructor's function element is returned.
1115 */ 1131 */
1116 FunctionElement resolveInitializers(FunctionElement constructor, 1132 FunctionElement resolveInitializers(FunctionElement constructor,
1117 FunctionExpression functionNode) { 1133 FunctionExpression functionNode) {
1118 // Keep track of all "this.param" parameters specified for constructor so 1134 // Keep track of all "this.param" parameters specified for constructor so
1119 // that we can ensure that fields are initialized only once. 1135 // that we can ensure that fields are initialized only once.
1120 FunctionSignature functionParameters = 1136 FunctionSignature functionParameters =
1121 constructor.computeSignature(visitor.compiler); 1137 constructor.computeSignature(visitor.compiler);
1122 functionParameters.forEachParameter((Element element) { 1138 functionParameters.forEachParameter((Element element) {
1123 if (identical(element.kind, ElementKind.FIELD_PARAMETER)) { 1139 if (identical(element.kind, ElementKind.FIELD_PARAMETER)) {
1124 checkForDuplicateInitializers(element.name, 1140 FieldParameterElement fieldParameter = element;
1141 checkForDuplicateInitializers(fieldParameter.fieldElement,
1125 element.parseNode(visitor.compiler)); 1142 element.parseNode(visitor.compiler));
1126 } 1143 }
1127 }); 1144 });
1128 1145
1129 if (functionNode.initializers == null) { 1146 if (functionNode.initializers == null) {
1130 initializers = const Link<Node>(); 1147 initializers = const Link<Node>();
1131 } else { 1148 } else {
1132 initializers = functionNode.initializers.nodes; 1149 initializers = functionNode.initializers.nodes;
1133 } 1150 }
1134 FunctionElement result; 1151 FunctionElement result;
(...skipping 2565 matching lines...) Expand 10 before | Expand all | Expand 10 after
3700 return e; 3717 return e;
3701 } 3718 }
3702 3719
3703 /// Assumed to be called by [resolveRedirectingFactory]. 3720 /// Assumed to be called by [resolveRedirectingFactory].
3704 Element visitReturn(Return node) { 3721 Element visitReturn(Return node) {
3705 Node expression = node.expression; 3722 Node expression = node.expression;
3706 return finishConstructorReference(visit(expression), 3723 return finishConstructorReference(visit(expression),
3707 expression, expression); 3724 expression, expression);
3708 } 3725 }
3709 } 3726 }
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