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

Unified Diff: dart/sdk/lib/_internal/compiler/implementation/enqueue.dart

Issue 14646031: Implement invoke, setField, and getField (unminified). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Make expando private Created 7 years, 7 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/sdk/lib/_internal/compiler/implementation/enqueue.dart
diff --git a/dart/sdk/lib/_internal/compiler/implementation/enqueue.dart b/dart/sdk/lib/_internal/compiler/implementation/enqueue.dart
index 1278cd0627fcbf7a39a63994e254360737f4b5c9..6ffab718eb65a03192044a8447484d8891fcce4a 100644
--- a/dart/sdk/lib/_internal/compiler/implementation/enqueue.dart
+++ b/dart/sdk/lib/_internal/compiler/implementation/enqueue.dart
@@ -29,9 +29,15 @@ abstract class Enqueuer {
final String name;
final Compiler compiler; // TODO(ahe): Remove this dependency.
final Function itemCompilationContextCreator;
- final Map<String, Link<Element>> instanceMembersByName;
- final Set<ClassElement> seenClasses;
- final Universe universe;
+ final Map<String, Link<Element>> instanceMembersByName
+ = new Map<String, Link<Element>>();
+ final Set<ClassElement> seenClasses = new Set<ClassElement>();
+ final Universe universe = new Universe();
+
+ /// A reverse map from name to *all* elements with that name, not
+ /// just instance members of instantiated classes.
+ final Map<String, Link<Element>> allElementsByName
+ = new Map<String, Link<Element>>();
ngeoffray 2013/05/08 12:34:06 I think this should be in the world. It will be th
ahe 2013/05/08 21:47:53 I'm really opposed to the class World. I'll move
bool queueIsClosed = false;
EnqueueTask task;
@@ -39,10 +45,7 @@ abstract class Enqueuer {
Enqueuer(this.name, this.compiler,
ItemCompilationContext itemCompilationContextCreator())
- : this.itemCompilationContextCreator = itemCompilationContextCreator,
- instanceMembersByName = new Map<String, Link<Element>>(),
- universe = new Universe(),
- seenClasses = new Set<ClassElement>();
+ : this.itemCompilationContextCreator = itemCompilationContextCreator;
/// Returns [:true:] if this enqueuer is the resolution enqueuer.
bool get isResolutionQueue => false;
@@ -272,6 +275,104 @@ abstract class Enqueuer {
});
}
+ /// Called when [:const Symbol(name):] is seen.
+ void registerConstSymbol(String name, TreeElements elements) {
+ // If dart:mirrors is loaded, a const symbol may be used to call a
+ // static/top-level method or accessor, instantiate a class, call
+ // an instance method or accessor with the given name.
+ if (compiler.mirrorSystemClass == null) return;
+
+ ensureAllElementsByName();
+
+ for (var link = allElementsByName[name];
+ link != null && !link.isEmpty;
+ link = link.tail) {
+ Element element = link.head;
+ if (Elements.isUnresolved(element)) {
ngeoffray 2013/05/08 12:34:06 Could you just avoid adding them? Also, because yo
ahe 2013/05/08 21:47:53 This is defensive programming. Whenever you look
+ // Ignore.
+ } else if (element.isConstructor()) {
+ ClassElement cls = element.declaration.getEnclosingClass();
+ registerInstantiatedType(cls.rawType, elements);
+ registerStaticUse(element.declaration);
+ } else if (element.impliesType()) {
+ // Don't enqueue classes, typedefs, and type variables.
+ } else if (Elements.isStaticOrTopLevel(element)) {
+ registerStaticUse(element.declaration);
+ } else if (element.isInstanceMember()) {
+ if (element.isFunction()) {
+ int arity =
+ element.asFunctionElement().requiredParameterCount(compiler);
+ Selector selector =
+ new Selector.call(element.name, element.getLibrary(), arity);
+ registerInvocation(element.name, selector);
+ } else if (element.isSetter()) {
+ Selector selector =
+ new Selector.setter(element.name, element.getLibrary());
+ registerInvokedSetter(element.name, selector);
+ } else if (element.isGetter()) {
+ Selector selector =
+ new Selector.getter(element.name, element.getLibrary());
+ registerInvokedGetter(element.name, selector);
+ } else if (element.isField()) {
+ Selector selector =
+ new Selector.setter(element.name, element.getLibrary());
+ registerInvokedSetter(element.name, selector);
+ selector =
+ new Selector.getter(element.name, element.getLibrary());
+ registerInvokedGetter(element.name, selector);
+ }
+ }
+ }
+ }
+
+ void ensureAllElementsByName() {
+ if (!allElementsByName.isEmpty) return;
+
+ void addMemberByName(Element element) {
+ element = element.declaration;
+ String name = element.name.slowToString();
+ Link<Element> members = const Link<Element>();
+ if (element.isLibrary()) {
+ LibraryElementX library = element;
+ Uri uri = library.canonicalUri;
+ if (uri.scheme != 'dart' && !uri.path.startsWith('_')) {
Johnni Winther 2013/05/08 08:22:08 What are you trying to compute in this block?
ahe 2013/05/08 08:57:43 Top-level members. However, some of the special c
+ members = library.localMembers;
+ // TODO(ahe): Is this right? Is this necessary?
+ name = library.getLibraryOrScriptName();
+ }
+ } else if (element.isClass() && !element.isMixinApplication) {
ngeoffray 2013/05/08 12:34:06 What could go wrong with a mixin application?
ahe 2013/05/08 21:47:53 Not sure. Added a TODO.
+ ClassElementX cls = element;
+ cls.ensureResolved(compiler);
+ members = cls.localMembers;
+ for (var link = cls.computeTypeParameters(compiler);
+ !link.isEmpty;
+ link = link.tail) {
+ addMemberByName(link.head.element);
ngeoffray 2013/05/08 12:34:06 Why do you want to add type parameters? Potential
ahe 2013/05/08 21:47:53 Yes. testNames in mirrors_test.dart will test tha
+ }
+ } else if (element.isConstructor()) {
+ SourceString source = Elements.deconstructConstructorName(
+ element.name, element.getEnclosingClass());
+ if (source == null) {
+ // source is null for unnamed constructors.
+ name = '';
+ } else {
+ name = source.slowToString();
+ }
+ }
+ allElementsByName[name] = allElementsByName.putIfAbsent(
+ name, () => const Link<Element>()).prepend(element);
+ for (var link = members; !link.isEmpty; link = link.tail) {
+ addMemberByName(link.head);
+ }
+ }
+
+ compiler.libraries.values.forEach(addMemberByName);
+ }
+
+ /// Called when [:new Symbol(...):] is seen.
+ void registerNewSymbol(TreeElements elements) {
+ }
+
processInstanceMembers(SourceString n, bool f(Element e)) {
String memberName = n.slowToString();
Link<Element> members = instanceMembersByName[memberName];

Powered by Google App Engine
This is Rietveld 408576698