| Index: dart/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
|
| diff --git a/dart/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/dart/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
|
| index b2175c53090a95f4f25ac2adb7729698fd04cc82..970af53587d96a11a2e9bec8ee20a0de1653bbc5 100644
|
| --- a/dart/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
|
| +++ b/dart/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
|
| @@ -308,6 +308,9 @@ class JavaScriptBackend extends Backend {
|
| /// True if a call to disableTreeShaking has been seen.
|
| bool isTreeShakingDisabled = false;
|
|
|
| + /// True if there isn't sufficient @MirrorsUsed data.
|
| + bool hasInsufficientMirrorsUsed = false;
|
| +
|
| /// List of instantiated types from metadata. If metadata must be preserved,
|
| /// these types must registered.
|
| final List<Dependency> metadataInstantiatedTypes = <Dependency>[];
|
| @@ -1359,10 +1362,9 @@ class JavaScriptBackend extends Backend {
|
|
|
| void registerStaticUse(Element element, Enqueuer enqueuer) {
|
| if (element == disableTreeShakingMarker) {
|
| - enqueuer.enqueueEverything();
|
| - if (isTreeShakingDisabled) return;
|
| compiler.disableTypeInferenceForMirrors = true;
|
| isTreeShakingDisabled = true;
|
| + enqueuer.enqueueEverything();
|
| } else if (element == preserveNamesMarker) {
|
| if (mustPreserveNames) return;
|
| mustPreserveNames = true;
|
| @@ -1395,17 +1397,25 @@ class JavaScriptBackend extends Backend {
|
|
|
| /// Called when [:const Symbol(name):] is seen.
|
| void registerConstSymbol(String name, TreeElements elements) {
|
| + symbolsUsed.add(name);
|
| }
|
|
|
| /// Called when [:new Symbol(...):] is seen.
|
| void registerNewSymbol(TreeElements elements) {
|
| }
|
|
|
| - bool retainGetter(Element element) => isTreeShakingDisabled;
|
| + /// Should [element] (a getter) be retained for reflection?
|
| + bool shouldRetainGetter(Element element) => isNeededForReflection(element);
|
|
|
| - bool retainSetter(Element element) => isTreeShakingDisabled;
|
| + /// Should [element] (a setter) be retained for reflection?
|
| + bool shouldRetainSetter(Element element) => isNeededForReflection(element);
|
|
|
| - bool retainName(SourceString name) => mustPreserveNames;
|
| + /// Should [name] be retained for reflection?
|
| + bool shouldRetainName(SourceString name) {
|
| + if (hasInsufficientMirrorsUsed) return mustPreserveNames;
|
| + if (name == const SourceString('')) return false;
|
| + return symbolsUsed.contains(name.slowToString());
|
| + }
|
|
|
| bool get rememberLazies => isTreeShakingDisabled;
|
|
|
| @@ -1460,6 +1470,12 @@ class JavaScriptBackend extends Backend {
|
| void registerMirrorUsage(Set<String> symbols,
|
| Set<Element> targets,
|
| Set<Element> metaTargets) {
|
| + if (symbols == null && targets == null && metaTargets == null) {
|
| + // The user didn't specify anything, or there are imports of
|
| + // 'dart:mirrors' without @MirrorsUsed.
|
| + hasInsufficientMirrorsUsed = true;
|
| + return;
|
| + }
|
| if (symbols != null) symbolsUsed.addAll(symbols);
|
| if (targets != null) {
|
| for (Element target in targets) {
|
| @@ -1476,11 +1492,25 @@ class JavaScriptBackend extends Backend {
|
| }
|
|
|
| bool isNeededForReflection(Element element) {
|
| - // TODO(ahe): Implement this.
|
| - if (!metaTargetsUsed.isEmpty) return true;
|
| + if (hasInsufficientMirrorsUsed) return isTreeShakingDisabled;
|
| + /// Record the name of [element] in [symbolsUsed]. Return true for
|
| + /// convenience.
|
| + bool registerNameOf(Element element) {
|
| + symbolsUsed.add(element.name.slowToString());
|
| + if (element.isConstructor()) {
|
| + symbolsUsed.add(element.getEnclosingClass().name.slowToString());
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + if (!metaTargetsUsed.isEmpty) {
|
| + // TODO(ahe): Implement this.
|
| + return registerNameOf(element);
|
| + }
|
| +
|
| if (!targetsUsed.isEmpty) {
|
| for (Element e = element; e != null; e = e.enclosingElement) {
|
| - if (targetsUsed.contains(e)) return true;
|
| + if (targetsUsed.contains(e)) return registerNameOf(element);
|
| }
|
| }
|
| return false;
|
|
|