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

Unified Diff: lib/compiler/implementation/dart_backend/placeholder_collector.dart

Issue 10836128: A visitor that builds a map from node to "Usage". (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
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: lib/compiler/implementation/dart_backend/placeholder_collector.dart
diff --git a/lib/compiler/implementation/dart_backend/placeholder_collector.dart b/lib/compiler/implementation/dart_backend/placeholder_collector.dart
new file mode 100644
index 0000000000000000000000000000000000000000..abb443f016ff9884367703a6a0b57a75d9641412
--- /dev/null
+++ b/lib/compiler/implementation/dart_backend/placeholder_collector.dart
@@ -0,0 +1,182 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class SendVisitor extends ResolvedVisitor {
+ final PlaceholderCollector collector;
+
+ SendVisitor(this.collector, TreeElements elements) : super(elements);
+
+ visitSuperSend(Send node) {}
+ visitOperatorSend(Send node) {}
+ visitClosureSend(Send node) {}
+ visitForeignSend(Send node) {}
+
+ visitDynamicSend(Send node) {
+ tryRenamePrivateId(node);
+ }
+
+ tryRenamePrivateId(Send node) {
+ Node selector = node.selector;
+ assert(selector !== null);
+ if (selector.source.isPrivate()) {
+ collector.makePrivateIdentifier(selector);
+ }
+ }
+
+ visitGetterSend(Send node) {
+ final element = elements[node];
+ // element === null means dynamic property access.
+ // We don't want to rename non top-level element access.
+ if (element === null || !element.isTopLevel()) {
+ tryRenamePrivateId(node);
+ return;
+ }
+ // Unqualified <class> in static invocation, why it's not a type annotation?
+ // Another option would be to process in visitStaticSend, NB:
+ // those elements are not top-level.
+ // OR: unqualified top level.
+ collector.makeElementPlaceholder(node.selector, element);
+ if (node.receiver !== null) {
+ // <lib prefix>.<top level>.
+ collector.makeNullPlaceholder(node.receiver); // Cut library prefix.
+ }
+ }
+
+ visitStaticSend(Send node) {
+ final element = elements[node];
+ if (!element.isTopLevel()) return;
+ // Another ugly case: <lib prefix>.<top level> is represented as
+ // receiver: lib prefix, selector: top level.
+ collector.makeElementPlaceholder(node.selector, element);
+ if (node.receiver !== null) {
+ assert(elements[node.receiver].isPrefix());
+ // Hack: putting null into map overrides receiver of original node.
+ collector.makeNullPlaceholder(node.receiver);
+ }
+ }
+}
+
+class PlaceholderCollector extends AbstractVisitor {
+ final Compiler compiler;
+ final Map<Node, Placeholder> placeholders;
+ Element currentElement;
+ TreeElements treeElements;
+
+ PlaceholderCollector(this.compiler) :
+ placeholders = new Map<Node, Placeholder>();
+
+ void collectFunctionDeclarationPlaceholder(
+ FunctionElement element, Node node) {
+ if (element.isGenerativeConstructor() || element.isFactoryConstructor()) {
+ // Two complicated cases for class/interface renaming:
+ // 1) class which implements constructors of other interfaces, but not
+ // implements interfaces themselves:
+ // 0.dart: class C { I(); }
+ // 1.dart and 2.dart: interface I default C { I(); }
+ // now we have to duplicate our I() constructor in C class with
+ // proper names.
+ // 2) (even worse for us):
+ // 0.dart: class C { C(); }
+ // 1.dart: interface C default p0.C { C(); }
+ // the second case is just a bug now.
+ final enclosingClass = element.getEnclosingClass();
+ Node nameNode = node.name;
+ if (nameNode is Send) nameNode = nameNode.receiver;
+ // For cases like class C implements I { I(); }
+ if (nameNode.token.slowToString() == enclosingClass.name.slowToString()) {
+ makeTypePlaceholder(nameNode, enclosingClass.type);
+ }
+ } else if (element.isTopLevel()) {
+ makeElementPlaceholder(node.name, element);
+ }
+ }
+
+ void collect(Element element, TreeElements elements) {
+ // Skip AbstractFieldElement, it has no node.
+ // Instead getters and setters should be processed explicitly.
+ if (element is AbstractFieldElement) return;
+ if (element.isField()) {
+ currentElement = element;
+ // TODO(smok): In the future make sure we don't process same
+ // variable list element twice, better merge this with emitter logic.
+ element = element.variables;
+ }
+ currentElement = element;
+ treeElements = elements;
+ Node elementNode = element.parseNode(compiler);
+ if (element is FunctionElement) {
+ collectFunctionDeclarationPlaceholder(element, elementNode);
+ }
+ elementNode.accept(this);
+ }
+
+ Type resolveType(TypeAnnotation typeAnnotation) {
+ if (treeElements === null) return null;
+ var result = treeElements.getType(typeAnnotation);
+ // TODO: Have better type resolution.
+ if (result === null) {
+ result = compiler.resolveTypeAnnotation(currentElement, typeAnnotation);
+ }
+ return result;
+ }
+
+ void makeTypePlaceholder(Node node, Type type) {
+ makeElementPlaceholder(node, type.element);
+ }
+
+ void makeNullPlaceholder(Node node) {
+ placeholders[node] = new NullPlaceholder();
+ }
+
+ void makeElementPlaceholder(Node node, Element element) {
+ assert(element !== null);
+ placeholders[node] = new ElementPlaceholder(element);
+ }
+
+ void makePrivateIdentifier(Identifier node) {
+ assert(node !== null);
+ placeholders[node] =
+ new PrivatePlaceholder(currentElement.getLibrary(), node);
+ }
+
+ void internalError(String reason, [Node node]) {
+ compiler.cancel(reason: reason, node: node);
+ }
+
+ visit(Node node) => (node === null) ? null : node.accept(this);
+
+ visitNode(Node node) { node.visitChildren(this); } // We must go deeper.
+
+ visitClassNode(ClassNode node) {
+ internalError('Should never meet ClassNode', node);
+ }
+
+ void visitIdentifier(Identifier node) {
+ if (node.source.isPrivate()) {
+ makePrivateIdentifier(node);
+ }
+ }
+
+ visitSend(Send send) {
+ new SendVisitor(this, treeElements).visitSend(send);
+ super.visitSend(send);
+ }
+
+ visitTypeAnnotation(TypeAnnotation node) {
+ final type = compiler.resolveTypeAnnotation(currentElement, node);
+ if (type is !InterfaceType) return null;
+ var target = node.typeName;
+ if (node.typeName is Send) {
+ final element = treeElements[node];
+ if (element !== null) {
+ final send = node.typeName.asSend();
+ final hasPrefix = element.lookupConstructor(
+ send.receiver.source, send.selector.source) === null;
+ if (!hasPrefix) target = send.receiver;
+ }
+ }
+ makeTypePlaceholder(target, type);
+ visit(node.typeArguments);
+ }
+}
« no previous file with comments | « lib/compiler/implementation/dart_backend/placeholder.dart ('k') | lib/compiler/implementation/dart_backend/renamer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698