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 library dart2js.js.enqueue; | 5 library dart2js.js.enqueue; |
6 | 6 |
7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
8 | 8 |
9 import '../common/backend_api.dart' show Backend; | 9 import '../common/backend_api.dart' show Backend; |
10 import '../common/codegen.dart' show CodegenWorkItem; | 10 import '../common/codegen.dart' show CodegenWorkItem; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 * Invariant: [element] must be a declaration element. | 102 * Invariant: [element] must be a declaration element. |
103 */ | 103 */ |
104 void addToWorkList(Element element) { | 104 void addToWorkList(Element element) { |
105 assert(invariant(element, element.isDeclaration)); | 105 assert(invariant(element, element.isDeclaration)); |
106 // Don't generate code for foreign elements. | 106 // Don't generate code for foreign elements. |
107 if (backend.isForeign(element)) return; | 107 if (backend.isForeign(element)) return; |
108 | 108 |
109 // Codegen inlines field initializers. It only needs to generate | 109 // Codegen inlines field initializers. It only needs to generate |
110 // code for checked setters. | 110 // code for checked setters. |
111 if (element.isField && element.isInstanceMember) { | 111 if (element.isField && element.isInstanceMember) { |
112 if (!options.enableTypeAssertions || | 112 if (!options.enableTypeAssertions || element.enclosingElement.isClosure) { |
113 element.enclosingElement.isClosure) { | |
114 return; | 113 return; |
115 } | 114 } |
116 } | 115 } |
117 | 116 |
118 if (options.hasIncrementalSupport && !isProcessed(element)) { | 117 if (options.hasIncrementalSupport && !isProcessed(element)) { |
119 newlyEnqueuedElements.add(element); | 118 newlyEnqueuedElements.add(element); |
120 } | 119 } |
121 | 120 |
122 if (queueIsClosed) { | 121 if (queueIsClosed) { |
123 throw new SpannableAssertionFailure( | 122 throw new SpannableAssertionFailure( |
(...skipping 14 matching lines...) Expand all Loading... |
138 .visitImpact(element, worldImpact, impactVisitor, impactUse); | 137 .visitImpact(element, worldImpact, impactVisitor, impactUse); |
139 } | 138 } |
140 | 139 |
141 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) { | 140 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) { |
142 task.measure(() { | 141 task.measure(() { |
143 ClassElement cls = type.element; | 142 ClassElement cls = type.element; |
144 bool isNative = backend.isNative(cls); | 143 bool isNative = backend.isNative(cls); |
145 universe.registerTypeInstantiation(type, | 144 universe.registerTypeInstantiation(type, |
146 isNative: isNative, | 145 isNative: isNative, |
147 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { | 146 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { |
148 backend | 147 backend.registerImplementedClass(cls, this, globalDependencies); |
149 .registerImplementedClass(cls, this, globalDependencies); | |
150 }); | 148 }); |
151 // TODO(johnniwinther): Share this reasoning with [Universe]. | 149 // TODO(johnniwinther): Share this reasoning with [Universe]. |
152 if (!cls.isAbstract || isNative || mirrorUsage) { | 150 if (!cls.isAbstract || isNative || mirrorUsage) { |
153 processInstantiatedClass(cls); | 151 processInstantiatedClass(cls); |
154 } | 152 } |
155 }); | 153 }); |
156 } | 154 } |
157 | 155 |
158 bool checkNoEnqueuedInvokedInstanceMethods() { | 156 bool checkNoEnqueuedInvokedInstanceMethods() { |
159 return filter.checkNoEnqueuedInvokedInstanceMethods(this); | 157 return filter.checkNoEnqueuedInvokedInstanceMethods(this); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 message: "Class $superclass has not been " | 262 message: "Class $superclass has not been " |
265 "processed in resolution.")); | 263 "processed in resolution.")); |
266 */ | 264 */ |
267 | 265 |
268 _processedClasses.add(superclass); | 266 _processedClasses.add(superclass); |
269 recentClasses.add(superclass); | 267 recentClasses.add(superclass); |
270 superclass.implementation.forEachMember(processInstantiatedClassMember); | 268 superclass.implementation.forEachMember(processInstantiatedClassMember); |
271 // We only tell the backend once that [superclass] was instantiated, so | 269 // We only tell the backend once that [superclass] was instantiated, so |
272 // any additional dependencies must be treated as global | 270 // any additional dependencies must be treated as global |
273 // dependencies. | 271 // dependencies. |
274 backend.registerInstantiatedClass( | 272 backend.registerInstantiatedClass(superclass, this, globalDependencies); |
275 superclass, this, globalDependencies); | |
276 } | 273 } |
277 | 274 |
278 ClassElement superclass = cls; | 275 ClassElement superclass = cls; |
279 while (superclass != null) { | 276 while (superclass != null) { |
280 processClass(superclass); | 277 processClass(superclass); |
281 superclass = superclass.superclass; | 278 superclass = superclass.superclass; |
282 } | 279 } |
283 }); | 280 }); |
284 } | 281 } |
285 | 282 |
(...skipping 14 matching lines...) Expand all Loading... |
300 /// Enqeue the constructor [ctor] if it is required for reflection. | 297 /// Enqeue the constructor [ctor] if it is required for reflection. |
301 /// | 298 /// |
302 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 299 /// [enclosingWasIncluded] provides a hint whether the enclosing element was |
303 /// needed for reflection. | 300 /// needed for reflection. |
304 void enqueueReflectiveConstructor( | 301 void enqueueReflectiveConstructor( |
305 ConstructorElement ctor, bool enclosingWasIncluded) { | 302 ConstructorElement ctor, bool enclosingWasIncluded) { |
306 if (shouldIncludeElementDueToMirrors(ctor, | 303 if (shouldIncludeElementDueToMirrors(ctor, |
307 includedEnclosing: enclosingWasIncluded)) { | 304 includedEnclosing: enclosingWasIncluded)) { |
308 logEnqueueReflectiveAction(ctor); | 305 logEnqueueReflectiveAction(ctor); |
309 ClassElement cls = ctor.declaration.enclosingClass; | 306 ClassElement cls = ctor.declaration.enclosingClass; |
310 backend.registerInstantiatedType( | 307 backend.registerInstantiatedType(cls.rawType, this, mirrorDependencies, |
311 cls.rawType, this, mirrorDependencies, | |
312 mirrorUsage: true); | 308 mirrorUsage: true); |
313 registerStaticUse(new StaticUse.foreignUse(ctor.declaration)); | 309 registerStaticUse(new StaticUse.foreignUse(ctor.declaration)); |
314 } | 310 } |
315 } | 311 } |
316 | 312 |
317 /// Enqeue the member [element] if it is required for reflection. | 313 /// Enqeue the member [element] if it is required for reflection. |
318 /// | 314 /// |
319 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 315 /// [enclosingWasIncluded] provides a hint whether the enclosing element was |
320 /// needed for reflection. | 316 /// needed for reflection. |
321 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { | 317 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { |
(...skipping 27 matching lines...) Expand all Loading... |
349 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 345 /// [enclosingWasIncluded] provides a hint whether the enclosing element was |
350 /// needed for reflection. | 346 /// needed for reflection. |
351 void enqueueReflectiveElementsInClass(ClassElement cls, | 347 void enqueueReflectiveElementsInClass(ClassElement cls, |
352 Iterable<ClassElement> recents, bool enclosingWasIncluded) { | 348 Iterable<ClassElement> recents, bool enclosingWasIncluded) { |
353 if (cls.library.isInternalLibrary || cls.isInjected) return; | 349 if (cls.library.isInternalLibrary || cls.isInjected) return; |
354 bool includeClass = shouldIncludeElementDueToMirrors(cls, | 350 bool includeClass = shouldIncludeElementDueToMirrors(cls, |
355 includedEnclosing: enclosingWasIncluded); | 351 includedEnclosing: enclosingWasIncluded); |
356 if (includeClass) { | 352 if (includeClass) { |
357 logEnqueueReflectiveAction(cls, "register"); | 353 logEnqueueReflectiveAction(cls, "register"); |
358 ClassElement decl = cls.declaration; | 354 ClassElement decl = cls.declaration; |
359 backend.registerInstantiatedType( | 355 backend.registerInstantiatedType(decl.rawType, this, mirrorDependencies, |
360 decl.rawType, this, mirrorDependencies, | |
361 mirrorUsage: true); | 356 mirrorUsage: true); |
362 } | 357 } |
363 // If the class is never instantiated, we know nothing of it can possibly | 358 // If the class is never instantiated, we know nothing of it can possibly |
364 // be reflected upon. | 359 // be reflected upon. |
365 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. | 360 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. |
366 if (recents.contains(cls.declaration)) { | 361 if (recents.contains(cls.declaration)) { |
367 logEnqueueReflectiveAction(cls, "members"); | 362 logEnqueueReflectiveAction(cls, "members"); |
368 cls.constructors.forEach((Element element) { | 363 cls.constructors.forEach((Element element) { |
369 enqueueReflectiveConstructor(element, includeClass); | 364 enqueueReflectiveConstructor(element, includeClass); |
370 }); | 365 }); |
371 cls.forEachClassMember((Member member) { | 366 cls.forEachClassMember((Member member) { |
372 enqueueReflectiveMember(member.element, includeClass); | 367 enqueueReflectiveMember(member.element, includeClass); |
373 }); | 368 }); |
374 } | 369 } |
375 } | 370 } |
376 | 371 |
377 /// Enqeue special classes that might not be visible by normal means or that | 372 /// Enqeue special classes that might not be visible by normal means or that |
378 /// would not normally be enqueued: | 373 /// would not normally be enqueued: |
379 /// | 374 /// |
380 /// [Closure] is treated specially as it is the superclass of all closures. | 375 /// [Closure] is treated specially as it is the superclass of all closures. |
381 /// Although it is in an internal library, we mark it as reflectable. Note | 376 /// Although it is in an internal library, we mark it as reflectable. Note |
382 /// that none of its methods are reflectable, unless reflectable by | 377 /// that none of its methods are reflectable, unless reflectable by |
383 /// inheritance. | 378 /// inheritance. |
384 void enqueueReflectiveSpecialClasses() { | 379 void enqueueReflectiveSpecialClasses() { |
385 Iterable<ClassElement> classes = | 380 Iterable<ClassElement> classes = backend.classesRequiredForReflection; |
386 backend.classesRequiredForReflection; | |
387 for (ClassElement cls in classes) { | 381 for (ClassElement cls in classes) { |
388 if (backend.referencedFromMirrorSystem(cls)) { | 382 if (backend.referencedFromMirrorSystem(cls)) { |
389 logEnqueueReflectiveAction(cls); | 383 logEnqueueReflectiveAction(cls); |
390 backend.registerInstantiatedType( | 384 backend.registerInstantiatedType(cls.rawType, this, mirrorDependencies, |
391 cls.rawType, this, mirrorDependencies, | |
392 mirrorUsage: true); | 385 mirrorUsage: true); |
393 } | 386 } |
394 } | 387 } |
395 } | 388 } |
396 | 389 |
397 /// Enqeue all local members of the library [lib] if they are required for | 390 /// Enqeue all local members of the library [lib] if they are required for |
398 /// reflection. | 391 /// reflection. |
399 void enqueueReflectiveElementsInLibrary( | 392 void enqueueReflectiveElementsInLibrary( |
400 LibraryElement lib, Iterable<ClassElement> recents) { | 393 LibraryElement lib, Iterable<ClassElement> recents) { |
401 bool includeLibrary = | 394 bool includeLibrary = |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 @override | 701 @override |
709 void visitStaticUse(StaticUse staticUse) { | 702 void visitStaticUse(StaticUse staticUse) { |
710 enqueuer.registerStaticUse(staticUse); | 703 enqueuer.registerStaticUse(staticUse); |
711 } | 704 } |
712 | 705 |
713 @override | 706 @override |
714 void visitTypeUse(TypeUse typeUse) { | 707 void visitTypeUse(TypeUse typeUse) { |
715 enqueuer.registerTypeUse(typeUse); | 708 enqueuer.registerTypeUse(typeUse); |
716 } | 709 } |
717 } | 710 } |
OLD | NEW |