| 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 |