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

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

Issue 11412245: MalformedType used for all invalid type annotations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 8 years 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 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 breakTargetStack = breakTargetStack.tail; 1031 breakTargetStack = breakTargetStack.tail;
1032 labels = labels.outer; 1032 labels = labels.outer;
1033 } 1033 }
1034 } 1034 }
1035 1035
1036 class TypeResolver { 1036 class TypeResolver {
1037 final Compiler compiler; 1037 final Compiler compiler;
1038 1038
1039 TypeResolver(this.compiler); 1039 TypeResolver(this.compiler);
1040 1040
1041 bool anyMalformedTypes(Link<DartType> list) { 1041 Element resolveTypeName(Scope scope,
1042 for (Link<DartType> link = list; 1042 SourceString prefixName,
1043 !link.isEmpty; 1043 Identifier typeName) {
1044 link = link.tail) { 1044 if (prefixName != null) {
1045 DartType dtype = link.head; 1045 Element e = scope.lookup(prefixName);
1046 if (dtype is MalformedType) { 1046 if (e != null) {
1047 return true; 1047 if (identical(e.kind, ElementKind.PREFIX)) {
1048 } 1048 // The receiver is a prefix. Lookup in the imported members.
1049 } 1049 PrefixElement prefix = e;
1050 return false; 1050 return prefix.lookupLocalMember(typeName.source);
1051 } 1051 } else if (identical(e.kind, ElementKind.CLASS)) {
1052 1052 // TODO(johnniwinther): Remove this case.
1053 Element resolveTypeName(Scope scope, TypeAnnotation node) { 1053 // The receiver is the class part of a named constructor.
1054 Identifier typeName = node.typeName.asIdentifier(); 1054 return e;
1055 Send send = node.typeName.asSend(); 1055 }
1056 return resolveTypeNameInternal(scope, typeName, send);
1057 }
1058
1059 Element resolveTypeNameInternal(Scope scope, Identifier typeName, Send send) {
1060 if (send != null) {
1061 typeName = send.selector;
1062 }
1063 String stringValue = typeName.source.stringValue;
1064 if (identical(stringValue, 'void')) {
1065 return compiler.types.voidType.element;
1066 } else if (identical(stringValue, 'Dynamic')) {
1067 // TODO(aprelev@gmail.com): Remove deprecated Dynamic keyword support.
1068 compiler.onDeprecatedFeature(typeName, 'Dynamic');
1069 return compiler.dynamicClass;
1070 } else if (identical(stringValue, 'dynamic')) {
1071 return compiler.dynamicClass;
1072 } else if (send != null) {
1073 Element e = scope.lookup(send.receiver.asIdentifier().source);
1074 if (e != null && identical(e.kind, ElementKind.PREFIX)) {
1075 // The receiver is a prefix. Lookup in the imported members.
1076 PrefixElement prefix = e;
1077 return prefix.lookupLocalMember(typeName.source);
1078 } else if (e != null && identical(e.kind, ElementKind.CLASS)) {
1079 // The receiver is the class part of a named constructor.
1080 return e;
1081 } else { 1056 } else {
1057 // The caller creates the ErroneousElement for the MalformedType.
1082 return null; 1058 return null;
1083 } 1059 }
1084 } else { 1060 } else {
1085 return scope.lookup(typeName.source); 1061 String stringValue = typeName.source.stringValue;
1062 if (identical(stringValue, 'void')) {
1063 return compiler.types.voidType.element;
1064 } else if (identical(stringValue, 'Dynamic')) {
1065 // TODO(aprelev@gmail.com): Remove deprecated Dynamic keyword support.
1066 compiler.onDeprecatedFeature(typeName, 'Dynamic');
1067 return compiler.dynamicClass;
1068 } else if (identical(stringValue, 'dynamic')) {
1069 return compiler.dynamicClass;
1070 } else {
1071 return scope.lookup(typeName.source);
1072 }
1086 } 1073 }
1087 } 1074 }
1088 1075
1089 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean 1076 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean
1090 // flags instead of closures. 1077 // flags instead of closures.
1091 // TODO(johnniwinther): Should never return [null] but instead an erroneous
1092 // type.
1093 DartType resolveTypeAnnotation( 1078 DartType resolveTypeAnnotation(
1094 TypeAnnotation node, 1079 TypeAnnotation node,
1095 Scope scope, 1080 Scope scope,
1096 bool inStaticContext, 1081 Element enclosingElement,
1097 {onFailure(Node node, MessageKind kind, [List arguments]), 1082 {onFailure(Node node, MessageKind kind, [List arguments]),
1098 whenResolved(Node node, DartType type)}) { 1083 whenResolved(Node node, DartType type)}) {
1099 if (onFailure == null) { 1084 if (onFailure == null) {
1100 onFailure = (n, k, [arguments]) {}; 1085 onFailure = (n, k, [arguments]) {};
1101 } 1086 }
1102 if (whenResolved == null) { 1087 if (whenResolved == null) {
1103 whenResolved = (n, t) {}; 1088 whenResolved = (n, t) {};
1104 } 1089 }
1105 if (scope == null) { 1090 if (scope == null) {
1106 compiler.internalError('resolveTypeAnnotation: no scope specified'); 1091 compiler.internalError('resolveTypeAnnotation: no scope specified');
1107 } 1092 }
1108 return resolveTypeAnnotationInContext(scope, node, inStaticContext, 1093 return resolveTypeAnnotationInContext(scope, node, enclosingElement,
1109 onFailure, whenResolved); 1094 onFailure, whenResolved);
1110 } 1095 }
1111 1096
1112 DartType resolveTypeAnnotationInContext(Scope scope, TypeAnnotation node, 1097 DartType resolveTypeAnnotationInContext(Scope scope, TypeAnnotation node,
1113 bool inStaticContext, 1098 Element enclosingElement,
1114 onFailure, whenResolved) { 1099 onFailure, whenResolved) {
1115 Element element = resolveTypeName(scope, node); 1100 Identifier typeName;
1101 SourceString prefixName;
1102 Send send = node.typeName.asSend();
1103 if (send != null) {
1104 // The type name is of the form [: prefix . identifier :].
1105 prefixName = send.receiver.asIdentifier().source;
1106 typeName = send.selector.asIdentifier();
1107 } else {
1108 typeName = node.typeName.asIdentifier();
1109 }
1110
1111 Element element = resolveTypeName(scope, prefixName, typeName);
1116 DartType type; 1112 DartType type;
1113
1114 DartType reportFailureAndCreateType(MessageKind messageKind,
1115 List messageArguments) {
1116 onFailure(node, messageKind, messageArguments);
1117 var erroneousElement = new ErroneousElement(
1118 messageKind, messageArguments, typeName.source, enclosingElement);
1119 var arguments = new LinkBuilder<DartType>();
1120 resolveTypeArguments(
1121 node, null, enclosingElement,
1122 scope, onFailure, whenResolved, arguments);
1123 return new MalformedType(erroneousElement, null, arguments.toLink());
1124 }
1125
1126 DartType checkNoTypeArguments(DartType type) {
1127 var arguments = new LinkBuilder<DartType>();
1128 bool hashTypeArgumentMismatch = resolveTypeArguments(
1129 node, const Link<DartType>(), enclosingElement,
1130 scope, onFailure, whenResolved, arguments);
1131 if (hashTypeArgumentMismatch) {
1132 type = new MalformedType(
1133 new ErroneousElement(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
1134 [node], typeName.source, enclosingElement),
1135 type, arguments.toLink());
1136 }
1137 return type;
1138 }
1139
1117 if (element == null) { 1140 if (element == null) {
1118 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); 1141 type = reportFailureAndCreateType(
1142 MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]);
1119 } else if (element.isAmbiguous()) { 1143 } else if (element.isAmbiguous()) {
1120 AmbiguousElement ambiguous = element; 1144 AmbiguousElement ambiguous = element;
1121 onFailure(node, ambiguous.messageKind, ambiguous.messageArguments); 1145 type = reportFailureAndCreateType(
1146 ambiguous.messageKind, ambiguous.messageArguments);
1122 } else if (!element.impliesType()) { 1147 } else if (!element.impliesType()) {
1123 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); 1148 type = reportFailureAndCreateType(
1149 MessageKind.NOT_A_TYPE, [node.typeName]);
1124 } else { 1150 } else {
1125 if (identical(element, compiler.types.voidType.element) || 1151 if (identical(element, compiler.types.voidType.element) ||
1126 identical(element, compiler.types.dynamicType.element)) { 1152 identical(element, compiler.types.dynamicType.element)) {
1127 type = element.computeType(compiler); 1153 type = checkNoTypeArguments(element.computeType(compiler));
1128 } else if (element.isClass()) { 1154 } else if (element.isClass()) {
1129 ClassElement cls = element; 1155 ClassElement cls = element;
1130 cls.ensureResolved(compiler); 1156 cls.ensureResolved(compiler);
1131 Link<DartType> arguments = 1157 var arguments = new LinkBuilder<DartType>();
1132 resolveTypeArguments(node, cls.typeVariables, 1158 bool hashTypeArgumentMismatch = resolveTypeArguments(
1133 inStaticContext, scope, 1159 node, cls.typeVariables, enclosingElement,
1134 onFailure, whenResolved); 1160 scope, onFailure, whenResolved, arguments);
1135 if (cls.typeVariables.isEmpty && arguments.isEmpty) { 1161 if (hashTypeArgumentMismatch) {
1136 // Use the canonical type if it has no type parameters. 1162 type = new MalformedType(
1137 type = cls.computeType(compiler); 1163 new ErroneousElement(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
1164 [node], typeName.source, enclosingElement),
1165 new InterfaceType(cls.declaration, arguments.toLink()));
1138 } else { 1166 } else {
1139 if (anyMalformedTypes(arguments)) { 1167 if (arguments.isEmpty) {
1140 // Build interface type (with malformed arguments in it) and 1168 type = cls.rawType;
1141 // call [whenResolved] to let [ConstructorResolver] create
1142 // constructor selectors, which are used by
1143 // [SsaBuilder.visitNewSend] to figure out what class needs
1144 // to be built.
1145 whenResolved(node,
1146 new InterfaceType(cls.declaration, arguments));
1147 // Return malformed type element below so that
1148 // [ConstructorResolver.visitTypeAnnotation] gets [:MalformedType:]
1149 // and can map (via resolver.mapping) NewExpression node to
1150 // this malformed type.
1151 // [SsaBuilder.visitNewExpression] picks up the fact that
1152 // NewExpression is mapped to malformed type and generates
1153 // runtime error in checked mode.
1154 type = new MalformedType(new MalformedTypeElement(node, element));
1155 return type;
1156 } else { 1169 } else {
1157 if (arguments.isEmpty) { 1170 type = new InterfaceType(cls.declaration, arguments.toLink());
1158 // Use the canonical raw type if the class is generic.
1159 type = cls.rawType;
1160 } else {
1161 type = new InterfaceType(cls.declaration, arguments);
1162 }
1163 } 1171 }
1164 } 1172 }
1165 } else if (element.isTypedef()) { 1173 } else if (element.isTypedef()) {
1166 TypedefElement typdef = element; 1174 TypedefElement typdef = element;
1167 // TODO(ahe): Should be [ensureResolved]. 1175 // TODO(ahe): Should be [ensureResolved].
1168 compiler.resolveTypedef(typdef); 1176 compiler.resolveTypedef(typdef);
1169 Link<DartType> arguments = resolveTypeArguments( 1177 var arguments = new LinkBuilder<DartType>();
1170 node, typdef.typeVariables, inStaticContext, 1178 bool hashTypeArgumentMismatch = resolveTypeArguments(
1171 scope, onFailure, whenResolved); 1179 node, typdef.typeVariables, enclosingElement,
1172 if (typdef.typeVariables.isEmpty && arguments.isEmpty) { 1180 scope, onFailure, whenResolved, arguments);
1173 // Return the canonical type if it has no type parameters. 1181 if (hashTypeArgumentMismatch) {
1174 type = typdef.computeType(compiler); 1182 type = new MalformedType(
1183 new ErroneousElement(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
1184 [node], typeName.source, enclosingElement),
1185 new TypedefType(typdef, arguments.toLink()));
1175 } else { 1186 } else {
1176 if (arguments.isEmpty) { 1187 if (arguments.isEmpty) {
1177 type = typdef.rawType; 1188 type = typdef.rawType;
1178 } else { 1189 } else {
1179 type = new TypedefType(typdef, arguments); 1190 type = new TypedefType(typdef, arguments.toLink());
1180 } 1191 }
1181 } 1192 }
1182 } else if (element.isTypeVariable()) { 1193 } else if (element.isTypeVariable()) {
1183 if (inStaticContext) { 1194 if (enclosingElement.isInStaticMember()) {
1184 compiler.reportWarning(node, 1195 compiler.reportWarning(node,
1185 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message( 1196 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message(
1186 [element])); 1197 [node]));
1187 type = new MalformedType(new MalformedTypeElement(node, element)); 1198 type = new MalformedType(
1199 new ErroneousElement(
1200 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
1201 [node], typeName.source, enclosingElement),
1202 element.computeType(compiler));
1188 } else { 1203 } else {
1189 type = element.computeType(compiler); 1204 type = element.computeType(compiler);
1190 } 1205 }
1206 type = checkNoTypeArguments(type);
1191 } else { 1207 } else {
1192 compiler.cancel("unexpected element kind ${element.kind}", 1208 compiler.cancel("unexpected element kind ${element.kind}",
1193 node: node); 1209 node: node);
1194 } 1210 }
1195 } 1211 }
1196 whenResolved(node, type); 1212 whenResolved(node, type);
1197 return type; 1213 return type;
1198 } 1214 }
1199 1215
1200 Link<DartType> resolveTypeArguments(TypeAnnotation node, 1216 /**
1201 Link<DartType> typeVariables, 1217 * Resolves the type arguments of [node] and adds these to [arguments].
1202 bool inStaticContext, 1218 *
1203 Scope scope, onFailure, whenResolved) { 1219 * Returns [: true :] if the number of type arguments did not match the
1220 * number of type variables.
1221 */
1222 bool resolveTypeArguments(
1223 TypeAnnotation node,
1224 Link<DartType> typeVariables,
1225 Element enclosingElement,
1226 Scope scope,
1227 onFailure, whenResolved,
1228 LinkBuilder<DartType> arguments) {
1204 if (node.typeArguments == null) { 1229 if (node.typeArguments == null) {
1205 return const Link<DartType>(); 1230 return false;
1206 } 1231 }
1207 var arguments = new LinkBuilder<DartType>(); 1232 bool typeArgumentCountMismatch = false;
1208 for (Link<Node> typeArguments = node.typeArguments.nodes; 1233 for (Link<Node> typeArguments = node.typeArguments.nodes;
1209 !typeArguments.isEmpty; 1234 !typeArguments.isEmpty;
1210 typeArguments = typeArguments.tail) { 1235 typeArguments = typeArguments.tail) {
1211 if (typeVariables.isEmpty) { 1236 if (typeVariables != null && typeVariables.isEmpty) {
1212 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); 1237 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
1238 typeArgumentCountMismatch = true;
1213 } 1239 }
1214 DartType argType = resolveTypeAnnotationInContext(scope, 1240 DartType argType = resolveTypeAnnotationInContext(scope,
1215 typeArguments.head, 1241 typeArguments.head,
1216 inStaticContext, 1242 enclosingElement,
1217 onFailure, 1243 onFailure,
1218 whenResolved); 1244 whenResolved);
1219 arguments.addLast(argType); 1245 arguments.addLast(argType);
1220 if (!typeVariables.isEmpty) { 1246 if (typeVariables != null && !typeVariables.isEmpty) {
1221 typeVariables = typeVariables.tail; 1247 typeVariables = typeVariables.tail;
1222 } 1248 }
1223 } 1249 }
1224 if (!typeVariables.isEmpty) { 1250 if (typeVariables != null && !typeVariables.isEmpty) {
1225 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); 1251 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT);
1252 typeArgumentCountMismatch = true;
1226 } 1253 }
1227 return arguments.toLink(); 1254 return typeArgumentCountMismatch;
1228 } 1255 }
1229 } 1256 }
1230 1257
1231 /** 1258 /**
1232 * Core implementation of resolution. 1259 * Core implementation of resolution.
1233 * 1260 *
1234 * Do not subclass or instantiate this class outside this library 1261 * Do not subclass or instantiate this class outside this library
1235 * except for testing. 1262 * except for testing.
1236 */ 1263 */
1237 class ResolverVisitor extends CommonResolverVisitor<Element> { 1264 class ResolverVisitor extends CommonResolverVisitor<Element> {
(...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after
2111 InterfaceType type = argument; 2138 InterfaceType type = argument;
2112 type.typeArguments.forEach((DartType argument) { 2139 type.typeArguments.forEach((DartType argument) {
2113 analyzeTypeArgument(type, argument); 2140 analyzeTypeArgument(type, argument);
2114 }); 2141 });
2115 } 2142 }
2116 } 2143 }
2117 2144
2118 DartType resolveTypeAnnotation(TypeAnnotation node) { 2145 DartType resolveTypeAnnotation(TypeAnnotation node) {
2119 Function report = typeRequired ? error : warning; 2146 Function report = typeRequired ? error : warning;
2120 DartType type = typeResolver.resolveTypeAnnotation( 2147 DartType type = typeResolver.resolveTypeAnnotation(
2121 node, scope, enclosingElement.isInStaticMember(), 2148 node, scope, enclosingElement,
2122 onFailure: report, whenResolved: useType); 2149 onFailure: report, whenResolved: useType);
2123 if (type == null) return null; 2150 if (type == null) return null;
2124 if (inCheckContext) { 2151 if (inCheckContext) {
2125 compiler.enqueuer.resolution.registerIsCheck(type); 2152 compiler.enqueuer.resolution.registerIsCheck(type);
2126 } 2153 }
2127 if (typeRequired || inCheckContext) { 2154 if (typeRequired || inCheckContext) {
2128 if (type is InterfaceType) { 2155 if (type is InterfaceType) {
2129 InterfaceType itf = type; 2156 InterfaceType itf = type;
2130 itf.typeArguments.forEach((DartType argument) { 2157 itf.typeArguments.forEach((DartType argument) {
2131 analyzeTypeArgument(type, argument); 2158 analyzeTypeArgument(type, argument);
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
2479 SourceString typeName = typeVariable.name; 2506 SourceString typeName = typeVariable.name;
2480 TypeVariable typeNode = nodeLink.head; 2507 TypeVariable typeNode = nodeLink.head;
2481 if (nameSet.contains(typeName)) { 2508 if (nameSet.contains(typeName)) {
2482 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]); 2509 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]);
2483 } 2510 }
2484 nameSet.add(typeName); 2511 nameSet.add(typeName);
2485 2512
2486 TypeVariableElement variableElement = typeVariable.element; 2513 TypeVariableElement variableElement = typeVariable.element;
2487 if (typeNode.bound != null) { 2514 if (typeNode.bound != null) {
2488 DartType boundType = typeResolver.resolveTypeAnnotation( 2515 DartType boundType = typeResolver.resolveTypeAnnotation(
2489 typeNode.bound, scope, element.isInStaticMember(), 2516 typeNode.bound, scope, element,
2490 onFailure: warning); 2517 onFailure: warning);
2491 if (boundType != null && boundType.element == variableElement) { 2518 if (boundType != null && boundType.element == variableElement) {
2492 // TODO(johnniwinther): Check for more general cycles, like 2519 // TODO(johnniwinther): Check for more general cycles, like
2493 // [: <A extends B, B extends C, C extends B> :]. 2520 // [: <A extends B, B extends C, C extends B> :].
2494 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, 2521 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE,
2495 [variableElement.name]); 2522 [variableElement.name]);
2496 } else if (boundType != null) { 2523 } else if (boundType != null) {
2497 variableElement.bound = boundType; 2524 variableElement.bound = boundType;
2498 } else { 2525 } else {
2499 // TODO(johnniwinther): Should be an erroneous type. 2526 // TODO(johnniwinther): Should be an erroneous type.
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after
3171 return e; 3198 return e;
3172 } 3199 }
3173 3200
3174 /// Assumed to be called by [resolveRedirectingFactory]. 3201 /// Assumed to be called by [resolveRedirectingFactory].
3175 Element visitReturn(Return node) { 3202 Element visitReturn(Return node) {
3176 Node expression = node.expression; 3203 Node expression = node.expression;
3177 return finishConstructorReference(visit(expression), 3204 return finishConstructorReference(visit(expression),
3178 expression, expression); 3205 expression, expression);
3179 } 3206 }
3180 } 3207 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698