OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart2js; | 5 library dart2js.enqueue; |
| 6 |
| 7 import 'dart:collection' show |
| 8 Queue; |
| 9 import 'dart2jslib.dart' show |
| 10 invariant, |
| 11 CodegenWorkItem, |
| 12 Compiler, |
| 13 CompilerTask, |
| 14 DeferredAction, |
| 15 DeferredTask, |
| 16 ItemCompilationContext, |
| 17 Registry, |
| 18 ResolutionWorkItem, |
| 19 WorkItem; |
| 20 import 'dart_types.dart' show |
| 21 DartType, |
| 22 InterfaceType; |
| 23 import 'elements/elements.dart' show |
| 24 AnalyzableElement, |
| 25 AstElement, |
| 26 ClassElement, |
| 27 ConstructorElement, |
| 28 Element, |
| 29 Elements, |
| 30 FunctionElement, |
| 31 LibraryElement, |
| 32 LocalFunctionElement, |
| 33 Member, |
| 34 MemberElement, |
| 35 MethodElement, |
| 36 TypedElement, |
| 37 TypedefElement; |
| 38 import 'js/js.dart' as js; |
| 39 import 'native/native.dart' as native; |
| 40 import 'resolution/resolution.dart' show |
| 41 ResolverVisitor; |
| 42 import 'tree/tree.dart' show |
| 43 Send; |
| 44 import 'universe/universe.dart'; |
| 45 import 'util/util.dart' show |
| 46 Link, |
| 47 Setlet, |
| 48 SpannableAssertionFailure; |
6 | 49 |
7 typedef ItemCompilationContext ItemCompilationContextCreator(); | 50 typedef ItemCompilationContext ItemCompilationContextCreator(); |
8 | 51 |
9 class EnqueueTask extends CompilerTask { | 52 class EnqueueTask extends CompilerTask { |
10 final ResolutionEnqueuer resolution; | 53 final ResolutionEnqueuer resolution; |
11 final CodegenEnqueuer codegen; | 54 final CodegenEnqueuer codegen; |
12 | 55 |
13 String get name => 'Enqueue'; | 56 String get name => 'Enqueue'; |
14 | 57 |
15 EnqueueTask(Compiler compiler) | 58 EnqueueTask(Compiler compiler) |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 void processInstantiatedClassMembers(ClassElement cls) { | 182 void processInstantiatedClassMembers(ClassElement cls) { |
140 cls.implementation.forEachMember(processInstantiatedClassMember); | 183 cls.implementation.forEachMember(processInstantiatedClassMember); |
141 } | 184 } |
142 | 185 |
143 void processInstantiatedClassMember(ClassElement cls, Element member) { | 186 void processInstantiatedClassMember(ClassElement cls, Element member) { |
144 assert(invariant(member, member.isDeclaration)); | 187 assert(invariant(member, member.isDeclaration)); |
145 if (isProcessed(member)) return; | 188 if (isProcessed(member)) return; |
146 if (!member.isInstanceMember) return; | 189 if (!member.isInstanceMember) return; |
147 String memberName = member.name; | 190 String memberName = member.name; |
148 | 191 |
149 if (member.kind == ElementKind.FIELD) { | 192 if (member.isField) { |
150 // The obvious thing to test here would be "member.isNative", | 193 // The obvious thing to test here would be "member.isNative", |
151 // however, that only works after metadata has been parsed/analyzed, | 194 // however, that only works after metadata has been parsed/analyzed, |
152 // and that may not have happened yet. | 195 // and that may not have happened yet. |
153 // So instead we use the enclosing class, which we know have had | 196 // So instead we use the enclosing class, which we know have had |
154 // its metadata parsed and analyzed. | 197 // its metadata parsed and analyzed. |
155 // Note: this assumes that there are no non-native fields on native | 198 // Note: this assumes that there are no non-native fields on native |
156 // classes, which may not be the case when a native class is subclassed. | 199 // classes, which may not be the case when a native class is subclassed. |
157 if (cls.isNative) { | 200 if (cls.isNative) { |
158 compiler.world.registerUsedElement(member); | 201 compiler.world.registerUsedElement(member); |
159 nativeEnqueuer.handleFieldAnnotations(member); | 202 nativeEnqueuer.handleFieldAnnotations(member); |
(...skipping 20 matching lines...) Expand all Loading... |
180 } | 223 } |
181 // Native fields need to go into instanceMembersByName as they | 224 // Native fields need to go into instanceMembersByName as they |
182 // are virtual instantiation points and escape points. | 225 // are virtual instantiation points and escape points. |
183 } else { | 226 } else { |
184 // All field initializers must be resolved as they could | 227 // All field initializers must be resolved as they could |
185 // have an observable side-effect (and cannot be tree-shaken | 228 // have an observable side-effect (and cannot be tree-shaken |
186 // away). | 229 // away). |
187 addToWorkList(member); | 230 addToWorkList(member); |
188 return; | 231 return; |
189 } | 232 } |
190 } else if (member.kind == ElementKind.FUNCTION) { | 233 } else if (member.isFunction) { |
191 FunctionElement function = member; | 234 FunctionElement function = member; |
192 function.computeType(compiler); | 235 function.computeType(compiler); |
193 if (function.name == Compiler.NO_SUCH_METHOD) { | 236 if (function.name == Compiler.NO_SUCH_METHOD) { |
194 registerNoSuchMethod(function); | 237 registerNoSuchMethod(function); |
195 } | 238 } |
196 if (function.name == Compiler.CALL_OPERATOR_NAME && | 239 if (function.name == Compiler.CALL_OPERATOR_NAME && |
197 !cls.typeVariables.isEmpty) { | 240 !cls.typeVariables.isEmpty) { |
198 registerCallMethodWithFreeTypeVariables( | 241 registerCallMethodWithFreeTypeVariables( |
199 function, compiler.globalDependencies); | 242 function, compiler.globalDependencies); |
200 } | 243 } |
201 // If there is a property access with the same name as a method we | 244 // If there is a property access with the same name as a method we |
202 // need to emit the method. | 245 // need to emit the method. |
203 if (universe.hasInvokedGetter(function, compiler.world)) { | 246 if (universe.hasInvokedGetter(function, compiler.world)) { |
204 registerClosurizedMember(function, compiler.globalDependencies); | 247 registerClosurizedMember(function, compiler.globalDependencies); |
205 addToWorkList(function); | 248 addToWorkList(function); |
206 return; | 249 return; |
207 } | 250 } |
208 // Store the member in [instanceFunctionsByName] to catch | 251 // Store the member in [instanceFunctionsByName] to catch |
209 // getters on the function. | 252 // getters on the function. |
210 instanceFunctionsByName.putIfAbsent(memberName, () => new Set<Element>()) | 253 instanceFunctionsByName.putIfAbsent(memberName, () => new Set<Element>()) |
211 .add(member); | 254 .add(member); |
212 if (universe.hasInvocation(function, compiler.world)) { | 255 if (universe.hasInvocation(function, compiler.world)) { |
213 addToWorkList(function); | 256 addToWorkList(function); |
214 return; | 257 return; |
215 } | 258 } |
216 } else if (member.kind == ElementKind.GETTER) { | 259 } else if (member.isGetter) { |
217 FunctionElement getter = member; | 260 FunctionElement getter = member; |
218 getter.computeType(compiler); | 261 getter.computeType(compiler); |
219 if (universe.hasInvokedGetter(getter, compiler.world)) { | 262 if (universe.hasInvokedGetter(getter, compiler.world)) { |
220 addToWorkList(getter); | 263 addToWorkList(getter); |
221 return; | 264 return; |
222 } | 265 } |
223 // We don't know what selectors the returned closure accepts. If | 266 // We don't know what selectors the returned closure accepts. If |
224 // the set contains any selector we have to assume that it matches. | 267 // the set contains any selector we have to assume that it matches. |
225 if (universe.hasInvocation(getter, compiler.world)) { | 268 if (universe.hasInvocation(getter, compiler.world)) { |
226 addToWorkList(getter); | 269 addToWorkList(getter); |
227 return; | 270 return; |
228 } | 271 } |
229 } else if (member.kind == ElementKind.SETTER) { | 272 } else if (member.isSetter) { |
230 FunctionElement setter = member; | 273 FunctionElement setter = member; |
231 setter.computeType(compiler); | 274 setter.computeType(compiler); |
232 if (universe.hasInvokedSetter(setter, compiler.world)) { | 275 if (universe.hasInvokedSetter(setter, compiler.world)) { |
233 addToWorkList(setter); | 276 addToWorkList(setter); |
234 return; | 277 return; |
235 } | 278 } |
236 } | 279 } |
237 | 280 |
238 // The element is not yet used. Add it to the list of instance | 281 // The element is not yet used. Add it to the list of instance |
239 // members to still be processed. | 282 // members to still be processed. |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 | 635 |
593 void registerFieldSetter(Element element) { | 636 void registerFieldSetter(Element element) { |
594 universe.fieldSetters.add(element); | 637 universe.fieldSetters.add(element); |
595 } | 638 } |
596 | 639 |
597 void registerIsCheck(DartType type) { | 640 void registerIsCheck(DartType type) { |
598 type = universe.registerIsCheck(type, compiler); | 641 type = universe.registerIsCheck(type, compiler); |
599 // Even in checked mode, type annotations for return type and argument | 642 // Even in checked mode, type annotations for return type and argument |
600 // types do not imply type checks, so there should never be a check | 643 // types do not imply type checks, so there should never be a check |
601 // against the type variable of a typedef. | 644 // against the type variable of a typedef. |
602 assert(type.kind != TypeKind.TYPE_VARIABLE || | 645 assert(!type.isTypeVariable || |
603 !type.element.enclosingElement.isTypedef); | 646 !type.element.enclosingElement.isTypedef); |
604 } | 647 } |
605 | 648 |
606 void registerCallMethodWithFreeTypeVariables( | 649 void registerCallMethodWithFreeTypeVariables( |
607 Element element, | 650 Element element, |
608 Registry registry) { | 651 Registry registry) { |
609 compiler.backend.registerCallMethodWithFreeTypeVariables( | 652 compiler.backend.registerCallMethodWithFreeTypeVariables( |
610 element, this, registry); | 653 element, this, registry); |
611 universe.callMethodsWithFreeTypeVariables.add(element); | 654 universe.callMethodsWithFreeTypeVariables.add(element); |
612 } | 655 } |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 void processWorkItem(void f(WorkItem work), WorkItem work) { | 995 void processWorkItem(void f(WorkItem work), WorkItem work) { |
953 f(work); | 996 f(work); |
954 } | 997 } |
955 } | 998 } |
956 | 999 |
957 void removeFromSet(Map<String, Set<Element>> map, Element element) { | 1000 void removeFromSet(Map<String, Set<Element>> map, Element element) { |
958 Set<Element> set = map[element.name]; | 1001 Set<Element> set = map[element.name]; |
959 if (set == null) return; | 1002 if (set == null) return; |
960 set.remove(element); | 1003 set.remove(element); |
961 } | 1004 } |
OLD | NEW |