Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2826)

Unified Diff: dart/lib/compiler/implementation/resolver.dart

Issue 10661029: Ensure interfaces are loaded. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698