Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| index 6939285c37cdb45cdd7e125c0b6af8fba9ba965c..9b83f9bee4bd76eaaa6efc97218a319c58752554 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| @@ -1081,6 +1081,7 @@ class TypeResolver { |
| DartType resolveTypeAnnotation( |
| TypeAnnotation node, |
| Scope scope, |
| + bool inStaticContext, |
| {onFailure(Node node, MessageKind kind, [List arguments]), |
| whenResolved(Node node, DartType type)}) { |
| if (onFailure == null) { |
| @@ -1092,11 +1093,12 @@ class TypeResolver { |
| if (scope == null) { |
| compiler.internalError('resolveTypeAnnotation: no scope specified'); |
| } |
| - return resolveTypeAnnotationInContext(scope, node, onFailure, |
| - whenResolved); |
| + return resolveTypeAnnotationInContext(scope, node, inStaticContext, |
| + onFailure, whenResolved); |
| } |
| DartType resolveTypeAnnotationInContext(Scope scope, TypeAnnotation node, |
| + bool inStaticContext, |
| onFailure, whenResolved) { |
| Element element = resolveTypeName(scope, node); |
| DartType type; |
| @@ -1115,13 +1117,30 @@ class TypeResolver { |
| ClassElement cls = element; |
| cls.ensureResolved(compiler); |
| Link<DartType> arguments = |
| - resolveTypeArguments(node, cls.typeVariables, scope, |
| + resolveTypeArguments(node, cls.typeVariables, |
| + inStaticContext, scope, |
| onFailure, whenResolved); |
| if (cls.typeVariables.isEmpty && arguments.isEmpty) { |
| // Use the canonical type if it has no type parameters. |
| type = cls.computeType(compiler); |
| } else { |
| - type = new InterfaceType(cls, arguments); |
| + // Bubble-up malformed-ness of the type. |
| + bool isMalformedType = false; |
| + for (Link<DartType> link = arguments; |
| + !link.isEmpty; |
| + link = link.tail) { |
| + DartType dtype = link.head; |
| + if (dtype is MalformedType) { |
| + isMalformedType = true; |
| + break; |
| + } |
| + } |
|
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.
|
| + if (isMalformedType) { |
| + type = new MalformedType( |
| + new MalformedTypeElement(node, element)); |
| + } else { |
| + type = new InterfaceType(cls, arguments); |
| + } |
| } |
| } else if (element.isTypedef()) { |
| TypedefElement typdef = element; |
| @@ -1129,7 +1148,7 @@ class TypeResolver { |
| compiler.resolveTypedef(typdef); |
| typdef.computeType(compiler); |
| Link<DartType> arguments = resolveTypeArguments( |
| - node, typdef.typeVariables, |
| + node, typdef.typeVariables, inStaticContext, |
| scope, onFailure, whenResolved); |
| if (typdef.typeVariables.isEmpty && arguments.isEmpty) { |
| // Return the canonical type if it has no type parameters. |
| @@ -1138,7 +1157,15 @@ class TypeResolver { |
| type = new TypedefType(typdef, arguments); |
| } |
| } else if (element.isTypeVariable()) { |
| - type = element.computeType(compiler); |
| + if (inStaticContext) { |
| + ResolutionWarning warning = |
| + new ResolutionWarning(MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
|
ahe
2012/11/22 12:41:30
Long line.
aam-me
2012/11/23 02:16:47
Done.
|
| + [element]); |
| + compiler.reportWarning(node, warning); |
| + type = new MalformedType(new MalformedTypeElement(node, element)); |
| + } else { |
| + type = element.computeType(compiler); |
| + } |
| } else { |
| compiler.cancel("unexpected element kind ${element.kind}", |
| node: node); |
| @@ -1150,6 +1177,7 @@ class TypeResolver { |
| Link<DartType> resolveTypeArguments(TypeAnnotation node, |
| Link<DartType> typeVariables, |
| + bool inStaticContext, |
| Scope scope, onFailure, whenResolved) { |
| if (node.typeArguments == null) { |
| return const Link<DartType>(); |
| @@ -1163,6 +1191,7 @@ class TypeResolver { |
| } |
| DartType argType = resolveTypeAnnotationInContext(scope, |
| typeArguments.head, |
| + inStaticContext, |
| onFailure, |
| whenResolved); |
| arguments.addLast(argType); |
| @@ -2061,21 +2090,10 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
| } |
| DartType resolveTypeAnnotation(TypeAnnotation node) { |
| - // TODO(johnniwinther): Remove this together with the named arguments |
| - // on [TypeResolver.resolveTypeAnnotation]. |
| - void checkAndUseType(TypeAnnotation annotation, DartType type) { |
| - useType(annotation, type); |
| - if (type != null && |
| - identical(type.kind, TypeKind.TYPE_VARIABLE) && |
| - enclosingElement.isInStaticMember()) { |
| - warning(annotation, MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
| - [type]); |
| - } |
| - } |
| - |
| Function report = typeRequired ? error : warning; |
| DartType type = typeResolver.resolveTypeAnnotation( |
| - node, scope, onFailure: report, whenResolved: checkAndUseType); |
| + node, scope, enclosingElement.isInStaticMember(), |
| + onFailure: report, whenResolved: useType); |
| if (type == null) return null; |
| if (inCheckContext) { |
| compiler.enqueuer.resolution.registerIsCheck(type); |
| @@ -2442,7 +2460,8 @@ class TypeDefinitionVisitor extends CommonResolverVisitor<DartType> { |
| TypeVariableElement variableElement = typeVariable.element; |
| if (typeNode.bound != null) { |
| DartType boundType = typeResolver.resolveTypeAnnotation( |
| - typeNode.bound, scope, onFailure: warning); |
| + typeNode.bound, scope, element.isInStaticMember(), |
| + onFailure: warning); |
| if (boundType != null && boundType.element == variableElement) { |
| // TODO(johnniwinther): Check for more general cycles, like |
| // [: <A extends B, B extends C, C extends B> :]. |