Version 1.2.0-dev.2.3
svn merge -c 32159 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 32160 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@32163 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/sdk/lib/_internal/compiler/implementation/enqueue.dart b/sdk/lib/_internal/compiler/implementation/enqueue.dart
index 2be6abe..f4ee00c 100644
--- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
+++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
@@ -85,7 +85,7 @@
EnqueueTask task;
native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask
- bool hasEnqueuedEverything = false;
+ bool hasEnqueuedReflectiveElements = false;
Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator);
@@ -359,7 +359,7 @@
}
void enqueueEverything() {
- if (hasEnqueuedEverything) return;
+ if (hasEnqueuedReflectiveElements) return;
compiler.log('Enqueuing everything');
task.ensureAllElementsByName();
for (Link link in task.allElementsByName.values) {
@@ -367,7 +367,17 @@
pretendElementWasUsed(element, compiler.globalDependencies);
}
}
- hasEnqueuedEverything = true;
+ hasEnqueuedReflectiveElements = true;
+ }
+
+ /// Enqueue the static fields that have been marked as used by reflective
+ /// usage through `MirrorsUsed`.
+ void enqueueReflectiveStaticFields(Iterable<Element> elements) {
+ if (hasEnqueuedReflectiveElements) return;
+ hasEnqueuedReflectiveElements = true;
+ for (Element element in elements) {
+ pretendElementWasUsed(element, compiler.globalDependencies);
+ }
}
processLink(Map<String, Link<Element>> map,
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 56bf967..35abf1c 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -1744,13 +1744,47 @@
return isTypedArray(mask) || mask.containsMask(indexing, compiler);
}
+ /// Returns all static fields that are referenced through [targetsUsed].
+ /// If the target is a library or class all nested static fields are
+ /// included too.
+ Iterable<Element> _findStaticFieldTargets() {
+ List staticFields = [];
+
+ void addFieldsInContainer(ScopeContainerElement container) {
+ container.forEachLocalMember((Element member) {
+ if (!member.isInstanceMember() && member.isField()) {
+ staticFields.add(member);
+ } else if (member.isClass()) {
+ addFieldsInContainer(member);
+ }
+ });
+ }
+
+ for (Element target in targetsUsed) {
+ if (target == null) continue;
+ if (target.isField()) {
+ staticFields.add(target);
+ } else if (target.isLibrary() || target.isClass()) {
+ addFieldsInContainer(target);
+ }
+ }
+ return staticFields;
+ }
+
/// Called when [enqueuer] is empty, but before it is closed.
void onQueueEmpty(Enqueuer enqueuer) {
if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) {
preMirrorsMethodCount = generatedCode.length;
}
- if (isTreeShakingDisabled) enqueuer.enqueueEverything();
+ if (isTreeShakingDisabled) {
+ enqueuer.enqueueEverything();
+ } else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) {
+ // Add all static elements (not classes) that have been requested for
+ // reflection. If there is no mirror-usage these are probably not
+ // necessary, but the backend relies on them being resolved.
+ enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets());
+ }
if (mustPreserveNames) compiler.log('Preserving names.');
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
index 5667204..7632220 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
@@ -97,14 +97,9 @@
bool emitStatics: false,
bool onlyForRti: false }) {
assert(!emitStatics || !onlyForRti);
- bool isClass = false;
- bool isLibrary = false;
- if (element.isClass()) {
- isClass = true;
- } else if (element.isLibrary()) {
- isLibrary = false;
+ if (element.isLibrary()) {
assert(invariant(element, emitStatics));
- } else {
+ } else if (!element.isClass()) {
throw new SpannableAssertionFailure(
element, 'Must be a ClassElement or a LibraryElement');
}
diff --git a/tests/compiler/dart2js/mirror_tree_shaking_test.dart b/tests/compiler/dart2js/mirror_tree_shaking_test.dart
index 5caab85..06e28d0 100644
--- a/tests/compiler/dart2js/mirror_tree_shaking_test.dart
+++ b/tests/compiler/dart2js/mirror_tree_shaking_test.dart
@@ -45,8 +45,8 @@
{});
asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
Expect.isFalse(compiler.compilationFailed);
- Expect.isFalse(compiler.enqueuer.resolution.hasEnqueuedEverything);
- Expect.isFalse(compiler.enqueuer.codegen.hasEnqueuedEverything);
+ Expect.isFalse(compiler.enqueuer.resolution.hasEnqueuedReflectiveElements);
+ Expect.isFalse(compiler.enqueuer.codegen.hasEnqueuedReflectiveElements);
Expect.isFalse(compiler.disableTypeInference);
Expect.isFalse(compiler.backend.hasRetainedMetadata);
}));
diff --git a/tests/lib/mirrors/unused_mirrors2_test.dart b/tests/lib/mirrors/unused_mirrors2_test.dart
new file mode 100644
index 0000000..8215464
--- /dev/null
+++ b/tests/lib/mirrors/unused_mirrors2_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that MirrorsUsed without usage of the static field does not crash
+// dart2js.
+
+library lib;
+
+@MirrorsUsed(targets: const ["lib"])
+import 'dart:mirrors';
+
+Bar foo = new Bar();
+
+typedef int FunctionTypeDef();
+
+class Bar {
+ final FunctionTypeDef gee;
+ Bar() : gee = (() => 499);
+}
+
+main() {
+ // Don't do anything.
+}
diff --git a/tests/lib/mirrors/unused_mirrors3_test.dart b/tests/lib/mirrors/unused_mirrors3_test.dart
new file mode 100644
index 0000000..4770bea
--- /dev/null
+++ b/tests/lib/mirrors/unused_mirrors3_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that MirrorsUsed without usage of the static field does not crash
+// dart2js.
+
+library lib;
+
+@MirrorsUsed(targets: const ["C"])
+import 'dart:mirrors';
+
+class C {
+ static Bar foo = new Bar();
+}
+
+typedef int FunctionTypeDef();
+
+class Bar {
+ final FunctionTypeDef gee;
+ Bar() : gee = (() => 499);
+}
+
+main() {
+ // Don't do anything.
+}
diff --git a/tests/lib/mirrors/unused_mirrors4_test.dart b/tests/lib/mirrors/unused_mirrors4_test.dart
new file mode 100644
index 0000000..936b5ef
--- /dev/null
+++ b/tests/lib/mirrors/unused_mirrors4_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that MirrorsUsed without usage of the static field does not crash
+// dart2js.
+
+@MirrorsUsed(targets: const ["foo"])
+import 'dart:mirrors';
+
+Bar get foo => new Bar();
+
+typedef int FunctionTypeDef();
+
+class Bar {
+ final FunctionTypeDef gee;
+ Bar() : gee = (() => 499);
+}
+
+main() {
+ // Don't do anything.
+}
diff --git a/tests/lib/mirrors/unused_mirrors5_test.dart b/tests/lib/mirrors/unused_mirrors5_test.dart
new file mode 100644
index 0000000..2c05029
--- /dev/null
+++ b/tests/lib/mirrors/unused_mirrors5_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that MirrorsUsed without usage of the static field does not crash
+// dart2js.
+
+library lib;
+
+@MirrorsUsed(targets: const ["lib"])
+import 'dart:mirrors';
+
+Bar get foo => new Bar();
+
+typedef int FunctionTypeDef();
+
+class Bar {
+ final FunctionTypeDef gee;
+ Bar() : gee = (() => 499);
+}
+
+main() {
+ // Don't do anything.
+}
diff --git a/tests/lib/mirrors/unused_mirrors6_test.dart b/tests/lib/mirrors/unused_mirrors6_test.dart
new file mode 100644
index 0000000..36d14d5
--- /dev/null
+++ b/tests/lib/mirrors/unused_mirrors6_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that MirrorsUsed without usage of the static field does not crash
+// dart2js.
+
+library lib;
+
+@MirrorsUsed(targets: const ["C"])
+import 'dart:mirrors';
+
+class C {
+ static Bar get foo => new Bar();
+}
+
+typedef int FunctionTypeDef();
+
+class Bar {
+ final FunctionTypeDef gee;
+ Bar() : gee = (() => 499);
+}
+
+main() {
+ // Don't do anything.
+}
diff --git a/tests/lib/mirrors/unused_mirrors7_test.dart b/tests/lib/mirrors/unused_mirrors7_test.dart
new file mode 100644
index 0000000..5d34940
--- /dev/null
+++ b/tests/lib/mirrors/unused_mirrors7_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that MirrorsUsed without usage of the static field does not crash
+// dart2js.
+
+@MirrorsUsed(targets: const ["NON_EXISTING_STATIC"])
+import 'dart:mirrors';
+
+Bar foo = new Bar();
+
+typedef int FunctionTypeDef();
+
+class Bar {
+ final FunctionTypeDef gee;
+ Bar() : gee = (() => 499);
+}
+
+main() {
+ // Don't do anything.
+}
diff --git a/tests/lib/mirrors/unused_mirrors8_test.dart b/tests/lib/mirrors/unused_mirrors8_test.dart
new file mode 100644
index 0000000..68a6f02
--- /dev/null
+++ b/tests/lib/mirrors/unused_mirrors8_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that MirrorsUsed without usage of the static field does not crash
+// dart2js.
+
+library lib;
+
+@MirrorsUsed(targets: const ["lib"])
+import 'dart:mirrors';
+
+class C {
+ static Bar foo = new Bar();
+}
+
+typedef int FunctionTypeDef();
+
+class Bar {
+ final FunctionTypeDef gee;
+ Bar() : gee = (() => 499);
+}
+
+main() {
+ // Don't do anything.
+}
diff --git a/tests/lib/mirrors/unused_mirrors9_test.dart b/tests/lib/mirrors/unused_mirrors9_test.dart
new file mode 100644
index 0000000..b1166cb
--- /dev/null
+++ b/tests/lib/mirrors/unused_mirrors9_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that MirrorsUsed without usage of the static field does not crash
+// dart2js.
+
+library lib;
+
+@MirrorsUsed(targets: const ["C.foo"])
+import 'dart:mirrors';
+
+class C {
+ static Bar foo = new Bar();
+}
+
+typedef int FunctionTypeDef();
+
+class Bar {
+ final FunctionTypeDef gee;
+ Bar() : gee = (() => 499);
+}
+
+main() {
+ // Don't do anything.
+}
diff --git a/tests/lib/mirrors/unused_mirrors_test.dart b/tests/lib/mirrors/unused_mirrors_test.dart
new file mode 100644
index 0000000..a8f9f14
--- /dev/null
+++ b/tests/lib/mirrors/unused_mirrors_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that MirrorsUsed without usage of the static field does not crash
+// dart2js.
+
+@MirrorsUsed(targets: const ["foo"])
+import 'dart:mirrors';
+
+Bar foo = new Bar();
+
+typedef int FunctionTypeDef();
+
+class Bar {
+ final FunctionTypeDef gee;
+ Bar() : gee = (() => 499);
+}
+
+main() {
+ // Don't do anything.
+}
diff --git a/tools/VERSION b/tools/VERSION
index b1c8afb..d31a8d9 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 2
PATCH 0
PRERELEASE 2
-PRERELEASE_PATCH 2
+PRERELEASE_PATCH 3