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