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