| 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 '../diagnostics/diagnostic_listener.dart'; | 9 import '../diagnostics/diagnostic_listener.dart'; |
| 10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
| 11 import '../elements/entities.dart'; |
| 11 import '../universe/selector.dart'; | 12 import '../universe/selector.dart'; |
| 12 import '../universe/use.dart'; | 13 import '../universe/use.dart'; |
| 13 import '../universe/world_impact.dart'; | 14 import '../universe/world_impact.dart'; |
| 14 import 'backend.dart'; | 15 import 'backend.dart'; |
| 15 | 16 |
| 16 class MirrorsAnalysis { | 17 class MirrorsAnalysis { |
| 17 final MirrorsHandler resolutionHandler; | 18 final MirrorsHandler resolutionHandler; |
| 18 final MirrorsHandler codegenHandler; | 19 final MirrorsHandler codegenHandler; |
| 19 | 20 |
| 20 MirrorsAnalysis(JavaScriptBackend backend, Resolution resolution) | 21 MirrorsAnalysis(JavaScriptBackend backend, Resolution resolution) |
| 21 : resolutionHandler = new MirrorsHandler(backend, resolution), | 22 : resolutionHandler = new MirrorsHandler(backend, resolution), |
| 22 codegenHandler = new MirrorsHandler(backend, resolution); | 23 codegenHandler = new MirrorsHandler(backend, resolution); |
| 23 | 24 |
| 24 /// Compute the impact for elements that are matched by the mirrors used | 25 /// Compute the impact for elements that are matched by the mirrors used |
| 25 /// annotation or, in lack thereof, all elements. | 26 /// annotation or, in lack thereof, all elements. |
| 26 WorldImpact computeImpactForReflectiveElements( | 27 WorldImpact computeImpactForReflectiveElements( |
| 27 Iterable<ClassElement> recents, | 28 Iterable<ClassEntity> recents, |
| 28 Iterable<ClassElement> processedClasses, | 29 Iterable<ClassEntity> processedClasses, |
| 29 Iterable<LibraryElement> loadedLibraries, | 30 Iterable<LibraryElement> loadedLibraries, |
| 30 {bool forResolution}) { | 31 {bool forResolution}) { |
| 31 MirrorsHandler handler = forResolution ? resolutionHandler : codegenHandler; | 32 MirrorsHandler handler = forResolution ? resolutionHandler : codegenHandler; |
| 32 handler.enqueueReflectiveElements( | 33 handler.enqueueReflectiveElements( |
| 33 recents, processedClasses, loadedLibraries); | 34 recents, processedClasses, loadedLibraries); |
| 34 return handler.flush(); | 35 return handler.flush(); |
| 35 } | 36 } |
| 36 | 37 |
| 37 /// Compute the impact for the static fields that have been marked as used by | 38 /// Compute the impact for the static fields that have been marked as used by |
| 38 /// reflective usage through `MirrorsUsed`. | 39 /// reflective usage through `MirrorsUsed`. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 } | 129 } |
| 129 } | 130 } |
| 130 } | 131 } |
| 131 } | 132 } |
| 132 | 133 |
| 133 /// Enqeue the member [element] if it is required for reflection. | 134 /// Enqeue the member [element] if it is required for reflection. |
| 134 /// | 135 /// |
| 135 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 136 /// [enclosingWasIncluded] provides a hint whether the enclosing element was |
| 136 /// needed for reflection. | 137 /// needed for reflection. |
| 137 void _enqueueReflectiveElementsInClass( | 138 void _enqueueReflectiveElementsInClass( |
| 138 ClassElement cls, Iterable<ClassElement> recents, | 139 ClassElement cls, Iterable<ClassEntity> recents, |
| 139 {bool enclosingWasIncluded}) { | 140 {bool enclosingWasIncluded}) { |
| 140 if (cls.library.isInternalLibrary || cls.isInjected) return; | 141 if (cls.library.isInternalLibrary || cls.isInjected) return; |
| 141 bool includeClass = _shouldIncludeElementDueToMirrors(cls, | 142 bool includeClass = _shouldIncludeElementDueToMirrors(cls, |
| 142 includedEnclosing: enclosingWasIncluded); | 143 includedEnclosing: enclosingWasIncluded); |
| 143 if (includeClass) { | 144 if (includeClass) { |
| 144 _logEnqueueReflectiveAction(cls, "register"); | 145 _logEnqueueReflectiveAction(cls, "register"); |
| 145 ClassElement declaration = cls.declaration; | 146 ClassElement declaration = cls.declaration; |
| 146 declaration.ensureResolved(_resolution); | 147 declaration.ensureResolved(_resolution); |
| 147 impactBuilder.registerTypeUse( | 148 impactBuilder.registerTypeUse( |
| 148 new TypeUse.mirrorInstantiation(declaration.rawType)); | 149 new TypeUse.mirrorInstantiation(declaration.rawType)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 177 cls.ensureResolved(_resolution); | 178 cls.ensureResolved(_resolution); |
| 178 impactBuilder | 179 impactBuilder |
| 179 .registerTypeUse(new TypeUse.mirrorInstantiation(cls.rawType)); | 180 .registerTypeUse(new TypeUse.mirrorInstantiation(cls.rawType)); |
| 180 } | 181 } |
| 181 } | 182 } |
| 182 } | 183 } |
| 183 | 184 |
| 184 /// Enqeue all local members of the library [lib] if they are required for | 185 /// Enqeue all local members of the library [lib] if they are required for |
| 185 /// reflection. | 186 /// reflection. |
| 186 void _enqueueReflectiveElementsInLibrary( | 187 void _enqueueReflectiveElementsInLibrary( |
| 187 LibraryElement lib, Iterable<ClassElement> recents) { | 188 LibraryElement lib, Iterable<ClassEntity> recents) { |
| 188 bool includeLibrary = | 189 bool includeLibrary = |
| 189 _shouldIncludeElementDueToMirrors(lib, includedEnclosing: false); | 190 _shouldIncludeElementDueToMirrors(lib, includedEnclosing: false); |
| 190 lib.forEachLocalMember((Element member) { | 191 lib.forEachLocalMember((Element member) { |
| 191 if (member.isInjected) return; | 192 if (member.isInjected) return; |
| 192 if (member.isClass) { | 193 if (member.isClass) { |
| 193 ClassElement cls = member; | 194 ClassElement cls = member; |
| 194 cls.ensureResolved(_resolution); | 195 cls.ensureResolved(_resolution); |
| 195 do { | 196 do { |
| 196 _enqueueReflectiveElementsInClass(cls, recents, | 197 _enqueueReflectiveElementsInClass(cls, recents, |
| 197 enclosingWasIncluded: includeLibrary); | 198 enclosingWasIncluded: includeLibrary); |
| 198 cls = cls.superclass; | 199 cls = cls.superclass; |
| 199 } while (cls != null && cls.isUnnamedMixinApplication); | 200 } while (cls != null && cls.isUnnamedMixinApplication); |
| 200 } else { | 201 } else { |
| 201 _enqueueReflectiveMember(member, includeLibrary); | 202 _enqueueReflectiveMember(member, includeLibrary); |
| 202 } | 203 } |
| 203 }); | 204 }); |
| 204 } | 205 } |
| 205 | 206 |
| 206 /// Enqueue all elements that are matched by the mirrors used | 207 /// Enqueue all elements that are matched by the mirrors used |
| 207 /// annotation or, in lack thereof, all elements. | 208 /// annotation or, in lack thereof, all elements. |
| 208 // TODO(johnniwinther): Compute [WorldImpact] instead of enqueuing directly. | 209 // TODO(johnniwinther): Compute [WorldImpact] instead of enqueuing directly. |
| 209 void enqueueReflectiveElements( | 210 void enqueueReflectiveElements( |
| 210 Iterable<ClassElement> recents, | 211 Iterable<ClassEntity> recents, |
| 211 Iterable<ClassElement> processedClasses, | 212 Iterable<ClassEntity> processedClasses, |
| 212 Iterable<LibraryElement> loadedLibraries) { | 213 Iterable<LibraryElement> loadedLibraries) { |
| 213 if (!hasEnqueuedReflectiveElements) { | 214 if (!hasEnqueuedReflectiveElements) { |
| 214 _logEnqueueReflectiveAction("!START enqueueAll"); | 215 _logEnqueueReflectiveAction("!START enqueueAll"); |
| 215 // First round of enqueuing, visit everything that is visible to | 216 // First round of enqueuing, visit everything that is visible to |
| 216 // also pick up static top levels, etc. | 217 // also pick up static top levels, etc. |
| 217 // Also, during the first round, consider all classes that have been seen | 218 // Also, during the first round, consider all classes that have been seen |
| 218 // as recently seen, as we do not know how many rounds of resolution might | 219 // as recently seen, as we do not know how many rounds of resolution might |
| 219 // have run before tree shaking is disabled and thus everything is | 220 // have run before tree shaking is disabled and thus everything is |
| 220 // enqueued. | 221 // enqueued. |
| 221 recents = processedClasses.toSet(); | 222 recents = processedClasses.toSet(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 243 /// usage through `MirrorsUsed`. | 244 /// usage through `MirrorsUsed`. |
| 244 // TODO(johnniwinther): Compute [WorldImpact] instead of enqueuing directly. | 245 // TODO(johnniwinther): Compute [WorldImpact] instead of enqueuing directly. |
| 245 void enqueueReflectiveStaticFields(Iterable<Element> elements) { | 246 void enqueueReflectiveStaticFields(Iterable<Element> elements) { |
| 246 if (hasEnqueuedReflectiveStaticFields) return; | 247 if (hasEnqueuedReflectiveStaticFields) return; |
| 247 hasEnqueuedReflectiveStaticFields = true; | 248 hasEnqueuedReflectiveStaticFields = true; |
| 248 for (Element element in elements) { | 249 for (Element element in elements) { |
| 249 _enqueueReflectiveMember(element, true); | 250 _enqueueReflectiveMember(element, true); |
| 250 } | 251 } |
| 251 } | 252 } |
| 252 } | 253 } |
| OLD | NEW |