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