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