Index: lib/compiler/implementation/resolver.dart |
diff --git a/lib/compiler/implementation/resolver.dart b/lib/compiler/implementation/resolver.dart |
index 94808dc9e4b4d63e5c9a268f40e52da970dde9cf..771c5dc12db4721d708bbf8cec6c9cdc9d12e5e9 100644 |
--- a/lib/compiler/implementation/resolver.dart |
+++ b/lib/compiler/implementation/resolver.dart |
@@ -569,7 +569,8 @@ class CommonResolverVisitor<R> extends AbstractVisitor<R> { |
CommonResolverVisitor(Compiler this.compiler); |
R visitNode(Node node) { |
- cancel(node, 'internal error'); |
+ cancel(node, |
+ 'internal error: Unhandled node: ${node.getObjectDescription()}'); |
} |
R visitEmptyStatement(Node node) => null; |
@@ -1654,22 +1655,14 @@ class ClassResolverVisitor extends CommonResolverVisitor<Type> { |
Type visitClassNode(ClassNode node) { |
compiler.ensure(classElement !== null); |
compiler.ensure(!classElement.isResolved); |
- final Link<Node> parameters = |
+ |
+ classElement.ensureParametersAndType(compiler); |
+ context = new TypeVariablesScope(context, classElement); |
+ |
+ // Resolve the bounds of type variables. |
+ Link<Node> parameters = |
node.typeParameters !== null ? node.typeParameters.nodes |
: const EmptyLink<TypeVariable>(); |
- // Create types and elements for type variable. |
- for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) { |
- TypeVariable typeNode = link.head; |
- SourceString variableName = typeNode.name.source; |
- TypeVariableType variableType = new TypeVariableType(variableName); |
- TypeVariableElement variableElement = |
- new TypeVariableElement(variableName, classElement, node, |
- variableType); |
- variableType.element = variableElement; |
- classElement.typeParameters[variableName] = variableElement; |
- context = new TypeVariablesScope(context, classElement); |
- } |
- // Resolve the bounds of type variables. |
for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) { |
TypeVariable typeNode = link.head; |
SourceString variableName = typeNode.name.source; |
@@ -1687,6 +1680,7 @@ class ClassResolverVisitor extends CommonResolverVisitor<Type> { |
} |
} |
} |
+ |
// Find super type. |
Type supertype = visit(node.superclass); |
if (supertype !== null && supertype.element.isExtendable()) { |
@@ -1730,7 +1724,30 @@ class ClassResolverVisitor extends CommonResolverVisitor<Type> { |
} |
Type visitTypeAnnotation(TypeAnnotation node) { |
- return visit(node.typeName); |
+ Type type = visit(node.typeName); |
+ if (type is! InterfaceType) { |
+ // TODO(johnniwinther): Handle function types. |
+ return type; |
+ } |
+ if (node.typeArguments === null) { |
+ if (type.arguments.isEmpty()) { |
+ return type; |
+ } |
+ // Return the 'raw' version, for example List for List<E>. |
+ return new InterfaceType(type.element); |
+ } |
+ var typeArguments = new LinkBuilder<Type>(); |
+ var link = node.typeArguments.nodes; |
+ while (!link.isEmpty()) { |
+ typeArguments.addLast(visit(link.head)); |
+ link = link.tail; |
+ } |
+ // TODO(johnniwinther): Check argument count and bounds. |
+ return new InterfaceType(type.element, typeArguments.toLink()); |
+ } |
+ |
+ Type visitTypeVariable(TypeVariable node) { |
+ return visit(node.name); |
} |
Type visitIdentifier(Identifier node) { |
@@ -1751,7 +1768,7 @@ class ClassResolverVisitor extends CommonResolverVisitor<Type> { |
} else if (element.isTypedef()) { |
compiler.unimplemented('visitIdentifier for typedefs', node: node); |
} else { |
- // TODO(ngeoffray): Use type variables. |
+ // Type variables are handled in [visitTypeAnnotation]. |
return element.computeType(compiler); |
} |
} |
@@ -1799,11 +1816,10 @@ class ClassResolverVisitor extends CommonResolverVisitor<Type> { |
} |
void calculateAllSupertypes(ClassElement cls, Set<ClassElement> seen) { |
- // TODO(karlklose): substitute type variables. |
// TODO(karlklose): check if type arguments match, if a classelement occurs |
// more than once in the supertypes. |
if (cls.allSupertypes !== null) return; |
- final Type supertype = cls.supertype; |
+ final InterfaceType supertype = cls.supertype; |
if (seen.contains(cls)) { |
error(cls.parseNode(compiler), |
MessageKind.CYCLIC_CLASS_HIERARCHY, |
@@ -1811,9 +1827,24 @@ class ClassResolverVisitor extends CommonResolverVisitor<Type> { |
cls.allSupertypes = const EmptyLink<Type>(); |
} else if (supertype != null) { |
seen.add(cls); |
+ ClassElement supertypeElement = supertype.element; |
Link<Type> superSupertypes = |
- getOrCalculateAllSupertypes(supertype.element, seen); |
- Link<Type> supertypes = new Link<Type>(supertype, superSupertypes); |
+ getOrCalculateAllSupertypes(supertypeElement, seen); |
+ var superTypesBuilder = new LinkBuilder<Type>(); |
+ superTypesBuilder.addLast(supertype); |
+ |
+ // Substitute type variables in supertypes. |
+ var superTypeParameters = <Type>[]; |
+ var typeVariableElements = supertypeElement.typeParameters.getValues(); |
+ for (TypeVariableElement typeVariableElement in typeVariableElements) { |
+ superTypeParameters.add(typeVariableElement.type); |
+ } |
+ for (Type superSupertype in superSupertypes) { |
+ superTypesBuilder.addLast(superSupertype.subst( |
+ supertype.arguments, superTypeParameters)); |
+ } |
+ |
+ Link<Type> supertypes = superTypesBuilder.toLink(); |
for (Link<Type> interfaces = cls.interfaces; |
!interfaces.isEmpty(); |
interfaces = interfaces.tail) { |