Index: lib/compiler/implementation/elements/elements.dart |
diff --git a/lib/compiler/implementation/elements/elements.dart b/lib/compiler/implementation/elements/elements.dart |
index a104749521a57a0089f9f97975d1dc8d53b23074..00ead02f822f0dc39e470fa607a31239f2e76fd2 100644 |
--- a/lib/compiler/implementation/elements/elements.dart |
+++ b/lib/compiler/implementation/elements/elements.dart |
@@ -850,10 +850,39 @@ class ClassElement extends ContainerElement { |
} |
} |
- Type computeType(compiler) { |
+ /** |
+ * Called to ensure that type parameters and the type of this class have been |
+ * created. The bounds of the type variables are not set here but instead |
+ * during resolution of the class. This split is needed to create the type |
+ * of the class before it has been resolved, which in turns enables the |
+ * resolution to handle cyclic dependencies as for instance imposed by default |
+ * classes. |
+ */ |
+ void ensureParametersAndType(Compiler compiler) { |
if (type === null) { |
floitsch
2012/07/26 11:14:40
no need to === anymore. == is enough.
|
- type = new InterfaceType(this); |
+ ClassNode node = parseNode(compiler); |
+ Link<Node> parameters = |
+ node.typeParameters !== null ? node.typeParameters.nodes |
+ : const EmptyLink<TypeVariable>(); |
+ // Create types and elements for type variable. |
+ var arguments = new LinkBuilder<Type>(); |
+ for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) { |
+ TypeVariable typeNode = link.head; |
+ SourceString variableName = typeNode.name.source; |
+ TypeVariableType variableType = new TypeVariableType(variableName); |
+ arguments.addLast(variableType); |
+ TypeVariableElement variableElement = |
+ new TypeVariableElement(variableName, this, node, |
+ variableType); |
+ variableType.element = variableElement; |
+ typeParameters[variableName] = variableElement; |
+ } |
+ type = new InterfaceType(this, arguments.toLink()); |
} |
+ } |
+ |
+ Type computeType(compiler) { |
+ ensureParametersAndType(compiler); |
return type; |
} |