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

Side by Side Diff: frog/leg/enqueue.dart

Issue 9873021: Move frog/leg to lib/compiler/implementation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/leg/emitter.dart ('k') | frog/leg/frog_leg.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 class EnqueueTask extends CompilerTask {
6 final Map<String, Link<Element>> instanceMembersByName;
7 final Set<ClassElement> seenClasses;
8
9 String get name() => 'Enqueue';
10
11 EnqueueTask(Compiler compiler)
12 : instanceMembersByName = new Map<String, Link<Element>>(),
13 seenClasses = new Set<ClassElement>(),
14 super(compiler);
15
16 bool checkNoEnqueuedInvokedInstanceMethods() {
17 measure(() {
18 // Run through the classes and see if we need to compile methods.
19 for (ClassElement classElement in compiler.universe.instantiatedClasses) {
20 for (ClassElement currentClass = classElement;
21 currentClass !== null;
22 currentClass = currentClass.superclass) {
23 processInstantiatedClass(currentClass);
24 }
25 }
26 });
27 return true;
28 }
29
30 void processInstantiatedClass(ClassElement cls) {
31 cls.members.forEach(processInstantiatedClassMember);
32 }
33
34 void registerFieldClosureInvocations() {
35 measure(() {
36 // Make sure that the closure understands a call with the given
37 // selector. For a method-invocation of the form o.foo(a: 499), we
38 // need to make sure that closures can handle the optional argument if
39 // there exists a field or getter 'foo'.
40 var names = compiler.universe.instantiatedClassInstanceFields;
41 // TODO(ahe): Might be enough to use invokedGetters.
42 for (SourceString name in names) {
43 Set<Selector> invokedSelectors = compiler.universe.invokedNames[name];
44 if (invokedSelectors != null) {
45 for (Selector selector in invokedSelectors) {
46 compiler.registerDynamicInvocation(Namer.CLOSURE_INVOCATION_NAME,
47 selector);
48 }
49 }
50 }
51 });
52 }
53
54 void processInstantiatedClassMember(Element member) {
55 if (compiler.universe.generatedCode.containsKey(member)) return;
56
57 if (!member.isInstanceMember()) return;
58
59 String memberName = member.name.slowToString();
60 Link<Element> members = instanceMembersByName.putIfAbsent(
61 memberName, () => const EmptyLink<Element>());
62 instanceMembersByName[memberName] = members.prepend(member);
63
64 if (member.kind === ElementKind.GETTER ||
65 member.kind === ElementKind.FIELD) {
66 compiler.universe.instantiatedClassInstanceFields.add(member.name);
67 }
68
69 if (member.kind == ElementKind.FUNCTION) {
70 if (member.name == Compiler.NO_SUCH_METHOD) {
71 compiler.enableNoSuchMethod(member);
72 }
73 Set<Selector> selectors = compiler.universe.invokedNames[member.name];
74 if (selectors != null) {
75 FunctionElement functionMember = member;
76 FunctionParameters parameters =
77 functionMember.computeParameters(compiler);
78 for (Selector selector in selectors) {
79 if (selector.applies(parameters)) {
80 return compiler.addToWorkList(member);
81 }
82 }
83 }
84 // If there is a property access with the same name as a method we
85 // need to emit the method.
86 if (compiler.universe.invokedGetters.contains(member.name)) {
87 // We will emit a closure, so make sure the closure class is
88 // generated.
89 compiler.closureClass.ensureResolved(compiler);
90 compiler.registerInstantiatedClass(compiler.closureClass);
91 return compiler.addToWorkList(member);
92 }
93 } else if (member.kind == ElementKind.GETTER) {
94 if (compiler.universe.invokedGetters.contains(member.name)) {
95 return compiler.addToWorkList(member);
96 }
97 // A method invocation like in o.foo(x, y) might actually be an
98 // invocation of the getter foo followed by an invocation of the
99 // returned closure.
100 Set<Selector> invokedSelectors =
101 compiler.universe.invokedNames[member.name];
102 // We don't know what selectors the returned closure accepts. If
103 // the set contains any selector we have to assume that it matches.
104 if (invokedSelectors !== null && !invokedSelectors.isEmpty()) {
105 return compiler.addToWorkList(member);
106 }
107 } else if (member.kind === ElementKind.SETTER) {
108 if (compiler.universe.invokedSetters.contains(member.name)) {
109 return compiler.addToWorkList(member);
110 }
111 }
112 }
113
114 void onRegisterInstantiatedClass(ClassElement cls) => measure(() {
115 while (cls !== null) {
116 if (seenClasses.contains(cls)) return;
117 seenClasses.add(cls);
118 // TODO(ahe): Don't call resolveType, instead, call this method
119 // when resolveType is called.
120 compiler.resolveType(cls);
121 cls.members.forEach(processInstantiatedClassMember);
122 cls = cls.superclass;
123 }
124 });
125
126 void registerInvocation(SourceString methodName, Selector selector) {
127 measure(() {
128 Map<SourceString, Set<Selector>> invokedNames =
129 compiler.universe.invokedNames;
130 Set<Selector> selectors =
131 invokedNames.putIfAbsent(methodName, () => new Set<Selector>());
132 if (!selectors.contains(selector)) {
133 selectors.add(selector);
134 handleUnseenInvocation(methodName, selector);
135 }
136 });
137 }
138
139 void registerGetter(SourceString methodName) {
140 measure(() {
141 if (!compiler.universe.invokedGetters.contains(methodName)) {
142 compiler.universe.invokedGetters.add(methodName);
143 handleUnseenGetter(methodName);
144 }
145 });
146 }
147
148 void registerSetter(SourceString methodName) {
149 measure(() {
150 if (!compiler.universe.invokedSetters.contains(methodName)) {
151 compiler.universe.invokedSetters.add(methodName);
152 handleUnseenSetter(methodName);
153 }
154 });
155 }
156
157 processInstanceMembers(SourceString n, bool f(Element e)) {
158 String memberName = n.slowToString();
159 Link<Element> members = instanceMembersByName[memberName];
160 if (members !== null) {
161 LinkBuilder<Element> remaining = new LinkBuilder<Element>();
162 for (; !members.isEmpty(); members = members.tail) {
163 if (!f(members.head)) remaining.addLast(members.head);
164 }
165 instanceMembersByName[memberName] = remaining.toLink();
166 }
167 }
168
169 void handleUnseenInvocation(SourceString methodName, Selector selector) {
170 processInstanceMembers(methodName, (Element member) {
171 if (member.isGetter()) {
172 compiler.addToWorkList(member);
173 return true;
174 } else if (member.isFunction()) {
175 FunctionElement functionMember = member;
176 FunctionParameters parameters =
177 functionMember.computeParameters(compiler);
178 if (selector.applies(parameters)) {
179 compiler.addToWorkList(member);
180 return true;
181 }
182 }
183 return false;
184 });
185 }
186
187 void handleUnseenGetter(SourceString methodName) {
188 processInstanceMembers(methodName, (Element member) {
189 if (member.isGetter() || member.isFunction()) {
190 compiler.addToWorkList(member);
191 return true;
192 } else {
193 return false;
194 }
195 });
196 }
197
198 void handleUnseenSetter(SourceString methodName) {
199 processInstanceMembers(methodName, (Element member) {
200 if (member.isSetter()) {
201 compiler.addToWorkList(member);
202 return true;
203 } else {
204 return false;
205 }
206 });
207 }
208 }
OLDNEW
« no previous file with comments | « frog/leg/emitter.dart ('k') | frog/leg/frog_leg.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698