| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |