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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 | 54 |
55 DiagnosticReporter get _reporter => _backend.reporter; | 55 DiagnosticReporter get _reporter => _backend.reporter; |
56 Compiler get _compiler => _backend.compiler; | 56 Compiler get _compiler => _backend.compiler; |
57 JavaScriptConstantCompiler get _constants => _backend.constants; | 57 JavaScriptConstantCompiler get _constants => _backend.constants; |
58 MirrorsData get _mirrorsData => _backend.mirrorsData; | 58 MirrorsData get _mirrorsData => _backend.mirrorsData; |
59 | 59 |
60 /// Returns all static fields that are referenced through | 60 /// Returns all static fields that are referenced through |
61 /// `mirrorsData.targetsUsed`. If the target is a library or class all nested | 61 /// `mirrorsData.targetsUsed`. If the target is a library or class all nested |
62 /// static fields are included too. | 62 /// static fields are included too. |
63 Iterable<Element> _findStaticFieldTargets() { | 63 Iterable<Element> _findStaticFieldTargets() { |
64 List staticFields = []; | 64 List<Element> staticFields = <Element>[]; |
65 | 65 |
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 } |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 ClassElement declaration = cls.declaration; | 364 ClassElement declaration = cls.declaration; |
365 declaration.ensureResolved(_resolution); | 365 declaration.ensureResolved(_resolution); |
366 impactBuilder.registerTypeUse( | 366 impactBuilder.registerTypeUse( |
367 new TypeUse.mirrorInstantiation(declaration.rawType)); | 367 new TypeUse.mirrorInstantiation(declaration.rawType)); |
368 } | 368 } |
369 // If the class is never instantiated, we know nothing of it can possibly | 369 // If the class is never instantiated, we know nothing of it can possibly |
370 // be reflected upon. | 370 // be reflected upon. |
371 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. | 371 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. |
372 if (recents.contains(cls.declaration)) { | 372 if (recents.contains(cls.declaration)) { |
373 _logEnqueueReflectiveAction(cls, "members"); | 373 _logEnqueueReflectiveAction(cls, "members"); |
374 cls.constructors.forEach((ConstructorElement element) { | 374 cls.constructors.forEach((Element element) { |
375 _enqueueReflectiveConstructor(element.declaration, | 375 _enqueueReflectiveConstructor(element.declaration, |
376 enclosingWasIncluded: includeClass); | 376 enclosingWasIncluded: includeClass); |
377 }); | 377 }); |
378 cls.forEachClassMember((Member member) { | 378 cls.forEachClassMember((Member member) { |
379 _enqueueReflectiveMember(member.element, includeClass); | 379 _enqueueReflectiveMember(member.element, includeClass); |
380 }); | 380 }); |
381 } | 381 } |
382 } | 382 } |
383 | 383 |
384 /// Set of classes that need to be considered for reflection although not | 384 /// Set of classes that need to be considered for reflection although not |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 for (LibraryElement lib in loadedLibraries) { | 456 for (LibraryElement lib in loadedLibraries) { |
457 _enqueueReflectiveElementsInLibrary(lib, recents); | 457 _enqueueReflectiveElementsInLibrary(lib, recents); |
458 } | 458 } |
459 _enqueueReflectiveSpecialClasses(); | 459 _enqueueReflectiveSpecialClasses(); |
460 hasEnqueuedReflectiveElements = true; | 460 hasEnqueuedReflectiveElements = true; |
461 hasEnqueuedReflectiveStaticFields = true; | 461 hasEnqueuedReflectiveStaticFields = true; |
462 _logEnqueueReflectiveAction("!DONE enqueueAll"); | 462 _logEnqueueReflectiveAction("!DONE enqueueAll"); |
463 } else if (recents.isNotEmpty) { | 463 } else if (recents.isNotEmpty) { |
464 // Keep looking at new classes until fixpoint is reached. | 464 // Keep looking at new classes until fixpoint is reached. |
465 _logEnqueueReflectiveAction("!START enqueueRecents"); | 465 _logEnqueueReflectiveAction("!START enqueueRecents"); |
466 recents.forEach((ClassElement cls) { | 466 recents.forEach((ClassEntity _cls) { |
| 467 ClassElement cls = _cls; |
467 _enqueueReflectiveElementsInClass(cls, recents, | 468 _enqueueReflectiveElementsInClass(cls, recents, |
468 enclosingWasIncluded: _shouldIncludeElementDueToMirrors(cls.library, | 469 enclosingWasIncluded: _shouldIncludeElementDueToMirrors(cls.library, |
469 includedEnclosing: false)); | 470 includedEnclosing: false)); |
470 }); | 471 }); |
471 _logEnqueueReflectiveAction("!DONE enqueueRecents"); | 472 _logEnqueueReflectiveAction("!DONE enqueueRecents"); |
472 } | 473 } |
473 } | 474 } |
474 | 475 |
475 /// Enqueue the static fields that have been marked as used by reflective | 476 /// Enqueue the static fields that have been marked as used by reflective |
476 /// usage through `MirrorsUsed`. | 477 /// usage through `MirrorsUsed`. |
477 // TODO(johnniwinther): Compute [WorldImpact] instead of enqueuing directly. | 478 // TODO(johnniwinther): Compute [WorldImpact] instead of enqueuing directly. |
478 void enqueueReflectiveStaticFields(Iterable<Element> elements) { | 479 void enqueueReflectiveStaticFields(Iterable<Element> elements) { |
479 if (hasEnqueuedReflectiveStaticFields) return; | 480 if (hasEnqueuedReflectiveStaticFields) return; |
480 hasEnqueuedReflectiveStaticFields = true; | 481 hasEnqueuedReflectiveStaticFields = true; |
481 for (Element element in elements) { | 482 for (Element element in elements) { |
482 _enqueueReflectiveMember(element, true); | 483 _enqueueReflectiveMember(element, true); |
483 } | 484 } |
484 } | 485 } |
485 } | 486 } |
486 | 487 |
487 /// Records that [constant] is used by the element behind [registry]. | 488 /// Records that [constant] is used by the element behind [registry]. |
488 class Dependency { | 489 class Dependency { |
489 final ConstantValue constant; | 490 final ConstantValue constant; |
490 final Element annotatedElement; | 491 final Element annotatedElement; |
491 | 492 |
492 const Dependency(this.constant, this.annotatedElement); | 493 const Dependency(this.constant, this.annotatedElement); |
493 | 494 |
494 String toString() => '$annotatedElement:${constant.toStructuredText()}'; | 495 String toString() => '$annotatedElement:${constant.toStructuredText()}'; |
495 } | 496 } |
OLD | NEW |