OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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.mirrors_handler; | 5 library dart2js.mirrors_handler; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/resolution.dart'; | 8 import '../common/resolution.dart'; |
9 import '../compiler.dart'; | 9 import '../compiler.dart'; |
10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 void addFieldsInContainer(ScopeContainerElement container) { | 66 void addFieldsInContainer(ScopeContainerElement container) { |
67 container.forEachLocalMember((Element member) { | 67 container.forEachLocalMember((Element member) { |
68 if (!member.isInstanceMember && member.isField) { | 68 if (!member.isInstanceMember && member.isField) { |
69 staticFields.add(member); | 69 staticFields.add(member); |
70 } else if (member.isClass) { | 70 } else if (member.isClass) { |
71 addFieldsInContainer(member); | 71 addFieldsInContainer(member); |
72 } | 72 } |
73 }); | 73 }); |
74 } | 74 } |
75 | 75 |
76 for (Element target in _mirrorsData.targetsUsed) { | 76 for (MemberElement target in _mirrorsData.membersInMirrorsUsedTargets) { |
77 if (target == null) continue; | |
78 if (target.isField) { | 77 if (target.isField) { |
79 staticFields.add(target); | 78 staticFields.add(target); |
80 } else if (target.isLibrary || target.isClass) { | |
81 addFieldsInContainer(target); | |
82 } | 79 } |
83 } | 80 } |
| 81 for (ClassElement target in _mirrorsData.classesInMirrorsUsedTargets) { |
| 82 addFieldsInContainer(target); |
| 83 } |
| 84 for (LibraryElement target in _mirrorsData.librariesInMirrorsUsedTargets) { |
| 85 addFieldsInContainer(target); |
| 86 } |
84 return staticFields; | 87 return staticFields; |
85 } | 88 } |
86 | 89 |
87 /// Compute the impact for elements that are matched by the mirrors used | 90 /// Compute the impact for elements that are matched by the mirrors used |
88 /// annotation or, in lack thereof, all elements. | 91 /// annotation or, in lack thereof, all elements. |
89 WorldImpact _computeImpactForReflectiveElements( | 92 WorldImpact _computeImpactForReflectiveElements( |
90 Iterable<ClassEntity> recents, | 93 Iterable<ClassEntity> recents, |
91 Iterable<ClassEntity> processedClasses, | 94 Iterable<ClassEntity> processedClasses, |
92 Iterable<LibraryElement> loadedLibraries) { | 95 Iterable<LibraryElement> loadedLibraries) { |
93 handler.enqueueReflectiveElements( | 96 handler.enqueueReflectiveElements( |
94 recents, processedClasses, loadedLibraries); | 97 recents, processedClasses, loadedLibraries); |
95 return handler.flush(); | 98 return handler.flush(); |
96 } | 99 } |
97 | 100 |
98 /// Compute the impact for the static fields that have been marked as used by | 101 /// Compute the impact for the static fields that have been marked as used by |
99 /// reflective usage through `MirrorsUsed`. | 102 /// reflective usage through `MirrorsUsed`. |
100 WorldImpact _computeImpactForReflectiveStaticFields( | 103 WorldImpact _computeImpactForReflectiveStaticFields( |
101 Iterable<Element> elements) { | 104 Iterable<Element> elements) { |
102 handler.enqueueReflectiveStaticFields(elements); | 105 handler.enqueueReflectiveStaticFields(elements); |
103 return handler.flush(); | 106 return handler.flush(); |
104 } | 107 } |
105 | 108 |
106 void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) { | 109 void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) { |
107 if (_mirrorsData.isTreeShakingDisabled) { | 110 if (_mirrorsData.isTreeShakingDisabled) { |
108 enqueuer.applyImpact(_computeImpactForReflectiveElements(recentClasses, | 111 enqueuer.applyImpact(_computeImpactForReflectiveElements(recentClasses, |
109 enqueuer.processedClasses, _compiler.libraryLoader.libraries)); | 112 enqueuer.processedClasses, _compiler.libraryLoader.libraries)); |
110 } else if (!_mirrorsData.targetsUsed.isEmpty) { | 113 } else if (_mirrorsData.membersInMirrorsUsedTargets.isNotEmpty || |
| 114 _mirrorsData.classesInMirrorsUsedTargets.isNotEmpty || |
| 115 _mirrorsData.librariesInMirrorsUsedTargets.isNotEmpty) { |
111 // Add all static elements (not classes) that have been requested for | 116 // Add all static elements (not classes) that have been requested for |
112 // reflection. If there is no mirror-usage these are probably not | 117 // reflection. If there is no mirror-usage these are probably not |
113 // necessary, but the backend relies on them being resolved. | 118 // necessary, but the backend relies on them being resolved. |
114 enqueuer.applyImpact( | 119 enqueuer.applyImpact( |
115 _computeImpactForReflectiveStaticFields(_findStaticFieldTargets())); | 120 _computeImpactForReflectiveStaticFields(_findStaticFieldTargets())); |
116 } | 121 } |
117 | 122 |
118 if (_mirrorsData.mustPreserveNames) _reporter.log('Preserving names.'); | 123 if (_mirrorsData.mustPreserveNames) _reporter.log('Preserving names.'); |
119 | 124 |
120 if (_mirrorsData.mustRetainMetadata) { | 125 if (_mirrorsData.mustRetainMetadata) { |
121 _reporter.log('Retaining metadata.'); | 126 _reporter.log('Retaining metadata.'); |
122 | 127 |
123 _compiler.libraryLoader.libraries.forEach(_mirrorsData.retainMetadataOf); | 128 _compiler.libraryLoader.libraries |
| 129 .forEach(_mirrorsData.retainMetadataOfLibrary); |
124 | 130 |
125 if (!enqueuer.queueIsClosed) { | 131 if (!enqueuer.queueIsClosed) { |
126 /// Register the constant value of [metadata] as live in resolution. | 132 /// Register the constant value of [metadata] as live in resolution. |
127 void registerMetadataConstant(MetadataAnnotation metadata) { | 133 void registerMetadataConstant(MetadataAnnotation metadata) { |
128 ConstantValue constant = | 134 ConstantValue constant = |
129 _constants.getConstantValueForMetadata(metadata); | 135 _constants.getConstantValueForMetadata(metadata); |
130 Dependency dependency = | 136 Dependency dependency = |
131 new Dependency(constant, metadata.annotatedElement); | 137 new Dependency(constant, metadata.annotatedElement); |
132 _metadataConstants.add(dependency); | 138 _metadataConstants.add(dependency); |
133 _impactBuilder.registerConstantUse(new ConstantUse.mirrors(constant)); | 139 _impactBuilder.registerConstantUse(new ConstantUse.mirrors(constant)); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 if (_mirrorsData.isTreeShakingDisabled) { | 242 if (_mirrorsData.isTreeShakingDisabled) { |
237 enqueuer.applyImpact(_computeImpactForReflectiveElements(recentClasses, | 243 enqueuer.applyImpact(_computeImpactForReflectiveElements(recentClasses, |
238 enqueuer.processedClasses, _compiler.libraryLoader.libraries)); | 244 enqueuer.processedClasses, _compiler.libraryLoader.libraries)); |
239 } | 245 } |
240 | 246 |
241 if (_mirrorsData.mustPreserveNames) _reporter.log('Preserving names.'); | 247 if (_mirrorsData.mustPreserveNames) _reporter.log('Preserving names.'); |
242 | 248 |
243 if (_mirrorsData.mustRetainMetadata) { | 249 if (_mirrorsData.mustRetainMetadata) { |
244 _reporter.log('Retaining metadata.'); | 250 _reporter.log('Retaining metadata.'); |
245 | 251 |
246 _compiler.libraryLoader.libraries.forEach(_mirrorsData.retainMetadataOf); | 252 _compiler.libraryLoader.libraries |
| 253 .forEach(_mirrorsData.retainMetadataOfLibrary); |
247 | 254 |
248 for (Dependency dependency in _metadataConstants) { | 255 for (Dependency dependency in _metadataConstants) { |
249 _impactBuilder | 256 _impactBuilder |
250 .registerConstantUse(new ConstantUse.mirrors(dependency.constant)); | 257 .registerConstantUse(new ConstantUse.mirrors(dependency.constant)); |
251 } | 258 } |
252 _metadataConstants.clear(); | 259 _metadataConstants.clear(); |
253 enqueuer.applyImpact(_impactBuilder.flush()); | 260 enqueuer.applyImpact(_impactBuilder.flush()); |
254 } | 261 } |
255 } | 262 } |
256 } | 263 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 /// Enqueue special classes that might not be visible by normal means or that | 383 /// Enqueue special classes that might not be visible by normal means or that |
377 /// would not normally be enqueued: | 384 /// would not normally be enqueued: |
378 /// | 385 /// |
379 /// [Closure] is treated specially as it is the superclass of all closures. | 386 /// [Closure] is treated specially as it is the superclass of all closures. |
380 /// Although it is in an internal library, we mark it as reflectable. Note | 387 /// Although it is in an internal library, we mark it as reflectable. Note |
381 /// that none of its methods are reflectable, unless reflectable by | 388 /// that none of its methods are reflectable, unless reflectable by |
382 /// inheritance. | 389 /// inheritance. |
383 void _enqueueReflectiveSpecialClasses() { | 390 void _enqueueReflectiveSpecialClasses() { |
384 Iterable<ClassElement> classes = _backend.classesRequiredForReflection; | 391 Iterable<ClassElement> classes = _backend.classesRequiredForReflection; |
385 for (ClassElement cls in classes) { | 392 for (ClassElement cls in classes) { |
386 if (_backend.mirrorsData.referencedFromMirrorSystem(cls)) { | 393 if (_backend.mirrorsData.isClassReferencedFromMirrorSystem(cls)) { |
387 _logEnqueueReflectiveAction(cls); | 394 _logEnqueueReflectiveAction(cls); |
388 cls.ensureResolved(_resolution); | 395 cls.ensureResolved(_resolution); |
389 impactBuilder | 396 impactBuilder |
390 .registerTypeUse(new TypeUse.mirrorInstantiation(cls.rawType)); | 397 .registerTypeUse(new TypeUse.mirrorInstantiation(cls.rawType)); |
391 } | 398 } |
392 } | 399 } |
393 } | 400 } |
394 | 401 |
395 /// Enqueue all local members of the library [lib] if they are required for | 402 /// Enqueue all local members of the library [lib] if they are required for |
396 /// reflection. | 403 /// reflection. |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 | 475 |
469 /// Records that [constant] is used by the element behind [registry]. | 476 /// Records that [constant] is used by the element behind [registry]. |
470 class Dependency { | 477 class Dependency { |
471 final ConstantValue constant; | 478 final ConstantValue constant; |
472 final Element annotatedElement; | 479 final Element annotatedElement; |
473 | 480 |
474 const Dependency(this.constant, this.annotatedElement); | 481 const Dependency(this.constant, this.annotatedElement); |
475 | 482 |
476 String toString() => '$annotatedElement:${constant.toStructuredText()}'; | 483 String toString() => '$annotatedElement:${constant.toStructuredText()}'; |
477 } | 484 } |
OLD | NEW |