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; |
(...skipping 14 matching lines...) Expand all Loading... |
25 resolution.nativeEnqueuer = | 25 resolution.nativeEnqueuer = |
26 compiler.backend.nativeResolutionEnqueuer(resolution); | 26 compiler.backend.nativeResolutionEnqueuer(resolution); |
27 } | 27 } |
28 | 28 |
29 void forgetElement(Element element) { | 29 void forgetElement(Element element) { |
30 resolution.forgetElement(element); | 30 resolution.forgetElement(element); |
31 codegen.forgetElement(element); | 31 codegen.forgetElement(element); |
32 } | 32 } |
33 } | 33 } |
34 | 34 |
| 35 class WorldImpact { |
| 36 const WorldImpact(); |
| 37 |
| 38 Iterable<Selector> get dynamicInvocations => const <Selector>[]; |
| 39 Iterable<Selector> get dynamicGetters => const <Selector>[]; |
| 40 Iterable<Selector> get dynamicSetters => const <Selector>[]; |
| 41 |
| 42 // TODO(johnniwinther): Split this into more precise subsets. |
| 43 Iterable<Element> get staticUses => const <Element>[]; |
| 44 |
| 45 // TODO(johnniwinther): Replace this by called constructors with type |
| 46 // arguments. |
| 47 Iterable<InterfaceType> get instantiatedTypes => const <InterfaceType>[]; |
| 48 |
| 49 // TODO(johnniwinther): Collect checked types for checked mode separately to |
| 50 // support serialization. |
| 51 Iterable<DartType> get checkedTypes => const <DartType>[]; |
| 52 |
| 53 Iterable<MethodElement> get closurizedFunctions => const <MethodElement>[]; |
| 54 } |
| 55 |
35 abstract class Enqueuer { | 56 abstract class Enqueuer { |
36 final String name; | 57 final String name; |
37 final Compiler compiler; // TODO(ahe): Remove this dependency. | 58 final Compiler compiler; // TODO(ahe): Remove this dependency. |
38 final ItemCompilationContextCreator itemCompilationContextCreator; | 59 final ItemCompilationContextCreator itemCompilationContextCreator; |
39 final Map<String, Set<Element>> instanceMembersByName | 60 final Map<String, Set<Element>> instanceMembersByName |
40 = new Map<String, Set<Element>>(); | 61 = new Map<String, Set<Element>>(); |
41 final Map<String, Set<Element>> instanceFunctionsByName | 62 final Map<String, Set<Element>> instanceFunctionsByName |
42 = new Map<String, Set<Element>>(); | 63 = new Map<String, Set<Element>>(); |
43 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); | 64 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); |
44 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); | 65 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 internalAddToWorkList(element); | 98 internalAddToWorkList(element); |
78 } | 99 } |
79 | 100 |
80 /** | 101 /** |
81 * Adds [element] to the work list if it has not already been processed. | 102 * Adds [element] to the work list if it has not already been processed. |
82 * | 103 * |
83 * Returns [true] if the element was actually added to the queue. | 104 * Returns [true] if the element was actually added to the queue. |
84 */ | 105 */ |
85 bool internalAddToWorkList(Element element); | 106 bool internalAddToWorkList(Element element); |
86 | 107 |
| 108 /// Apply the [worldImpact] of processing [element] to this enqueuer. |
| 109 void applyImpact(Element element, WorldImpact worldImpact) { |
| 110 // TODO(johnniwinther): Optimize the application of the world impact. |
| 111 worldImpact.dynamicInvocations.forEach(registerDynamicInvocation); |
| 112 worldImpact.dynamicGetters.forEach(registerDynamicGetter); |
| 113 worldImpact.dynamicSetters.forEach(registerDynamicSetter); |
| 114 worldImpact.staticUses.forEach(registerStaticUse); |
| 115 // TODO(johnniwinther): Register [worldImpact.instantiatedTypes] when it |
| 116 // doesn't require a [Registry]. |
| 117 worldImpact.checkedTypes.forEach(registerIsCheck); |
| 118 worldImpact.closurizedFunctions.forEach(registerGetOfStaticFunction); |
| 119 } |
| 120 |
| 121 // TODO(johnniwinther): Remove the need for passing the [registry]. |
87 void registerInstantiatedType(InterfaceType type, Registry registry, | 122 void registerInstantiatedType(InterfaceType type, Registry registry, |
88 {bool mirrorUsage: false}) { | 123 {bool mirrorUsage: false}) { |
89 task.measure(() { | 124 task.measure(() { |
90 ClassElement cls = type.element; | 125 ClassElement cls = type.element; |
91 registry.registerDependency(cls); | 126 registry.registerDependency(cls); |
92 cls.ensureResolved(compiler); | 127 cls.ensureResolved(compiler); |
93 universe.registerTypeInstantiation(type, byMirrors: mirrorUsage); | 128 universe.registerTypeInstantiation(type, byMirrors: mirrorUsage); |
94 processInstantiatedClass(cls); | 129 processInstantiatedClass(cls); |
95 compiler.backend.registerInstantiatedType(type, registry); | 130 compiler.backend.registerInstantiatedType(type, registry); |
96 }); | 131 }); |
97 } | 132 } |
98 | 133 |
99 void registerInstantiatedClass(ClassElement cls, Registry registry, | |
100 {bool mirrorUsage: false}) { | |
101 cls.ensureResolved(compiler); | |
102 registerInstantiatedType(cls.rawType, registry, mirrorUsage: mirrorUsage); | |
103 } | |
104 | |
105 bool checkNoEnqueuedInvokedInstanceMethods() { | 134 bool checkNoEnqueuedInvokedInstanceMethods() { |
106 return filter.checkNoEnqueuedInvokedInstanceMethods(this); | 135 return filter.checkNoEnqueuedInvokedInstanceMethods(this); |
107 } | 136 } |
108 | 137 |
109 void processInstantiatedClassMembers(ClassElement cls) { | 138 void processInstantiatedClassMembers(ClassElement cls) { |
110 cls.implementation.forEachMember(processInstantiatedClassMember); | 139 cls.implementation.forEachMember(processInstantiatedClassMember); |
111 } | 140 } |
112 | 141 |
113 void processInstantiatedClassMember(ClassElement cls, Element member) { | 142 void processInstantiatedClassMember(ClassElement cls, Element member) { |
114 assert(invariant(member, member.isDeclaration)); | 143 assert(invariant(member, member.isDeclaration)); |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 /// needed for reflection. | 372 /// needed for reflection. |
344 void enqueueReflectiveElementsInClass(ClassElement cls, | 373 void enqueueReflectiveElementsInClass(ClassElement cls, |
345 Iterable<ClassElement> recents, | 374 Iterable<ClassElement> recents, |
346 bool enclosingWasIncluded) { | 375 bool enclosingWasIncluded) { |
347 if (cls.library.isInternalLibrary || cls.isInjected) return; | 376 if (cls.library.isInternalLibrary || cls.isInjected) return; |
348 bool includeClass = shouldIncludeElementDueToMirrors(cls, | 377 bool includeClass = shouldIncludeElementDueToMirrors(cls, |
349 includedEnclosing: enclosingWasIncluded); | 378 includedEnclosing: enclosingWasIncluded); |
350 if (includeClass) { | 379 if (includeClass) { |
351 logEnqueueReflectiveAction(cls, "register"); | 380 logEnqueueReflectiveAction(cls, "register"); |
352 ClassElement decl = cls.declaration; | 381 ClassElement decl = cls.declaration; |
353 registerInstantiatedClass(decl, compiler.mirrorDependencies, | 382 decl.ensureResolved(compiler); |
| 383 registerInstantiatedType(decl.rawType, compiler.mirrorDependencies, |
354 mirrorUsage: true); | 384 mirrorUsage: true); |
355 } | 385 } |
356 // If the class is never instantiated, we know nothing of it can possibly | 386 // If the class is never instantiated, we know nothing of it can possibly |
357 // be reflected upon. | 387 // be reflected upon. |
358 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. | 388 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. |
359 if (recents.contains(cls.declaration)) { | 389 if (recents.contains(cls.declaration)) { |
360 logEnqueueReflectiveAction(cls, "members"); | 390 logEnqueueReflectiveAction(cls, "members"); |
361 cls.constructors.forEach((Element element) { | 391 cls.constructors.forEach((Element element) { |
362 enqueueReflectiveConstructor(element, includeClass); | 392 enqueueReflectiveConstructor(element, includeClass); |
363 }); | 393 }); |
364 cls.forEachClassMember((Member member) { | 394 cls.forEachClassMember((Member member) { |
365 enqueueReflectiveMember(member.element, includeClass); | 395 enqueueReflectiveMember(member.element, includeClass); |
366 }); | 396 }); |
367 } | 397 } |
368 } | 398 } |
369 | 399 |
370 /// Enqeue special classes that might not be visible by normal means or that | 400 /// Enqeue special classes that might not be visible by normal means or that |
371 /// would not normally be enqueued: | 401 /// would not normally be enqueued: |
372 /// | 402 /// |
373 /// [Closure] is treated specially as it is the superclass of all closures. | 403 /// [Closure] is treated specially as it is the superclass of all closures. |
374 /// Although it is in an internal library, we mark it as reflectable. Note | 404 /// Although it is in an internal library, we mark it as reflectable. Note |
375 /// that none of its methods are reflectable, unless reflectable by | 405 /// that none of its methods are reflectable, unless reflectable by |
376 /// inheritance. | 406 /// inheritance. |
377 void enqueueReflectiveSpecialClasses() { | 407 void enqueueReflectiveSpecialClasses() { |
378 Iterable<ClassElement> classes = | 408 Iterable<ClassElement> classes = |
379 compiler.backend.classesRequiredForReflection; | 409 compiler.backend.classesRequiredForReflection; |
380 for (ClassElement cls in classes) { | 410 for (ClassElement cls in classes) { |
381 if (compiler.backend.referencedFromMirrorSystem(cls)) { | 411 if (compiler.backend.referencedFromMirrorSystem(cls)) { |
382 logEnqueueReflectiveAction(cls); | 412 logEnqueueReflectiveAction(cls); |
383 registerInstantiatedClass(cls, compiler.mirrorDependencies, | 413 cls.ensureResolved(compiler); |
| 414 registerInstantiatedType(cls.rawType, compiler.mirrorDependencies, |
384 mirrorUsage: true); | 415 mirrorUsage: true); |
385 } | 416 } |
386 } | 417 } |
387 } | 418 } |
388 | 419 |
389 /// Enqeue all local members of the library [lib] if they are required for | 420 /// Enqeue all local members of the library [lib] if they are required for |
390 /// reflection. | 421 /// reflection. |
391 void enqueueReflectiveElementsInLibrary(LibraryElement lib, | 422 void enqueueReflectiveElementsInLibrary(LibraryElement lib, |
392 Iterable<ClassElement> recents) { | 423 Iterable<ClassElement> recents) { |
393 bool includeLibrary = shouldIncludeElementDueToMirrors(lib, | 424 bool includeLibrary = shouldIncludeElementDueToMirrors(lib, |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 } | 588 } |
558 | 589 |
559 void registerFieldGetter(Element element) { | 590 void registerFieldGetter(Element element) { |
560 universe.fieldGetters.add(element); | 591 universe.fieldGetters.add(element); |
561 } | 592 } |
562 | 593 |
563 void registerFieldSetter(Element element) { | 594 void registerFieldSetter(Element element) { |
564 universe.fieldSetters.add(element); | 595 universe.fieldSetters.add(element); |
565 } | 596 } |
566 | 597 |
567 void registerIsCheck(DartType type, Registry registry) { | 598 void registerIsCheck(DartType type) { |
568 type = universe.registerIsCheck(type, compiler); | 599 type = universe.registerIsCheck(type, compiler); |
569 // Even in checked mode, type annotations for return type and argument | 600 // Even in checked mode, type annotations for return type and argument |
570 // types do not imply type checks, so there should never be a check | 601 // types do not imply type checks, so there should never be a check |
571 // against the type variable of a typedef. | 602 // against the type variable of a typedef. |
572 assert(type.kind != TypeKind.TYPE_VARIABLE || | 603 assert(type.kind != TypeKind.TYPE_VARIABLE || |
573 !type.element.enclosingElement.isTypedef); | 604 !type.element.enclosingElement.isTypedef); |
574 } | 605 } |
575 | 606 |
576 void registerCallMethodWithFreeTypeVariables( | 607 void registerCallMethodWithFreeTypeVariables( |
577 Element element, | 608 Element element, |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
912 void processWorkItem(void f(WorkItem work), WorkItem work) { | 943 void processWorkItem(void f(WorkItem work), WorkItem work) { |
913 f(work); | 944 f(work); |
914 } | 945 } |
915 } | 946 } |
916 | 947 |
917 void removeFromSet(Map<String, Set<Element>> map, Element element) { | 948 void removeFromSet(Map<String, Set<Element>> map, Element element) { |
918 Set<Element> set = map[element.name]; | 949 Set<Element> set = map[element.name]; |
919 if (set == null) return; | 950 if (set == null) return; |
920 set.remove(element); | 951 set.remove(element); |
921 } | 952 } |
OLD | NEW |