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 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1074 } | 1074 } |
1075 } | 1075 } |
1076 | 1076 |
1077 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean | 1077 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean |
1078 // flags instead of closures. | 1078 // flags instead of closures. |
1079 // TODO(johnniwinther): Should never return [null] but instead an erroneous | 1079 // TODO(johnniwinther): Should never return [null] but instead an erroneous |
1080 // type. | 1080 // type. |
1081 DartType resolveTypeAnnotation( | 1081 DartType resolveTypeAnnotation( |
1082 TypeAnnotation node, | 1082 TypeAnnotation node, |
1083 Scope scope, | 1083 Scope scope, |
1084 bool inStaticContext, | |
1084 {onFailure(Node node, MessageKind kind, [List arguments]), | 1085 {onFailure(Node node, MessageKind kind, [List arguments]), |
1085 whenResolved(Node node, DartType type)}) { | 1086 whenResolved(Node node, DartType type)}) { |
1086 if (onFailure == null) { | 1087 if (onFailure == null) { |
1087 onFailure = (n, k, [arguments]) {}; | 1088 onFailure = (n, k, [arguments]) {}; |
1088 } | 1089 } |
1089 if (whenResolved == null) { | 1090 if (whenResolved == null) { |
1090 whenResolved = (n, t) {}; | 1091 whenResolved = (n, t) {}; |
1091 } | 1092 } |
1092 if (scope == null) { | 1093 if (scope == null) { |
1093 compiler.internalError('resolveTypeAnnotation: no scope specified'); | 1094 compiler.internalError('resolveTypeAnnotation: no scope specified'); |
1094 } | 1095 } |
1095 return resolveTypeAnnotationInContext(scope, node, onFailure, | 1096 return resolveTypeAnnotationInContext(scope, node, inStaticContext, |
1096 whenResolved); | 1097 onFailure, whenResolved); |
1097 } | 1098 } |
1098 | 1099 |
1099 DartType resolveTypeAnnotationInContext(Scope scope, TypeAnnotation node, | 1100 DartType resolveTypeAnnotationInContext(Scope scope, TypeAnnotation node, |
1101 bool inStaticContext, | |
1100 onFailure, whenResolved) { | 1102 onFailure, whenResolved) { |
1101 Element element = resolveTypeName(scope, node); | 1103 Element element = resolveTypeName(scope, node); |
1102 DartType type; | 1104 DartType type; |
1103 if (element == null) { | 1105 if (element == null) { |
1104 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); | 1106 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); |
1105 } else if (element.isAmbiguous()) { | 1107 } else if (element.isAmbiguous()) { |
1106 AmbiguousElement ambiguous = element; | 1108 AmbiguousElement ambiguous = element; |
1107 onFailure(node, ambiguous.messageKind, ambiguous.messageArguments); | 1109 onFailure(node, ambiguous.messageKind, ambiguous.messageArguments); |
1108 } else if (!element.impliesType()) { | 1110 } else if (!element.impliesType()) { |
1109 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); | 1111 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); |
1110 } else { | 1112 } else { |
1111 if (identical(element, compiler.types.voidType.element) || | 1113 if (identical(element, compiler.types.voidType.element) || |
1112 identical(element, compiler.types.dynamicType.element)) { | 1114 identical(element, compiler.types.dynamicType.element)) { |
1113 type = element.computeType(compiler); | 1115 type = element.computeType(compiler); |
1114 } else if (element.isClass()) { | 1116 } else if (element.isClass()) { |
1115 ClassElement cls = element; | 1117 ClassElement cls = element; |
1116 cls.ensureResolved(compiler); | 1118 cls.ensureResolved(compiler); |
1117 Link<DartType> arguments = | 1119 Link<DartType> arguments = |
1118 resolveTypeArguments(node, cls.typeVariables, scope, | 1120 resolveTypeArguments(node, cls.typeVariables, |
1121 inStaticContext, scope, | |
1119 onFailure, whenResolved); | 1122 onFailure, whenResolved); |
1120 if (cls.typeVariables.isEmpty && arguments.isEmpty) { | 1123 if (cls.typeVariables.isEmpty && arguments.isEmpty) { |
1121 // Use the canonical type if it has no type parameters. | 1124 // Use the canonical type if it has no type parameters. |
1122 type = cls.computeType(compiler); | 1125 type = cls.computeType(compiler); |
1123 } else { | 1126 } else { |
1124 type = new InterfaceType(cls, arguments); | 1127 // Bubble-up malformed-ness of the type. |
1128 bool isMalformedType = false; | |
1129 for (Link<DartType> link = arguments; | |
1130 !link.isEmpty; | |
1131 link = link.tail) { | |
1132 DartType dtype = link.head; | |
1133 if (dtype is MalformedType) { | |
1134 isMalformedType = true; | |
1135 break; | |
1136 } | |
1137 } | |
ahe
2012/11/22 12:41:30
This for loop is a great candidate for a helper me
aam-me
2012/11/23 02:16:47
Done.
| |
1138 if (isMalformedType) { | |
1139 type = new MalformedType( | |
1140 new MalformedTypeElement(node, element)); | |
1141 } else { | |
1142 type = new InterfaceType(cls, arguments); | |
1143 } | |
1125 } | 1144 } |
1126 } else if (element.isTypedef()) { | 1145 } else if (element.isTypedef()) { |
1127 TypedefElement typdef = element; | 1146 TypedefElement typdef = element; |
1128 // TODO(ahe): Should be [ensureResolved]. | 1147 // TODO(ahe): Should be [ensureResolved]. |
1129 compiler.resolveTypedef(typdef); | 1148 compiler.resolveTypedef(typdef); |
1130 typdef.computeType(compiler); | 1149 typdef.computeType(compiler); |
1131 Link<DartType> arguments = resolveTypeArguments( | 1150 Link<DartType> arguments = resolveTypeArguments( |
1132 node, typdef.typeVariables, | 1151 node, typdef.typeVariables, inStaticContext, |
1133 scope, onFailure, whenResolved); | 1152 scope, onFailure, whenResolved); |
1134 if (typdef.typeVariables.isEmpty && arguments.isEmpty) { | 1153 if (typdef.typeVariables.isEmpty && arguments.isEmpty) { |
1135 // Return the canonical type if it has no type parameters. | 1154 // Return the canonical type if it has no type parameters. |
1136 type = typdef.computeType(compiler); | 1155 type = typdef.computeType(compiler); |
1137 } else { | 1156 } else { |
1138 type = new TypedefType(typdef, arguments); | 1157 type = new TypedefType(typdef, arguments); |
1139 } | 1158 } |
1140 } else if (element.isTypeVariable()) { | 1159 } else if (element.isTypeVariable()) { |
1141 type = element.computeType(compiler); | 1160 if (inStaticContext) { |
1161 ResolutionWarning warning = | |
1162 new ResolutionWarning(MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMB ER, | |
ahe
2012/11/22 12:41:30
Long line.
aam-me
2012/11/23 02:16:47
Done.
| |
1163 [element]); | |
1164 compiler.reportWarning(node, warning); | |
1165 type = new MalformedType(new MalformedTypeElement(node, element)); | |
1166 } else { | |
1167 type = element.computeType(compiler); | |
1168 } | |
1142 } else { | 1169 } else { |
1143 compiler.cancel("unexpected element kind ${element.kind}", | 1170 compiler.cancel("unexpected element kind ${element.kind}", |
1144 node: node); | 1171 node: node); |
1145 } | 1172 } |
1146 } | 1173 } |
1147 whenResolved(node, type); | 1174 whenResolved(node, type); |
1148 return type; | 1175 return type; |
1149 } | 1176 } |
1150 | 1177 |
1151 Link<DartType> resolveTypeArguments(TypeAnnotation node, | 1178 Link<DartType> resolveTypeArguments(TypeAnnotation node, |
1152 Link<DartType> typeVariables, | 1179 Link<DartType> typeVariables, |
1180 bool inStaticContext, | |
1153 Scope scope, onFailure, whenResolved) { | 1181 Scope scope, onFailure, whenResolved) { |
1154 if (node.typeArguments == null) { | 1182 if (node.typeArguments == null) { |
1155 return const Link<DartType>(); | 1183 return const Link<DartType>(); |
1156 } | 1184 } |
1157 var arguments = new LinkBuilder<DartType>(); | 1185 var arguments = new LinkBuilder<DartType>(); |
1158 for (Link<Node> typeArguments = node.typeArguments.nodes; | 1186 for (Link<Node> typeArguments = node.typeArguments.nodes; |
1159 !typeArguments.isEmpty; | 1187 !typeArguments.isEmpty; |
1160 typeArguments = typeArguments.tail) { | 1188 typeArguments = typeArguments.tail) { |
1161 if (typeVariables.isEmpty) { | 1189 if (typeVariables.isEmpty) { |
1162 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 1190 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
1163 } | 1191 } |
1164 DartType argType = resolveTypeAnnotationInContext(scope, | 1192 DartType argType = resolveTypeAnnotationInContext(scope, |
1165 typeArguments.head, | 1193 typeArguments.head, |
1194 inStaticContext, | |
1166 onFailure, | 1195 onFailure, |
1167 whenResolved); | 1196 whenResolved); |
1168 arguments.addLast(argType); | 1197 arguments.addLast(argType); |
1169 if (!typeVariables.isEmpty) { | 1198 if (!typeVariables.isEmpty) { |
1170 typeVariables = typeVariables.tail; | 1199 typeVariables = typeVariables.tail; |
1171 } | 1200 } |
1172 } | 1201 } |
1173 if (!typeVariables.isEmpty) { | 1202 if (!typeVariables.isEmpty) { |
1174 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); | 1203 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); |
1175 } | 1204 } |
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2054 argument.element.enclosingElement); | 2083 argument.element.enclosingElement); |
2055 } else if (argument is InterfaceType) { | 2084 } else if (argument is InterfaceType) { |
2056 InterfaceType type = argument; | 2085 InterfaceType type = argument; |
2057 type.arguments.forEach((DartType argument) { | 2086 type.arguments.forEach((DartType argument) { |
2058 analyzeTypeArgument(type, argument); | 2087 analyzeTypeArgument(type, argument); |
2059 }); | 2088 }); |
2060 } | 2089 } |
2061 } | 2090 } |
2062 | 2091 |
2063 DartType resolveTypeAnnotation(TypeAnnotation node) { | 2092 DartType resolveTypeAnnotation(TypeAnnotation node) { |
2064 // TODO(johnniwinther): Remove this together with the named arguments | |
2065 // on [TypeResolver.resolveTypeAnnotation]. | |
2066 void checkAndUseType(TypeAnnotation annotation, DartType type) { | |
2067 useType(annotation, type); | |
2068 if (type != null && | |
2069 identical(type.kind, TypeKind.TYPE_VARIABLE) && | |
2070 enclosingElement.isInStaticMember()) { | |
2071 warning(annotation, MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | |
2072 [type]); | |
2073 } | |
2074 } | |
2075 | |
2076 Function report = typeRequired ? error : warning; | 2093 Function report = typeRequired ? error : warning; |
2077 DartType type = typeResolver.resolveTypeAnnotation( | 2094 DartType type = typeResolver.resolveTypeAnnotation( |
2078 node, scope, onFailure: report, whenResolved: checkAndUseType); | 2095 node, scope, enclosingElement.isInStaticMember(), |
2096 onFailure: report, whenResolved: useType); | |
2079 if (type == null) return null; | 2097 if (type == null) return null; |
2080 if (inCheckContext) { | 2098 if (inCheckContext) { |
2081 compiler.enqueuer.resolution.registerIsCheck(type); | 2099 compiler.enqueuer.resolution.registerIsCheck(type); |
2082 } | 2100 } |
2083 if (typeRequired || inCheckContext) { | 2101 if (typeRequired || inCheckContext) { |
2084 if (type is InterfaceType) { | 2102 if (type is InterfaceType) { |
2085 InterfaceType itf = type; | 2103 InterfaceType itf = type; |
2086 itf.arguments.forEach((DartType argument) { | 2104 itf.arguments.forEach((DartType argument) { |
2087 analyzeTypeArgument(type, argument); | 2105 analyzeTypeArgument(type, argument); |
2088 }); | 2106 }); |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2435 SourceString typeName = typeVariable.name; | 2453 SourceString typeName = typeVariable.name; |
2436 TypeVariable typeNode = nodeLink.head; | 2454 TypeVariable typeNode = nodeLink.head; |
2437 if (nameSet.contains(typeName)) { | 2455 if (nameSet.contains(typeName)) { |
2438 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]); | 2456 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]); |
2439 } | 2457 } |
2440 nameSet.add(typeName); | 2458 nameSet.add(typeName); |
2441 | 2459 |
2442 TypeVariableElement variableElement = typeVariable.element; | 2460 TypeVariableElement variableElement = typeVariable.element; |
2443 if (typeNode.bound != null) { | 2461 if (typeNode.bound != null) { |
2444 DartType boundType = typeResolver.resolveTypeAnnotation( | 2462 DartType boundType = typeResolver.resolveTypeAnnotation( |
2445 typeNode.bound, scope, onFailure: warning); | 2463 typeNode.bound, scope, element.isInStaticMember(), |
2464 onFailure: warning); | |
2446 if (boundType != null && boundType.element == variableElement) { | 2465 if (boundType != null && boundType.element == variableElement) { |
2447 // TODO(johnniwinther): Check for more general cycles, like | 2466 // TODO(johnniwinther): Check for more general cycles, like |
2448 // [: <A extends B, B extends C, C extends B> :]. | 2467 // [: <A extends B, B extends C, C extends B> :]. |
2449 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, | 2468 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, |
2450 [variableElement.name]); | 2469 [variableElement.name]); |
2451 } else if (boundType != null) { | 2470 } else if (boundType != null) { |
2452 variableElement.bound = boundType; | 2471 variableElement.bound = boundType; |
2453 } else { | 2472 } else { |
2454 // TODO(johnniwinther): Should be an erroneous type. | 2473 // TODO(johnniwinther): Should be an erroneous type. |
2455 variableElement.bound = compiler.objectClass.computeType(compiler); | 2474 variableElement.bound = compiler.objectClass.computeType(compiler); |
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3123 return e; | 3142 return e; |
3124 } | 3143 } |
3125 | 3144 |
3126 /// Assumed to be called by [resolveRedirectingFactory]. | 3145 /// Assumed to be called by [resolveRedirectingFactory]. |
3127 Element visitReturn(Return node) { | 3146 Element visitReturn(Return node) { |
3128 Node expression = node.expression; | 3147 Node expression = node.expression; |
3129 return finishConstructorReference(visit(expression), | 3148 return finishConstructorReference(visit(expression), |
3130 expression, expression); | 3149 expression, expression); |
3131 } | 3150 } |
3132 } | 3151 } |
OLD | NEW |