| 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) {
|
|
|