Dart 2 Libraries Wave 3

Add `typeArguments` to Invocation.
Add constructors to Invocation, making it less necessary for users to create their own implementations.
Add tests.
Add Symbol.unaryMinus and Symbol.empty constants.

Change-Id: I70cb3265f9413617cf57fce1297e393a29eeb26a
Reviewed-on: https://dart-review.googlesource.com/40741
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cc134e8..4d1f835 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -124,6 +124,10 @@
     `SECONDS_PER_DAY` to `secondsPerDay`,
     `MINUTES_PER_DAY` to `minutesPerDay`, and
     `ZERO` to `zero`.
+  * Added `typeArguments` to `Invocation` class.
+  * Added constructors to invocation class that allows creation of
+    `Invocation` objects directly, without going through `noSuchMethod`.
+  * Added `unaryMinus` and `empty` constant symbols on the `Symbol` class.
 
 * `dart:developer`
 
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
index b78c49f..9f59400 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
@@ -15,7 +15,7 @@
   final bool isGetter;
   final bool isSetter;
 
-  InvocationImpl(memberName, this.positionalArguments,
+  InvocationImpl(memberName, List<Object> positionalArguments,
       {namedArguments,
       List typeArguments,
       this.isMethod: false,
@@ -23,6 +23,7 @@
       this.isSetter: false})
       : memberName =
             isSetter ? _setterSymbol(memberName) : _dartSymbol(memberName),
+        positionalArguments = new List.unmodifiable(positionalArguments),
         namedArguments = _namedArgsToSymbols(namedArguments),
         typeArguments = typeArguments == null
             ? const []
diff --git a/pkg/front_end/testcases/shaker/empty_program.dart.outline.expect b/pkg/front_end/testcases/shaker/empty_program.dart.outline.expect
index 8e30b21..636512b 100644
--- a/pkg/front_end/testcases/shaker/empty_program.dart.outline.expect
+++ b/pkg/front_end/testcases/shaker/empty_program.dart.outline.expect
@@ -321,6 +321,7 @@
 }
 abstract class Invocation extends self::Object {
   abstract get memberName() → self::Symbol;
+  get typeArguments() → self::List<self::Type>;
   abstract get positionalArguments() → self::List<dynamic>;
   abstract get namedArguments() → self::Map<self::Symbol, dynamic>;
   abstract get isMethod() → self::bool;
diff --git a/pkg/front_end/testcases/shaker/empty_program.dart.shaker.expect b/pkg/front_end/testcases/shaker/empty_program.dart.shaker.expect
index 56ce3ff..3844c72 100644
--- a/pkg/front_end/testcases/shaker/empty_program.dart.shaker.expect
+++ b/pkg/front_end/testcases/shaker/empty_program.dart.shaker.expect
@@ -263,6 +263,7 @@
     - toRadixString
   - class Invocation
     - memberName
+    - typeArguments
     - positionalArguments
     - namedArguments
     - isMethod
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 26d8f3d..6ee28f1 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -294,7 +294,7 @@
   bool get isPrivate => _n(simpleName).startsWith('_');
 
   Symbol get qualifiedName => _computeQualifiedName(owner, simpleName);
-  Symbol get constructorName => const Symbol('');
+  Symbol get constructorName => Symbol.empty;
 
   TypeMirror get returnType => _target.type;
   List<ParameterMirror> get parameters {
diff --git a/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart b/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
index db3605e..7aebc9e 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
@@ -1602,7 +1602,7 @@
   bool get isPrivate => n(simpleName).startsWith('_');
 
   Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
-  Symbol get constructorName => const Symbol('');
+  Symbol get constructorName => Symbol.empty;
 
   TypeMirror get returnType => _target.type;
   List<ParameterMirror> get parameters {
@@ -2462,10 +2462,10 @@
   Symbol get constructorName {
     // TODO(ahe): I believe it is more appropriate to throw an exception or
     // return null.
-    if (!isConstructor) return const Symbol('');
+    if (!isConstructor) return Symbol.empty;
     String name = n(simpleName);
     int index = name.indexOf('.');
-    if (index == -1) return const Symbol('');
+    if (index == -1) return Symbol.empty;
     return s(name.substring(index + 1));
   }
 
diff --git a/sdk/lib/core/invocation.dart b/sdk/lib/core/invocation.dart
index 9e32581..3cae040 100644
--- a/sdk/lib/core/invocation.dart
+++ b/sdk/lib/core/invocation.dart
@@ -12,22 +12,77 @@
  * on it.
  */
 abstract class Invocation {
+  Invocation();
+
+  /**
+   * Creates an invocation corresponding to a method invocation.
+   *
+   * The method invocation has no type arguments.
+   * If the named arguments are omitted, they default to no named arguments.
+   */
+  factory Invocation.method(
+          Symbol memberName, Iterable<Object> positionalArguments,
+          [Map<Symbol, Object> namedArguments]) =>
+      new _Invocation.method(
+          memberName, null, positionalArguments, namedArguments);
+
+  /**
+   * Creates an invocation corresponding to a generic method invocation.
+   *
+   * If [typeArguments] is `null` or empty, the constructor is equivalent to
+   * calling [Invocation.method] with the remaining arguments.
+   * All the individual type arguments must be non-null.
+   *
+   * If the named arguments are omitted, they default to no named arguments.
+   */
+  factory Invocation.genericMethod(Symbol memberName,
+          Iterable<Type> typeArguments, Iterable<Object> positionalArguments,
+          [Map<Symbol, Object> namedArguments]) =>
+      new _Invocation.method(
+          memberName, typeArguments, positionalArguments, namedArguments);
+
+  /**
+   * Creates an invocation corresponding to a getter invocation.
+   */
+  factory Invocation.getter(Symbol name) = _Invocation.getter;
+
+  /**
+   * Creates an invocation corresponding to a setter invocation.
+   *
+   * This constructor accepts any [Symbol] as [memberName], but remember that
+   * *actual setter names* end in `=`, so the invocation corresponding
+   * to `object.member = value` is
+   * ```dart
+   * Invocation.setter(const Symbol("member="), value)
+   * ```
+   */
+  factory Invocation.setter(Symbol memberName, Object argument) =
+      _Invocation.setter;
+
   /** The name of the invoked member. */
   Symbol get memberName;
 
   /**
+   * An unmodifiable view of the type arguments of the call.
+   *
+   * If the member is a getter, setter or operator,
+   * the type argument list is always empty.
+   */
+  List<Type> get typeArguments => const <Type>[];
+
+  /**
    * An unmodifiable view of the positional arguments of the call.
    *
    * If the member is a getter, the positional arguments list is
-   * empty.
+   * always empty.
    */
-  List get positionalArguments;
+  List<dynamic> get positionalArguments;
 
   /**
    * An unmodifiable view of the named arguments of the call.
    *
-   * If the member is a getter, setter or operator, the named
-   * arguments map is empty.
+   * If the member is a getter, setter or operator,
+   * the named arguments map is always empty.
    */
   Map<Symbol, dynamic> get namedArguments;
 
@@ -52,3 +107,57 @@
   /** Whether the invocation was a getter or a setter call. */
   bool get isAccessor => isGetter || isSetter;
 }
+
+/** Implementation of [Invocation] used by its factory constructors. */
+class _Invocation implements Invocation {
+  final Symbol memberName;
+  final List<Type> typeArguments;
+  // Positional arguments is `null` for getters only.
+  final List<Object> _positional;
+  // Named arguments is `null` for accessors only.
+  final Map<Symbol, Object> _named;
+
+  _Invocation.method(this.memberName, Iterable<Type> types,
+      Iterable<Object> positional, Map<Symbol, Object> named)
+      : typeArguments = _ensureNonNullTypes(_makeUnmodifiable<Type>(types)),
+        _positional = _makeUnmodifiable<Object>(positional) ?? const <Object>[],
+        _named = (named == null || named.isEmpty)
+            ? const <Symbol, Object>{}
+            : new Map<Symbol, Object>.unmodifiable(named);
+
+  _Invocation.getter(this.memberName)
+      : typeArguments = const <Type>[],
+        _positional = null,
+        _named = null;
+
+  _Invocation.setter(this.memberName, Object argument)
+      : typeArguments = const <Type>[],
+        _positional = new List<Object>.unmodifiable([argument]),
+        _named = null;
+
+  List<dynamic> get positionalArguments => _positional ?? const <Object>[];
+
+  Map<Symbol, dynamic> get namedArguments => _named ?? const <Symbol, Object>{};
+
+  bool get isMethod => _named != null;
+  bool get isGetter => _positional == null;
+  bool get isSetter => _positional != null && _named == null;
+  bool get isAccessor => _named == null;
+
+  /// Checks that the elements of [types] are not null.
+  static List<Type> _ensureNonNullTypes(List<Type> types) {
+    if (types == null) return const <Type>[];
+    for (int i = 0; i < types.length; i++) {
+      if (types[i] == null) {
+        throw new ArgumentError(
+            "Type arguments must be non-null, was null at index $i.");
+      }
+    }
+    return types;
+  }
+
+  static List<T> _makeUnmodifiable<T>(Iterable<T> elements) {
+    if (elements == null) return null;
+    return new List<T>.unmodifiable(elements);
+  }
+}
diff --git a/sdk/lib/core/symbol.dart b/sdk/lib/core/symbol.dart
index e399d9c..ac0fc65 100644
--- a/sdk/lib/core/symbol.dart
+++ b/sdk/lib/core/symbol.dart
@@ -6,6 +6,17 @@
 
 /// Opaque name used by mirrors, invocations and [Function.apply].
 abstract class Symbol {
+  /** The symbol corresponding to the name of the unary minus operator. */
+  static const Symbol unaryMinus = const Symbol("unary-");
+
+  /**
+   * The empty symbol.
+   *
+   * The empty symbol is the name of libraries with no library declaration,
+   * and the base-name of the unnamed constructor.
+   */
+  static const Symbol empty = const Symbol("");
+
   /**
    * Constructs a new Symbol.
    *
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index b28fdcd..011448e 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -65,6 +65,9 @@
 string_case_test/01: Fail, OK # German double S.
 unicode_test: Fail
 
+[ $runtime != none ]
+nsm_invocation_generic_test: RuntimeError # Not implemented yet. Issue 27323.
+
 [ $runtime == safari ]
 double_round3_test: Fail, OK # Runtime rounds 0.49999999999999994 to 1.
 double_round_to_double2_test: Fail, OK # Runtime rounds 0.49999999999999994 to 1.
@@ -280,6 +283,7 @@
 list_test/none: RuntimeError
 list_unmodifiable_test: RuntimeError
 nan_infinity_test/01: RuntimeError
+nsm_invocation_test: RuntimeError # Symbols don't match due to minifiaction.
 queue_test: RuntimeError
 reg_exp_all_matches_test: RuntimeError
 reg_exp_start_end_test: RuntimeError
diff --git a/tests/corelib_2/invocation_test.dart b/tests/corelib_2/invocation_test.dart
new file mode 100644
index 0000000..286f12f
--- /dev/null
+++ b/tests/corelib_2/invocation_test.dart
@@ -0,0 +1,420 @@
+// Copyright (c) 2018, 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.
+
+import "package:expect/expect.dart";
+
+// Tests the constructors of the Invocation class.
+
+main() {
+  {
+    var name = "getter";
+    var invocation = new Invocation.getter(#name);
+    Expect.isTrue(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isTrue(invocation.isAccessor, "$name:isAccessor");
+    Expect.isFalse(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals([], invocation.typeArguments, "$name:types");
+    Expect.listEquals([], invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals({}, invocation.namedArguments, "$name: named");
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+  }
+  {
+    var name = "setter";
+    var argument = new Object();
+    var invocation = new Invocation.setter(const Symbol("name="), argument);
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isTrue(invocation.isSetter, "$name:isSetter");
+    Expect.isTrue(invocation.isAccessor, "$name:isAccessor");
+    Expect.isFalse(invocation.isMethod, "$name:isMethod");
+    Expect.equals(const Symbol("name="), invocation.memberName, "$name:name");
+    Expect.listEquals([], invocation.typeArguments, "$name:types");
+    Expect.listEquals([argument], invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals({}, invocation.namedArguments, "$name: named");
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+  }
+  {
+    var name = ".name()";
+    var invocation = new Invocation.method(#name, []);
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isFalse(invocation.isAccessor, "$name:isAccessor");
+    Expect.isTrue(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals([], invocation.typeArguments, "$name:types");
+    Expect.listEquals([], invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals({}, invocation.namedArguments, "$name: named");
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+
+    expectInvocation("$name:", invocation, new Invocation.method(#name, null));
+    expectInvocation(
+        "$name:", invocation, new Invocation.method(#name, [], null));
+    expectInvocation(
+        "$name:", invocation, new Invocation.method(#name, [], {}));
+
+    expectInvocation(
+        "$name:", invocation, new Invocation.genericMethod(#name, [], []));
+    expectInvocation(
+        "$name:", invocation, new Invocation.genericMethod(#name, [], null));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, [], [], null));
+    expectInvocation(
+        "$name:", invocation, new Invocation.genericMethod(#name, [], [], {}));
+    expectInvocation(
+        "$name:", invocation, new Invocation.genericMethod(#name, null, []));
+    expectInvocation(
+        "$name:", invocation, new Invocation.genericMethod(#name, null, null));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, null, [], null));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, null, [], {}));
+  }
+  {
+    var name = ".name(a)";
+    var argument = new Object();
+    var invocation = new Invocation.method(#name, [argument]);
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isFalse(invocation.isAccessor, "$name:isAccessor");
+    Expect.isTrue(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals([], invocation.typeArguments, "$name:types");
+    Expect.listEquals([argument], invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals({}, invocation.namedArguments, "$name: named");
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+
+    expectInvocation(
+        "$name:", invocation, new Invocation.method(#name, [argument], null));
+    expectInvocation(
+        "$name:", invocation, new Invocation.method(#name, [argument], {}));
+
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, [], [argument], null));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, [], [argument], {}));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, null, [argument], null));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, null, [argument], {}));
+  }
+  {
+    var name = ".name(a,b)";
+    var argument = new Object();
+    var argument2 = new Object();
+    var invocation = new Invocation.method(#name, [argument, argument2]);
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isFalse(invocation.isAccessor, "$name:isAccessor");
+    Expect.isTrue(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals([], invocation.typeArguments, "$name:types");
+    Expect.listEquals(
+        [argument, argument2], invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals({}, invocation.namedArguments, "$name: named");
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+
+    expectInvocation("$name:", invocation,
+        new Invocation.method(#name, [argument, argument2], null));
+    expectInvocation("$name:", invocation,
+        new Invocation.method(#name, [argument, argument2], {}));
+
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, [], [argument, argument2], null));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, [], [argument, argument2], {}));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, null, [argument, argument2], null));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, null, [argument, argument2], {}));
+  }
+  {
+    var name = ".name(a,b:)";
+    var argument = new Object();
+    var argument2 = new Object();
+    var invocation =
+        new Invocation.method(#name, [argument], {#arg: argument2});
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isFalse(invocation.isAccessor, "$name:isAccessor");
+    Expect.isTrue(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals([], invocation.typeArguments, "$name:types");
+    Expect.listEquals([argument], invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals(
+        {#arg: argument2}, invocation.namedArguments, "$name: named");
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+
+    expectInvocation(
+        "$name:",
+        invocation,
+        new Invocation.genericMethod(
+            #name, null, [argument], {#arg: argument2}));
+  }
+  {
+    var name = ".name(a:,b:)";
+    var argument = new Object();
+    var argument2 = new Object();
+    var invocation =
+        new Invocation.method(#name, [], {#arg: argument, #arg2: argument2});
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isFalse(invocation.isAccessor, "$name:isAccessor");
+    Expect.isTrue(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals([], invocation.typeArguments, "$name:types");
+    Expect.listEquals([], invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals({#arg: argument, #arg2: argument2},
+        invocation.namedArguments, "$name: named");
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+
+    expectInvocation("$name:", invocation,
+        new Invocation.method(#name, null, {#arg: argument, #arg2: argument2}));
+    expectInvocation(
+        "$name:",
+        invocation,
+        new Invocation.genericMethod(
+            #name, null, [], {#arg: argument, #arg2: argument2}));
+    expectInvocation(
+        "$name:",
+        invocation,
+        new Invocation.genericMethod(
+            #name, null, null, {#arg: argument, #arg2: argument2}));
+  }
+  {
+    var name = ".name<i>()";
+    var invocation = new Invocation.genericMethod(#name, [int], []);
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isFalse(invocation.isAccessor, "$name:isAccessor");
+    Expect.isTrue(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals([int], invocation.typeArguments, "$name:types");
+    Expect.listEquals([], invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals({}, invocation.namedArguments, "$name: named");
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+
+    expectInvocation(
+        "$name:", invocation, new Invocation.genericMethod(#name, [int], null));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, [int], [], null));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, [int], null, null));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, [int], [], {}));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, [int], null, {}));
+  }
+  {
+    var name = ".name<i>(a)";
+    var argument = new Object();
+    var invocation = new Invocation.genericMethod(#name, [int], [argument]);
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isFalse(invocation.isAccessor, "$name:isAccessor");
+    Expect.isTrue(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals([int], invocation.typeArguments, "$name:types");
+    Expect.listEquals([argument], invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals({}, invocation.namedArguments, "$name: named");
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, [int], [argument], null));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, [int], [argument], {}));
+  }
+  {
+    var name = ".name<i>(a,b)";
+    var argument = new Object();
+    var argument2 = new Object();
+    var invocation =
+        new Invocation.genericMethod(#name, [int], [argument, argument2]);
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isFalse(invocation.isAccessor, "$name:isAccessor");
+    Expect.isTrue(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals([int], invocation.typeArguments, "$name:types");
+    Expect.listEquals(
+        [argument, argument2], invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals({}, invocation.namedArguments, "$name: named");
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+
+    expectInvocation(
+        "$name:",
+        invocation,
+        new Invocation.genericMethod(
+            #name, [int], [argument, argument2], null));
+    expectInvocation("$name:", invocation,
+        new Invocation.genericMethod(#name, [int], [argument, argument2], {}));
+  }
+  {
+    var name = ".name<i>(a,b:)";
+    var argument = new Object();
+    var argument2 = new Object();
+    var invocation = new Invocation.genericMethod(
+        #name, [int], [argument], {#arg: argument2});
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isFalse(invocation.isAccessor, "$name:isAccessor");
+    Expect.isTrue(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals([int], invocation.typeArguments, "$name:types");
+    Expect.listEquals([argument], invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals(
+        {#arg: argument2}, invocation.namedArguments, "$name: named");
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+  }
+  {
+    var name = ".name<i>(a:,b:)";
+    var argument = new Object();
+    var argument2 = new Object();
+    var invocation = new Invocation.genericMethod(
+        #name, [int], [], {#arg: argument, #arg2: argument2});
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isFalse(invocation.isAccessor, "$name:isAccessor");
+    Expect.isTrue(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals([int], invocation.typeArguments, "$name:types");
+    Expect.listEquals([], invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals({#arg: argument, #arg2: argument2},
+        invocation.namedArguments, "$name: named");
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+
+    expectInvocation(
+        "$name:",
+        invocation,
+        new Invocation.genericMethod(
+            #name, [int], null, {#arg: argument, #arg2: argument2}));
+  }
+  {
+    // Many arguments.
+    var name = ".name<..>(..,..:)";
+    var argument = new Object();
+    var argument2 = new Object();
+    Type intList = new TypeHelper<List<int>>().type;
+    var invocation = new Invocation.genericMethod(
+        #name,
+        [int, double, intList],
+        [argument, argument2, null, argument],
+        {#arg: argument, #arg2: argument2, #arg3: null, #arg4: argument});
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isFalse(invocation.isAccessor, "$name:isAccessor");
+    Expect.isTrue(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals(
+        [int, double, intList], invocation.typeArguments, "$name:types");
+    Expect.listEquals([argument, argument2, null, argument],
+        invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals(
+        {#arg: argument, #arg2: argument2, #arg3: null, #arg4: argument},
+        invocation.namedArguments);
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+  }
+  {
+    // Accepts iterables, not just lists.
+    var name = "iterables";
+    var argument = new Object();
+    var argument2 = new Object();
+    Type intList = new TypeHelper<List<int>>().type;
+    var invocation = new Invocation.genericMethod(
+        #name,
+        [int, double, intList].where(kTrue),
+        [argument, argument2, null, argument].where(kTrue),
+        {#arg: argument, #arg2: argument2, #arg3: null, #arg4: argument});
+    Expect.isFalse(invocation.isGetter, "$name:isGetter");
+    Expect.isFalse(invocation.isSetter, "$name:isSetter");
+    Expect.isFalse(invocation.isAccessor, "$name:isAccessor");
+    Expect.isTrue(invocation.isMethod, "$name:isMethod");
+    Expect.equals(#name, invocation.memberName, "$name:name");
+    Expect.listEquals(
+        [int, double, intList], invocation.typeArguments, "$name:types");
+    Expect.listEquals([argument, argument2, null, argument],
+        invocation.positionalArguments, "$name:pos");
+    Expect.mapEquals(
+        {#arg: argument, #arg2: argument2, #arg3: null, #arg4: argument},
+        invocation.namedArguments);
+    checkUnmodifiableList("$name types", invocation.typeArguments);
+    checkUnmodifiableList("$name positional", invocation.positionalArguments);
+    checkUnmodifiableMap("$name named", invocation.namedArguments);
+  }
+  // No null type arguments.
+  Expect.throws(() {
+    new Invocation.genericMethod(#name, [null], []);
+  });
+  Expect.throws(() {
+    new Invocation.genericMethod(#name, [int, null], []);
+  });
+}
+
+void checkUnmodifiableList(String name, List<Object> list) {
+  if (list.isNotEmpty) {
+    Expect.throws(() {
+      list[0] = null;
+    }, null, "$name: list not unmodifiable");
+  }
+  Expect.throws(() {
+    list.add(null);
+  }, null, "$name: list not unmodifiable");
+}
+
+void checkUnmodifiableMap(String name, Map<Symbol, Object> map) {
+  Expect.throws(() {
+    map[#key] = null;
+  }, null, "$name: map not unmodifiable");
+}
+
+class TypeHelper<T> {
+  Type get type => T;
+}
+
+expectInvocation(String name, Invocation expect, Invocation actual) {
+  Expect.equals(expect.isGetter, actual.isGetter, "$name:isGetter");
+  Expect.equals(expect.isSetter, actual.isSetter, "$name:isSetter");
+  Expect.equals(expect.isAccessor, actual.isAccessor, "$name:isAccessor");
+  Expect.equals(actual.isGetter || actual.isSetter, actual.isAccessor);
+  Expect.equals(expect.isMethod, actual.isMethod, "$name:isMethod");
+  Expect.isTrue(actual.isMethod || actual.isGetter || actual.isSetter);
+  Expect.isFalse(actual.isMethod && actual.isGetter);
+  Expect.isFalse(actual.isMethod && actual.isSetter);
+  Expect.isFalse(actual.isSetter && actual.isGetter);
+  Expect.equals(expect.memberName, actual.memberName, "$name:memberName");
+  Expect.listEquals(expect.typeArguments, actual.typeArguments, "$name:types");
+  Expect.listEquals(
+      expect.positionalArguments, actual.positionalArguments, "$name:pos");
+  Expect.mapEquals(expect.namedArguments, actual.namedArguments, "$name:named");
+  checkUnmodifiableList(name, actual.typeArguments);
+  checkUnmodifiableList(name, actual.positionalArguments);
+  checkUnmodifiableMap(name, actual.namedArguments);
+}
+
+bool kTrue(_) => true;
diff --git a/tests/corelib_2/nsm_invocation_generic_test.dart b/tests/corelib_2/nsm_invocation_generic_test.dart
new file mode 100644
index 0000000..5813857
--- /dev/null
+++ b/tests/corelib_2/nsm_invocation_generic_test.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2018, 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.
+
+import "package:expect/expect.dart";
+
+// Test the invocations passed to noSuchMethod for generic invocations.
+
+main() {
+  var argument = new Object();
+  var argument2 = new Object();
+  // Method invocation.
+  expectInvocation(
+      new Invocation.genericMethod(#name, [int], []), nsm.name<int>());
+  expectInvocation(new Invocation.genericMethod(#name, [int], [argument]),
+      nsm.name<int>(argument));
+  expectInvocation(
+      new Invocation.genericMethod(#name, [int], [], {#arg: argument}),
+      nsm.name<int>(arg: argument));
+  expectInvocation(
+      new Invocation.genericMethod(#name, [int], [argument], {#arg: argument2}),
+      nsm.name<int>(argument, arg: argument));
+  // Call invocation.
+  expectInvocation(new Invocation.genericMethod(#call, [int], []), nsm<int>());
+  expectInvocation(new Invocation.genericMethod(#call, [int], [argument]),
+      nsm<int>(argument));
+  expectInvocation(
+      new Invocation.genericMethod(#call, [int], [], {#arg: argument}),
+      nsm<int>(arg: argument));
+  expectInvocation(
+      new Invocation.genericMethod(#call, [int], [argument], {#arg: argument2}),
+      nsm<int>(argument, arg: argument));
+}
+
+dynamic nsm = new Recorder();
+
+class Recorder {
+  noSuchMethod(Invocation invocation) {
+    return invocation;
+  }
+}
+
+void checkUnmodifiableList(List<Object> list) {
+  if (list.isNotEmpty) {
+    Expect.throws(() {
+      list[0] = null;
+    });
+  }
+  Expect.throws(() {
+    list.add(null);
+  });
+}
+
+void checkUnmodifiableMap(Map<Symbol, Object> map) {
+  Expect.throws(() {
+    map[#key] = null;
+  });
+}
+
+expectInvocation(Invocation expect, Invocation actual) {
+  Expect.equals(expect.isGetter, actual.isGetter, "isGetter");
+  Expect.equals(expect.isSetter, actual.isSetter, "isSetter");
+  Expect.equals(expect.isAccessor, actual.isAccessor, "isAccessor");
+  Expect.equals(actual.isGetter || actual.isSetter, actual.isAccessor);
+  Expect.equals(expect.isMethod, actual.isMethod, "isMethod");
+  Expect.isTrue(actual.isMethod || actual.isGetter || actual.isSetter);
+  Expect.isFalse(actual.isMethod && actual.isGetter);
+  Expect.isFalse(actual.isMethod && actual.isSetter);
+  Expect.isFalse(actual.isSetter && actual.isGetter);
+  Expect.equals(expect.memberName, actual.memberName, "memberName");
+  Expect.listEquals(expect.typeArguments, actual.typeArguments, "types");
+  Expect.listEquals(
+      expect.positionalArguments, actual.positionalArguments, "positional");
+  Expect.mapEquals(expect.namedArguments, actual.namedArguments, "named");
+  checkUnmodifiableList(actual.typeArguments);
+  checkUnmodifiableList(actual.positionalArguments);
+  checkUnmodifiableMap(actual.namedArguments);
+}
diff --git a/tests/corelib_2/nsm_invocation_test.dart b/tests/corelib_2/nsm_invocation_test.dart
new file mode 100644
index 0000000..8dc183c
--- /dev/null
+++ b/tests/corelib_2/nsm_invocation_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2018, 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.
+
+import "package:expect/expect.dart";
+
+// Tests the constructors of the Invocation class.
+
+main() {
+  var argument = new Object();
+  var argument2 = new Object();
+  // Getter Invocation.
+  expectInvocation(new Invocation.getter(#name), nsm.name);
+  // Setter Invocation.
+  expectInvocation(new Invocation.setter(const Symbol("name="), argument),
+      (nsm..name = argument).last);
+  // Method invocation.
+  expectInvocation(new Invocation.method(#name, []), nsm.name());
+  expectInvocation(
+      new Invocation.method(#name, [argument]), nsm.name(argument));
+  expectInvocation(new Invocation.method(#name, [], {#arg: argument}),
+      nsm.name(arg: argument));
+  expectInvocation(new Invocation.method(#name, [argument], {#arg: argument2}),
+      nsm.name(argument, arg: argument2));
+  // Operator invocation.
+  expectInvocation(new Invocation.method(#+, [argument]), nsm + argument);
+  expectInvocation(new Invocation.method(#-, [argument]), nsm - argument);
+  expectInvocation(new Invocation.method(#~, []), ~nsm);
+  expectInvocation(new Invocation.method(Symbol.unaryMinus, []), -nsm);
+  expectInvocation(new Invocation.method(#[], [argument]), nsm[argument]);
+  nsm[argument] = argument2;
+  expectInvocation(
+      new Invocation.method(#[]=, [argument, argument2]), nsm.last);
+  // Call invocation.
+  expectInvocation(new Invocation.method(#call, []), nsm());
+  expectInvocation(new Invocation.method(#call, [argument]), nsm(argument));
+  expectInvocation(
+      new Invocation.method(#call, [], {#arg: argument}), nsm(arg: argument));
+  expectInvocation(new Invocation.method(#call, [argument], {#arg: argument2}),
+      nsm(argument, arg: argument2));
+}
+
+dynamic nsm = new Recorder();
+
+class Recorder {
+  Invocation last;
+  noSuchMethod(Invocation invocation) {
+    return last = invocation;
+  }
+}
+
+void checkUnmodifiableList(List<Object> list) {
+  if (list.isNotEmpty) {
+    Expect.throws(() {
+      list[0] = null;
+    });
+  }
+  Expect.throws(() {
+    list.add(null);
+  });
+}
+
+void checkUnmodifiableMap(Map<Symbol, Object> map) {
+  Expect.throws(() {
+    map[#key] = null;
+  });
+}
+
+expectInvocation(Invocation expect, Invocation actual) {
+  Expect.equals(expect.isGetter, actual.isGetter, "isGetter");
+  Expect.equals(expect.isSetter, actual.isSetter, "isSetter");
+  Expect.equals(expect.isAccessor, actual.isAccessor, "isAccessor");
+  Expect.equals(actual.isGetter || actual.isSetter, actual.isAccessor);
+  Expect.equals(expect.isMethod, actual.isMethod, "isMethod");
+  Expect.isTrue(actual.isMethod || actual.isGetter || actual.isSetter);
+  Expect.isFalse(actual.isMethod && actual.isGetter);
+  Expect.isFalse(actual.isMethod && actual.isSetter);
+  Expect.isFalse(actual.isSetter && actual.isGetter);
+  Expect.equals(expect.memberName, actual.memberName, "memberName");
+  Expect.listEquals(expect.typeArguments, actual.typeArguments, "types");
+  Expect.listEquals(
+      expect.positionalArguments, actual.positionalArguments, "positional");
+  Expect.mapEquals(expect.namedArguments, actual.namedArguments, "named");
+  checkUnmodifiableList(actual.typeArguments);
+  checkUnmodifiableList(actual.positionalArguments);
+  checkUnmodifiableMap(actual.namedArguments);
+}
diff --git a/tests/corelib_2/symbol_operator_test.dart b/tests/corelib_2/symbol_operator_test.dart
index 62a394b..ac79499 100644
--- a/tests/corelib_2/symbol_operator_test.dart
+++ b/tests/corelib_2/symbol_operator_test.dart
@@ -26,7 +26,7 @@
   testSymbol(#==, new Symbol("=="), "=="); // Can't hit noSuchMethod.
   testSymbol(#[], $[$], "[]");
   testSymbol(#[]=, ($[$] = $).lastMember, "[]=");
-  testSymbol(const Symbol("unary-"), -$, "unary-");
+  testSymbol(Symbol.unaryMinus, -$, "unary-");
 
   testSymbolThrows(">>>"); // //# 03: ok
   testSymbolThrows("!"); //   //# 03: continued
diff --git a/tests/corelib_2/symbol_test.dart b/tests/corelib_2/symbol_test.dart
index 7a4d0e5..ec47d45 100644
--- a/tests/corelib_2/symbol_test.dart
+++ b/tests/corelib_2/symbol_test.dart
@@ -73,7 +73,7 @@
     throw "non-const Symbol's hashCode not equal to its const equivalent";
   }
 
-  if (new Symbol('') != const Symbol('')) {
+  if (new Symbol('') != Symbol.empty) {
     throw 'empty Symbol not equals to itself';
   }
 }
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 76fec0e..71846f3 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -792,7 +792,6 @@
 integer_division_by_zero_test: RuntimeError # Issue 29920; Expect.throws: Unexpected 'Unsupported operation: Infinity'
 internal_library_test/02: Crash
 invocation_mirror2_test: RuntimeError # UnimplementedError: JsInstanceMirror.delegate unimplemented
-invocation_mirror_empty_arguments_test: RuntimeError # Expect.throws(UnsupportedError) fails: Did not throw
 invocation_mirror_invoke_on2_test: RuntimeError # UnimplementedError: JsInstanceMirror.delegate unimplemented
 invocation_mirror_invoke_on_test: RuntimeError # UnimplementedError: JsInstanceMirror.delegate unimplemented
 invocation_mirror_test: RuntimeError # Type 'NativeJavaScriptObject' is not a subtype of type 'int' in strong mode
diff --git a/tests/language_2/redirecting_factory_reflection_test.dart b/tests/language_2/redirecting_factory_reflection_test.dart
index af39373..b1ae524 100644
--- a/tests/language_2/redirecting_factory_reflection_test.dart
+++ b/tests/language_2/redirecting_factory_reflection_test.dart
@@ -17,6 +17,6 @@
 
 main() {
   ClassMirror m = reflectClass(A);
-  var i = m.newInstance(const Symbol(''), []).reflectee;
+  var i = m.newInstance(Symbol.empty, []).reflectee;
   Expect.equals(i.t.toString(), 'A');
 }
diff --git a/tests/language_2/regress_28255_test.dart b/tests/language_2/regress_28255_test.dart
index 0441e8b..b127045 100644
--- a/tests/language_2/regress_28255_test.dart
+++ b/tests/language_2/regress_28255_test.dart
@@ -19,5 +19,5 @@
 }
 
 main() {
-  reflectClass(Class).newInstance(const Symbol(''), []).reflectee.foo();
+  reflectClass(Class).newInstance(Symbol.empty, []).reflectee.foo();
 }
diff --git a/tests/lib_2/mirrors/constructor_optional_args_test.dart b/tests/lib_2/mirrors/constructor_optional_args_test.dart
index 22a9acb..94f84f7 100644
--- a/tests/lib_2/mirrors/constructor_optional_args_test.dart
+++ b/tests/lib_2/mirrors/constructor_optional_args_test.dart
@@ -39,9 +39,9 @@
 
   ClassMirror cm = reflectClass(A);
 
-  var v1 = cm.newInstance(const Symbol(''), []).reflectee;
-  var v2 = cm.newInstance(const Symbol(''), [1]).reflectee;
-  var v3 = cm.newInstance(const Symbol(''), [2, 3]).reflectee;
+  var v1 = cm.newInstance(Symbol.empty, []).reflectee;
+  var v2 = cm.newInstance(Symbol.empty, [1]).reflectee;
+  var v3 = cm.newInstance(Symbol.empty, [2, 3]).reflectee;
 
   Expect.equals('B(x=x, y=y, z=null)', '$v1', 'unnamed 1');
   Expect.equals('B(x=1, y=y, z=null)', '$v2', 'unnamed 2');
diff --git a/tests/lib_2/mirrors/deferred_mirrors_metatarget_lib.dart b/tests/lib_2/mirrors/deferred_mirrors_metatarget_lib.dart
index 1c2ec2f..a5f49e2 100644
--- a/tests/lib_2/mirrors/deferred_mirrors_metatarget_lib.dart
+++ b/tests/lib_2/mirrors/deferred_mirrors_metatarget_lib.dart
@@ -18,5 +18,5 @@
 
 String foo() {
   ClassMirror a = currentMirrorSystem().findLibrary(#lib).declarations[#A];
-  return a.newInstance(const Symbol(""), []).invoke(#toString, []).reflectee;
+  return a.newInstance(Symbol.empty, []).invoke(#toString, []).reflectee;
 }
diff --git a/tests/lib_2/mirrors/invoke_named_test.dart b/tests/lib_2/mirrors/invoke_named_test.dart
index 242d064..1cc4806 100644
--- a/tests/lib_2/mirrors/invoke_named_test.dart
+++ b/tests/lib_2/mirrors/invoke_named_test.dart
@@ -122,21 +122,19 @@
   ClassMirror cm = reflectClass(E);
   InstanceMirror result;
 
-  result = cm.newInstance(const Symbol(''), ['X']);
+  result = cm.newInstance(Symbol.empty, ['X']);
   Expect.equals('X-B-null', result.reflectee.field);
-  result = cm.newInstance(const Symbol(''), ['X'], {const Symbol('b'): 'Y'});
+  result = cm.newInstance(Symbol.empty, ['X'], {const Symbol('b'): 'Y'});
   Expect.equals('X-Y-null', result.reflectee.field);
-  result = cm.newInstance(const Symbol(''), ['X'],
-      {const Symbol('c'): 'Z', const Symbol('b'): 'Y'});
+  result = cm.newInstance(
+      Symbol.empty, ['X'], {const Symbol('c'): 'Z', const Symbol('b'): 'Y'});
   Expect.equals('X-Y-Z', result.reflectee.field);
-  Expect.throwsNoSuchMethodError(() => cm.newInstance(const Symbol(''), []),
+  Expect.throwsNoSuchMethodError(() => cm.newInstance(Symbol.empty, []),
       'Insufficient positional arguments');
-  Expect.throwsNoSuchMethodError(
-      () => cm.newInstance(const Symbol(''), ['X', 'Y']),
+  Expect.throwsNoSuchMethodError(() => cm.newInstance(Symbol.empty, ['X', 'Y']),
       'Extra positional arguments');
   Expect.throwsNoSuchMethodError(
-      () =>
-          cm.newInstance(const Symbol(''), ['X'], {const Symbol('undef'): 'Y'}),
+      () => cm.newInstance(Symbol.empty, ['X'], {const Symbol('undef'): 'Y'}),
       'Unmatched named argument');
 
   result = cm.newInstance(const Symbol('b'), []);
diff --git a/tests/lib_2/mirrors/invoke_test.dart b/tests/lib_2/mirrors/invoke_test.dart
index b0b6117..a8be6e5 100644
--- a/tests/lib_2/mirrors/invoke_test.dart
+++ b/tests/lib_2/mirrors/invoke_test.dart
@@ -97,7 +97,7 @@
       () => cm.setField(const Symbol('doesntExist'), 'sbar'), 'Not defined');
 
   // ClassMirror invokeConstructor
-  result = cm.newInstance(const Symbol(''), []);
+  result = cm.newInstance(Symbol.empty, []);
   Expect.isTrue(result.reflectee is C);
   Expect.equals('default', result.reflectee.field);
   result = cm.newInstance(const Symbol('named'), ['my value']);
@@ -123,8 +123,8 @@
   Expect.equals('lget a priori', result.reflectee);
   result = lm.getField(const Symbol('libraryField'));
   Expect.equals('a priori', result.reflectee);
-  Expect.throwsNoSuchMethodError(() => lm.getField(const Symbol('doesntExist')),
-      'Not defined');
+  Expect.throwsNoSuchMethodError(
+      () => lm.getField(const Symbol('doesntExist')), 'Not defined');
 
   // LibraryMirror invokeSetter
   result = lm.setField(const Symbol('librarySetter'), 'lfoo');
diff --git a/tests/lib_2/mirrors/list_constructor_test.dart b/tests/lib_2/mirrors/list_constructor_test.dart
index ea78dbb..16f3c45 100644
--- a/tests/lib_2/mirrors/list_constructor_test.dart
+++ b/tests/lib_2/mirrors/list_constructor_test.dart
@@ -8,9 +8,9 @@
 
 main() {
   var cls = reflectClass(List);
-  Expect.throwsArgumentError(() => cls.newInstance(const Symbol(''), [null]));
+  Expect.throwsArgumentError(() => cls.newInstance(Symbol.empty, [null]));
 
-  var list = cls.newInstance(const Symbol(''), [42]).reflectee;
+  var list = cls.newInstance(Symbol.empty, [42]).reflectee;
   // Check that the list is fixed.
   Expect.equals(42, list.length);
   Expect.throwsUnsupportedError(() => list.add(2));
@@ -22,7 +22,7 @@
 
 testGrowableList() {
   var cls = reflectClass(List);
-  var list = cls.newInstance(const Symbol(''), []).reflectee;
+  var list = cls.newInstance(Symbol.empty, []).reflectee;
   // Check that the list is growable.
   Expect.equals(0, list.length);
   list.add(42);
diff --git a/tests/lib_2/mirrors/mirrors_resolve_fields_test.dart b/tests/lib_2/mirrors/mirrors_resolve_fields_test.dart
index e24d356..3725aa2 100644
--- a/tests/lib_2/mirrors/mirrors_resolve_fields_test.dart
+++ b/tests/lib_2/mirrors/mirrors_resolve_fields_test.dart
@@ -21,6 +21,6 @@
 main() {
   var mirrors = currentMirrorSystem();
   var classMirror = reflectClass(A);
-  var instanceMirror = classMirror.newInstance(const Symbol(''), []);
+  var instanceMirror = classMirror.newInstance(Symbol.empty, []);
   Expect.equals(A._STATE_INITIAL, instanceMirror.reflectee._state);
 }
diff --git a/tests/lib_2/mirrors/mirrors_test.dart b/tests/lib_2/mirrors/mirrors_test.dart
index 44f1467..378074f 100644
--- a/tests/lib_2/mirrors/mirrors_test.dart
+++ b/tests/lib_2/mirrors/mirrors_test.dart
@@ -119,7 +119,7 @@
 testInvokeConstructor(mirrors) {
   var classMirror = reflectClass(Class);
 
-  var instanceMirror = classMirror.newInstance(const Symbol(''), []);
+  var instanceMirror = classMirror.newInstance(Symbol.empty, []);
   expect(instanceMirror.reflectee is Class, equals(true));
   expect(instanceMirror.reflectee.field, equals("default value"));
 
@@ -149,7 +149,7 @@
   expect(classMirror is ClassMirror, equals(true));
   var symbolClassMirror = reflectClass(Symbol);
   var symbolMirror =
-      symbolClassMirror.newInstance(const Symbol(''), ['withInitialValue']);
+      symbolClassMirror.newInstance(Symbol.empty, ['withInitialValue']);
   var objectMirror = classMirror.newInstance(symbolMirror.reflectee, [1234]);
   expect(objectMirror.reflectee is Class, equals(true));
   expect(objectMirror.reflectee.field, equals(1234));
diff --git a/tests/lib_2/mirrors/new_instance_with_type_arguments_test.dart b/tests/lib_2/mirrors/new_instance_with_type_arguments_test.dart
index aa7df8a..5d227de 100644
--- a/tests/lib_2/mirrors/new_instance_with_type_arguments_test.dart
+++ b/tests/lib_2/mirrors/new_instance_with_type_arguments_test.dart
@@ -38,11 +38,10 @@
   Expect.equals(String, c_string.s);
   Expect.equals(dynamic, c_dynamic.s);
 
-  var reflective_a_int =
-      cmB.superclass.newInstance(const Symbol(''), []).reflectee;
-  var reflective_a_dynamic = cmA.newInstance(const Symbol(''), []).reflectee;
-  var reflective_b = cmB.newInstance(const Symbol(''), []).reflectee;
-  var reflective_c_dynamic = cmC.newInstance(const Symbol(''), []).reflectee;
+  var reflective_a_int = cmB.superclass.newInstance(Symbol.empty, []).reflectee;
+  var reflective_a_dynamic = cmA.newInstance(Symbol.empty, []).reflectee;
+  var reflective_b = cmB.newInstance(Symbol.empty, []).reflectee;
+  var reflective_c_dynamic = cmC.newInstance(Symbol.empty, []).reflectee;
 
   Expect.equals(int, reflective_a_int.t);
   Expect.equals(dynamic, reflective_a_dynamic.t);
diff --git a/tests/lib_2/mirrors/redirecting_factory_different_type_test.dart b/tests/lib_2/mirrors/redirecting_factory_different_type_test.dart
index 527765b..3c5b8ba 100644
--- a/tests/lib_2/mirrors/redirecting_factory_different_type_test.dart
+++ b/tests/lib_2/mirrors/redirecting_factory_different_type_test.dart
@@ -14,7 +14,7 @@
     String //# 01: compile-time error
     var    //# 02: compile-time error
     int    //# none: ok
-      x) = B; 
+      x) = B;
   A._();
 }
 
@@ -28,7 +28,7 @@
 main() {
   var cm = reflectClass(A);
   // The type-annotation in A's constructor must be ignored.
-  var b = cm.newInstance(const Symbol(''), [499]).reflectee;
+  var b = cm.newInstance(Symbol.empty, [499]).reflectee;
   Expect.equals(499, b.x);
-  Expect.throws(() => cm.newInstance(const Symbol(''), ["str"]), (e) => e is TypeError); 
+  Expect.throwsTypeError(() => cm.newInstance(Symbol.empty, ["str"]));
 }
diff --git a/tests/lib_2/mirrors/redirecting_factory_test.dart b/tests/lib_2/mirrors/redirecting_factory_test.dart
index 8a93d6b..78e7fe5 100644
--- a/tests/lib_2/mirrors/redirecting_factory_test.dart
+++ b/tests/lib_2/mirrors/redirecting_factory_test.dart
@@ -41,8 +41,8 @@
   factory Class.redirectingFactoryStringIntTypeParameters(a, b) =
       Class<String, int>.factoryNoOptional;
 
-  factory Class.redirectingFactoryStringTypeParameters(a, b) = Class
-        <String> // //# 02: static type warning
+  factory Class.redirectingFactoryStringTypeParameters(a, b) = Class //
+      <String> //# 02: static type warning
       .factoryNoOptional;
 
   factory Class.redirectingFactoryTypeParameters(a, b) =
@@ -55,7 +55,7 @@
 main() {
   var classMirror = reflectClass(Class);
 
-  var instanceMirror = classMirror.newInstance(const Symbol(''), [2]);
+  var instanceMirror = classMirror.newInstance(Symbol.empty, [2]);
   Expect.equals(2, instanceMirror.reflectee.field);
 
   instanceMirror =
diff --git a/tests/lib_2/mirrors/reflected_type_generics_test.dart b/tests/lib_2/mirrors/reflected_type_generics_test.dart
index e26a6a0..7557e8f 100644
--- a/tests/lib_2/mirrors/reflected_type_generics_test.dart
+++ b/tests/lib_2/mirrors/reflected_type_generics_test.dart
@@ -95,6 +95,6 @@
 
   // Instantiation of a generic class preserves type information:
   ClassMirror m = reflectType(A, [P]) as ClassMirror;
-  var instance = m.newInstance(const Symbol(""), []).reflectee;
+  var instance = m.newInstance(Symbol.empty, []).reflectee;
   Expect.equals(new A<P>().runtimeType, instance.runtimeType);
 }
diff --git a/tests/lib_2/mirrors/reflectively_instantiate_uninstantiated_class_test.dart b/tests/lib_2/mirrors/reflectively_instantiate_uninstantiated_class_test.dart
index b19bfc2..6282bda 100644
--- a/tests/lib_2/mirrors/reflectively_instantiate_uninstantiated_class_test.dart
+++ b/tests/lib_2/mirrors/reflectively_instantiate_uninstantiated_class_test.dart
@@ -14,7 +14,7 @@
 main() {
   // Do NOT instantiate Foo.
   var m = reflectClass(Foo);
-  var instance = m.newInstance(const Symbol(''), []);
+  var instance = m.newInstance(Symbol.empty, []);
   print(instance);
   bool threw = false;
   try {
diff --git a/tests/lib_2/mirrors/syntax_error_test.dart b/tests/lib_2/mirrors/syntax_error_test.dart
index 96d912e..686e06e 100644
--- a/tests/lib_2/mirrors/syntax_error_test.dart
+++ b/tests/lib_2/mirrors/syntax_error_test.dart
@@ -25,5 +25,5 @@
 
 main() {
   reflectClass(A).metadata;
-  reflectClass(B).newInstance(const Symbol(''), []);
+  reflectClass(B).newInstance(Symbol.empty, []);
 }