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

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

Issue 11416144: Produce run-time error when type parameters are accessed from static context. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Removed redundant malformed type replacement with dynamic type. 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 anyMalformedTypesInThere(Link<DartType> list) {
ngeoffray 2012/11/27 09:37:35 Personal taste, but I would remove 'InThere'.
aam-me 2012/11/28 01:49:47 I understand. No objections to this.
1042 for (Link<DartType> link = list;
1043 !link.isEmpty;
1044 link = link.tail) {
1045 DartType dtype = link.head;
1046 if (dtype is MalformedType) {
1047 return true;
1048 }
1049 }
1050 return false;
1051 }
1052
1041 Element resolveTypeName(Scope scope, TypeAnnotation node) { 1053 Element resolveTypeName(Scope scope, TypeAnnotation node) {
1042 Identifier typeName = node.typeName.asIdentifier(); 1054 Identifier typeName = node.typeName.asIdentifier();
1043 Send send = node.typeName.asSend(); 1055 Send send = node.typeName.asSend();
1044 return resolveTypeNameInternal(scope, typeName, send); 1056 return resolveTypeNameInternal(scope, typeName, send);
1045 } 1057 }
1046 1058
1047 Element resolveTypeNameInternal(Scope scope, Identifier typeName, Send send) { 1059 Element resolveTypeNameInternal(Scope scope, Identifier typeName, Send send) {
1048 if (send != null) { 1060 if (send != null) {
1049 typeName = send.selector; 1061 typeName = send.selector;
1050 } 1062 }
(...skipping 23 matching lines...) Expand all
1074 } 1086 }
1075 } 1087 }
1076 1088
1077 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean 1089 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean
1078 // flags instead of closures. 1090 // flags instead of closures.
1079 // TODO(johnniwinther): Should never return [null] but instead an erroneous 1091 // TODO(johnniwinther): Should never return [null] but instead an erroneous
1080 // type. 1092 // type.
1081 DartType resolveTypeAnnotation( 1093 DartType resolveTypeAnnotation(
1082 TypeAnnotation node, 1094 TypeAnnotation node,
1083 Scope scope, 1095 Scope scope,
1096 bool inStaticContext,
1084 {onFailure(Node node, MessageKind kind, [List arguments]), 1097 {onFailure(Node node, MessageKind kind, [List arguments]),
1085 whenResolved(Node node, DartType type)}) { 1098 whenResolved(Node node, DartType type)}) {
1086 if (onFailure == null) { 1099 if (onFailure == null) {
1087 onFailure = (n, k, [arguments]) {}; 1100 onFailure = (n, k, [arguments]) {};
1088 } 1101 }
1089 if (whenResolved == null) { 1102 if (whenResolved == null) {
1090 whenResolved = (n, t) {}; 1103 whenResolved = (n, t) {};
1091 } 1104 }
1092 if (scope == null) { 1105 if (scope == null) {
1093 compiler.internalError('resolveTypeAnnotation: no scope specified'); 1106 compiler.internalError('resolveTypeAnnotation: no scope specified');
1094 } 1107 }
1095 return resolveTypeAnnotationInContext(scope, node, onFailure, 1108 return resolveTypeAnnotationInContext(scope, node, inStaticContext,
1096 whenResolved); 1109 onFailure, whenResolved);
1097 } 1110 }
1098 1111
1099 DartType resolveTypeAnnotationInContext(Scope scope, TypeAnnotation node, 1112 DartType resolveTypeAnnotationInContext(Scope scope, TypeAnnotation node,
1113 bool inStaticContext,
1100 onFailure, whenResolved) { 1114 onFailure, whenResolved) {
1101 Element element = resolveTypeName(scope, node); 1115 Element element = resolveTypeName(scope, node);
1102 DartType type; 1116 DartType type;
1103 if (element == null) { 1117 if (element == null) {
1104 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); 1118 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]);
1105 } else if (element.isAmbiguous()) { 1119 } else if (element.isAmbiguous()) {
1106 AmbiguousElement ambiguous = element; 1120 AmbiguousElement ambiguous = element;
1107 onFailure(node, ambiguous.messageKind, ambiguous.messageArguments); 1121 onFailure(node, ambiguous.messageKind, ambiguous.messageArguments);
1108 } else if (!element.impliesType()) { 1122 } else if (!element.impliesType()) {
1109 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); 1123 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]);
1110 } else { 1124 } else {
1111 if (identical(element, compiler.types.voidType.element) || 1125 if (identical(element, compiler.types.voidType.element) ||
1112 identical(element, compiler.types.dynamicType.element)) { 1126 identical(element, compiler.types.dynamicType.element)) {
1113 type = element.computeType(compiler); 1127 type = element.computeType(compiler);
1114 } else if (element.isClass()) { 1128 } else if (element.isClass()) {
1115 ClassElement cls = element; 1129 ClassElement cls = element;
1116 cls.ensureResolved(compiler); 1130 cls.ensureResolved(compiler);
1117 Link<DartType> arguments = 1131 Link<DartType> arguments =
1118 resolveTypeArguments(node, cls.typeVariables, scope, 1132 resolveTypeArguments(node, cls.typeVariables,
1133 inStaticContext, scope,
1119 onFailure, whenResolved); 1134 onFailure, whenResolved);
1120 if (cls.typeVariables.isEmpty && arguments.isEmpty) { 1135 if (cls.typeVariables.isEmpty && arguments.isEmpty) {
1121 // Use the canonical type if it has no type parameters. 1136 // Use the canonical type if it has no type parameters.
1122 type = cls.computeType(compiler); 1137 type = cls.computeType(compiler);
1123 } else { 1138 } else {
1124 type = new InterfaceType(cls.declaration, arguments); 1139 // In checked mode malformed-ness of the type argument bubbles up.
ngeoffray 2012/11/27 09:37:35 Why not in non-checked mode? Is that an optimizati
aam-me 2012/11/28 01:49:47 When we produce MalformedTypeElement here, it trig
ahe 2012/11/28 02:08:50 I think what Nicolas is saying is that we generall
1140 if (anyMalformedTypesInThere(arguments) &&
1141 compiler.enableTypeAssertions) {
1142 type = new MalformedType(
1143 new MalformedTypeElement(node, element));
1144 } else {
1145 type = new InterfaceType(cls.declaration, arguments);
1146 }
1125 } 1147 }
1126 } else if (element.isTypedef()) { 1148 } else if (element.isTypedef()) {
1127 TypedefElement typdef = element; 1149 TypedefElement typdef = element;
1128 // TODO(ahe): Should be [ensureResolved]. 1150 // TODO(ahe): Should be [ensureResolved].
1129 compiler.resolveTypedef(typdef); 1151 compiler.resolveTypedef(typdef);
1130 typdef.computeType(compiler); 1152 typdef.computeType(compiler);
1131 Link<DartType> arguments = resolveTypeArguments( 1153 Link<DartType> arguments = resolveTypeArguments(
1132 node, typdef.typeVariables, 1154 node, typdef.typeVariables, inStaticContext,
1133 scope, onFailure, whenResolved); 1155 scope, onFailure, whenResolved);
1134 if (typdef.typeVariables.isEmpty && arguments.isEmpty) { 1156 if (typdef.typeVariables.isEmpty && arguments.isEmpty) {
1135 // Return the canonical type if it has no type parameters. 1157 // Return the canonical type if it has no type parameters.
1136 type = typdef.computeType(compiler); 1158 type = typdef.computeType(compiler);
1137 } else { 1159 } else {
1138 type = new TypedefType(typdef, arguments); 1160 type = new TypedefType(typdef, arguments);
1139 } 1161 }
1140 } else if (element.isTypeVariable()) { 1162 } else if (element.isTypeVariable()) {
1141 type = element.computeType(compiler); 1163 if (inStaticContext) {
1164 compiler.reportWarning(node,
1165 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message(
1166 [element]));
1167 type = new MalformedType(new MalformedTypeElement(node, element));
1168 } else {
1169 type = element.computeType(compiler);
1170 }
1142 } else { 1171 } else {
1143 compiler.cancel("unexpected element kind ${element.kind}", 1172 compiler.cancel("unexpected element kind ${element.kind}",
1144 node: node); 1173 node: node);
1145 } 1174 }
1146 } 1175 }
1147 whenResolved(node, type); 1176 whenResolved(node, type);
1148 return type; 1177 return type;
1149 } 1178 }
1150 1179
1151 Link<DartType> resolveTypeArguments(TypeAnnotation node, 1180 Link<DartType> resolveTypeArguments(TypeAnnotation node,
1152 Link<DartType> typeVariables, 1181 Link<DartType> typeVariables,
1182 bool inStaticContext,
1153 Scope scope, onFailure, whenResolved) { 1183 Scope scope, onFailure, whenResolved) {
1154 if (node.typeArguments == null) { 1184 if (node.typeArguments == null) {
1155 return const Link<DartType>(); 1185 return const Link<DartType>();
1156 } 1186 }
1157 var arguments = new LinkBuilder<DartType>(); 1187 var arguments = new LinkBuilder<DartType>();
1158 for (Link<Node> typeArguments = node.typeArguments.nodes; 1188 for (Link<Node> typeArguments = node.typeArguments.nodes;
1159 !typeArguments.isEmpty; 1189 !typeArguments.isEmpty;
1160 typeArguments = typeArguments.tail) { 1190 typeArguments = typeArguments.tail) {
1161 if (typeVariables.isEmpty) { 1191 if (typeVariables.isEmpty) {
1162 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); 1192 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
1163 } 1193 }
1164 DartType argType = resolveTypeAnnotationInContext(scope, 1194 DartType argType = resolveTypeAnnotationInContext(scope,
1165 typeArguments.head, 1195 typeArguments.head,
1196 inStaticContext,
1166 onFailure, 1197 onFailure,
1167 whenResolved); 1198 whenResolved);
1168 arguments.addLast(argType); 1199 arguments.addLast(argType);
1169 if (!typeVariables.isEmpty) { 1200 if (!typeVariables.isEmpty) {
1170 typeVariables = typeVariables.tail; 1201 typeVariables = typeVariables.tail;
1171 } 1202 }
1172 } 1203 }
1173 if (!typeVariables.isEmpty) { 1204 if (!typeVariables.isEmpty) {
1174 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); 1205 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT);
1175 } 1206 }
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after
2050 argument.element.enclosingElement); 2081 argument.element.enclosingElement);
2051 } else if (argument is InterfaceType) { 2082 } else if (argument is InterfaceType) {
2052 InterfaceType type = argument; 2083 InterfaceType type = argument;
2053 type.arguments.forEach((DartType argument) { 2084 type.arguments.forEach((DartType argument) {
2054 analyzeTypeArgument(type, argument); 2085 analyzeTypeArgument(type, argument);
2055 }); 2086 });
2056 } 2087 }
2057 } 2088 }
2058 2089
2059 DartType resolveTypeAnnotation(TypeAnnotation node) { 2090 DartType resolveTypeAnnotation(TypeAnnotation node) {
2060 // TODO(johnniwinther): Remove this together with the named arguments
2061 // on [TypeResolver.resolveTypeAnnotation].
2062 void checkAndUseType(TypeAnnotation annotation, DartType type) {
2063 useType(annotation, type);
2064 if (type != null &&
2065 identical(type.kind, TypeKind.TYPE_VARIABLE) &&
2066 enclosingElement.isInStaticMember()) {
2067 warning(annotation, MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
2068 [type]);
2069 }
2070 }
2071
2072 Function report = typeRequired ? error : warning; 2091 Function report = typeRequired ? error : warning;
2073 DartType type = typeResolver.resolveTypeAnnotation( 2092 DartType type = typeResolver.resolveTypeAnnotation(
2074 node, scope, onFailure: report, whenResolved: checkAndUseType); 2093 node, scope, enclosingElement.isInStaticMember(),
2094 onFailure: report, whenResolved: useType);
2075 if (type == null) return null; 2095 if (type == null) return null;
2076 if (inCheckContext) { 2096 if (inCheckContext) {
2077 compiler.enqueuer.resolution.registerIsCheck(type); 2097 compiler.enqueuer.resolution.registerIsCheck(type);
2078 } 2098 }
2079 if (typeRequired || inCheckContext) { 2099 if (typeRequired || inCheckContext) {
2080 if (type is InterfaceType) { 2100 if (type is InterfaceType) {
2081 InterfaceType itf = type; 2101 InterfaceType itf = type;
2082 itf.arguments.forEach((DartType argument) { 2102 itf.arguments.forEach((DartType argument) {
2083 analyzeTypeArgument(type, argument); 2103 analyzeTypeArgument(type, argument);
2084 }); 2104 });
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
2431 SourceString typeName = typeVariable.name; 2451 SourceString typeName = typeVariable.name;
2432 TypeVariable typeNode = nodeLink.head; 2452 TypeVariable typeNode = nodeLink.head;
2433 if (nameSet.contains(typeName)) { 2453 if (nameSet.contains(typeName)) {
2434 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]); 2454 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]);
2435 } 2455 }
2436 nameSet.add(typeName); 2456 nameSet.add(typeName);
2437 2457
2438 TypeVariableElement variableElement = typeVariable.element; 2458 TypeVariableElement variableElement = typeVariable.element;
2439 if (typeNode.bound != null) { 2459 if (typeNode.bound != null) {
2440 DartType boundType = typeResolver.resolveTypeAnnotation( 2460 DartType boundType = typeResolver.resolveTypeAnnotation(
2441 typeNode.bound, scope, onFailure: warning); 2461 typeNode.bound, scope, element.isInStaticMember(),
2462 onFailure: warning);
2442 if (boundType != null && boundType.element == variableElement) { 2463 if (boundType != null && boundType.element == variableElement) {
2443 // TODO(johnniwinther): Check for more general cycles, like 2464 // TODO(johnniwinther): Check for more general cycles, like
2444 // [: <A extends B, B extends C, C extends B> :]. 2465 // [: <A extends B, B extends C, C extends B> :].
2445 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, 2466 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE,
2446 [variableElement.name]); 2467 [variableElement.name]);
2447 } else if (boundType != null) { 2468 } else if (boundType != null) {
2448 variableElement.bound = boundType; 2469 variableElement.bound = boundType;
2449 } else { 2470 } else {
2450 // TODO(johnniwinther): Should be an erroneous type. 2471 // TODO(johnniwinther): Should be an erroneous type.
2451 variableElement.bound = compiler.objectClass.computeType(compiler); 2472 variableElement.bound = compiler.objectClass.computeType(compiler);
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
3119 return e; 3140 return e;
3120 } 3141 }
3121 3142
3122 /// Assumed to be called by [resolveRedirectingFactory]. 3143 /// Assumed to be called by [resolveRedirectingFactory].
3123 Element visitReturn(Return node) { 3144 Element visitReturn(Return node) {
3124 Node expression = node.expression; 3145 Node expression = node.expression;
3125 return finishConstructorReference(visit(expression), 3146 return finishConstructorReference(visit(expression),
3126 expression, expression); 3147 expression, expression);
3127 } 3148 }
3128 } 3149 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698