| 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 part of dart2js; |
| 6 | 6 |
| 7 typedef ItemCompilationContext ItemCompilationContextCreator(); | 7 typedef ItemCompilationContext ItemCompilationContextCreator(); |
| 8 | 8 |
| 9 class EnqueueTask extends CompilerTask { | 9 class EnqueueTask extends CompilerTask { |
| 10 final ResolutionEnqueuer resolution; | 10 final ResolutionEnqueuer resolution; |
| 11 final CodegenEnqueuer codegen; | 11 final CodegenEnqueuer codegen; |
| 12 | 12 |
| 13 /// A reverse map from name to *all* elements with that name, not | 13 /// A reverse map from name to *all* elements with that name, not |
| 14 /// just instance members of instantiated classes. | 14 /// just instance members of instantiated classes. |
| 15 final Map<String, Link<Element>> allElementsByName | 15 final Map<String, Link<Element>> allElementsByName |
| 16 = new Map<String, Link<Element>>(); | 16 = new Map<String, Link<Element>>(); |
| 17 | 17 |
| 18 void ensureAllElementsByName() { | 18 void ensureAllElementsByName() { |
| 19 if (!allElementsByName.isEmpty) return; | 19 if (!allElementsByName.isEmpty) return; |
| 20 | 20 |
| 21 void addMemberByName(Element element) { | 21 void addMemberByName(Element element) { |
| 22 element = element.declaration; | 22 element = element.declaration; |
| 23 String name = element.name; | 23 String name = element.name; |
| 24 ScopeContainerElement container = null; | 24 ScopeContainerElement container = null; |
| 25 if (element.isLibrary()) { | 25 if (element.isLibrary) { |
| 26 LibraryElement library = element; | 26 LibraryElement library = element; |
| 27 // Don't include private implementation libraries. These | 27 // Don't include private implementation libraries. These |
| 28 // libraries contain special classes that cause problems | 28 // libraries contain special classes that cause problems |
| 29 // in other parts of the resolver (in particular Null and Void). | 29 // in other parts of the resolver (in particular Null and Void). |
| 30 // TODO(ahe): Consider lifting this restriction. | 30 // TODO(ahe): Consider lifting this restriction. |
| 31 if (!library.isInternalLibrary) { | 31 if (!library.isInternalLibrary) { |
| 32 container = library; | 32 container = library; |
| 33 // TODO(ahe): Is this right? Is this necessary? | 33 // TODO(ahe): Is this right? Is this necessary? |
| 34 name = library.getLibraryOrScriptName(); | 34 name = library.getLibraryOrScriptName(); |
| 35 } | 35 } |
| 36 } else if (element.isClass()) { | 36 } else if (element.isClass) { |
| 37 ClassElement cls = element; | 37 ClassElement cls = element; |
| 38 cls.ensureResolved(compiler); | 38 cls.ensureResolved(compiler); |
| 39 container = cls; | 39 container = cls; |
| 40 for (var link = cls.computeTypeParameters(compiler); | 40 for (var link = cls.computeTypeParameters(compiler); |
| 41 !link.isEmpty; | 41 !link.isEmpty; |
| 42 link = link.tail) { | 42 link = link.tail) { |
| 43 addMemberByName(link.head.element); | 43 addMemberByName(link.head.element); |
| 44 } | 44 } |
| 45 } | 45 } |
| 46 allElementsByName[name] = allElementsByName.putIfAbsent( | 46 allElementsByName[name] = allElementsByName.putIfAbsent( |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 task.measure(() { | 117 task.measure(() { |
| 118 ClassElement cls = type.element; | 118 ClassElement cls = type.element; |
| 119 elements.registerDependency(cls); | 119 elements.registerDependency(cls); |
| 120 cls.ensureResolved(compiler); | 120 cls.ensureResolved(compiler); |
| 121 universe.instantiatedTypes.add(type); | 121 universe.instantiatedTypes.add(type); |
| 122 if (!cls.isAbstract | 122 if (!cls.isAbstract |
| 123 // We can't use the closed-world assumption with native abstract | 123 // We can't use the closed-world assumption with native abstract |
| 124 // classes; a native abstract class may have non-abstract subclasses | 124 // classes; a native abstract class may have non-abstract subclasses |
| 125 // not declared to the program. Instances of these classes are | 125 // not declared to the program. Instances of these classes are |
| 126 // indistinguishable from the abstract class. | 126 // indistinguishable from the abstract class. |
| 127 || cls.isNative()) { | 127 || cls.isNative) { |
| 128 universe.instantiatedClasses.add(cls); | 128 universe.instantiatedClasses.add(cls); |
| 129 } | 129 } |
| 130 onRegisterInstantiatedClass(cls); | 130 onRegisterInstantiatedClass(cls); |
| 131 }); | 131 }); |
| 132 } | 132 } |
| 133 | 133 |
| 134 void registerInstantiatedClass(ClassElement cls, TreeElements elements) { | 134 void registerInstantiatedClass(ClassElement cls, TreeElements elements) { |
| 135 cls.ensureResolved(compiler); | 135 cls.ensureResolved(compiler); |
| 136 registerInstantiatedType(cls.rawType, elements); | 136 registerInstantiatedType(cls.rawType, elements); |
| 137 } | 137 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 155 return true; | 155 return true; |
| 156 } | 156 } |
| 157 | 157 |
| 158 void processInstantiatedClass(ClassElement cls) { | 158 void processInstantiatedClass(ClassElement cls) { |
| 159 cls.implementation.forEachMember(processInstantiatedClassMember); | 159 cls.implementation.forEachMember(processInstantiatedClassMember); |
| 160 } | 160 } |
| 161 | 161 |
| 162 void processInstantiatedClassMember(ClassElement cls, Element member) { | 162 void processInstantiatedClassMember(ClassElement cls, Element member) { |
| 163 assert(invariant(member, member.isDeclaration)); | 163 assert(invariant(member, member.isDeclaration)); |
| 164 if (isProcessed(member)) return; | 164 if (isProcessed(member)) return; |
| 165 if (!member.isInstanceMember()) return; | 165 if (!member.isInstanceMember) return; |
| 166 | 166 |
| 167 String memberName = member.name; | 167 String memberName = member.name; |
| 168 | 168 |
| 169 if (member.kind == ElementKind.FIELD) { | 169 if (member.kind == ElementKind.FIELD) { |
| 170 // The obvious thing to test here would be "member.isNative()", | 170 // The obvious thing to test here would be "member.isNative", |
| 171 // however, that only works after metadata has been parsed/analyzed, | 171 // however, that only works after metadata has been parsed/analyzed, |
| 172 // and that may not have happened yet. | 172 // and that may not have happened yet. |
| 173 // So instead we use the enclosing class, which we know have had | 173 // So instead we use the enclosing class, which we know have had |
| 174 // its metadata parsed and analyzed. | 174 // its metadata parsed and analyzed. |
| 175 // Note: this assumes that there are no non-native fields on native | 175 // Note: this assumes that there are no non-native fields on native |
| 176 // classes, which may not be the case when a native class is subclassed. | 176 // classes, which may not be the case when a native class is subclassed. |
| 177 if (cls.isNative()) { | 177 if (cls.isNative) { |
| 178 compiler.world.registerUsedElement(member); | 178 compiler.world.registerUsedElement(member); |
| 179 nativeEnqueuer.handleFieldAnnotations(member); | 179 nativeEnqueuer.handleFieldAnnotations(member); |
| 180 if (universe.hasInvokedGetter(member, compiler) || | 180 if (universe.hasInvokedGetter(member, compiler) || |
| 181 universe.hasInvocation(member, compiler)) { | 181 universe.hasInvocation(member, compiler)) { |
| 182 nativeEnqueuer.registerFieldLoad(member); | 182 nativeEnqueuer.registerFieldLoad(member); |
| 183 // In handleUnseenSelector we can't tell if the field is loaded or | 183 // In handleUnseenSelector we can't tell if the field is loaded or |
| 184 // stored. We need the basic algorithm to be Church-Rosser, since the | 184 // stored. We need the basic algorithm to be Church-Rosser, since the |
| 185 // resolution 'reduction' order is different to the codegen order. So | 185 // resolution 'reduction' order is different to the codegen order. So |
| 186 // register that the field is also stored. In other words: if we | 186 // register that the field is also stored. In other words: if we |
| 187 // don't register the store here during resolution, the store could be | 187 // don't register the store here during resolution, the store could be |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 /// Called when [:const Symbol(name):] is seen. | 321 /// Called when [:const Symbol(name):] is seen. |
| 322 void registerConstSymbol(String name, TreeElements elements) { | 322 void registerConstSymbol(String name, TreeElements elements) { |
| 323 compiler.backend.registerConstSymbol(name, elements); | 323 compiler.backend.registerConstSymbol(name, elements); |
| 324 } | 324 } |
| 325 | 325 |
| 326 void pretendElementWasUsed(Element element, TreeElements elements) { | 326 void pretendElementWasUsed(Element element, TreeElements elements) { |
| 327 if (!compiler.backend.isNeededForReflection(element)) return; | 327 if (!compiler.backend.isNeededForReflection(element)) return; |
| 328 if (Elements.isUnresolved(element)) { | 328 if (Elements.isUnresolved(element)) { |
| 329 // Ignore. | 329 // Ignore. |
| 330 } else if (element.isSynthesized | 330 } else if (element.isSynthesized |
| 331 && element.getLibrary().isPlatformLibrary) { | 331 && element.library.isPlatformLibrary) { |
| 332 // TODO(ahe): Work-around for http://dartbug.com/11205. | 332 // TODO(ahe): Work-around for http://dartbug.com/11205. |
| 333 } else if (element.isConstructor()) { | 333 } else if (element.isConstructor) { |
| 334 ClassElement cls = element.declaration.getEnclosingClass(); | 334 ClassElement cls = element.declaration.enclosingClass; |
| 335 registerInstantiatedType(cls.rawType, elements); | 335 registerInstantiatedType(cls.rawType, elements); |
| 336 registerStaticUse(element.declaration); | 336 registerStaticUse(element.declaration); |
| 337 } else if (element.isClass()) { | 337 } else if (element.isClass) { |
| 338 ClassElement cls = element.declaration; | 338 ClassElement cls = element.declaration; |
| 339 registerInstantiatedClass(cls, elements); | 339 registerInstantiatedClass(cls, elements); |
| 340 // Make sure that even abstract classes are considered instantiated. | 340 // Make sure that even abstract classes are considered instantiated. |
| 341 universe.instantiatedClasses.add(cls); | 341 universe.instantiatedClasses.add(cls); |
| 342 } else if (element.impliesType()) { | 342 } else if (element.impliesType) { |
| 343 // Don't enqueue typedefs, and type variables. | 343 // Don't enqueue typedefs, and type variables. |
| 344 } else if (Elements.isStaticOrTopLevel(element)) { | 344 } else if (Elements.isStaticOrTopLevel(element)) { |
| 345 registerStaticUse(element.declaration); | 345 registerStaticUse(element.declaration); |
| 346 } else if (element.isInstanceMember()) { | 346 } else if (element.isInstanceMember) { |
| 347 Selector selector = new Selector.fromElement(element, compiler); | 347 Selector selector = new Selector.fromElement(element, compiler); |
| 348 registerSelectorUse(selector); | 348 registerSelectorUse(selector); |
| 349 if (element.isField()) { | 349 if (element.isField) { |
| 350 Selector selector = | 350 Selector selector = |
| 351 new Selector.setter(element.name, element.getLibrary()); | 351 new Selector.setter(element.name, element.library); |
| 352 registerInvokedSetter(selector); | 352 registerInvokedSetter(selector); |
| 353 } | 353 } |
| 354 } | 354 } |
| 355 } | 355 } |
| 356 | 356 |
| 357 /// Called when [:new Symbol(...):] is seen. | 357 /// Called when [:new Symbol(...):] is seen. |
| 358 void registerNewSymbol(TreeElements elements) { | 358 void registerNewSymbol(TreeElements elements) { |
| 359 compiler.backend.registerNewSymbol(elements); | 359 compiler.backend.registerNewSymbol(elements); |
| 360 } | 360 } |
| 361 | 361 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 processLink(instanceMembersByName, n, f); | 403 processLink(instanceMembersByName, n, f); |
| 404 } | 404 } |
| 405 | 405 |
| 406 processInstanceFunctions(String n, bool f(Element e)) { | 406 processInstanceFunctions(String n, bool f(Element e)) { |
| 407 processLink(instanceFunctionsByName, n, f); | 407 processLink(instanceFunctionsByName, n, f); |
| 408 } | 408 } |
| 409 | 409 |
| 410 void handleUnseenSelector(String methodName, Selector selector) { | 410 void handleUnseenSelector(String methodName, Selector selector) { |
| 411 processInstanceMembers(methodName, (Element member) { | 411 processInstanceMembers(methodName, (Element member) { |
| 412 if (selector.appliesUnnamed(member, compiler)) { | 412 if (selector.appliesUnnamed(member, compiler)) { |
| 413 if (member.isFunction() && selector.isGetter()) { | 413 if (member.isFunction && selector.isGetter) { |
| 414 registerClosurizedMember(member, compiler.globalDependencies); | 414 registerClosurizedMember(member, compiler.globalDependencies); |
| 415 } | 415 } |
| 416 if (member.isField() && member.getEnclosingClass().isNative()) { | 416 if (member.isField && member.enclosingClass.isNative) { |
| 417 if (selector.isGetter() || selector.isCall()) { | 417 if (selector.isGetter || selector.isCall) { |
| 418 nativeEnqueuer.registerFieldLoad(member); | 418 nativeEnqueuer.registerFieldLoad(member); |
| 419 // We have to also handle storing to the field because we only get | 419 // We have to also handle storing to the field because we only get |
| 420 // one look at each member and there might be a store we have not | 420 // one look at each member and there might be a store we have not |
| 421 // seen yet. | 421 // seen yet. |
| 422 // TODO(sra): Process fields for storing separately. | 422 // TODO(sra): Process fields for storing separately. |
| 423 nativeEnqueuer.registerFieldStore(member); | 423 nativeEnqueuer.registerFieldStore(member); |
| 424 } else { | 424 } else { |
| 425 assert(selector.isSetter()); | 425 assert(selector.isSetter); |
| 426 nativeEnqueuer.registerFieldStore(member); | 426 nativeEnqueuer.registerFieldStore(member); |
| 427 // We have to also handle loading from the field because we only get | 427 // We have to also handle loading from the field because we only get |
| 428 // one look at each member and there might be a load we have not | 428 // one look at each member and there might be a load we have not |
| 429 // seen yet. | 429 // seen yet. |
| 430 // TODO(sra): Process fields for storing separately. | 430 // TODO(sra): Process fields for storing separately. |
| 431 nativeEnqueuer.registerFieldLoad(member); | 431 nativeEnqueuer.registerFieldLoad(member); |
| 432 } | 432 } |
| 433 } | 433 } |
| 434 addToWorkList(member); | 434 addToWorkList(member); |
| 435 return true; | 435 return true; |
| 436 } | 436 } |
| 437 return false; | 437 return false; |
| 438 }); | 438 }); |
| 439 if (selector.isGetter()) { | 439 if (selector.isGetter) { |
| 440 processInstanceFunctions(methodName, (Element member) { | 440 processInstanceFunctions(methodName, (Element member) { |
| 441 if (selector.appliesUnnamed(member, compiler)) { | 441 if (selector.appliesUnnamed(member, compiler)) { |
| 442 registerClosurizedMember(member, compiler.globalDependencies); | 442 registerClosurizedMember(member, compiler.globalDependencies); |
| 443 return true; | 443 return true; |
| 444 } | 444 } |
| 445 return false; | 445 return false; |
| 446 }); | 446 }); |
| 447 } | 447 } |
| 448 } | 448 } |
| 449 | 449 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 465 compiler.globalDependencies); | 465 compiler.globalDependencies); |
| 466 universe.staticFunctionsNeedingGetter.add(element); | 466 universe.staticFunctionsNeedingGetter.add(element); |
| 467 } | 467 } |
| 468 | 468 |
| 469 void registerDynamicInvocation(Selector selector) { | 469 void registerDynamicInvocation(Selector selector) { |
| 470 assert(selector != null); | 470 assert(selector != null); |
| 471 registerInvocation(selector); | 471 registerInvocation(selector); |
| 472 } | 472 } |
| 473 | 473 |
| 474 void registerSelectorUse(Selector selector) { | 474 void registerSelectorUse(Selector selector) { |
| 475 if (selector.isGetter()) { | 475 if (selector.isGetter) { |
| 476 registerInvokedGetter(selector); | 476 registerInvokedGetter(selector); |
| 477 } else if (selector.isSetter()) { | 477 } else if (selector.isSetter) { |
| 478 registerInvokedSetter(selector); | 478 registerInvokedSetter(selector); |
| 479 } else { | 479 } else { |
| 480 registerInvocation(selector); | 480 registerInvocation(selector); |
| 481 } | 481 } |
| 482 } | 482 } |
| 483 | 483 |
| 484 void registerDynamicGetter(Selector selector) { | 484 void registerDynamicGetter(Selector selector) { |
| 485 registerInvokedGetter(selector); | 485 registerInvokedGetter(selector); |
| 486 } | 486 } |
| 487 | 487 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 500 void registerFieldSetter(Element element) { | 500 void registerFieldSetter(Element element) { |
| 501 universe.fieldSetters.add(element); | 501 universe.fieldSetters.add(element); |
| 502 } | 502 } |
| 503 | 503 |
| 504 void registerIsCheck(DartType type, TreeElements elements) { | 504 void registerIsCheck(DartType type, TreeElements elements) { |
| 505 type = universe.registerIsCheck(type, compiler); | 505 type = universe.registerIsCheck(type, compiler); |
| 506 // Even in checked mode, type annotations for return type and argument | 506 // Even in checked mode, type annotations for return type and argument |
| 507 // types do not imply type checks, so there should never be a check | 507 // types do not imply type checks, so there should never be a check |
| 508 // against the type variable of a typedef. | 508 // against the type variable of a typedef. |
| 509 assert(type.kind != TypeKind.TYPE_VARIABLE || | 509 assert(type.kind != TypeKind.TYPE_VARIABLE || |
| 510 !type.element.enclosingElement.isTypedef()); | 510 !type.element.enclosingElement.isTypedef); |
| 511 compiler.backend.registerIsCheck(type, this, elements); | 511 compiler.backend.registerIsCheck(type, this, elements); |
| 512 } | 512 } |
| 513 | 513 |
| 514 /** | 514 /** |
| 515 * If a factory constructor is used with type arguments, we lose track | 515 * If a factory constructor is used with type arguments, we lose track |
| 516 * which arguments could be used to create instances of classes that use their | 516 * which arguments could be used to create instances of classes that use their |
| 517 * type variables as expressions, so we have to remember if we saw such a use. | 517 * type variables as expressions, so we have to remember if we saw such a use. |
| 518 */ | 518 */ |
| 519 void registerFactoryWithTypeArguments(TreeElements elements) { | 519 void registerFactoryWithTypeArguments(TreeElements elements) { |
| 520 universe.usingFactoryWithTypeArguments = true; | 520 universe.usingFactoryWithTypeArguments = true; |
| 521 } | 521 } |
| 522 | 522 |
| 523 void registerAsCheck(DartType type, TreeElements elements) { | 523 void registerAsCheck(DartType type, TreeElements elements) { |
| 524 registerIsCheck(type, elements); | 524 registerIsCheck(type, elements); |
| 525 compiler.backend.registerAsCheck(type, this, elements); | 525 compiler.backend.registerAsCheck(type, this, elements); |
| 526 } | 526 } |
| 527 | 527 |
| 528 void registerGenericCallMethod(Element element, TreeElements elements) { | 528 void registerGenericCallMethod(Element element, TreeElements elements) { |
| 529 compiler.backend.registerGenericCallMethod(element, this, elements); | 529 compiler.backend.registerGenericCallMethod(element, this, elements); |
| 530 universe.genericCallMethods.add(element); | 530 universe.genericCallMethods.add(element); |
| 531 } | 531 } |
| 532 | 532 |
| 533 void registerBoundClosure() { | 533 void registerBoundClosure() { |
| 534 registerInstantiatedClass(compiler.boundClosureClass, | 534 registerInstantiatedClass(compiler.boundClosureClass, |
| 535 // Precise dependency is not important here. | 535 // Precise dependency is not important here. |
| 536 compiler.globalDependencies); | 536 compiler.globalDependencies); |
| 537 } | 537 } |
| 538 | 538 |
| 539 void registerClosurizedMember(Element element, TreeElements elements) { | 539 void registerClosurizedMember(Element element, TreeElements elements) { |
| 540 assert(element.isInstanceMember()); | 540 assert(element.isInstanceMember); |
| 541 registerIfGeneric(element, elements); | 541 registerIfGeneric(element, elements); |
| 542 registerBoundClosure(); | 542 registerBoundClosure(); |
| 543 universe.closurizedMembers.add(element); | 543 universe.closurizedMembers.add(element); |
| 544 } | 544 } |
| 545 | 545 |
| 546 | 546 |
| 547 void registerIfGeneric(Element element, TreeElements elements) { | 547 void registerIfGeneric(Element element, TreeElements elements) { |
| 548 if (element.computeType(compiler).containsTypeVariables) { | 548 if (element.computeType(compiler).containsTypeVariables) { |
| 549 compiler.backend.registerGenericClosure(element, this, elements); | 549 compiler.backend.registerGenericClosure(element, this, elements); |
| 550 universe.genericClosures.add(element); | 550 universe.genericClosures.add(element); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 | 611 |
| 612 /// Returns [:true:] if [element] has actually been used. | 612 /// Returns [:true:] if [element] has actually been used. |
| 613 bool isLive(Element element) { | 613 bool isLive(Element element) { |
| 614 if (seenClasses.contains(element)) return true; | 614 if (seenClasses.contains(element)) return true; |
| 615 if (getCachedElements(element) != null) return true; | 615 if (getCachedElements(element) != null) return true; |
| 616 return false; | 616 return false; |
| 617 } | 617 } |
| 618 | 618 |
| 619 TreeElements getCachedElements(Element element) { | 619 TreeElements getCachedElements(Element element) { |
| 620 // TODO(ngeoffray): Get rid of this check. | 620 // TODO(ngeoffray): Get rid of this check. |
| 621 if (element.enclosingElement.isClosure()) { | 621 if (element.enclosingElement.isClosure) { |
| 622 closureMapping.ClosureClassElement cls = element.enclosingElement; | 622 closureMapping.ClosureClassElement cls = element.enclosingElement; |
| 623 element = cls.methodElement; | 623 element = cls.methodElement; |
| 624 } else if (element.isGenerativeConstructorBody()) { | 624 } else if (element.isGenerativeConstructorBody) { |
| 625 ConstructorBodyElement body = element; | 625 ConstructorBodyElement body = element; |
| 626 element = body.constructor; | 626 element = body.constructor; |
| 627 } | 627 } |
| 628 Element owner = element.getOutermostEnclosingMemberOrTopLevel(); | 628 Element owner = element.outermostEnclosingMemberOrTopLevel; |
| 629 if (owner == null) { | 629 if (owner == null) { |
| 630 owner = element; | 630 owner = element; |
| 631 } | 631 } |
| 632 return resolvedElements[owner.declaration]; | 632 return resolvedElements[owner.declaration]; |
| 633 } | 633 } |
| 634 | 634 |
| 635 void internalAddToWorkList(Element element) { | 635 void internalAddToWorkList(Element element) { |
| 636 assert(invariant(element, element is AnalyzableElement, | 636 assert(invariant(element, element is AnalyzableElement, |
| 637 message: 'Element $element is not analyzable.')); | 637 message: 'Element $element is not analyzable.')); |
| 638 if (getCachedElements(element) != null) return; | 638 if (getCachedElements(element) != null) return; |
| 639 if (queueIsClosed) { | 639 if (queueIsClosed) { |
| 640 throw new SpannableAssertionFailure(element, | 640 throw new SpannableAssertionFailure(element, |
| 641 "Resolution work list is closed. Trying to add $element."); | 641 "Resolution work list is closed. Trying to add $element."); |
| 642 } | 642 } |
| 643 | 643 |
| 644 compiler.world.registerUsedElement(element); | 644 compiler.world.registerUsedElement(element); |
| 645 | 645 |
| 646 queue.add(new ResolutionWorkItem(element, itemCompilationContextCreator())); | 646 queue.add(new ResolutionWorkItem(element, itemCompilationContextCreator())); |
| 647 | 647 |
| 648 // Enable isolate support if we start using something from the isolate | 648 // Enable isolate support if we start using something from the isolate |
| 649 // library, or timers for the async library. We exclude constant fields, | 649 // library, or timers for the async library. We exclude constant fields, |
| 650 // which are ending here because their initializing expression is compiled. | 650 // which are ending here because their initializing expression is compiled. |
| 651 LibraryElement library = element.getLibrary(); | 651 LibraryElement library = element.library; |
| 652 if (!compiler.hasIsolateSupport() && | 652 if (!compiler.hasIsolateSupport() && |
| 653 (!element.isField() || !element.modifiers.isConst())) { | 653 (!element.isField || !element.modifiers.isConst)) { |
| 654 String uri = library.canonicalUri.toString(); | 654 String uri = library.canonicalUri.toString(); |
| 655 if (uri == 'dart:isolate') { | 655 if (uri == 'dart:isolate') { |
| 656 enableIsolateSupport(library); | 656 enableIsolateSupport(library); |
| 657 } else if (uri == 'dart:async') { | 657 } else if (uri == 'dart:async') { |
| 658 if (element.name == '_createTimer' || | 658 if (element.name == '_createTimer' || |
| 659 element.name == '_createPeriodicTimer') { | 659 element.name == '_createPeriodicTimer') { |
| 660 // The [:Timer:] class uses the event queue of the isolate | 660 // The [:Timer:] class uses the event queue of the isolate |
| 661 // library, so we make sure that event queue is generated. | 661 // library, so we make sure that event queue is generated. |
| 662 enableIsolateSupport(library); | 662 enableIsolateSupport(library); |
| 663 } | 663 } |
| 664 } | 664 } |
| 665 } | 665 } |
| 666 | 666 |
| 667 if (element.isGetter() && element.name == Compiler.RUNTIME_TYPE) { | 667 if (element.isGetter && element.name == Compiler.RUNTIME_TYPE) { |
| 668 // Enable runtime type support if we discover a getter called runtimeType. | 668 // Enable runtime type support if we discover a getter called runtimeType. |
| 669 // We have to enable runtime type before hitting the codegen, so | 669 // We have to enable runtime type before hitting the codegen, so |
| 670 // that constructors know whether they need to generate code for | 670 // that constructors know whether they need to generate code for |
| 671 // runtime type. | 671 // runtime type. |
| 672 compiler.enabledRuntimeType = true; | 672 compiler.enabledRuntimeType = true; |
| 673 // TODO(ahe): Record precise dependency here. | 673 // TODO(ahe): Record precise dependency here. |
| 674 compiler.backend.registerRuntimeType(this, compiler.globalDependencies); | 674 compiler.backend.registerRuntimeType(this, compiler.globalDependencies); |
| 675 } else if (element == compiler.functionApplyMethod) { | 675 } else if (element == compiler.functionApplyMethod) { |
| 676 compiler.enabledFunctionApply = true; | 676 compiler.enabledFunctionApply = true; |
| 677 } else if (element == compiler.invokeOnMethod) { | 677 } else if (element == compiler.invokeOnMethod) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 | 752 |
| 753 bool isProcessed(Element member) => | 753 bool isProcessed(Element member) => |
| 754 member.isAbstract || generatedCode.containsKey(member); | 754 member.isAbstract || generatedCode.containsKey(member); |
| 755 | 755 |
| 756 void internalAddToWorkList(Element element) { | 756 void internalAddToWorkList(Element element) { |
| 757 // Don't generate code for foreign elements. | 757 // Don't generate code for foreign elements. |
| 758 if (element.isForeign(compiler)) return; | 758 if (element.isForeign(compiler)) return; |
| 759 | 759 |
| 760 // Codegen inlines field initializers. It only needs to generate | 760 // Codegen inlines field initializers. It only needs to generate |
| 761 // code for checked setters. | 761 // code for checked setters. |
| 762 if (element.isField() && element.isInstanceMember()) { | 762 if (element.isField && element.isInstanceMember) { |
| 763 if (!compiler.enableTypeAssertions | 763 if (!compiler.enableTypeAssertions |
| 764 || element.enclosingElement.isClosure()) { | 764 || element.enclosingElement.isClosure) { |
| 765 return; | 765 return; |
| 766 } | 766 } |
| 767 } | 767 } |
| 768 | 768 |
| 769 if (queueIsClosed) { | 769 if (queueIsClosed) { |
| 770 throw new SpannableAssertionFailure(element, | 770 throw new SpannableAssertionFailure(element, |
| 771 "Codegen work list is closed. Trying to add $element"); | 771 "Codegen work list is closed. Trying to add $element"); |
| 772 } | 772 } |
| 773 CodegenWorkItem workItem = new CodegenWorkItem( | 773 CodegenWorkItem workItem = new CodegenWorkItem( |
| 774 element, itemCompilationContextCreator()); | 774 element, itemCompilationContextCreator()); |
| 775 queue.add(workItem); | 775 queue.add(workItem); |
| 776 } | 776 } |
| 777 | 777 |
| 778 void _logSpecificSummary(log(message)) { | 778 void _logSpecificSummary(log(message)) { |
| 779 log('Compiled ${generatedCode.length} methods.'); | 779 log('Compiled ${generatedCode.length} methods.'); |
| 780 } | 780 } |
| 781 } | 781 } |
| OLD | NEW |