| Index: lib/compiler/implementation/resolver.dart
|
| diff --git a/lib/compiler/implementation/resolver.dart b/lib/compiler/implementation/resolver.dart
|
| index 8f6842d9a23809f18a08023a9ddf36b7931f1ca4..246a546edf7ae8b40d13e80b57ae7a63b3775156 100644
|
| --- a/lib/compiler/implementation/resolver.dart
|
| +++ b/lib/compiler/implementation/resolver.dart
|
| @@ -1657,6 +1657,58 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
|
| }
|
| }
|
|
|
| +class TypeDefinitionVisitor extends CommonResolverVisitor<Type> {
|
| + Scope scope;
|
| + TypeDeclarationElement element;
|
| + TypeResolver typeResolver;
|
| +
|
| + TypeDefinitionVisitor(Compiler compiler, TypeDeclarationElement element)
|
| + : this.element = element,
|
| + scope = element.enclosingElement.buildScope(),
|
| + typeResolver = new TypeResolver(compiler),
|
| + super(compiler);
|
| +
|
| + void resolveTypeVariableBounds(NodeList node) {
|
| + if (node === null) return;
|
| +
|
| + var nameSet = new Set<SourceString>();
|
| + // Resolve the bounds of type variables.
|
| + Link<Type> typeLink = element.typeVariables;
|
| + Link<Node> nodeLink = node.nodes;
|
| + while (!nodeLink.isEmpty()) {
|
| + TypeVariableType typeVariable = typeLink.head;
|
| + SourceString typeName = typeVariable.name;
|
| + TypeVariable typeNode = nodeLink.head;
|
| + if (nameSet.contains(typeName)) {
|
| + error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]);
|
| + }
|
| + nameSet.add(typeName);
|
| +
|
| + TypeVariableElement variableElement = typeVariable.element;
|
| + if (typeNode.bound !== null) {
|
| + Type boundType = typeResolver.resolveTypeAnnotation(
|
| + typeNode.bound, inScope: scope, 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> :].
|
| + warning(node, MessageKind.CYCLIC_TYPE_VARIABLE,
|
| + [variableElement.name]);
|
| + } else if (boundType !== null) {
|
| + variableElement.bound = boundType;
|
| + } else {
|
| + // TODO(johnniwinther): Should be an erroneous type.
|
| + variableElement.bound = compiler.objectClass.computeType(compiler);
|
| + }
|
| + } else {
|
| + variableElement.bound = compiler.objectClass.computeType(compiler);
|
| + }
|
| + nodeLink = nodeLink.tail;
|
| + typeLink = typeLink.tail;
|
| + }
|
| + assert(typeLink.isEmpty());
|
| + }
|
| +}
|
| +
|
| class ClassResolverVisitor extends TypeDefinitionVisitor {
|
| ClassElement get element() => super.element;
|
|
|
| @@ -1854,58 +1906,6 @@ class ClassResolverVisitor extends TypeDefinitionVisitor {
|
| }
|
| }
|
|
|
| -class TypeDefinitionVisitor extends CommonResolverVisitor<Type> {
|
| - Scope scope;
|
| - TypeDeclarationElement element;
|
| - TypeResolver typeResolver;
|
| -
|
| - TypeDefinitionVisitor(Compiler compiler, TypeDeclarationElement element)
|
| - : this.element = element,
|
| - scope = element.enclosingElement.buildScope(),
|
| - typeResolver = new TypeResolver(compiler),
|
| - super(compiler);
|
| -
|
| - void resolveTypeVariableBounds(NodeList node) {
|
| - if (node === null) return;
|
| -
|
| - var nameSet = new Set<SourceString>();
|
| - // Resolve the bounds of type variables.
|
| - Link<Type> typeLink = element.typeVariables;
|
| - Link<Node> nodeLink = node.nodes;
|
| - while (!nodeLink.isEmpty()) {
|
| - TypeVariableType typeVariable = typeLink.head;
|
| - SourceString typeName = typeVariable.name;
|
| - TypeVariable typeNode = nodeLink.head;
|
| - if (nameSet.contains(typeName)) {
|
| - error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]);
|
| - }
|
| - nameSet.add(typeName);
|
| -
|
| - TypeVariableElement variableElement = typeVariable.element;
|
| - if (typeNode.bound !== null) {
|
| - Type boundType = typeResolver.resolveTypeAnnotation(
|
| - typeNode.bound, inScope: scope, 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> :].
|
| - warning(node, MessageKind.CYCLIC_TYPE_VARIABLE,
|
| - [variableElement.name]);
|
| - } else if (boundType !== null) {
|
| - variableElement.bound = boundType;
|
| - } else {
|
| - // TODO(johnniwinther): Should be an erroneous type.
|
| - variableElement.bound = compiler.objectClass.computeType(compiler);
|
| - }
|
| - } else {
|
| - variableElement.bound = compiler.objectClass.computeType(compiler);
|
| - }
|
| - nodeLink = nodeLink.tail;
|
| - typeLink = typeLink.tail;
|
| - }
|
| - assert(typeLink.isEmpty());
|
| - }
|
| -}
|
| -
|
| class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> {
|
| VariableDefinitions definitions;
|
| ResolverVisitor resolver;
|
|
|