Chromium Code Reviews| Index: dart/lib/compiler/implementation/resolver.dart |
| diff --git a/dart/lib/compiler/implementation/resolver.dart b/dart/lib/compiler/implementation/resolver.dart |
| index 246a546edf7ae8b40d13e80b57ae7a63b3775156..50cdd1db87c1e3cf89873efc149b886f90cd7535 100644 |
| --- a/dart/lib/compiler/implementation/resolver.dart |
| +++ b/dart/lib/compiler/implementation/resolver.dart |
| @@ -225,11 +225,40 @@ class ResolverTask extends CompilerTask { |
| return result; |
| } |
| + void loadSupertypes(ClassElement cls, Node from) { |
| + compiler.withCurrentElement(cls, () => measure(() { |
| + if (cls.supertypesAreLoaded) return; |
| + if (cls.isLoadingSupertypes) { |
| + compiler.reportMessage( |
| + compiler.spanFromNode(from), |
| + MessageKind.CYCLIC_CLASS_HIERARCHY.error([cls.name]), |
| + api.Diagnostic.ERROR); |
| + cls.allSupertypes = const EmptyLink<Type>().prepend( |
| + compiler.objectClass.computeType(compiler)); |
| + return; |
| + } |
| + cls.isLoadingSupertypes = true; |
| + compiler.withCurrentElement(cls, () { |
| + // TODO(ahe): Cache the node in cls. |
| + cls.parseNode(compiler).accept(new ClassSupertypeResolver(compiler, |
| + cls)); |
| + }); |
| + cls.isLoadingSupertypes = false; |
| + cls.supertypesAreLoaded = true; |
| + toResolve.add(cls); |
| + })); |
| + } |
| + |
| + /** |
| + * Do not call this method directly. Instead use |
| + * [:element.ensureResolved(compiler):]. |
| + */ |
| void resolveClass(ClassElement element) { |
| - if (element.isResolved || element.isBeingResolved) return; |
| - element.isBeingResolved = true; |
| - measure(() { |
| + compiler.withCurrentElement(element, () => measure(() { |
| + assert(element.isBeingResolved && !element.isResolved); |
| + loadSupertypes(element, null); |
| ClassNode tree = element.parseNode(compiler); |
| + |
| ClassResolverVisitor visitor = |
| new ClassResolverVisitor(compiler, element); |
| visitor.visit(tree); |
| @@ -242,7 +271,7 @@ class ResolverTask extends CompilerTask { |
| } |
| checkMembers(element); |
| - }); |
| + })); |
| } |
| checkMembers(ClassElement cls) { |
| @@ -288,7 +317,6 @@ class ResolverTask extends CompilerTask { |
| api.Diagnostic.INFO); |
| } |
| - |
| void checkValidOverride(Element member, Element superMember) { |
| if (superMember === null) return; |
| if (member.modifiers.isStatic()) { |
| @@ -769,7 +797,7 @@ class TypeResolver { |
| type = element.computeType(compiler); |
| } else if (element.isClass()) { |
| ClassElement cls = element; |
| - if (!cls.isResolved) compiler.resolveClass(cls); |
| + cls.ensureResolved(compiler); |
| Link<Type> arguments = |
| resolveTypeArguments(node, cls.typeVariables, scope, |
| onFailure, whenResolved); |
| @@ -1906,6 +1934,78 @@ class ClassResolverVisitor extends TypeDefinitionVisitor { |
| } |
| } |
| +class ClassSupertypeResolver extends CommonResolverVisitor { |
| + Scope context; |
| + ClassElement classElement; |
| + |
| + ClassSupertypeResolver(Compiler compiler, ClassElement cls) |
| + : context = new TopScope(cls.getLibrary()), |
| + this.classElement = cls, |
| + super(compiler); |
| + |
| + void visitClassNode(ClassNode node) { |
| + if (node.superclass === null) { |
| + // TODO(ahe): Handle this. |
| + } else { |
| + node.superclass.accept(this); |
| + } |
| + if (node.interfaces === null) { |
| + // TODO(ahe): Can this happen? |
|
Lasse Reichstein Nielsen
2012/08/07 09:02:17
If it can, it should be fixed.
|
| + } else { |
| + node.interfaces.accept(this); |
| + } |
| + } |
| + |
| + void visitTypeAnnotation(TypeAnnotation node) { |
| + node.typeName.accept(this); |
| + } |
| + |
| + void visitIdentifier(Identifier node) { |
| + Element element = context.lookup(node.source); |
| + if (element === null) { |
| + error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); |
| + } else if (!element.impliesType()) { |
| + error(node, MessageKind.NOT_A_TYPE, [node]); |
| + } else { |
| + if (element.isClass()) { |
| + compiler.resolver.loadSupertypes(element, node); |
| + } else { |
| + compiler.reportMessage( |
| + compiler.spanFromNode(node), |
| + MessageKind.TYPE_NAME_EXPECTED.error([]), |
| + api.Diagnostic.ERROR); |
| + } |
| + } |
| + } |
| + |
| + void visitNodeList(NodeList node) { |
| + for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { |
| + visit(link.head); |
| + } |
| + } |
| + |
| + void visitSend(Send node) { |
| + Identifier prefix = node.receiver.asIdentifier(); |
| + if (prefix === null) { |
| + error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); |
| + return; |
| + } |
| + Element element = context.lookup(prefix.source); |
| + if (element === null || element.kind !== ElementKind.PREFIX) { |
| + error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); |
| + return; |
| + } |
| + PrefixElement prefixElement = element; |
| + Identifier selector = node.selector.asIdentifier(); |
| + var e = prefixElement.lookupLocalMember(selector.source); |
| + if (e === null || !e.impliesType()) { |
| + error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); |
| + return; |
| + } |
| + compiler.resolver.loadSupertypes(e, node); |
| + } |
| +} |
| + |
| class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { |
| VariableDefinitions definitions; |
| ResolverVisitor resolver; |